blob: e84dc770810d754253482c068f0ed8b0c715ac47 [file] [log] [blame]
/*==============================================================================
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