actor.hpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*=============================================================================
  2. Copyright (c) 2005-2010 Joel de Guzman
  3. Copyright (c) 2010 Eric Niebler
  4. Copyright (c) 2010 Thomas Heller
  5. Copyright (c) 2014 John Fletcher
  6. Distributed under the Boost Software License, Version 1.0. (See accompanying
  7. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. ==============================================================================*/
  9. #ifndef BOOST_PHOENIX_CORE_ACTOR_HPP
  10. #define BOOST_PHOENIX_CORE_ACTOR_HPP
  11. #include <boost/phoenix/core/limits.hpp>
  12. #include <boost/is_placeholder.hpp>
  13. #include <boost/mpl/identity.hpp>
  14. #include <boost/mpl/eval_if.hpp>
  15. #include <boost/phoenix/core/domain.hpp>
  16. #include <boost/phoenix/core/environment.hpp>
  17. #include <boost/phoenix/core/is_nullary.hpp>
  18. #include <boost/phoenix/core/meta_grammar.hpp>
  19. #include <boost/phoenix/support/iterate.hpp>
  20. #include <boost/phoenix/support/vector.hpp>
  21. #include <boost/proto/extends.hpp>
  22. #include <boost/proto/make_expr.hpp>
  23. #include <boost/utility/result_of.hpp>
  24. #include <boost/mpl/void.hpp>
  25. #include <cstring>
  26. #ifndef BOOST_PHOENIX_NO_VARIADIC_ACTOR
  27. # include <boost/mpl/if.hpp>
  28. # include <boost/type_traits/is_reference.hpp>
  29. # include <boost/phoenix/core/detail/index_sequence.hpp>
  30. #endif
  31. #ifdef BOOST_MSVC
  32. #pragma warning(push)
  33. #pragma warning(disable: 4522) // 'this' used in base member initializer list
  34. #pragma warning(disable: 4510) // default constructor could not be generated
  35. #pragma warning(disable: 4610) // can never be instantiated - user defined cons
  36. #endif
  37. namespace boost { namespace phoenix
  38. {
  39. template <typename Expr>
  40. struct actor;
  41. namespace detail
  42. {
  43. struct error_expecting_arguments
  44. {
  45. template <typename T>
  46. error_expecting_arguments(T const&) {}
  47. };
  48. struct error_invalid_lambda_expr
  49. {
  50. template <typename T>
  51. error_invalid_lambda_expr(T const&) {}
  52. };
  53. template <typename T>
  54. struct result_type_deduction_helper
  55. {
  56. typedef T const & type;
  57. };
  58. template <typename T>
  59. struct result_type_deduction_helper<T &>
  60. {
  61. typedef T & type;
  62. };
  63. template <typename T>
  64. struct result_type_deduction_helper<T const &>
  65. {
  66. typedef T const & type;
  67. };
  68. }
  69. namespace result_of
  70. {
  71. #ifdef BOOST_PHOENIX_NO_VARIADIC_ACTOR
  72. // Bring in the result_of::actor<>
  73. #include <boost/phoenix/core/detail/cpp03/actor_result_of.hpp>
  74. #else
  75. template <typename Expr, typename... A>
  76. struct actor_impl
  77. {
  78. typedef
  79. typename boost::phoenix::evaluator::impl<
  80. Expr const&
  81. , vector2<
  82. typename vector_chooser<sizeof...(A) + 1>::
  83. template apply<const ::boost::phoenix::actor<Expr> *, A...>::type&
  84. , default_actions
  85. > const &
  86. , proto::empty_env
  87. >::result_type
  88. type;
  89. };
  90. template <typename Expr, typename... A>
  91. struct actor : actor_impl<Expr, A...> {};
  92. template <typename Expr>
  93. struct nullary_actor_result : actor_impl<Expr> {};
  94. #endif
  95. template <typename Expr>
  96. struct actor<Expr>
  97. {
  98. typedef
  99. // avoid calling result_of::actor when this is false
  100. typename mpl::eval_if_c<
  101. result_of::is_nullary<Expr>::value
  102. , nullary_actor_result<Expr>
  103. , mpl::identity<detail::error_expecting_arguments>
  104. >::type
  105. type;
  106. };
  107. }
  108. ////////////////////////////////////////////////////////////////////////////
  109. //
  110. // actor
  111. //
  112. // The actor class. The main thing! In phoenix, everything is an actor
  113. // This class is responsible for full function evaluation. Partial
  114. // function evaluation involves creating a hierarchy of actor objects.
  115. //
  116. ////////////////////////////////////////////////////////////////////////////
  117. #if defined __clang__ && defined __has_warning
  118. # pragma clang diagnostic push
  119. # if __has_warning("-Wdeprecated-copy")
  120. # pragma clang diagnostic ignored "-Wdeprecated-copy"
  121. # endif
  122. #endif
  123. template <typename Expr>
  124. struct actor
  125. {
  126. typedef typename
  127. mpl::eval_if_c<
  128. mpl::or_<
  129. is_custom_terminal<Expr>
  130. , mpl::bool_<is_placeholder<Expr>::value>
  131. >::value
  132. , proto::terminal<Expr>
  133. , mpl::identity<Expr>
  134. >::type
  135. expr_type;
  136. BOOST_PROTO_BASIC_EXTENDS(expr_type, actor<Expr>, phoenix_domain)
  137. BOOST_PROTO_EXTENDS_SUBSCRIPT()
  138. BOOST_PROTO_EXTENDS_ASSIGN_()
  139. template <typename Sig>
  140. struct result;
  141. typename result_of::actor<proto_base_expr>::type
  142. operator()()
  143. {
  144. typedef vector1<const actor<Expr> *> env_type;
  145. env_type env = {this};
  146. return phoenix::eval(*this, phoenix::context(env, default_actions()));
  147. }
  148. typename result_of::actor<proto_base_expr>::type
  149. operator()() const
  150. {
  151. typedef vector1<const actor<Expr> *> env_type;
  152. env_type env = {this};
  153. return phoenix::eval(*this, phoenix::context(env, default_actions()));
  154. }
  155. template <typename Env>
  156. typename evaluator::impl<
  157. proto_base_expr const &
  158. , typename result_of::context<
  159. Env const &
  160. , default_actions const &
  161. >::type
  162. , proto::empty_env
  163. >::result_type
  164. eval(Env const & env) const
  165. {
  166. return phoenix::eval(*this, phoenix::context(env, default_actions()));
  167. }
  168. #ifdef BOOST_PHOENIX_NO_VARIADIC_ACTOR
  169. // Bring in the rest
  170. #include <boost/phoenix/core/detail/cpp03/actor_operator.hpp>
  171. #else
  172. template <typename This, typename... A>
  173. struct result<This(A...)>
  174. : result_of::actor<
  175. proto_base_expr
  176. , typename mpl::if_<is_reference<A>, A, A const &>::type...
  177. >
  178. {};
  179. template <typename... A>
  180. typename result<actor(A...)>::type
  181. operator()(A &&... a)
  182. {
  183. typedef
  184. typename vector_chooser<sizeof...(A) + 1>::template apply<
  185. const actor<Expr> *
  186. , typename mpl::if_<is_reference<A>, A, A const &>::type...
  187. >::type
  188. env_type;
  189. env_type env = {this, a...};
  190. return phoenix::eval(*this, phoenix::context(env, default_actions()));
  191. }
  192. template <typename... A>
  193. typename result<actor(A...)>::type
  194. operator()(A &&... a) const
  195. {
  196. typedef
  197. typename vector_chooser<sizeof...(A) + 1>::template apply<
  198. const actor<Expr> *
  199. , typename mpl::if_<is_reference<A>, A, A const &>::type...
  200. >::type
  201. env_type;
  202. env_type env = {this, a...};
  203. return phoenix::eval(*this, phoenix::context(env, default_actions()));
  204. }
  205. #endif
  206. BOOST_DELETED_FUNCTION(actor& operator=(actor const&))
  207. };
  208. #if defined __clang__ && defined __has_warning
  209. # pragma clang diagnostic pop
  210. #endif
  211. }}
  212. namespace boost
  213. {
  214. // specialize boost::result_of to return the proper result type
  215. template <typename Expr>
  216. struct result_of<phoenix::actor<Expr>()>
  217. : phoenix::result_of::actor<typename phoenix::actor<Expr>::proto_base_expr>
  218. {};
  219. template <typename Expr>
  220. struct result_of<phoenix::actor<Expr> const()>
  221. : phoenix::result_of::actor<typename phoenix::actor<Expr>::proto_base_expr>
  222. {};
  223. }
  224. #ifdef BOOST_MSVC
  225. #pragma warning(pop)
  226. #endif
  227. #endif