blob: a53b4e567f19551723bd04a87613d22fd38ddc80 [file] [log] [blame]
/*==============================================================================
Copyright (c) 2005-2010 Joel de Guzman
Copyright (c) 2010 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_SCOPE_SCOPED_ENVIRONMENT_HPP
#define BOOST_PHOENIX_SCOPE_SCOPED_ENVIRONMENT_HPP
#include <boost/phoenix/core/limits.hpp>
#include <boost/mpl/int.hpp>
#include <boost/fusion/sequence/sequence_facade.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/intrinsic/value_at.hpp>
#include <boost/fusion/sequence/intrinsic/at.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/include/pop_front.hpp>
#include <boost/utility/result_of.hpp>
namespace boost { namespace phoenix
{
template<typename Env, typename OuterEnv, typename Locals, typename Map>
struct scoped_environment
: fusion::sequence_facade<
scoped_environment<Env, OuterEnv, Locals, Map>
, fusion::random_access_traversal_tag
>
{
typedef Env env_type;
typedef OuterEnv outer_env_type;
typedef Locals locals_type;
typedef Map map_type;
scoped_environment(
Env const & env
, OuterEnv const &outer_env
, Locals const &locals
)
: env(env)
, outer_env(outer_env)
, locals(locals)
{}
scoped_environment(scoped_environment const & o)
: env(o.env)
, outer_env(o.outer_env)
, locals(o.locals)
{};
Env const & env;
OuterEnv const & outer_env;
Locals const & locals;
typedef typename
fusion::result_of::pop_front<
typename add_const<
typename proto::detail::uncvref<Env>::type
>::type
>::type
args_type;
args_type args() const
{
return fusion::pop_front(env);
}
#define BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(INTRINSIC) \
template <typename Seq> \
struct INTRINSIC \
{ \
typedef \
typename fusion::result_of::INTRINSIC< \
typename mpl::eval_if_c< \
is_const< \
typename remove_reference< \
typename Seq::env_type \
>::type \
>::value \
, add_const< \
typename proto::detail::uncvref< \
typename Seq::env_type \
>::type \
> \
, proto::detail::uncvref< \
typename Seq::env_type \
> \
>::type \
>::type \
type; \
\
static type call(Seq & seq) \
{ \
return fusion::INTRINSIC(seq.env); \
} \
} \
/**/
BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(begin);
BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(end);
BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(size);
#undef BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT
template <typename Seq, typename N>
struct value_at
{
typedef
typename fusion::result_of::value_at<
typename mpl::eval_if_c<
is_const<
typename remove_reference<
typename Seq::env_type
>::type
>::value
, add_const<
typename proto::detail::uncvref<
typename Seq::env_type
>::type
>
, proto::detail::uncvref<
typename Seq::env_type
>
>::type
, N
>::type
type;
};
template <typename Seq, typename N>
struct at
{
typedef
typename fusion::result_of::at<
typename mpl::eval_if_c<
is_const<
typename remove_reference<
typename Seq::env_type
>::type
>::value
, add_const<
typename proto::detail::uncvref<
typename Seq::env_type
>::type
>
, proto::detail::uncvref<
typename Seq::env_type
>
>::type
, N
>::type
type;
static type call(Seq & seq)
{
return fusion::at<N>(seq.env);
}
};
};
template <typename Env, typename Dummy = void>
struct is_scoped_environment : mpl::false_ {};
template <typename Env>
struct is_scoped_environment<Env&> : is_scoped_environment<Env> {};
template <typename Env, typename OuterEnv, typename Locals, typename Map>
struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> >
: mpl::true_
{};
template <typename Env, typename OuterEnv, typename Locals, typename Map>
struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> const>
: mpl::true_
{};
}}
#endif