]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/phoenix/doc/inside/expression.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / phoenix / doc / inside / expression.qbk
CommitLineData
7c673cae
FG
1[/==============================================================================
2 Copyright (C) 2001-2010 Joel de Guzman
3 Copyright (C) 2001-2005 Dan Marsden
4 Copyright (C) 2001-2010 Thomas Heller
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8===============================================================================/]
9
10[section:expression Phoenix Expressions]
11
12A Phoenix Expression is a model of the __proto_expr__ Concept. These expressions
13are wrapped inside an [link phoenix.inside.actor Actor] template. The `actor` provides
14the function call operator which evaluates the expressions.
15The `actor` is the domain specific wrapper around Phoenix expressions.
16
17By design, Phoenix Expressions do not carry any information on how they will be
18evaluated later on. They are the data structure on which the `Actions` will work.
19
20The library provides a convenience template to define expressions:
21
22 template <template <typename> Actor, typename Tag, typename A0, ..., typename A1>
23 struct expr_ext
24 : proto::transform<expr_ext<Actor, Tag, A0, ..., A1> >
25 {
26 typedef __unspecified__ base_expr;
27 typedef Actor<base_expr> type;
28
29 typedef __unspecified__ proto_grammar;
30
31 static type make(A0 a0, ..., A1 a1);
32 };
33
34 template <typename Tag, typename A0, ..., typename A1>
35 struct expr : expr_ext<actor, Tag, A0, ..., A1> {};
36
37[*Notation]
38[variablelist
39 [[`A0...AN`] [Child node types]]
40 [[`a0...aN`] [Child node objects]]
41 [[`G0...GN`] [__proto__ grammar types]]
42]
43
44[*Expression Semantics]
45[table
46 [[Expression] [Semantics]]
47 [[`expr<Tag, A0...AN>::type`] [The type of Expression having tag `Tag` and `A0...AN` children]]
48 [[`expr<Tag, G0...GN>`] [A __proto__ grammar and __proto_pass_through_transform__]]
49 [[`expr<Tag, A0...AN>::make(a0...aN)`] [Returns a Phoenix Expression]]
50]
51
52[note
53 You might have noticed the template template argument `Actor` used in
54 `expr_ext`. This can be a user supplied custom Actor adding other member
55 functions or objects than the default `actor` template. See
56 [link phoenix.examples.extending_actors Extending Actors] for more details.
57]
58
59[heading meta_grammar]
60
61Defining expressions is only part of the game to make it a valid Phoenix Expression.
62In order to use the expressions in the Phoenix domain, we need to "register" them
63to our grammar.
64
65The `meta_grammar` is a struct for exactly that purpose. It is an openly extendable __proto__ Grammar:
66
67 struct meta_grammar
68 : proto::switch_<meta_grammar>
69 {
70 template <typename Tag, typename Dummy>
71 struct case_
72 : proto::not_<proto::_>
73 {};
74 };
75
76As you can see, by default the `meta_grammar` matches nothing. With every [link phoenix.modules Module]
77you include this grammar gets extended by various expressions.
78
79[heading Example]
80
81Define an expression:
82
83 template <typename Lhs, typename Rhs>
84 struct plus
85 : expr<proto::tag::plus, Lhs, Rhs>
86 {};
87
88And add it to the grammar:
89
90 template <>
91 struct meta_grammar::case_<proto::tag::plus>
92 : enable_rule<
93 plus<
94 meta_grammar
95 , meta_grammar
96 >
97 >
98 {};
99
100Define a generator function to make the life of our potential users easier:
101
102 template <typename Lhs, typename Rhs>
103 typename plus<Lhs, Rhs>::type
104 plus(Lhs const & lhs, Rhs const & rhs)
105 {
106 return expression::plus<Lhs, Rhs>::make(lhs, rhs);
107 }
108
109Look if it really works:
110
111 plus(6, 5)();
112
113returns 11!
114
115 proto::display_expr(plus(5, 6));
116
117prints:
118
119 plus(
120 terminal(6)
121 , terminal(5)
122 )
123
124See [@../../example/define_expression.cpp define_expression.cpp] for the full example.
125
126[note
127 The example shown here only works because `default_actions` knows how to handle
128 an expression having the `proto::tag::plus` and two children. This is because
129 `default_actions` uses the `proto::_default<meta_grammar>` transform to
130 evaluate operators and functions. Learn more about actions
131 [link phoenix.inside.actions here].
132]
133
134[section Boilerplate Macros]
135
136When having more and more expressions, you start to realize that this is a very
137repetetive task. Phoenix provides boilerplate macros that make defining Phoenix
138Expressions as you have seen in the
139[link phoenix.inside.expression previous section] look like a piece of cake.
140
141
142[/
143These expressions generate the following:
144* A tag (in the underlying namespace tag)
145* An expression
146* an expression type in namespace expression
147]
148
149[section BOOST_PHOENIX_DEFINE_EXPRESSION]
150
151[heading Description]
152
153`BOOST_PHOENIX_DEFINE_EXPRESSION` is a macro that can be used to generate all the
154necessary boilerplate to create Phoenix Expressions
155
156[heading Synopsis]
157
158 BOOST_PHOENIX_DEFINE_EXPRESSION(
159 (namespace_seq)(name)
160 , (child_grammar0)
161 (child_grammar1)
162 ...
163 )
164
165[heading Semantics]
166
167The above macro generates the necessary code for an expression `name` in
168namespace `namespace_seq`. The sequence of `(child_grammarN)` declares how many
169children the expression will have and what `proto::grammar` they match.
170
171The macro should be used at global scope. `namespace_seq` shall be the sequence
172of namespaces under which the following symbols will be defined:
173
174 namespace tag
175 {
176 struct name;
177 }
178
179 namespace expression
180 {
181 template <typename A0, typename A1 ... typename AN>
182 struct name
183 : boost::phoenix::expr<
184 tag::name
185 , A0
186 , A1
187 ...
188 , AN
189 >
190 }
191
192 namespace rule
193 {
194 struct name
195 : boost::phoenix::expr<
196 child_grammar0
197 , child_grammar1
198 ...
199 , child_grammarN
200 >
201 {};
202 }
203
204 namespace functional
205 {
206 struct make_name; // A polymorphic function object that can be called to create the expression node
207 }
208
209 namespace result_of
210 {
211 template <typename A0, typename A1 ... typename AN>
212 struct make_name; // The result type of the expression node
213 }
214
215 // convenience polymorphic function to create an expression node
216 template <typename A0, typename A1 ... typename AN>
217 result_of::make_name<A0, A1 ... AN>
218 make_name(A0 const & a0, A1 const & a1 ... AN const & an);
219
220This macros also adds a specialization for `meta_grammar::case_<tag::name>` to
221enable the rule for further use in actions.
222
223[heading Header]
224
225 #include <boost/phoenix/core/expression.hpp>
226
227[heading Example]
228
229The example from the previous section can be rewritten as:
230
231 BOOST_PHOENIX_DEFINE_EXPRESSION(
232 (plus)
233 , (meta_grammar) // Lhs
234 (meta_grammar) // Rhs
235 )
236
237 template <typename Lhs, typename Rhs>
238 typename plus<Lhs, Rhs>::type
239 plus(Lhs const & lhs, Rhs const & rhs)
240 {
241 return expression::plus<Lhs, Rhs>::make(lhs, rhs);
242 }
243
244[endsect]
245
246[section BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG]
247
248[heading Description]
249
250`BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG` is a macro that can be used to generate all the
251necessary boilerplate to create Phoenix Expressions
252
253[heading Synopsis]
254
255 BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG(
256 (namespace_seq)(name)
257 , (child_grammar0)
258 (child_grammar1)
259 ...
260 (child_grammarN)
261 , N
262 )
263
264[heading Semantics]
265
266The above macro generates the necessary code for an expression `name` in
267namespace `namespace_seq`. `N` is the maximum number of variable children.
268All but the last elements in the grammar sequence are required children of
269the expression, and the last denotes a variable number of children. The number
270of children an expression of this kind can hold is therefor `N-1` plus the size of
271the sequence
272
273The macro should be used at global scope. `namespace_seq` shall be the sequence
274of namespaces under which the following symbols will be defined:
275
276 namespace tag
277 {
278 struct name;
279 }
280
281 namespace expression
282 {
283 template <typename A0, typename A1 ... typename AN>
284 struct name
285 : boost::phoenix::expr<
286 tag::name
287 , A0
288 , A1
289 ...
290 , AN
291 >
292 {};
293 }
294
295 namespace rule
296 {
297 struct name
298 : expression::name<
299 child_grammar0
300 , child_grammar1
301 ...
302 , proto::vararg<child_grammarN>
303 >
304 {};
305 }
306
307 namespace functional
308 {
309 struct make_name; // A polymorphic function object that can be called to create the expression node
310 }
311
312 namespace result_of
313 {
314 template <typename A0, typename A1 ... typename AN>
315 struct make_name; // The result type of the expression node
316 }
317
318 // convenience polymorphic function to create an expression node
319 template <typename A0, typename A1 ... typename AN>
320 result_of::make_name<A0, A1 ... AN>
321 make_name(A0 const & a0, A1 const & a1 ... AN const & an);
322
323This macros also adds a specialization for `meta_grammar::case_<tag::name>` to
324enable the rule for further use in actions.
325
326[heading Header]
327
328 #include <boost/phoenix/core/expression.hpp>
329
330[heading Example]
331
332 BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG(
333 (boost)(phoenix)(mem_fun_ptr)
334 , (meta_grammar) // Pointer to Object
335 (meta_grammar) // Member pointer
336 (meta_grammar) // Variable number of arguments
337 , BOOST_PHOENIX_LIMIT
338 )
339
340This defines the member function pointer operator expression as described in
341[link phoenix.modules.operator operators].
342
343[endsect]
344
345[section BOOST_PHOENIX_DEFINE_EXPRESSION_EXT]
346
347[heading Description]
348
349`BOOST_PHOENIX_DEFINE_EXPRESSION_EXT` is a macro that can be used to generate all the
350necessary boilerplate to create Phoenix Expressions
351
352[heading Synopsis]
353
354 BOOST_PHOENIX_DEFINE_EXPRESSION_EXT(
355 actor
356 , (namespace_seq)(name)
357 , (child_grammar0)
358 (child_grammar1)
359 ...
360 (child_grammarN)
361 , N
362 )
363
364[heading Semantics]
365
366The above macro generates the necessary code for an expression `name` in
367namespace `namespace_seq`. The sequence of `(child_grammarN)` declares how many
368children the expression will have and what `proto::grammar` they match.
369
370The macro should be used at global scope. `namespace_seq` shall be the sequence
371of namespaces under which the following symbols will be defined:
372
373 namespace tag
374 {
375 struct name;
376 }
377
378 namespace expression
379 {
380 template <typename A0, typename A1 ... typename AN>
381 struct name
382 : boost::phoenix::expr_ext<
383 actor
384 , tag::name
385 , A0
386 , A1
387 ...
388 , AN
389 >
390 }
391
392 namespace rule
393 {
394 struct name
395 : boost::phoenix::expr<
396 child_grammar0
397 , child_grammar1
398 ...
399 , child_grammarN
400 >
401 {};
402 }
403
404 namespace functional
405 {
406 struct make_name; // A polymorphic function object that can be called to create the expression node
407 }
408
409 namespace result_of
410 {
411 template <typename A0, typename A1 ... typename AN>
412 struct make_name; // The result type of the expression node
413 }
414
415 // convenience polymorphic function to create an expression node
416 template <typename A0, typename A1 ... typename AN>
417 result_of::make_name<A0, A1 ... AN>
418 make_name(A0 const & a0, A1 const & a1 ... AN const & an);
419
420This macros also adds a specialization for `meta_grammar::case_<tag::name>` to
421enable the rule for further use in actions.
422
423[heading Header]
424
425 #include <boost/phoenix/core/expression.hpp>
426
427[heading Example]
428
429 BOOST_PHOENIX_DEFINE_EXPRESSION_EXT(
430 if_actor
431 , (boost)(phoenix)(if_)
432 , (meta_grammar) // Cond
433 (meta_grammar) // Then
434 )
435
436This defines the if_ expression. The custom actor defines `else_` as a member.
437
438[endsect]
439
440[section BOOST_PHOENIX_DEFINE_EXPRESSION_EXT_VARARG]
441
442[heading Description]
443
444`BOOST_PHOENIX_DEFINE_EXPRESSION_EXT_VARARG` is a macro that can be used to generate all the
445necessary boilerplate to create Phoenix Expressions
446
447[heading Synopsis]
448
449 BOOST_PHOENIX_DEFINE_EXPRESSION_EXT_VARARG(
450 actor
451 , (namespace_seq)(name)
452 , (child_grammar0)
453 (child_grammar1)
454 ...
455 (child_grammarN)
456 , N
457 )
458
459[heading Semantics]
460
461The above macro generates the necessary code for an expression `name` in
462namespace `namespace_seq`. `N` is the maximum number of variable children.
463All but the last elements in the grammar sequence are required children of
464the expression, and the last denotes a variable number of children. The number
465of children an expression of this kind can hold is therefor `N-1` plus the size of
466the sequence
467
468The macro should be used at global scope. `namespace_seq` shall be the sequence
469of namespaces under which the following symbols will be defined:
470
471 namespace tag
472 {
473 struct name;
474 }
475
476 namespace expression
477 {
478 template <typename A0, typename A1 ... typename AN>
479 struct name
480 : boost::phoenix::expr_ext<
481 actor
482 , tag::name
483 , A0
484 , A1
485 ...
486 , AN
487 >
488 {};
489 }
490
491 namespace rule
492 {
493 struct name
494 : expression::name<
495 child_grammar0
496 , child_grammar1
497 ...
498 , proto::vararg<child_grammarN>
499 >
500 {};
501 }
502
503 namespace functional
504 {
505 struct make_name; // A polymorphic function object that can be called to create the expression node
506 }
507
508 namespace result_of
509 {
510 template <typename A0, typename A1 ... typename AN>
511 struct make_name; // The result type of the expression node
512 }
513
514 // convenience polymorphic function to create an expression node
515 template <typename A0, typename A1 ... typename AN>
516 result_of::make_name<A0, A1 ... AN>
517 make_name(A0 const & a0, A1 const & a1 ... AN const & an);
518
519This macros also adds a specialization for `meta_grammar::case_<tag::name>` to
520enable the rule for further use in actions.
521
522[heading Header]
523
524 #include <boost/phoenix/core/expression.hpp>
525
526[heading Example]
527
528TBD
529
530[endsect]
531
532[endsect]
533
534[endsect]