File: actor.qbk

package info (click to toggle)
boost1.88 1.88.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 576,932 kB
  • sloc: cpp: 4,149,234; xml: 136,789; ansic: 35,092; python: 33,910; asm: 5,698; sh: 4,604; ada: 1,681; makefile: 1,633; pascal: 1,139; perl: 1,124; sql: 640; yacc: 478; ruby: 271; java: 77; lisp: 24; csh: 6
file content (206 lines) | stat: -rw-r--r-- 6,377 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
[/==============================================================================
    Copyright (C) 2001-2010 Joel de Guzman
    Copyright (C) 2001-2005 Dan Marsden
    Copyright (C) 2001-2010 Thomas Heller

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
===============================================================================/]

[section:actor Actors in Detail]

[heading Actor]

The main concept is the `Actor`. An `Actor` is a model of the __PFO__ concept
(that can accept 0 to N arguments (where N is a predefined maximum).

An `Actor` contains a valid Phoenix Expression, a call to one of the function
call operator overloads, starts the evaluation process.

[note You can set `BOOST_PHOENIX_LIMIT`, the predefined maximum arity an
actor can take. By default, `BOOST_PHOENIX_LIMIT` is set to 10.]

The `actor` template class models the `Actor` concept:

    template <typename Expr>
    struct actor
    {
        template <typename Sig>
        struct result;

        typename result_of::actor<Expr>::type
        operator()() const;

        template <typename T0>
        typename result_of::actor<Expr, T0 &>::type
        operator()(T0& _0) const;

        template <typename T0>
        typename result_of::actor<Expr, T0 const &>::type
        operator()(T0 const & _0) const;

        //...
    };

[table Actor Concept Requirements
    [
     [Expression]
     [Semantics]
    ]
    [
     [`actor(arg0, arg1, ..., argN)`]
     [Function call operators to start the evaluation]
    ]
    [
     [`boost::result_of<Actor<Expr>(Arg0, Arg1, ..., ArgN)>::type`]
     [Result of the evaluation]
    ]
    [
     [`result_of::actor<Expr, Arg0, Arg1, ..., ArgN>::type`]
     [Result of the evaluation]
    ]
]

[heading Function Call Operators]

There are 2*N function call operators for 0 to N arguments (N == `BOOST_PHOENIX_LIMIT`).
The actor class accepts the arguments and forwards the arguments to the default
evaluation action.

Additionally, there exist function call operators accepting permutations of const
and non-const references. These operators are created for all N <=
`BOOST_PHOENIX_PERFECT_FORWARD_LIMIT` (which defaults to 3).

[def $http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm]

[note *Forwarding Function Problem*

    There is a known issue with current C++ called the "__forwarding__".
    The problem is that given an arbitrary function `F`, using current C++
    language rules, one cannot create a forwarding function `FF` that
    transparently assumes the arguments of `F`.
]

[heading Context]

On an actor function call, before calling the evaluation function, the actor created a *context*.
This context consists of an `Environment` and an `Action` part. These contain all information
necessary to evaluate the given expression.

[table Context Concept Requirements
    [
     [Expression]
     [Semantics]
    ]
    [
     [`result_of::context<Env, Actions>::type`]
     [Type of a Context]
    ]
    [
     [`context(e, a)`]
     [A Context containing environment `e` and actions `a`]
    ]
    [
     [`result_of::env<Context>::type`]
     [Type of the contained Environment]
    ]
    [
     [`env(ctx)`]
     [The environment]
    ]
    [
     [`result_of::actions<Context>::type`]
     [Type of the contained Actions]
    ]
    [
     [`actions(ctx)`]
     [The actions]
    ]
]

[heading Environment]

The Environment is a model of __random_access__.

The arguments passed to the actor's function call operator are collected inside the Environment:

[$images/funnel_in.png]

Other parts of the library (e.g. the scope module) extends the `Environment`
concept to hold other information such as local variables, etc.

[heading Actions]

Actions is the part of Phoenix which are responsible for giving the actual expressions
a specific behaviour. During the traversal of the Phoenix Expression Tree these actions
are called whenever a specified rule in the grammar matches.

    struct actions
    {
        template <typename Rule>
        struct when;
    };

The nested `when` template is required to be __proto_primitive_transform__. No
worries, you don't have to learn __proto__ just yet! Phoenix provides some wrappers
to let you define simple actions without the need to dive deep into proto.

Phoenix ships with a predefined `default_actions` class that evaluates the expressions with
C++ semantics:

    struct default_actions
    {
        template <typename Rule, typename Dummy = void>
        struct when
            : proto::_default<meta_grammar>
        {};
    };

For more information on how to use the default_actions class and how to attach custom actions
to the evaluation process, see [link phoenix.inside.actions more on actions].

[heading Evaluation]

    struct evaluator
    {
        template <typename Expr, typename Context>
        __unspecified__ operator()(Expr &, Context &);
    };

    evaluator const eval = {};

The evaluation of a Phoenix expression is started by a call to the function call operator of
`evaluator`.

The evaluator is called by the `actor` function operator overloads after the context is built up.
For reference, here is a typical `actor::operator()` that accepts two arguments:

    template <typename T0, typename T1>
    typename result_of::actor<Expr, T0 &, T1 &>::type
    operator()(T0 &t0, T1 &t1) const
    {
        fusion::vector2<T0 &, T1 &> env(t0, t1);

        return eval(*this, context(env, default_actions()));
    }

[heading result_of::actor]

For reasons of symmetry to the family of `actor::operator()` there is a special
metafunction usable for actor result type calculation named `result_of::actor`. This
metafunction allows us to directly specify the types of the parameters to be
passed to the `actor::operator()` function. Here's a typical `actor_result` that
accepts two arguments:

    namespace result_of
    {
        template <typename Expr, typename T0, typename T1>
        struct actor
        {
            typedef fusion::vector2<T0, T1>                                           env_tpe;
            typedef typename result_of::context<env_type, default_actions>::type      ctx_type
            typedef typename boost::result_of<evaluator(Expr const&, ctx_type)>::type type;
        };
    }

[endsect]