207 lines
6.2 KiB
Plaintext
207 lines
6.2 KiB
Plaintext
[/==============================================================================
|
|
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]
|