1 /*============================================================================== 2 Copyright (c) 2001-2010 Joel de Guzman 3 Copyright (c) 2004 Daniel Wallin 4 Copyright (c) 2010 Thomas Heller 5 Copyright (c) 2016 Kohei Takahashi 6 7 Distributed under the Boost Software License, Version 1.0. (See accompanying 8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 ==============================================================================*/ 10 11 #ifndef BOOST_PHOENIX_SCOPE_LAMBDA_HPP 12 #define BOOST_PHOENIX_SCOPE_LAMBDA_HPP 13 14 #include <boost/phoenix/core/limits.hpp> 15 #include <boost/fusion/include/transform.hpp> 16 #include <boost/fusion/include/as_vector.hpp> 17 #include <boost/mpl/int.hpp> 18 #include <boost/phoenix/core/call.hpp> 19 #include <boost/phoenix/core/expression.hpp> 20 #include <boost/phoenix/core/meta_grammar.hpp> 21 #include <boost/phoenix/scope/local_variable.hpp> 22 #include <boost/phoenix/scope/scoped_environment.hpp> 23 24 BOOST_PHOENIX_DEFINE_EXPRESSION( 25 (boost)(phoenix)(lambda_actor) 26 , (proto::terminal<proto::_>) // Locals 27 (proto::terminal<proto::_>) // Map 28 (meta_grammar) // Lambda 29 ) 30 31 BOOST_PHOENIX_DEFINE_EXPRESSION( 32 (boost)(phoenix)(lambda) 33 , (proto::terminal<proto::_>) // OuterEnv 34 (proto::terminal<proto::_>) // Locals 35 (proto::terminal<proto::_>) // Map 36 (meta_grammar) // Lambda 37 ) 38 39 namespace boost { namespace phoenix 40 { 41 struct lambda_eval 42 { 43 BOOST_PROTO_CALLABLE() 44 45 template <typename Sig> 46 struct result; 47 48 template < 49 typename This 50 , typename OuterEnv 51 , typename Locals 52 , typename Map 53 , typename Lambda 54 , typename Context 55 > 56 struct result<This(OuterEnv, Locals, Map, Lambda, Context)> 57 { 58 typedef 59 typename proto::detail::uncvref< 60 typename proto::result_of::value< 61 OuterEnv 62 >::type 63 >::type 64 outer_env_type; 65 66 typedef 67 typename proto::detail::uncvref< 68 typename proto::result_of::value< 69 Locals 70 >::type 71 >::type 72 locals_type; 73 74 typedef 75 typename proto::detail::uncvref< 76 typename proto::result_of::value< 77 Map 78 >::type 79 >::type 80 map_type; 81 82 typedef 83 typename proto::detail::uncvref< 84 typename result_of::env<Context>::type 85 >::type 86 env_type; 87 88 typedef 89 typename result_of::eval< 90 Lambda 91 , typename result_of::context< 92 scoped_environment< 93 env_type 94 , outer_env_type 95 , locals_type 96 , map_type 97 > 98 , typename result_of::actions< 99 Context 100 >::type 101 >::type 102 >::type 103 type; 104 }; 105 106 template <typename OuterEnv, typename Locals, typename Map, typename Lambda, typename Context> 107 typename result<lambda_eval(OuterEnv const &, Locals const &, Map const &, Lambda const &, Context const &)>::type operator ()boost::phoenix::lambda_eval108 operator()(OuterEnv const & outer_env, Locals const & locals, Map const &, Lambda const & lambda, Context const & ctx) const 109 { 110 typedef 111 typename proto::detail::uncvref< 112 typename proto::result_of::value< 113 OuterEnv 114 >::type 115 >::type 116 outer_env_type; 117 118 typedef 119 typename proto::detail::uncvref< 120 typename proto::result_of::value< 121 Locals 122 >::type 123 >::type 124 locals_type; 125 126 typedef 127 typename proto::detail::uncvref< 128 typename proto::result_of::value< 129 Map 130 >::type 131 >::type 132 map_type; 133 134 typedef 135 typename proto::detail::uncvref< 136 typename result_of::env<Context>::type 137 >::type 138 env_type; 139 140 scoped_environment< 141 env_type 142 , outer_env_type 143 , locals_type 144 , map_type 145 > 146 env(phoenix::env(ctx), proto::value(outer_env), proto::value(locals)); 147 148 return eval(lambda, phoenix::context(env, phoenix::actions(ctx))); 149 } 150 }; 151 152 template <typename Dummy> 153 struct default_actions::when<rule::lambda, Dummy> 154 : call<lambda_eval, Dummy> 155 {}; 156 157 template <typename Dummy> 158 struct is_nullary::when<rule::lambda, Dummy> 159 : proto::call< 160 evaluator( 161 proto::_child_c<3> 162 , proto::call< 163 functional::context( 164 proto::make< 165 mpl::true_() 166 > 167 , proto::make< 168 detail::scope_is_nullary_actions() 169 > 170 ) 171 > 172 , proto::make< 173 proto::empty_env() 174 > 175 ) 176 > 177 {}; 178 179 template <typename Dummy> 180 struct is_nullary::when<rule::lambda_actor, Dummy> 181 : proto::or_< 182 proto::when< 183 expression::lambda_actor< 184 proto::terminal<vector0<> > 185 , proto::terminal<proto::_> 186 , meta_grammar 187 > 188 , mpl::true_() 189 > 190 , proto::when< 191 expression::lambda_actor< 192 proto::terminal<proto::_> 193 , proto::terminal<proto::_> 194 , meta_grammar 195 > 196 , proto::fold< 197 proto::call<proto::_value(proto::_child_c<0>)> 198 , proto::make<mpl::true_()> 199 , proto::make< 200 mpl::and_< 201 proto::_state 202 , proto::call< 203 evaluator( 204 proto::_ 205 , _context 206 , proto::make<proto::empty_env()> 207 ) 208 > 209 >() 210 > 211 > 212 > 213 > 214 {}; 215 216 struct lambda_actor_eval 217 { 218 template <typename Sig> 219 struct result; 220 221 template <typename This, typename Vars, typename Map, typename Lambda, typename Context> 222 struct result<This(Vars, Map, Lambda, Context)> 223 { 224 typedef 225 typename proto::detail::uncvref< 226 typename result_of::env<Context>::type 227 >::type 228 env_type; 229 typedef 230 typename proto::detail::uncvref< 231 typename result_of::actions<Context>::type 232 >::type 233 actions_type; 234 typedef 235 typename proto::detail::uncvref< 236 typename proto::result_of::value<Vars>::type 237 >::type 238 vars_type; 239 240 typedef typename 241 detail::result_of::initialize_locals< 242 vars_type 243 , Context 244 >::type 245 locals_type; 246 247 typedef 248 typename expression::lambda< 249 env_type 250 , locals_type 251 , Map 252 , Lambda 253 >::type const 254 type; 255 }; 256 257 template < 258 typename Vars 259 , typename Map 260 , typename Lambda 261 , typename Context 262 > 263 typename result< 264 lambda_actor_eval(Vars const&, Map const &, Lambda const&, Context const &) 265 >::type const operator ()boost::phoenix::lambda_actor_eval266 operator()(Vars const& vars, Map const& map, Lambda const& lambda, Context const & ctx) const 267 { 268 typedef 269 typename proto::detail::uncvref< 270 typename result_of::env<Context>::type 271 >::type 272 env_type; 273 /*typedef 274 typename proto::detail::uncvref< 275 typename result_of::actions<Context>::type 276 >::type 277 actions_type;*/ 278 typedef 279 typename proto::detail::uncvref< 280 typename proto::result_of::value<Vars>::type 281 >::type 282 vars_type; 283 /*typedef 284 typename proto::detail::uncvref< 285 typename proto::result_of::value<Map>::type 286 >::type 287 map_type;*/ 288 289 typedef typename 290 detail::result_of::initialize_locals< 291 vars_type 292 , Context 293 >::type 294 locals_type; 295 296 locals_type locals = initialize_locals(proto::value(vars), ctx); 297 298 return 299 expression:: 300 lambda<env_type, locals_type, Map, Lambda>:: 301 make(phoenix::env(ctx), locals, map, lambda); 302 } 303 }; 304 305 template <typename Dummy> 306 struct default_actions::when<rule::lambda_actor, Dummy> 307 : call<lambda_actor_eval, Dummy> 308 {}; 309 310 template <typename Locals = vector0<>, 311 typename Map = detail::map_local_index_to_tuple<>, 312 typename Dummy = void> 313 struct lambda_actor_gen; 314 315 template <> 316 struct lambda_actor_gen<vector0<>, detail::map_local_index_to_tuple<>, void> 317 { 318 template <typename Expr> 319 typename expression::lambda_actor<vector0<>, detail::map_local_index_to_tuple<>, Expr>::type const 320 operator[](Expr const & expr) const 321 { 322 typedef vector0<> locals_type; 323 typedef detail::map_local_index_to_tuple<> map_type; 324 return expression::lambda_actor<locals_type, map_type, Expr>::make(locals_type(), map_type(), expr); 325 } 326 }; 327 328 template <typename Locals, typename Map> 329 struct lambda_actor_gen<Locals, Map> 330 { lambda_actor_genboost::phoenix::lambda_actor_gen331 lambda_actor_gen(Locals const & locals_) 332 : locals(locals_) 333 {} 334 lambda_actor_genboost::phoenix::lambda_actor_gen335 lambda_actor_gen(lambda_actor_gen const & o) 336 : locals(o.locals) 337 {}; 338 339 template <typename Expr> 340 typename expression::lambda_actor< 341 Locals 342 , Map 343 , Expr 344 >::type const operator []boost::phoenix::lambda_actor_gen345 operator[](Expr const & expr) const 346 { 347 return expression::lambda_actor<Locals, Map, Expr>::make(locals, Map(), expr); 348 } 349 350 Locals locals; 351 }; 352 353 struct lambda_local_gen 354 : lambda_actor_gen<> 355 { 356 #if defined(BOOST_PHOENIX_NO_VARIADIC_SCOPE) 357 lambda_actor_gen<> const operator ()boost::phoenix::lambda_local_gen358 operator()() const 359 { 360 return lambda_actor_gen<>(); 361 } 362 363 #include <boost/phoenix/scope/detail/cpp03/lambda.hpp> 364 #else 365 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME lambda_actor_gen 366 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION operator() 367 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST const 368 #include <boost/phoenix/scope/detail/local_gen.hpp> 369 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME 370 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION 371 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST 372 #endif 373 }; 374 375 typedef lambda_local_gen lambda_type; 376 lambda_local_gen const lambda = lambda_local_gen(); 377 378 }} 379 380 #endif 381