• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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