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 an older version of Boost and was released in 2021. The current version is 1.90.0.
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 48.6. Expression Requirements
|
Expression |
Type |
Description |
Notes |
|---|---|---|---|
|
|
The kind of expression |
Must be a compile-time constant. |
|
|
|
|
The child expressions of |
The types of the elements must be appropriate to the kind of the expression. |
|
|
Construction/initialization of |
|
As stated above, the elements
data member must match the kind of the expression:
Table 48.7. Expression Requirements
|
|
|
Possible Tuple Element Types |
Notes |
|---|---|---|---|
|
|
1 |
Any non- |
|
|
|
1 |
Any non-Expression. |
A terminal with a |
|
Any unary operator |
1 |
Any Expression. |
|
|
Any binary operator |
2 |
Any Expression. |
|
|
|
3 |
Any Expression. |
|
|
|
Any number >= 1. |
Any Expression. |
ExpressionTemplate
is any template with two parameters that, when instantiated with an expr_kind
and a boost::hana::tuple<>, results in an Expression.
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 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 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) { // ... } }