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
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 ==============================================================================*/
11 #ifndef BOOST_PHOENIX_SCOPE_LAMBDA_HPP
12 #define BOOST_PHOENIX_SCOPE_LAMBDA_HPP
14 #include <boost/phoenix/core/limits.hpp>
15 #include <boost/fusion/include/transform.hpp>
16 #include <boost/fusion/include/as_vector.hpp>
17 #include <boost/mpl/int.hpp>
18 #include <boost/phoenix/core/call.hpp>
19 #include <boost/phoenix/core/expression.hpp>
20 #include <boost/phoenix/core/meta_grammar.hpp>
21 #include <boost/phoenix/scope/local_variable.hpp>
22 #include <boost/phoenix/scope/scoped_environment.hpp>
24 BOOST_PHOENIX_DEFINE_EXPRESSION(
25 (boost)(phoenix)(lambda_actor)
26 , (proto::terminal<proto::_>) // Locals
27 (proto::terminal<proto::_>) // Map
28 (meta_grammar) // Lambda
31 BOOST_PHOENIX_DEFINE_EXPRESSION(
32 (boost)(phoenix)(lambda)
33 , (proto::terminal<proto::_>) // OuterEnv
34 (proto::terminal<proto::_>) // Locals
35 (proto::terminal<proto::_>) // Map
36 (meta_grammar) // Lambda
39 namespace boost { namespace phoenix
43 BOOST_PROTO_CALLABLE()
45 template <typename Sig>
56 struct result<This(OuterEnv, Locals, Map, Lambda, Context)>
59 typename proto::detail::uncvref<
60 typename proto::result_of::value<
67 typename proto::detail::uncvref<
68 typename proto::result_of::value<
75 typename proto::detail::uncvref<
76 typename proto::result_of::value<
83 typename proto::detail::uncvref<
84 typename result_of::env<Context>::type
89 typename result_of::eval<
91 , typename result_of::context<
98 , typename result_of::actions<
106 template <typename OuterEnv, typename Locals, typename Map, typename Lambda, typename Context>
107 typename result<lambda_eval(OuterEnv const &, Locals const &, Map const &, Lambda const &, Context const &)>::type
108 operator()(OuterEnv const & outer_env, Locals const & locals, Map const &, Lambda const & lambda, Context const & ctx) const
111 typename proto::detail::uncvref<
112 typename proto::result_of::value<
119 typename proto::detail::uncvref<
120 typename proto::result_of::value<
127 typename proto::detail::uncvref<
128 typename proto::result_of::value<
135 typename proto::detail::uncvref<
136 typename result_of::env<Context>::type
146 env(phoenix::env(ctx), proto::value(outer_env), proto::value(locals));
148 return eval(lambda, phoenix::context(env, phoenix::actions(ctx)));
152 template <typename Dummy>
153 struct default_actions::when<rule::lambda, Dummy>
154 : call<lambda_eval, Dummy>
157 template <typename Dummy>
158 struct is_nullary::when<rule::lambda, Dummy>
168 detail::scope_is_nullary_actions()
179 template <typename Dummy>
180 struct is_nullary::when<rule::lambda_actor, Dummy>
183 expression::lambda_actor<
184 proto::terminal<vector0<> >
185 , proto::terminal<proto::_>
191 expression::lambda_actor<
192 proto::terminal<proto::_>
193 , proto::terminal<proto::_>
197 proto::call<proto::_value(proto::_child_c<0>)>
198 , proto::make<mpl::true_()>
206 , proto::make<proto::empty_env()>
216 struct lambda_actor_eval
218 template <typename Sig>
221 template <typename This, typename Vars, typename Map, typename Lambda, typename Context>
222 struct result<This(Vars, Map, Lambda, Context)>
225 typename proto::detail::uncvref<
226 typename result_of::env<Context>::type
230 typename proto::detail::uncvref<
231 typename result_of::actions<Context>::type
235 typename proto::detail::uncvref<
236 typename proto::result_of::value<Vars>::type
241 detail::result_of::initialize_locals<
248 typename expression::lambda<
264 lambda_actor_eval(Vars const&, Map const &, Lambda const&, Context const &)
266 operator()(Vars const& vars, Map const& map, Lambda const& lambda, Context const & ctx) const
269 typename proto::detail::uncvref<
270 typename result_of::env<Context>::type
274 typename proto::detail::uncvref<
275 typename result_of::actions<Context>::type
279 typename proto::detail::uncvref<
280 typename proto::result_of::value<Vars>::type
284 typename proto::detail::uncvref<
285 typename proto::result_of::value<Map>::type
290 detail::result_of::initialize_locals<
296 locals_type locals = initialize_locals(proto::value(vars), ctx);
300 lambda<env_type, locals_type, Map, Lambda>::
301 make(phoenix::env(ctx), locals, map, lambda);
305 template <typename Dummy>
306 struct default_actions::when<rule::lambda_actor, Dummy>
307 : call<lambda_actor_eval, Dummy>
310 template <typename Locals = vector0<>,
311 typename Map = detail::map_local_index_to_tuple<>,
312 typename Dummy = void>
313 struct lambda_actor_gen;
316 struct lambda_actor_gen<vector0<>, detail::map_local_index_to_tuple<>, void>
318 template <typename Expr>
319 typename expression::lambda_actor<vector0<>, detail::map_local_index_to_tuple<>, Expr>::type const
320 operator[](Expr const & expr) const
322 typedef vector0<> locals_type;
323 typedef detail::map_local_index_to_tuple<> map_type;
324 return expression::lambda_actor<locals_type, map_type, Expr>::make(locals_type(), map_type(), expr);
328 template <typename Locals, typename Map>
329 struct lambda_actor_gen<Locals, Map>
331 lambda_actor_gen(Locals const & locals_)
335 lambda_actor_gen(lambda_actor_gen const & o)
339 template <typename Expr>
340 typename expression::lambda_actor<
345 operator[](Expr const & expr) const
347 return expression::lambda_actor<Locals, Map, Expr>::make(locals, Map(), expr);
353 struct lambda_local_gen
356 #if defined(BOOST_PHOENIX_NO_VARIADIC_SCOPE)
357 lambda_actor_gen<> const
360 return lambda_actor_gen<>();
363 #include <boost/phoenix/scope/detail/cpp03/lambda.hpp>
365 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME lambda_actor_gen
366 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION operator()
367 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST const
368 #include <boost/phoenix/scope/detail/local_gen.hpp>
369 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME
370 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION
371 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
375 typedef lambda_local_gen lambda_type;
376 lambda_local_gen const lambda = lambda_local_gen();