1 /*============================================================================= 2 Copyright (c) 2005-2011 Joel de Guzman 3 Copyright (c) 2011 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_THIS_HPP 9 #define BOOST_PHOENIX_SCOPE_THIS_HPP 10 11 #include <boost/phoenix/core/limits.hpp> 12 #include <boost/phoenix/core/actor.hpp> 13 #include <boost/phoenix/core/environment.hpp> 14 #include <boost/phoenix/core/expression.hpp> 15 #include <boost/phoenix/core/meta_grammar.hpp> 16 #include <boost/phoenix/core/terminal.hpp> 17 #include <boost/phoenix/scope/lambda.hpp> 18 #include <boost/type_traits/remove_pointer.hpp> 19 20 BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG( 21 (boost)(phoenix)(this_) 22 , (meta_grammar)(meta_grammar) 23 , BOOST_PHOENIX_LIMIT 24 ) 25 26 namespace boost { namespace phoenix { 27 namespace detail 28 { 29 /* 30 struct infinite_recursion_detected {}; 31 32 struct last_non_this_actor 33 : proto::or_< 34 proto::when< 35 proto::nary_expr< 36 proto::_ 37 , proto::_ 38 , proto::_ 39 > 40 , proto::_child_c<1> 41 > 42 , proto::when< 43 proto::nary_expr< 44 proto::_ 45 , proto::_ 46 , proto::_ 47 , proto::_ 48 > 49 , proto::_child_c<2> 50 > 51 > 52 {}; 53 */ 54 } 55 struct this_eval 56 { 57 BOOST_PROTO_CALLABLE() 58 59 template <typename Sig> 60 struct result; 61 62 template <typename This, typename A0, typename Context> 63 struct result<This(A0, Context)> 64 { 65 typedef 66 typename proto::detail::uncvref< 67 typename result_of::env< 68 Context 69 >::type 70 >::type 71 outer_env_type; 72 73 typedef 74 typename remove_pointer< 75 typename remove_reference< 76 typename fusion::result_of::at_c< 77 outer_env_type 78 , 0 79 >::type 80 >::type 81 >::type 82 actor_type; 83 84 typedef 85 typename result_of::eval< 86 A0 const & 87 , Context const & 88 >::type 89 a0_type; 90 91 typedef 92 vector2<actor_type const *, a0_type> 93 inner_env_type; 94 95 typedef 96 scoped_environment< 97 inner_env_type 98 , outer_env_type 99 , vector0<> 100 , detail::map_local_index_to_tuple<> 101 > 102 env_type; 103 104 typedef 105 typename result_of::eval< 106 actor_type const & 107 , typename result_of::context< 108 inner_env_type 109 , typename result_of::actions< 110 Context 111 >::type 112 >::type 113 >::type 114 type; 115 }; 116 117 template <typename A0, typename Context> 118 typename result<this_eval(A0 const&, Context const &)>::type operator ()boost::phoenix::this_eval119 operator()(A0 const & a0, Context const & ctx) const 120 { 121 122 //std::cout << typeid(checker).name() << "\n"; 123 //std::cout << typeid(checker).name() << "\n"; 124 typedef 125 typename proto::detail::uncvref< 126 typename result_of::env< 127 Context 128 >::type 129 >::type 130 outer_env_type; 131 132 typedef 133 typename remove_pointer< 134 typename remove_reference< 135 typename fusion::result_of::at_c< 136 outer_env_type 137 , 0 138 >::type 139 >::type 140 >::type 141 actor_type; 142 143 typedef 144 typename result_of::eval< 145 A0 const & 146 , Context const & 147 >::type 148 a0_type; 149 150 typedef 151 vector2<actor_type const *, a0_type> 152 inner_env_type; 153 154 typedef 155 scoped_environment< 156 inner_env_type 157 , outer_env_type 158 , vector0<> 159 , detail::map_local_index_to_tuple<> 160 > 161 env_type; 162 163 inner_env_type inner_env = {fusion::at_c<0>(phoenix::env(ctx)), phoenix::eval(a0, ctx)}; 164 vector0<> locals; 165 env_type env(inner_env, phoenix::env(ctx), locals); 166 167 return phoenix::eval(*fusion::at_c<0>(phoenix::env(ctx)), phoenix::context(inner_env, phoenix::actions(ctx))); 168 //return (*fusion::at_c<0>(phoenix::env(ctx)))(eval(a0, ctx)); 169 } 170 }; 171 172 template <typename Dummy> 173 struct default_actions::when<rule::this_, Dummy> 174 : call<this_eval> 175 {}; 176 177 template <typename Dummy> 178 struct is_nullary::when<rule::this_, Dummy> 179 : proto::make<mpl::false_()> 180 {}; 181 182 template <typename A0> 183 typename expression::this_<A0>::type const this_(A0 const & a0)184 this_(A0 const & a0) 185 { 186 return expression::this_<A0>::make(a0); 187 } 188 189 }} 190 191 #endif 192