/*============================================================================== Copyright (c) 2001-2010 Joel de Guzman Copyright (c) 2004 Daniel Wallin Copyright (c) 2010 Thomas Heller Copyright (c) 2016 Kohei Takahashi 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) ==============================================================================*/ #ifndef BOOST_PHOENIX_SCOPE_LAMBDA_HPP #define BOOST_PHOENIX_SCOPE_LAMBDA_HPP #include #include #include #include #include #include #include #include #include BOOST_PHOENIX_DEFINE_EXPRESSION( (boost)(phoenix)(lambda_actor) , (proto::terminal) // Locals (proto::terminal) // Map (meta_grammar) // Lambda ) BOOST_PHOENIX_DEFINE_EXPRESSION( (boost)(phoenix)(lambda) , (proto::terminal) // OuterEnv (proto::terminal) // Locals (proto::terminal) // Map (meta_grammar) // Lambda ) namespace boost { namespace phoenix { struct lambda_eval { BOOST_PROTO_CALLABLE() template struct result; template < typename This , typename OuterEnv , typename Locals , typename Map , typename Lambda , typename Context > struct result { typedef typename proto::detail::uncvref< typename proto::result_of::value< OuterEnv >::type >::type outer_env_type; typedef typename proto::detail::uncvref< typename proto::result_of::value< Locals >::type >::type locals_type; typedef typename proto::detail::uncvref< typename proto::result_of::value< Map >::type >::type map_type; typedef typename proto::detail::uncvref< typename result_of::env::type >::type env_type; typedef typename result_of::eval< Lambda , typename result_of::context< scoped_environment< env_type , outer_env_type , locals_type , map_type > , typename result_of::actions< Context >::type >::type >::type type; }; template typename result::type operator()(OuterEnv const & outer_env, Locals const & locals, Map const &, Lambda const & lambda, Context const & ctx) const { typedef typename proto::detail::uncvref< typename proto::result_of::value< OuterEnv >::type >::type outer_env_type; typedef typename proto::detail::uncvref< typename proto::result_of::value< Locals >::type >::type locals_type; typedef typename proto::detail::uncvref< typename proto::result_of::value< Map >::type >::type map_type; typedef typename proto::detail::uncvref< typename result_of::env::type >::type env_type; scoped_environment< env_type , outer_env_type , locals_type , map_type > env(phoenix::env(ctx), proto::value(outer_env), proto::value(locals)); return eval(lambda, phoenix::context(env, phoenix::actions(ctx))); } }; template struct default_actions::when : call {}; template struct is_nullary::when : proto::call< evaluator( proto::_child_c<3> , proto::call< functional::context( proto::make< mpl::true_() > , proto::make< detail::scope_is_nullary_actions() > ) > , proto::make< proto::empty_env() > ) > {}; template struct is_nullary::when : proto::or_< proto::when< expression::lambda_actor< proto::terminal > , proto::terminal , meta_grammar > , mpl::true_() > , proto::when< expression::lambda_actor< proto::terminal , proto::terminal , meta_grammar > , proto::fold< proto::call)> , proto::make , proto::make< mpl::and_< proto::_state , proto::call< evaluator( proto::_ , _context , proto::make ) > >() > > > > {}; struct lambda_actor_eval { template struct result; template struct result { typedef typename proto::detail::uncvref< typename result_of::env::type >::type env_type; typedef typename proto::detail::uncvref< typename result_of::actions::type >::type actions_type; typedef typename proto::detail::uncvref< typename proto::result_of::value::type >::type vars_type; typedef typename detail::result_of::initialize_locals< vars_type , Context >::type locals_type; typedef typename expression::lambda< env_type , locals_type , Map , Lambda >::type const type; }; template < typename Vars , typename Map , typename Lambda , typename Context > typename result< lambda_actor_eval(Vars const&, Map const &, Lambda const&, Context const &) >::type const operator()(Vars const& vars, Map const& map, Lambda const& lambda, Context const & ctx) const { typedef typename proto::detail::uncvref< typename result_of::env::type >::type env_type; /*typedef typename proto::detail::uncvref< typename result_of::actions::type >::type actions_type;*/ typedef typename proto::detail::uncvref< typename proto::result_of::value::type >::type vars_type; /*typedef typename proto::detail::uncvref< typename proto::result_of::value::type >::type map_type;*/ typedef typename detail::result_of::initialize_locals< vars_type , Context >::type locals_type; locals_type locals = initialize_locals(proto::value(vars), ctx); return expression:: lambda:: make(phoenix::env(ctx), locals, map, lambda); } }; template struct default_actions::when : call {}; template , typename Map = detail::map_local_index_to_tuple<>, typename Dummy = void> struct lambda_actor_gen; template <> struct lambda_actor_gen, detail::map_local_index_to_tuple<>, void> { template typename expression::lambda_actor, detail::map_local_index_to_tuple<>, Expr>::type const operator[](Expr const & expr) const { typedef vector0<> locals_type; typedef detail::map_local_index_to_tuple<> map_type; return expression::lambda_actor::make(locals_type(), map_type(), expr); } }; template struct lambda_actor_gen { lambda_actor_gen(Locals const & locals_) : locals(locals_) {} lambda_actor_gen(lambda_actor_gen const & o) : locals(o.locals) {}; template typename expression::lambda_actor< Locals , Map , Expr >::type const operator[](Expr const & expr) const { return expression::lambda_actor::make(locals, Map(), expr); } Locals locals; }; struct lambda_local_gen : lambda_actor_gen<> { #if defined(BOOST_PHOENIX_NO_VARIADIC_SCOPE) lambda_actor_gen<> const operator()() const { return lambda_actor_gen<>(); } #include #else #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME lambda_actor_gen #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION operator() #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST const #include #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST #endif }; typedef lambda_local_gen lambda_type; lambda_local_gen const lambda = lambda_local_gen(); }} #endif