3 <meta http-equiv=
"Content-Type" content=
"text/html; charset=US-ASCII">
4 <title>Actors in Detail
</title>
5 <link rel=
"stylesheet" href=
"../../../../../../doc/src/boostbook.css" type=
"text/css">
6 <meta name=
"generator" content=
"DocBook XSL Stylesheets V1.75.2">
7 <link rel=
"home" href=
"../../index.html" title=
"Chapter 1. Phoenix 3.2.0">
8 <link rel=
"up" href=
"../inside.html" title=
"Inside Phoenix">
9 <link rel=
"prev" href=
"../inside.html" title=
"Inside Phoenix">
10 <link rel=
"next" href=
"expression.html" title=
"Phoenix Expressions">
12 <body bgcolor=
"white" text=
"black" link=
"#0000FF" vlink=
"#840084" alink=
"#0000FF">
13 <table cellpadding=
"2" width=
"100%"><tr>
14 <td valign=
"top"><img alt=
"Boost C++ Libraries" width=
"277" height=
"86" src=
"../../../../../../boost.png"></td>
15 <td align=
"center"><a href=
"../../../../../../index.html">Home
</a></td>
16 <td align=
"center"><a href=
"../../../../../../libs/libraries.htm">Libraries
</a></td>
17 <td align=
"center"><a href=
"http://www.boost.org/users/people.html">People
</a></td>
18 <td align=
"center"><a href=
"http://www.boost.org/users/faq.html">FAQ
</a></td>
19 <td align=
"center"><a href=
"../../../../../../more/index.htm">More
</a></td>
22 <div class=
"spirit-nav">
23 <a accesskey=
"p" href=
"../inside.html"><img src=
"../../../../../../doc/src/images/prev.png" alt=
"Prev"></a><a accesskey=
"u" href=
"../inside.html"><img src=
"../../../../../../doc/src/images/up.png" alt=
"Up"></a><a accesskey=
"h" href=
"../../index.html"><img src=
"../../../../../../doc/src/images/home.png" alt=
"Home"></a><a accesskey=
"n" href=
"expression.html"><img src=
"../../../../../../doc/src/images/next.png" alt=
"Next"></a>
26 <div class=
"titlepage"><div><div><h3 class=
"title">
27 <a name=
"phoenix.inside.actor"></a><a class=
"link" href=
"actor.html" title=
"Actors in Detail">Actors in Detail
</a>
28 </h3></div></div></div>
30 <a name=
"phoenix.inside.actor.h0"></a>
31 <span><a name=
"phoenix.inside.actor.actor"></a></span><a class=
"link" href=
"actor.html#phoenix.inside.actor.actor">Actor
</a>
34 The main concept is the
<code class=
"computeroutput"><span class=
"identifier">Actor
</span></code>.
35 An
<code class=
"computeroutput"><span class=
"identifier">Actor
</span></code> is a model of the
36 <a href=
"http://www.boost.org/doc/libs/release/libs/fusion/doc/html/fusion/functional/concepts/poly.html" target=
"_top">Polymorphic
37 Function Object
</a> concept (that can accept
0 to N arguments (where
38 N is a predefined maximum).
41 An
<code class=
"computeroutput"><span class=
"identifier">Actor
</span></code> contains a valid
42 Phoenix Expression, a call to one of the function call operator overloads,
43 starts the evaluation process.
45 <div class=
"note"><table border=
"0" summary=
"Note">
47 <td rowspan=
"2" align=
"center" valign=
"top" width=
"25"><img alt=
"[Note]" src=
"../../../../../../doc/src/images/note.png"></td>
48 <th align=
"left">Note
</th>
50 <tr><td align=
"left" valign=
"top"><p>
51 You can set
<code class=
"computeroutput"><span class=
"identifier">BOOST_PHOENIX_LIMIT
</span></code>,
52 the predefined maximum arity an actor can take. By default,
<code class=
"computeroutput"><span class=
"identifier">BOOST_PHOENIX_LIMIT
</span></code> is set to
10.
56 The
<code class=
"computeroutput"><span class=
"identifier">actor
</span></code> template class
57 models the
<code class=
"computeroutput"><span class=
"identifier">Actor
</span></code> concept:
59 <pre class=
"programlisting"><span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">Expr
</span><span class=
"special">></span>
60 <span class=
"keyword">struct
</span> <span class=
"identifier">actor
</span>
61 <span class=
"special">{
</span>
62 <span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">Sig
</span><span class=
"special">></span>
63 <span class=
"keyword">struct
</span> <span class=
"identifier">result
</span><span class=
"special">;
</span>
65 <span class=
"keyword">typename
</span> <span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">actor
</span><span class=
"special"><</span><span class=
"identifier">Expr
</span><span class=
"special">>::
</span><span class=
"identifier">type
</span>
66 <span class=
"keyword">operator
</span><span class=
"special">()()
</span> <span class=
"keyword">const
</span><span class=
"special">;
</span>
68 <span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">T0
</span><span class=
"special">></span>
69 <span class=
"keyword">typename
</span> <span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">actor
</span><span class=
"special"><</span><span class=
"identifier">Expr
</span><span class=
"special">,
</span> <span class=
"identifier">T0
</span> <span class=
"special">&>::
</span><span class=
"identifier">type
</span>
70 <span class=
"keyword">operator
</span><span class=
"special">()(
</span><span class=
"identifier">T0
</span><span class=
"special">&</span> <span class=
"identifier">_0
</span><span class=
"special">)
</span> <span class=
"keyword">const
</span><span class=
"special">;
</span>
72 <span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">T0
</span><span class=
"special">></span>
73 <span class=
"keyword">typename
</span> <span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">actor
</span><span class=
"special"><</span><span class=
"identifier">Expr
</span><span class=
"special">,
</span> <span class=
"identifier">T0
</span> <span class=
"keyword">const
</span> <span class=
"special">&>::
</span><span class=
"identifier">type
</span>
74 <span class=
"keyword">operator
</span><span class=
"special">()(
</span><span class=
"identifier">T0
</span> <span class=
"keyword">const
</span> <span class=
"special">&</span> <span class=
"identifier">_0
</span><span class=
"special">)
</span> <span class=
"keyword">const
</span><span class=
"special">;
</span>
76 <span class=
"comment">//...
</span>
77 <span class=
"special">};
</span>
80 <a name=
"phoenix.inside.actor.t0"></a><p class=
"title"><b>Table
 1.9.
 Actor Concept Requirements
</b></p>
81 <div class=
"table-contents"><table class=
"table" summary=
"Actor Concept Requirements">
102 <code class=
"computeroutput"><span class=
"identifier">actor
</span><span class=
"special">(
</span><span class=
"identifier">arg0
</span><span class=
"special">,
</span>
103 <span class=
"identifier">arg1
</span><span class=
"special">,
</span>
104 <span class=
"special">...,
</span> <span class=
"identifier">argN
</span><span class=
"special">)
</span></code>
109 Function call operators to start the evaluation
116 <code class=
"computeroutput"><span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">result_of
</span><span class=
"special"><</span><span class=
"identifier">Actor
</span><span class=
"special"><</span><span class=
"identifier">Expr
</span><span class=
"special">>(
</span><span class=
"identifier">Arg0
</span><span class=
"special">,
</span>
117 <span class=
"identifier">Arg1
</span><span class=
"special">,
</span>
118 <span class=
"special">...,
</span> <span class=
"identifier">ArgN
</span><span class=
"special">)
>::
</span><span class=
"identifier">type
</span></code>
123 Result of the evaluation
130 <code class=
"computeroutput"><span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">actor
</span><span class=
"special"><</span><span class=
"identifier">Expr
</span><span class=
"special">,
</span>
131 <span class=
"identifier">Arg0
</span><span class=
"special">,
</span>
132 <span class=
"identifier">Arg1
</span><span class=
"special">,
</span>
133 <span class=
"special">...,
</span> <span class=
"identifier">ArgN
</span><span class=
"special">>::
</span><span class=
"identifier">type
</span></code>
138 Result of the evaluation
145 <br class=
"table-break"><h5>
146 <a name=
"phoenix.inside.actor.h1"></a>
147 <span><a name=
"phoenix.inside.actor.function_call_operators"></a></span><a class=
"link" href=
"actor.html#phoenix.inside.actor.function_call_operators">Function
151 There are
2*N function call operators for
0 to N arguments (N ==
<code class=
"computeroutput"><span class=
"identifier">BOOST_PHOENIX_LIMIT
</span></code>). The actor class accepts
152 the arguments and forwards the arguments to the default evaluation action.
155 Additionally, there exist function call operators accepting permutations
156 of const and non-const references. These operators are created for all N
157 <=
<code class=
"computeroutput"><span class=
"identifier">BOOST_PHOENIX_PERFECT_FORWARD_LIMIT
</span></code>
158 (which defaults to
3).
160 <div class=
"note"><table border=
"0" summary=
"Note">
162 <td rowspan=
"2" align=
"center" valign=
"top" width=
"25"><img alt=
"[Note]" src=
"../../../../../../doc/src/images/note.png"></td>
163 <th align=
"left">Note
</th>
165 <tr><td align=
"left" valign=
"top">
167 <span class=
"bold"><strong>Forwarding Function Problem
</strong></span>
170 There is a known issue with current C++ called the
"<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/
2002/n1385.htm
" target="_top
">Forwarding
171 Function Problem</a>". The problem is that given an arbitrary
172 function
<code class=
"computeroutput"><span class=
"identifier">F
</span></code>, using current
173 C++ language rules, one cannot create a forwarding function
<code class=
"computeroutput"><span class=
"identifier">FF
</span></code> that transparently assumes the arguments
174 of
<code class=
"computeroutput"><span class=
"identifier">F
</span></code>.
179 <a name=
"phoenix.inside.actor.h2"></a>
180 <span><a name=
"phoenix.inside.actor.context"></a></span><a class=
"link" href=
"actor.html#phoenix.inside.actor.context">Context
</a>
183 On an actor function call, before calling the evaluation function, the actor
184 created a
<span class=
"bold"><strong>context
</strong></span>. This context consists
185 of an
<code class=
"computeroutput"><span class=
"identifier">Environment
</span></code> and an
186 <code class=
"computeroutput"><span class=
"identifier">Action
</span></code> part. These contain
187 all information necessary to evaluate the given expression.
190 <a name=
"phoenix.inside.actor.t1"></a><p class=
"title"><b>Table
 1.10.
 Context Concept Requirements
</b></p>
191 <div class=
"table-contents"><table class=
"table" summary=
"Context Concept Requirements">
212 <code class=
"computeroutput"><span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">context
</span><span class=
"special"><</span><span class=
"identifier">Env
</span><span class=
"special">,
</span>
213 <span class=
"identifier">Actions
</span><span class=
"special">>::
</span><span class=
"identifier">type
</span></code>
225 <code class=
"computeroutput"><span class=
"identifier">context
</span><span class=
"special">(
</span><span class=
"identifier">e
</span><span class=
"special">,
</span>
226 <span class=
"identifier">a
</span><span class=
"special">)
</span></code>
231 A Context containing environment
<code class=
"computeroutput"><span class=
"identifier">e
</span></code>
232 and actions
<code class=
"computeroutput"><span class=
"identifier">a
</span></code>
239 <code class=
"computeroutput"><span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">env
</span><span class=
"special"><</span><span class=
"identifier">Context
</span><span class=
"special">>::
</span><span class=
"identifier">type
</span></code>
244 Type of the contained Environment
251 <code class=
"computeroutput"><span class=
"identifier">env
</span><span class=
"special">(
</span><span class=
"identifier">ctx
</span><span class=
"special">)
</span></code>
263 <code class=
"computeroutput"><span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">actions
</span><span class=
"special"><</span><span class=
"identifier">Context
</span><span class=
"special">>::
</span><span class=
"identifier">type
</span></code>
268 Type of the contained Actions
275 <code class=
"computeroutput"><span class=
"identifier">actions
</span><span class=
"special">(
</span><span class=
"identifier">ctx
</span><span class=
"special">)
</span></code>
287 <br class=
"table-break"><h5>
288 <a name=
"phoenix.inside.actor.h3"></a>
289 <span><a name=
"phoenix.inside.actor.environment"></a></span><a class=
"link" href=
"actor.html#phoenix.inside.actor.environment">Environment
</a>
292 The Environment is a model of
<a href=
"http://www.boost.org/doc/libs/release/libs/fusion/doc/html/fusion/sequence/concepts/random_access_sequence.html" target=
"_top">Random
296 The arguments passed to the actor's function call operator are collected
297 inside the Environment:
300 <span class=
"inlinemediaobject"><img src=
"../../images/funnel_in.png"></span>
303 Other parts of the library (e.g. the scope module) extends the
<code class=
"computeroutput"><span class=
"identifier">Environment
</span></code> concept to hold other information
304 such as local variables, etc.
307 <a name=
"phoenix.inside.actor.h4"></a>
308 <span><a name=
"phoenix.inside.actor.actions"></a></span><a class=
"link" href=
"actor.html#phoenix.inside.actor.actions">Actions
</a>
311 Actions is the part of Phoenix which are responsible for giving the actual
312 expressions a specific behaviour. During the traversal of the Phoenix Expression
313 Tree these actions are called whenever a specified rule in the grammar matches.
315 <pre class=
"programlisting"><span class=
"keyword">struct
</span> <span class=
"identifier">actions
</span>
316 <span class=
"special">{
</span>
317 <span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">Rule
</span><span class=
"special">></span>
318 <span class=
"keyword">struct
</span> <span class=
"identifier">when
</span><span class=
"special">;
</span>
319 <span class=
"special">};
</span>
322 The nested
<code class=
"computeroutput"><span class=
"identifier">when
</span></code> template
323 is required to be
<a href=
"http://www.boost.org/doc/libs/release/doc/html/PrimitiveTransform.html" target=
"_top">Proto
324 Primitive Transform
</a>. No worries, you don't have to learn
<a href=
"http://www.boost.org/doc/libs/release/libs/proto/index.html" target=
"_top">Boost.Proto
</a>
325 just yet! Phoenix provides some wrappers to let you define simple actions
326 without the need to dive deep into proto.
329 Phoenix ships with a predefined
<code class=
"computeroutput"><span class=
"identifier">default_actions
</span></code>
330 class that evaluates the expressions with C++ semantics:
332 <pre class=
"programlisting"><span class=
"keyword">struct
</span> <span class=
"identifier">default_actions
</span>
333 <span class=
"special">{
</span>
334 <span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">Rule
</span><span class=
"special">,
</span> <span class=
"keyword">typename
</span> <span class=
"identifier">Dummy
</span> <span class=
"special">=
</span> <span class=
"keyword">void
</span><span class=
"special">></span>
335 <span class=
"keyword">struct
</span> <span class=
"identifier">when
</span>
336 <span class=
"special">:
</span> <span class=
"identifier">proto
</span><span class=
"special">::
</span><span class=
"identifier">_default
</span><span class=
"special"><</span><span class=
"identifier">meta_grammar
</span><span class=
"special">></span>
337 <span class=
"special">{};
</span>
338 <span class=
"special">};
</span>
341 For more information on how to use the default_actions class and how to attach
342 custom actions to the evaluation process, see
<a class=
"link" href=
"actions.html" title=
"More on Actions">more
346 <a name=
"phoenix.inside.actor.h5"></a>
347 <span><a name=
"phoenix.inside.actor.evaluation"></a></span><a class=
"link" href=
"actor.html#phoenix.inside.actor.evaluation">Evaluation
</a>
349 <pre class=
"programlisting"><span class=
"keyword">struct
</span> <span class=
"identifier">evaluator
</span>
350 <span class=
"special">{
</span>
351 <span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">Expr
</span><span class=
"special">,
</span> <span class=
"keyword">typename
</span> <span class=
"identifier">Context
</span><span class=
"special">></span>
352 <span class=
"emphasis"><em>unspecified
</em></span> <span class=
"keyword">operator
</span><span class=
"special">()(
</span><span class=
"identifier">Expr
</span> <span class=
"special">&,
</span> <span class=
"identifier">Context
</span> <span class=
"special">&);
</span>
353 <span class=
"special">};
</span>
355 <span class=
"identifier">evaluator
</span> <span class=
"keyword">const
</span> <span class=
"identifier">eval
</span> <span class=
"special">=
</span> <span class=
"special">{};
</span>
358 The evaluation of a Phoenix expression is started by a call to the function
359 call operator of
<code class=
"computeroutput"><span class=
"identifier">evaluator
</span></code>.
362 The evaluator is called by the
<code class=
"computeroutput"><span class=
"identifier">actor
</span></code>
363 function operator overloads after the context is built up. For reference,
364 here is a typical
<code class=
"computeroutput"><span class=
"identifier">actor
</span><span class=
"special">::
</span><span class=
"keyword">operator
</span><span class=
"special">()
</span></code>
365 that accepts two arguments:
367 <pre class=
"programlisting"><span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">T0
</span><span class=
"special">,
</span> <span class=
"keyword">typename
</span> <span class=
"identifier">T1
</span><span class=
"special">></span>
368 <span class=
"keyword">typename
</span> <span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">actor
</span><span class=
"special"><</span><span class=
"identifier">Expr
</span><span class=
"special">,
</span> <span class=
"identifier">T0
</span> <span class=
"special">&,
</span> <span class=
"identifier">T1
</span> <span class=
"special">&>::
</span><span class=
"identifier">type
</span>
369 <span class=
"keyword">operator
</span><span class=
"special">()(
</span><span class=
"identifier">T0
</span> <span class=
"special">&</span><span class=
"identifier">t0
</span><span class=
"special">,
</span> <span class=
"identifier">T1
</span> <span class=
"special">&</span><span class=
"identifier">t1
</span><span class=
"special">)
</span> <span class=
"keyword">const
</span>
370 <span class=
"special">{
</span>
371 <span class=
"identifier">fusion
</span><span class=
"special">::
</span><span class=
"identifier">vector2
</span><span class=
"special"><</span><span class=
"identifier">T0
</span> <span class=
"special">&,
</span> <span class=
"identifier">T1
</span> <span class=
"special">&></span> <span class=
"identifier">env
</span><span class=
"special">(
</span><span class=
"identifier">t0
</span><span class=
"special">,
</span> <span class=
"identifier">t1
</span><span class=
"special">);
</span>
373 <span class=
"keyword">return
</span> <span class=
"identifier">eval
</span><span class=
"special">(*
</span><span class=
"keyword">this
</span><span class=
"special">,
</span> <span class=
"identifier">context
</span><span class=
"special">(
</span><span class=
"identifier">env
</span><span class=
"special">,
</span> <span class=
"identifier">default_actions
</span><span class=
"special">()));
</span>
374 <span class=
"special">}
</span>
377 <a name=
"phoenix.inside.actor.h6"></a>
378 <span><a name=
"phoenix.inside.actor.result_of__actor"></a></span><a class=
"link" href=
"actor.html#phoenix.inside.actor.result_of__actor">result_of::actor
</a>
381 For reasons of symmetry to the family of
<code class=
"computeroutput"><span class=
"identifier">actor
</span><span class=
"special">::
</span><span class=
"keyword">operator
</span><span class=
"special">()
</span></code> there is a special metafunction usable
382 for actor result type calculation named
<code class=
"computeroutput"><span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">actor
</span></code>.
383 This metafunction allows us to directly specify the types of the parameters
384 to be passed to the
<code class=
"computeroutput"><span class=
"identifier">actor
</span><span class=
"special">::
</span><span class=
"keyword">operator
</span><span class=
"special">()
</span></code> function. Here's a typical
<code class=
"computeroutput"><span class=
"identifier">actor_result
</span></code> that accepts two arguments:
386 <pre class=
"programlisting"><span class=
"keyword">namespace
</span> <span class=
"identifier">result_of
</span>
387 <span class=
"special">{
</span>
388 <span class=
"keyword">template
</span> <span class=
"special"><</span><span class=
"keyword">typename
</span> <span class=
"identifier">Expr
</span><span class=
"special">,
</span> <span class=
"keyword">typename
</span> <span class=
"identifier">T0
</span><span class=
"special">,
</span> <span class=
"keyword">typename
</span> <span class=
"identifier">T1
</span><span class=
"special">></span>
389 <span class=
"keyword">struct
</span> <span class=
"identifier">actor
</span>
390 <span class=
"special">{
</span>
391 <span class=
"keyword">typedef
</span> <span class=
"identifier">fusion
</span><span class=
"special">::
</span><span class=
"identifier">vector2
</span><span class=
"special"><</span><span class=
"identifier">T0
</span><span class=
"special">,
</span> <span class=
"identifier">T1
</span><span class=
"special">></span> <span class=
"identifier">env_tpe
</span><span class=
"special">;
</span>
392 <span class=
"keyword">typedef
</span> <span class=
"keyword">typename
</span> <span class=
"identifier">result_of
</span><span class=
"special">::
</span><span class=
"identifier">context
</span><span class=
"special"><</span><span class=
"identifier">env_type
</span><span class=
"special">,
</span> <span class=
"identifier">default_actions
</span><span class=
"special">>::
</span><span class=
"identifier">type
</span> <span class=
"identifier">ctx_type
</span>
393 <span class=
"keyword">typedef
</span> <span class=
"keyword">typename
</span> <span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">result_of
</span><span class=
"special"><</span><span class=
"identifier">evaluator
</span><span class=
"special">(
</span><span class=
"identifier">Expr
</span> <span class=
"keyword">const
</span><span class=
"special">&,
</span> <span class=
"identifier">ctx_type
</span><span class=
"special">)
>::
</span><span class=
"identifier">type
</span> <span class=
"identifier">type
</span><span class=
"special">;
</span>
394 <span class=
"special">};
</span>
395 <span class=
"special">}
</span>
398 <table xmlns:
rev=
"http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width=
"100%"><tr>
399 <td align=
"left"></td>
400 <td align=
"right"><div class=
"copyright-footer">Copyright
© 2002-
2005,
2010,
2014,
2015 Joel de Guzman, Dan Marsden, Thomas
401 Heller, John Fletcher
<p>
402 Distributed under the Boost Software License, Version
1.0. (See accompanying
403 file LICENSE_1_0.txt or copy at
<a href=
"http://www.boost.org/LICENSE_1_0.txt" target=
"_top">http://www.boost.org/LICENSE_1_0.txt
</a>)
408 <div class=
"spirit-nav">
409 <a accesskey=
"p" href=
"../inside.html"><img src=
"../../../../../../doc/src/images/prev.png" alt=
"Prev"></a><a accesskey=
"u" href=
"../inside.html"><img src=
"../../../../../../doc/src/images/up.png" alt=
"Up"></a><a accesskey=
"h" href=
"../../index.html"><img src=
"../../../../../../doc/src/images/home.png" alt=
"Home"></a><a accesskey=
"n" href=
"expression.html"><img src=
"../../../../../../doc/src/images/next.png" alt=
"Next"></a>