179 lines
7.3 KiB
C++
179 lines
7.3 KiB
C++
/*==============================================================================
|
|
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
|