| /*============================================================================== |
| 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 |