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