• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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