123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- [/==============================================================================
- 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]
|