1 /*============================================================================== 2 Copyright (c) 2005-2010 Joel de Guzman 3 Copyright (c) 2010 Thomas Heller 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #ifndef BOOST_PHOENIX_SCOPE_SCOPED_ENVIRONMENT_HPP 9 #define BOOST_PHOENIX_SCOPE_SCOPED_ENVIRONMENT_HPP 10 11 #include <boost/phoenix/core/limits.hpp> 12 #include <boost/mpl/int.hpp> 13 #include <boost/fusion/sequence/sequence_facade.hpp> 14 #include <boost/fusion/sequence/intrinsic/begin.hpp> 15 #include <boost/fusion/sequence/intrinsic/end.hpp> 16 #include <boost/fusion/sequence/intrinsic/size.hpp> 17 #include <boost/fusion/sequence/intrinsic/value_at.hpp> 18 #include <boost/fusion/sequence/intrinsic/at.hpp> 19 #include <boost/fusion/support/category_of.hpp> 20 #include <boost/fusion/include/pop_front.hpp> 21 #include <boost/utility/result_of.hpp> 22 23 namespace boost { namespace phoenix 24 { 25 template<typename Env, typename OuterEnv, typename Locals, typename Map> 26 struct scoped_environment 27 : fusion::sequence_facade< 28 scoped_environment<Env, OuterEnv, Locals, Map> 29 , fusion::random_access_traversal_tag 30 > 31 { 32 typedef Env env_type; 33 typedef OuterEnv outer_env_type; 34 typedef Locals locals_type; 35 typedef Map map_type; 36 scoped_environmentboost::phoenix::scoped_environment37 scoped_environment( 38 Env const & env_ 39 , OuterEnv const &outer_env_ 40 , Locals const &locals_ 41 ) 42 : env(env_) 43 , outer_env(outer_env_) 44 , locals(locals_) 45 {} 46 scoped_environmentboost::phoenix::scoped_environment47 scoped_environment(scoped_environment const & o) 48 : env(o.env) 49 , outer_env(o.outer_env) 50 , locals(o.locals) 51 {} 52 53 Env const & env; 54 OuterEnv const & outer_env; 55 Locals const & locals; 56 57 typedef typename 58 fusion::result_of::pop_front< 59 typename add_const< 60 typename proto::detail::uncvref<Env>::type 61 >::type 62 >::type 63 args_type; 64 argsboost::phoenix::scoped_environment65 args_type args() const 66 { 67 return fusion::pop_front(env); 68 } 69 70 #define BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(INTRINSIC) \ 71 template <typename Seq> \ 72 struct INTRINSIC \ 73 { \ 74 typedef \ 75 typename fusion::result_of::INTRINSIC< \ 76 typename mpl::eval_if_c< \ 77 is_const< \ 78 typename remove_reference< \ 79 typename Seq::env_type \ 80 >::type \ 81 >::value \ 82 , add_const< \ 83 typename proto::detail::uncvref< \ 84 typename Seq::env_type \ 85 >::type \ 86 > \ 87 , proto::detail::uncvref< \ 88 typename Seq::env_type \ 89 > \ 90 >::type \ 91 >::type \ 92 type; \ 93 \ 94 static type call(Seq & seq) \ 95 { \ 96 return fusion::INTRINSIC(seq.env); \ 97 } \ 98 } \ 99 /**/ 100 BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(begin); 101 BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(end); 102 BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(size); 103 #undef BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT 104 105 template <typename Seq, typename N> 106 struct value_at 107 { 108 typedef 109 typename fusion::result_of::value_at< 110 typename mpl::eval_if_c< 111 is_const< 112 typename remove_reference< 113 typename Seq::env_type 114 >::type 115 >::value 116 , add_const< 117 typename proto::detail::uncvref< 118 typename Seq::env_type 119 >::type 120 > 121 , proto::detail::uncvref< 122 typename Seq::env_type 123 > 124 >::type 125 , N 126 >::type 127 type; 128 }; 129 130 template <typename Seq, typename N> 131 struct at 132 { 133 typedef 134 typename fusion::result_of::at< 135 typename mpl::eval_if_c< 136 is_const< 137 typename remove_reference< 138 typename Seq::env_type 139 >::type 140 >::value 141 , add_const< 142 typename proto::detail::uncvref< 143 typename Seq::env_type 144 >::type 145 > 146 , proto::detail::uncvref< 147 typename Seq::env_type 148 > 149 >::type 150 , N 151 >::type 152 type; 153 callboost::phoenix::scoped_environment::at154 static type call(Seq & seq) 155 { 156 return fusion::at<N>(seq.env); 157 } 158 }; 159 }; 160 161 template <typename Env, typename Dummy = void> 162 struct is_scoped_environment : mpl::false_ {}; 163 164 template <typename Env> 165 struct is_scoped_environment<Env&> : is_scoped_environment<Env> {}; 166 167 template <typename Env, typename OuterEnv, typename Locals, typename Map> 168 struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> > 169 : mpl::true_ 170 {}; 171 172 template <typename Env, typename OuterEnv, typename Locals, typename Map> 173 struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> const> 174 : mpl::true_ 175 {}; 176 }} 177 178 #endif 179