You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
454 lines
14 KiB
454 lines
14 KiB
/*============================================================================== |
|
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 |
|
|
|
|