lambda.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*==============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Copyright (c) 2004 Daniel Wallin
  4. Copyright (c) 2010 Thomas Heller
  5. Copyright (c) 2016 Kohei Takahashi
  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_SCOPE_LAMBDA_HPP
  10. #define BOOST_PHOENIX_SCOPE_LAMBDA_HPP
  11. #include <boost/phoenix/core/limits.hpp>
  12. #include <boost/fusion/include/transform.hpp>
  13. #include <boost/fusion/include/as_vector.hpp>
  14. #include <boost/mpl/int.hpp>
  15. #include <boost/phoenix/core/call.hpp>
  16. #include <boost/phoenix/core/expression.hpp>
  17. #include <boost/phoenix/core/meta_grammar.hpp>
  18. #include <boost/phoenix/scope/local_variable.hpp>
  19. #include <boost/phoenix/scope/scoped_environment.hpp>
  20. BOOST_PHOENIX_DEFINE_EXPRESSION(
  21. (boost)(phoenix)(lambda_actor)
  22. , (proto::terminal<proto::_>) // Locals
  23. (proto::terminal<proto::_>) // Map
  24. (meta_grammar) // Lambda
  25. )
  26. BOOST_PHOENIX_DEFINE_EXPRESSION(
  27. (boost)(phoenix)(lambda)
  28. , (proto::terminal<proto::_>) // OuterEnv
  29. (proto::terminal<proto::_>) // Locals
  30. (proto::terminal<proto::_>) // Map
  31. (meta_grammar) // Lambda
  32. )
  33. namespace boost { namespace phoenix
  34. {
  35. struct lambda_eval
  36. {
  37. BOOST_PROTO_CALLABLE()
  38. template <typename Sig>
  39. struct result;
  40. template <
  41. typename This
  42. , typename OuterEnv
  43. , typename Locals
  44. , typename Map
  45. , typename Lambda
  46. , typename Context
  47. >
  48. struct result<This(OuterEnv, Locals, Map, Lambda, Context)>
  49. {
  50. typedef
  51. typename proto::detail::uncvref<
  52. typename proto::result_of::value<
  53. OuterEnv
  54. >::type
  55. >::type
  56. outer_env_type;
  57. typedef
  58. typename proto::detail::uncvref<
  59. typename proto::result_of::value<
  60. Locals
  61. >::type
  62. >::type
  63. locals_type;
  64. typedef
  65. typename proto::detail::uncvref<
  66. typename proto::result_of::value<
  67. Map
  68. >::type
  69. >::type
  70. map_type;
  71. typedef
  72. typename proto::detail::uncvref<
  73. typename result_of::env<Context>::type
  74. >::type
  75. env_type;
  76. typedef
  77. typename result_of::eval<
  78. Lambda
  79. , typename result_of::context<
  80. scoped_environment<
  81. env_type
  82. , outer_env_type
  83. , locals_type
  84. , map_type
  85. >
  86. , typename result_of::actions<
  87. Context
  88. >::type
  89. >::type
  90. >::type
  91. type;
  92. };
  93. template <typename OuterEnv, typename Locals, typename Map, typename Lambda, typename Context>
  94. typename result<lambda_eval(OuterEnv const &, Locals const &, Map const &, Lambda const &, Context const &)>::type
  95. operator()(OuterEnv const & outer_env, Locals const & locals, Map const &, Lambda const & lambda, Context const & ctx) const
  96. {
  97. typedef
  98. typename proto::detail::uncvref<
  99. typename proto::result_of::value<
  100. OuterEnv
  101. >::type
  102. >::type
  103. outer_env_type;
  104. typedef
  105. typename proto::detail::uncvref<
  106. typename proto::result_of::value<
  107. Locals
  108. >::type
  109. >::type
  110. locals_type;
  111. typedef
  112. typename proto::detail::uncvref<
  113. typename proto::result_of::value<
  114. Map
  115. >::type
  116. >::type
  117. map_type;
  118. typedef
  119. typename proto::detail::uncvref<
  120. typename result_of::env<Context>::type
  121. >::type
  122. env_type;
  123. scoped_environment<
  124. env_type
  125. , outer_env_type
  126. , locals_type
  127. , map_type
  128. >
  129. env(phoenix::env(ctx), proto::value(outer_env), proto::value(locals));
  130. return eval(lambda, phoenix::context(env, phoenix::actions(ctx)));
  131. }
  132. };
  133. template <typename Dummy>
  134. struct default_actions::when<rule::lambda, Dummy>
  135. : call<lambda_eval, Dummy>
  136. {};
  137. template <typename Dummy>
  138. struct is_nullary::when<rule::lambda, Dummy>
  139. : proto::call<
  140. evaluator(
  141. proto::_child_c<3>
  142. , proto::call<
  143. functional::context(
  144. proto::make<
  145. mpl::true_()
  146. >
  147. , proto::make<
  148. detail::scope_is_nullary_actions()
  149. >
  150. )
  151. >
  152. , proto::make<
  153. proto::empty_env()
  154. >
  155. )
  156. >
  157. {};
  158. template <typename Dummy>
  159. struct is_nullary::when<rule::lambda_actor, Dummy>
  160. : proto::or_<
  161. proto::when<
  162. expression::lambda_actor<
  163. proto::terminal<vector0<> >
  164. , proto::terminal<proto::_>
  165. , meta_grammar
  166. >
  167. , mpl::true_()
  168. >
  169. , proto::when<
  170. expression::lambda_actor<
  171. proto::terminal<proto::_>
  172. , proto::terminal<proto::_>
  173. , meta_grammar
  174. >
  175. , proto::fold<
  176. proto::call<proto::_value(proto::_child_c<0>)>
  177. , proto::make<mpl::true_()>
  178. , proto::make<
  179. mpl::and_<
  180. proto::_state
  181. , proto::call<
  182. evaluator(
  183. proto::_
  184. , _context
  185. , proto::make<proto::empty_env()>
  186. )
  187. >
  188. >()
  189. >
  190. >
  191. >
  192. >
  193. {};
  194. struct lambda_actor_eval
  195. {
  196. template <typename Sig>
  197. struct result;
  198. template <typename This, typename Vars, typename Map, typename Lambda, typename Context>
  199. struct result<This(Vars, Map, Lambda, Context)>
  200. {
  201. typedef
  202. typename proto::detail::uncvref<
  203. typename result_of::env<Context>::type
  204. >::type
  205. env_type;
  206. typedef
  207. typename proto::detail::uncvref<
  208. typename result_of::actions<Context>::type
  209. >::type
  210. actions_type;
  211. typedef
  212. typename proto::detail::uncvref<
  213. typename proto::result_of::value<Vars>::type
  214. >::type
  215. vars_type;
  216. typedef typename
  217. detail::result_of::initialize_locals<
  218. vars_type
  219. , Context
  220. >::type
  221. locals_type;
  222. typedef
  223. typename expression::lambda<
  224. env_type
  225. , locals_type
  226. , Map
  227. , Lambda
  228. >::type const
  229. type;
  230. };
  231. template <
  232. typename Vars
  233. , typename Map
  234. , typename Lambda
  235. , typename Context
  236. >
  237. typename result<
  238. lambda_actor_eval(Vars const&, Map const &, Lambda const&, Context const &)
  239. >::type const
  240. operator()(Vars const& vars, Map const& map, Lambda const& lambda, Context const & ctx) const
  241. {
  242. typedef
  243. typename proto::detail::uncvref<
  244. typename result_of::env<Context>::type
  245. >::type
  246. env_type;
  247. /*typedef
  248. typename proto::detail::uncvref<
  249. typename result_of::actions<Context>::type
  250. >::type
  251. actions_type;*/
  252. typedef
  253. typename proto::detail::uncvref<
  254. typename proto::result_of::value<Vars>::type
  255. >::type
  256. vars_type;
  257. /*typedef
  258. typename proto::detail::uncvref<
  259. typename proto::result_of::value<Map>::type
  260. >::type
  261. map_type;*/
  262. typedef typename
  263. detail::result_of::initialize_locals<
  264. vars_type
  265. , Context
  266. >::type
  267. locals_type;
  268. locals_type locals = initialize_locals(proto::value(vars), ctx);
  269. return
  270. expression::
  271. lambda<env_type, locals_type, Map, Lambda>::
  272. make(phoenix::env(ctx), locals, map, lambda);
  273. }
  274. };
  275. template <typename Dummy>
  276. struct default_actions::when<rule::lambda_actor, Dummy>
  277. : call<lambda_actor_eval, Dummy>
  278. {};
  279. template <typename Locals = vector0<>,
  280. typename Map = detail::map_local_index_to_tuple<>,
  281. typename Dummy = void>
  282. struct lambda_actor_gen;
  283. template <>
  284. struct lambda_actor_gen<vector0<>, detail::map_local_index_to_tuple<>, void>
  285. {
  286. template <typename Expr>
  287. typename expression::lambda_actor<vector0<>, detail::map_local_index_to_tuple<>, Expr>::type const
  288. operator[](Expr const & expr) const
  289. {
  290. typedef vector0<> locals_type;
  291. typedef detail::map_local_index_to_tuple<> map_type;
  292. return expression::lambda_actor<locals_type, map_type, Expr>::make(locals_type(), map_type(), expr);
  293. }
  294. };
  295. template <typename Locals, typename Map>
  296. struct lambda_actor_gen<Locals, Map>
  297. {
  298. lambda_actor_gen(Locals const & locals_)
  299. : locals(locals_)
  300. {}
  301. lambda_actor_gen(lambda_actor_gen const & o)
  302. : locals(o.locals)
  303. {};
  304. template <typename Expr>
  305. typename expression::lambda_actor<
  306. Locals
  307. , Map
  308. , Expr
  309. >::type const
  310. operator[](Expr const & expr) const
  311. {
  312. return expression::lambda_actor<Locals, Map, Expr>::make(locals, Map(), expr);
  313. }
  314. Locals locals;
  315. };
  316. struct lambda_local_gen
  317. : lambda_actor_gen<>
  318. {
  319. #if defined(BOOST_PHOENIX_NO_VARIADIC_SCOPE)
  320. lambda_actor_gen<> const
  321. operator()() const
  322. {
  323. return lambda_actor_gen<>();
  324. }
  325. #include <boost/phoenix/scope/detail/cpp03/lambda.hpp>
  326. #else
  327. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME lambda_actor_gen
  328. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION operator()
  329. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST const
  330. #include <boost/phoenix/scope/detail/local_gen.hpp>
  331. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME
  332. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION
  333. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
  334. #endif
  335. };
  336. typedef lambda_local_gen lambda_type;
  337. lambda_local_gen const lambda = lambda_local_gen();
  338. }}
  339. #endif