1[section:concepts Concepts] 2 3[heading Expression] 4 5_Expr_ is the central concept in _yap_. It must contain at least an _kind_ 6and a _tuple_ of values. 7 8Here is a summary of the requirements on _Expr_. In the tables below, `E` is 9a type that models _Expr_; `e` is an object of type `E`; `Tuple` is an 10instantiation of _tuple_; and `t` is an object of type `Tuple`. 11 12[table Expression Requirements 13 [[Expression] [Type] [Description] [Notes]] 14 [[`E::kind`] [_kind_] [ The kind of expression `E` is. ] [ Must be a compile-time constant. ]] 15 [[`e.elements`] [`Tuple`] [ The child expressions of `e`. ] [ The types of the elements must be appropriate to the kind of the expression. ]] 16 [[`E e{t}`] [] [ Construction/initialization of `e`. ] [ `t` must be stored in `e.elements`. ]] 17] 18 19As stated above, the `elements` data member must match the kind of the expression: 20 21[table Expression Requirements 22 [[`E::kind`] [`hana::size(e.elements)`] [Possible Tuple Element Types] [Notes]] 23 24 [[`expr_kind::expr_ref`] [1] [ Any non-_expr_ref_ _Expr_. ] []] 25 [[`expr_kind::terminal`] [1] [ Any non-_Expr_. ] [A terminal with a _placeholder_ value will be treated as a placeholder. ]] 26 [[Any unary operator] [1] [ Any _Expr_. ] []] 27 [[Any binary operator] [2] [ Any _Expr_. ] []] 28 [[`expr_kind::if_else`] [3] [ Any _Expr_. ] []] 29 [[`expr_kind::call`] [Any number >= 1.] [ Any _Expr_. ] []] 30] 31 32[heading ExpressionTemplate] 33 34_ExprTmpl_ is any template with two parameters that, when instantiated with an 35_kind_ and a _tuple_, results in an _Expr_. 36 37[heading Transform] 38 39_xform_ takes a _XForm_ as its second parameter. A _XForm_ is a _Callable_ 40that takes expressions and returns values of unconstrained type. There are 41two sorts of overloads _XForm_ may use: _ExprXForm_ and _TagXForm_. 42 43A _XForm_ may have any number of overloads, including none. 44 45[heading ExpressionTransform] 46 47_ExprXForm_ takes an _Expr_ as its only parameter. Here are some examples. 48 49This one takes any _Expr_: 50 51 struct xform 52 { 53 template <typename Expr> 54 auto operator() (Expr const & expr) 55 { 56 // ... 57 } 58 }; 59 60This one takes any type of _Expr_ that satisfies the constraints imposed by 61its template parameters: 62 63 template <typename Expr1, typename Expr2, typename Expr3> 64 decltype(auto) xform ( 65 boost::yap::expression< 66 boost::yap::expr_kind::plus, 67 boost::hana::tuple< 68 boost::yap::expression< 69 boost::yap::expr_kind::multiplies, 70 boost::hana::tuple< 71 Expr1, 72 Expr2 73 > 74 >, 75 Expr3 76 > 77 > const & expr 78 ) { 79 // ... 80 } 81 82This one takes only a specific type: 83 84 decltype(auto) xform ( 85 decltype(term<number>{{0.0}} * number{} + number{}) const & expr 86 ) { 87 // ... 88 } 89 90[heading TagTransform] 91 92_TagXForm_ takes a tag-type as its first parameter, and the individual 93elements of an expression as the remaining parameters. 94 95Tags are named such that the tag for an expression with _kind_ 96`expr_kind::foo` is named `foo_tag`. Here are some examples. 97 98This one takes any terminal that contains a `user::number` (or reference to 99such a terminal): 100 101 struct xform 102 { 103 decltype(auto) operator() (boost::yap::terminal_tag, user::number const & n) 104 { 105 // ... 106 } 107 }; 108 109This one takes any plus expression that contains a pair of `user::number` 110terminals (or references to terminals): 111 112 decltype(auto) xform (boost::yap::plus_tag, user::number lhs, user::number rhs) 113 { 114 // ... 115 } 116 117This one takes any negation expression: 118 119 struct xform 120 { 121 template <typename Expr> 122 decltype(auto) operator() (boost::yap::negate_tag, Expr const & expr) 123 { 124 // ... 125 } 126 }; 127 128This one takes any call expression with two terminals (or references to 129terminals) containing values convertible to `double`: 130 131 struct xform 132 { 133 decltype(auto) operator() (boost::yap::call_tag, tag_type, double a, double b) 134 { 135 // ... 136 } 137 } 138 139[endsect] 140