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 1.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 1.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