| /*============================================================================== |
| Copyright (c) 2005-2010 Joel de Guzman |
| Copyright (c) 2010-2011 Thomas Heller |
| |
| 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_CORE_ENVIRONMENT_HPP |
| #define BOOST_PHOENIX_CORE_ENVIRONMENT_HPP |
| |
| #include <boost/phoenix/core/limits.hpp> |
| #include <boost/fusion/sequence/intrinsic/at.hpp> |
| #include <boost/fusion/support/is_sequence.hpp> |
| #include <boost/phoenix/support/vector.hpp> |
| #include <boost/proto/transform/impl.hpp> |
| #include <boost/utility/enable_if.hpp> |
| #include <boost/utility/result_of.hpp> |
| |
| #include <typeinfo> |
| |
| namespace boost { namespace phoenix |
| { |
| struct unused {}; |
| |
| namespace result_of |
| { |
| template <typename Env, typename Actions> |
| struct context |
| { |
| typedef vector2<Env, Actions> type; |
| }; |
| |
| template <typename Env, typename Actions> |
| struct make_context |
| : context<Env, Actions> |
| {}; |
| |
| template <typename Context> |
| struct env |
| { |
| typedef |
| typename fusion::result_of::at_c< |
| typename boost::remove_reference<Context>::type |
| , 0 |
| >::type |
| type; |
| }; |
| |
| template <typename Context> |
| struct actions |
| { |
| typedef |
| typename fusion::result_of::at_c< |
| typename boost::remove_reference<Context>::type |
| , 1 |
| >::type |
| type; |
| }; |
| } |
| |
| namespace functional |
| { |
| struct context |
| { |
| BOOST_PROTO_CALLABLE() |
| |
| template <typename Sig> |
| struct result; |
| |
| template <typename This, typename Env, typename Actions> |
| struct result<This(Env, Actions)> |
| : result<This(Env const &, Actions const &)> |
| {}; |
| |
| template <typename This, typename Env, typename Actions> |
| struct result<This(Env &, Actions)> |
| : result<This(Env &, Actions const &)> |
| {}; |
| |
| template <typename This, typename Env, typename Actions> |
| struct result<This(Env, Actions &)> |
| : result<This(Env const &, Actions &)> |
| {}; |
| |
| template <typename This, typename Env, typename Actions> |
| struct result<This(Env &, Actions &)> |
| : result_of::context<Env &, Actions &> |
| {}; |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env &, Actions &>::type |
| operator()(Env & env, Actions & actions) const |
| { |
| vector2<Env &, Actions &> e = {env, actions}; |
| return e; |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env const &, Actions &>::type |
| operator()(Env const & env, Actions & actions) const |
| { |
| vector2<Env const &, Actions &> e = {env, actions}; |
| return e; |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env &, Actions const &>::type |
| operator()(Env & env, Actions const & actions) const |
| { |
| vector2<Env &, Actions const &> e = {env, actions}; |
| return e; |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env const &, Actions const &>::type |
| operator()(Env const & env, Actions const & actions) const |
| { |
| vector2<Env const&, Actions const &> e = {env, actions}; |
| return e; |
| } |
| }; |
| |
| struct make_context |
| : context |
| {}; |
| |
| struct env |
| { |
| BOOST_PROTO_CALLABLE() |
| |
| template <typename Sig> |
| struct result; |
| |
| template <typename This, typename Context> |
| struct result<This(Context)> |
| : result<This(Context const &)> |
| {}; |
| |
| template <typename This, typename Context> |
| struct result<This(Context &)> |
| : result_of::env<Context> |
| {}; |
| |
| template <typename Context> |
| typename result_of::env<Context const>::type |
| operator()(Context const & ctx) const |
| { |
| return fusion::at_c<0>(ctx); |
| } |
| |
| template <typename Context> |
| typename result_of::env<Context>::type |
| operator()(Context & ctx) const |
| { |
| return fusion::at_c<0>(ctx); |
| } |
| }; |
| |
| struct actions |
| { |
| BOOST_PROTO_CALLABLE() |
| |
| template <typename Sig> |
| struct result; |
| |
| template <typename This, typename Context> |
| struct result<This(Context)> |
| : result<This(Context const &)> |
| {}; |
| |
| template <typename This, typename Context> |
| struct result<This(Context &)> |
| : result_of::actions<Context> |
| {}; |
| |
| template <typename Context> |
| typename result_of::actions<Context const>::type |
| operator()(Context const & ctx) const |
| { |
| return fusion::at_c<1>(ctx); |
| } |
| |
| template <typename Context> |
| typename result_of::actions<Context>::type |
| operator()(Context & ctx) const |
| { |
| return fusion::at_c<1>(ctx); |
| } |
| }; |
| |
| } |
| |
| struct _context |
| : proto::transform<_context> |
| { |
| template <typename Expr, typename State, typename Data> |
| struct impl |
| : proto::transform_impl<Expr, State, Data> |
| { |
| typedef vector2<State, Data> result_type; |
| |
| result_type operator()( |
| typename impl::expr_param |
| , typename impl::state_param s |
| , typename impl::data_param d |
| ) const |
| { |
| vector2<State, Data> e = {s, d}; |
| return e; |
| } |
| }; |
| }; |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env const &, Actions const&>::type const |
| inline context(Env const& env, Actions const& actions) |
| { |
| vector2<Env const&, Actions const &> e = {env, actions}; |
| return e; |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env const &, Actions const&>::type const |
| inline make_context(Env const& env, Actions const& actions) |
| { |
| return context(env, actions); |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env &, Actions const&>::type const |
| inline context(Env & env, Actions const& actions) |
| { |
| vector2<Env &, Actions const &> e = {env, actions}; |
| return e; |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env &, Actions const&>::type const |
| inline make_context(Env & env, Actions const& actions) |
| { |
| return context(env, actions); |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env const &, Actions &>::type const |
| inline context(Env const& env, Actions & actions) |
| { |
| vector2<Env const&, Actions &> e = {env, actions}; |
| return e; |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env const &, Actions &>::type const |
| inline make_context(Env const& env, Actions & actions) |
| { |
| return context(env, actions); |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env &, Actions &>::type const |
| inline context(Env & env, Actions & actions) |
| { |
| vector2<Env &, Actions &> e = {env, actions}; |
| return e; |
| } |
| |
| template <typename Env, typename Actions> |
| typename result_of::context<Env &, Actions &>::type const |
| inline make_context(Env & env, Actions & actions) |
| { |
| return context(env, actions); |
| } |
| |
| struct _env |
| : proto::transform<_env> |
| { |
| template <typename Expr, typename State, typename Data> |
| struct impl |
| : proto::transform_impl<Expr, State, Data> |
| { |
| typedef State result_type; |
| |
| result_type operator()( |
| typename impl::expr_param |
| , typename impl::state_param s |
| , typename impl::data_param |
| ) const |
| { |
| return s; |
| } |
| }; |
| }; |
| |
| template <typename Expr, typename State> |
| struct _env::impl<Expr, State, int> |
| : proto::transform_impl<Expr, State, int> |
| { |
| typedef |
| typename fusion::result_of::at_c< |
| typename boost::remove_reference<State>::type |
| , 0 |
| >::type |
| result_type; |
| |
| result_type operator()( |
| typename impl::expr_param |
| , typename impl::state_param s |
| , typename impl::data_param |
| ) const |
| { |
| return fusion::at_c<0>(s); |
| } |
| }; |
| |
| template <typename Expr, typename State> |
| struct _env::impl<Expr, State, unused> |
| : _env::impl<Expr, State, int> |
| {}; |
| |
| template <typename Context> |
| typename fusion::result_of::at_c<Context, 0>::type |
| inline env(Context & ctx) |
| { |
| return fusion::at_c<0>(ctx); |
| } |
| |
| template <typename Context> |
| typename fusion::result_of::at_c<Context const, 0>::type |
| inline env(Context const & ctx) |
| { |
| return fusion::at_c<0>(ctx); |
| } |
| |
| struct _actions |
| : proto::transform<_actions> |
| { |
| template <typename Expr, typename State, typename Data> |
| struct impl |
| : proto::transform_impl<Expr, State, Data> |
| { |
| typedef Data result_type; |
| |
| result_type operator()( |
| typename impl::expr_param |
| , typename impl::state_param |
| , typename impl::data_param d |
| ) const |
| { |
| return d; |
| } |
| }; |
| }; |
| |
| template <typename Expr, typename State> |
| struct _actions::impl<Expr, State, int> |
| : proto::transform_impl<Expr, State, int> |
| { |
| typedef |
| typename fusion::result_of::at_c< |
| typename boost::remove_reference<State>::type |
| , 1 |
| >::type |
| result_type; |
| |
| result_type operator()( |
| typename impl::expr_param |
| , typename impl::state_param s |
| , typename impl::data_param |
| ) const |
| { |
| return fusion::at_c<1>(s); |
| } |
| }; |
| |
| template <typename Expr, typename State> |
| struct _actions::impl<Expr, State, unused> |
| : _actions::impl<Expr, State, int> |
| {}; |
| |
| template <typename Context> |
| typename fusion::result_of::at_c<Context, 1>::type |
| inline actions(Context & ctx) |
| { |
| return fusion::at_c<1>(ctx); |
| } |
| |
| template <typename Context> |
| typename fusion::result_of::at_c<Context const, 1>::type |
| inline actions(Context const & ctx) |
| { |
| return fusion::at_c<1>(ctx); |
| } |
| |
| namespace result_of |
| { |
| template < |
| BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( |
| BOOST_PHOENIX_LIMIT |
| , typename A |
| , mpl::void_ |
| ) |
| , typename Dummy = void |
| > |
| struct make_env; |
| |
| #define BOOST_PHOENIX_M0(Z, N, D) \ |
| template <BOOST_PHOENIX_typename_A(N)> \ |
| struct make_env<BOOST_PHOENIX_A(N)> \ |
| { \ |
| typedef BOOST_PP_CAT(vector, N)<BOOST_PHOENIX_A(N)> type; \ |
| }; \ |
| /**/ |
| BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, BOOST_PHOENIX_M0, _) |
| #undef BOOST_PHOENIX_M0 |
| } |
| |
| result_of::make_env<>::type |
| inline make_env() |
| { |
| return result_of::make_env<>::type(); |
| } |
| #define BOOST_PHOENIX_M0(Z, N, D) \ |
| template <BOOST_PHOENIX_typename_A(N)> \ |
| typename result_of::make_env<BOOST_PHOENIX_A_ref(N)>::type \ |
| inline make_env(BOOST_PHOENIX_A_ref_a(N)) \ |
| { \ |
| typename result_of::make_env<BOOST_PHOENIX_A_ref(N)>::type \ |
| env = \ |
| { \ |
| BOOST_PHOENIX_a(N) \ |
| }; \ |
| return env; \ |
| } \ |
| template <BOOST_PHOENIX_typename_A(N)> \ |
| typename result_of::make_env<BOOST_PHOENIX_A_const_ref(N)>::type \ |
| inline make_env(BOOST_PHOENIX_A_const_ref_a(N)) \ |
| { \ |
| typename result_of::make_env<BOOST_PHOENIX_A_const_ref(N)>::type \ |
| env = \ |
| { \ |
| BOOST_PHOENIX_a(N) \ |
| }; \ |
| return env; \ |
| } \ |
| /**/ |
| BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, BOOST_PHOENIX_M0, _) |
| #undef BOOST_PHOENIX_M0 |
| |
| template <typename T, typename Enable = void> |
| struct is_environment : fusion::traits::is_sequence<T> {}; |
| }} |
| |
| #endif |
| |