Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

Concepts

Expression

Expression is the central concept in Boost.YAP. It must contain at least an expr_kind and a boost::hana::tuple<> of values.

Here is a summary of the requirements on Expression. In the tables below, E is a type that models Expression; e is an object of type E; Tuple is an instantiation of boost::hana::tuple<>; and t is an object of type Tuple.

Table 45.6. Expression Requirements

Expression

Type

Description

Notes

E::kind

expr_kind

The kind of expression E is.

Must be a compile-time constant.

e.elements

Tuple

The child expressions of e.

The types of the elements must be appropriate to the kind of the expression.

E e{t}

Construction/initialization of e.

t must be stored in e.elements.


As stated above, the elements data member must match the kind of the expression:

Table 45.7. Expression Requirements

E::kind

hana::size(e.elements)

Possible Tuple Element Types

Notes

expr_kind::expr_ref

1

Any non-expr_kind::expr_ref Expression.

expr_kind::terminal

1

Any non-Expression.

A terminal with a placeholder<> value will be treated as a placeholder.

Any unary operator

1

Any Expression.

Any binary operator

2

Any Expression.

expr_kind::if_else

3

Any Expression.

expr_kind::call

Any number >= 1.

Any Expression.


ExpressionTemplate

ExpressionTemplate is any template with two parameters that, when instantiated with an expr_kind and a boost::hana::tuple<>, results in an Expression.

Transform

transform() takes a Transform as its second parameter. A Transform is a Callable that takes expressions and returns values of unconstrained type. There are two sorts of overloads Transform may use: ExpressionTransform and TagTransform.

A Transform may have any number of overloads, including none.

ExpressionTransform

ExpressionTransform takes an Expression as its only parameter. Here are some examples.

This one takes any Expression:

struct xform
{
    template <typename Expr>
    auto operator() (Expr const & expr)
    {
        // ...
    }
};

This one takes any type of Expression that satisfies the constraints imposed by its template parameters:

template <typename Expr1, typename Expr2, typename Expr3>
decltype(auto) xform (
    boost::yap::expression<
        boost::yap::expr_kind::plus,
        boost::hana::tuple<
            boost::yap::expression<
                boost::yap::expr_kind::multiplies,
                boost::hana::tuple<
                    Expr1,
                    Expr2
                >
            >,
            Expr3
        >
    > const & expr
) {
    // ...
}

This one takes only a specific type:

decltype(auto) xform (
    decltype(term<number>{{0.0}} * number{} + number{}) const & expr
) {
    // ...
}

TagTransform

TagTransform takes a tag-type as its first parameter, and the individual elements of an expression as the remaining parameters.

Tags are named such that the tag for an expression with expr_kind expr_kind::foo is named foo_tag. Here are some examples.

This one takes any terminal that contains a user::number (or reference to such a terminal):

struct xform
{
    decltype(auto) operator() (boost::yap::terminal_tag, user::number const & n)
    {
        // ...
    }
};

This one takes any plus expression that contains a pair of user::number terminals (or references to terminals):

decltype(auto) xform (boost::yap::plus_tag, user::number lhs, user::number rhs)
{
    // ...
}

This one takes any negation expression:

struct xform
{
    template <typename Expr>
    decltype(auto) operator() (boost::yap::negate_tag, Expr const & expr)
    {
        // ...
    }
};

This one takes any call expression with two terminals (or references to terminals) containing values convertible to double:

struct xform
{
    decltype(auto) operator() (boost::yap::call_tag, tag_type, double a, double b)
    {
        // ...
    }
}

PrevUpHomeNext