actor.qbk 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. [/==============================================================================
  2. Copyright (C) 2001-2010 Joel de Guzman
  3. Copyright (C) 2001-2005 Dan Marsden
  4. Copyright (C) 2001-2010 Thomas Heller
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ===============================================================================/]
  8. [section:actor Actors in Detail]
  9. [heading Actor]
  10. The main concept is the `Actor`. An `Actor` is a model of the __PFO__ concept
  11. (that can accept 0 to N arguments (where N is a predefined maximum).
  12. An `Actor` contains a valid Phoenix Expression, a call to one of the function
  13. call operator overloads, starts the evaluation process.
  14. [note You can set `BOOST_PHOENIX_LIMIT`, the predefined maximum arity an
  15. actor can take. By default, `BOOST_PHOENIX_LIMIT` is set to 10.]
  16. The `actor` template class models the `Actor` concept:
  17. template <typename Expr>
  18. struct actor
  19. {
  20. template <typename Sig>
  21. struct result;
  22. typename result_of::actor<Expr>::type
  23. operator()() const;
  24. template <typename T0>
  25. typename result_of::actor<Expr, T0 &>::type
  26. operator()(T0& _0) const;
  27. template <typename T0>
  28. typename result_of::actor<Expr, T0 const &>::type
  29. operator()(T0 const & _0) const;
  30. //...
  31. };
  32. [table Actor Concept Requirements
  33. [
  34. [Expression]
  35. [Semantics]
  36. ]
  37. [
  38. [`actor(arg0, arg1, ..., argN)`]
  39. [Function call operators to start the evaluation]
  40. ]
  41. [
  42. [`boost::result_of<Actor<Expr>(Arg0, Arg1, ..., ArgN)>::type`]
  43. [Result of the evaluation]
  44. ]
  45. [
  46. [`result_of::actor<Expr, Arg0, Arg1, ..., ArgN>::type`]
  47. [Result of the evaluation]
  48. ]
  49. ]
  50. [heading Function Call Operators]
  51. There are 2*N function call operators for 0 to N arguments (N == `BOOST_PHOENIX_LIMIT`).
  52. The actor class accepts the arguments and forwards the arguments to the default
  53. evaluation action.
  54. Additionally, there exist function call operators accepting permutations of const
  55. and non-const references. These operators are created for all N <=
  56. `BOOST_PHOENIX_PERFECT_FORWARD_LIMIT` (which defaults to 3).
  57. [def $http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm]
  58. [note *Forwarding Function Problem*
  59. There is a known issue with current C++ called the "__forwarding__".
  60. The problem is that given an arbitrary function `F`, using current C++
  61. language rules, one cannot create a forwarding function `FF` that
  62. transparently assumes the arguments of `F`.
  63. ]
  64. [heading Context]
  65. On an actor function call, before calling the evaluation function, the actor created a *context*.
  66. This context consists of an `Environment` and an `Action` part. These contain all information
  67. necessary to evaluate the given expression.
  68. [table Context Concept Requirements
  69. [
  70. [Expression]
  71. [Semantics]
  72. ]
  73. [
  74. [`result_of::context<Env, Actions>::type`]
  75. [Type of a Context]
  76. ]
  77. [
  78. [`context(e, a)`]
  79. [A Context containing environment `e` and actions `a`]
  80. ]
  81. [
  82. [`result_of::env<Context>::type`]
  83. [Type of the contained Environment]
  84. ]
  85. [
  86. [`env(ctx)`]
  87. [The environment]
  88. ]
  89. [
  90. [`result_of::actions<Context>::type`]
  91. [Type of the contained Actions]
  92. ]
  93. [
  94. [`actions(ctx)`]
  95. [The actions]
  96. ]
  97. ]
  98. [heading Environment]
  99. The Environment is a model of __random_access__.
  100. The arguments passed to the actor's function call operator are collected inside the Environment:
  101. [$images/funnel_in.png]
  102. Other parts of the library (e.g. the scope module) extends the `Environment`
  103. concept to hold other information such as local variables, etc.
  104. [heading Actions]
  105. Actions is the part of Phoenix which are responsible for giving the actual expressions
  106. a specific behaviour. During the traversal of the Phoenix Expression Tree these actions
  107. are called whenever a specified rule in the grammar matches.
  108. struct actions
  109. {
  110. template <typename Rule>
  111. struct when;
  112. };
  113. The nested `when` template is required to be __proto_primitive_transform__. No
  114. worries, you don't have to learn __proto__ just yet! Phoenix provides some wrappers
  115. to let you define simple actions without the need to dive deep into proto.
  116. Phoenix ships with a predefined `default_actions` class that evaluates the expressions with
  117. C++ semantics:
  118. struct default_actions
  119. {
  120. template <typename Rule, typename Dummy = void>
  121. struct when
  122. : proto::_default<meta_grammar>
  123. {};
  124. };
  125. For more information on how to use the default_actions class and how to attach custom actions
  126. to the evaluation process, see [link phoenix.inside.actions more on actions].
  127. [heading Evaluation]
  128. struct evaluator
  129. {
  130. template <typename Expr, typename Context>
  131. __unspecified__ operator()(Expr &, Context &);
  132. };
  133. evaluator const eval = {};
  134. The evaluation of a Phoenix expression is started by a call to the function call operator of
  135. `evaluator`.
  136. The evaluator is called by the `actor` function operator overloads after the context is built up.
  137. For reference, here is a typical `actor::operator()` that accepts two arguments:
  138. template <typename T0, typename T1>
  139. typename result_of::actor<Expr, T0 &, T1 &>::type
  140. operator()(T0 &t0, T1 &t1) const
  141. {
  142. fusion::vector2<T0 &, T1 &> env(t0, t1);
  143. return eval(*this, context(env, default_actions()));
  144. }
  145. [heading result_of::actor]
  146. For reasons of symmetry to the family of `actor::operator()` there is a special
  147. metafunction usable for actor result type calculation named `result_of::actor`. This
  148. metafunction allows us to directly specify the types of the parameters to be
  149. passed to the `actor::operator()` function. Here's a typical `actor_result` that
  150. accepts two arguments:
  151. namespace result_of
  152. {
  153. template <typename Expr, typename T0, typename T1>
  154. struct actor
  155. {
  156. typedef fusion::vector2<T0, T1> env_tpe;
  157. typedef typename result_of::context<env_type, default_actions>::type ctx_type
  158. typedef typename boost::result_of<evaluator(Expr const&, ctx_type)>::type type;
  159. };
  160. }
  161. [endsect]