• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*==============================================================================
2     Copyright (c) 2005-2010 Joel de Guzman
3     Copyright (c) 2010-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_CORE_ENVIRONMENT_HPP
9 #define BOOST_PHOENIX_CORE_ENVIRONMENT_HPP
10 
11 #include <boost/phoenix/core/limits.hpp>
12 #include <boost/fusion/sequence/intrinsic/at.hpp>
13 #include <boost/fusion/support/is_sequence.hpp>
14 #include <boost/phoenix/support/vector.hpp>
15 #include <boost/proto/transform/impl.hpp>
16 #include <boost/utility/enable_if.hpp>
17 #include <boost/utility/result_of.hpp>
18 
19 #include <typeinfo>
20 
21 namespace boost { namespace phoenix
22 {
23     struct unused {};
24 
25     namespace result_of
26     {
27         template <typename Env, typename Actions>
28         struct context
29         {
30             typedef vector2<Env, Actions> type;
31         };
32 
33         template <typename Env, typename Actions>
34         struct make_context
35             : context<Env, Actions>
36         {};
37 
38         template <typename Context>
39         struct env
40         {
41             typedef
42                 typename fusion::result_of::at_c<
43                     typename boost::remove_reference<Context>::type
44                   , 0
45                 >::type
46                 type;
47         };
48 
49         template <typename Context>
50         struct actions
51         {
52             typedef
53                 typename fusion::result_of::at_c<
54                     typename boost::remove_reference<Context>::type
55                   , 1
56                 >::type
57                 type;
58         };
59     }
60 
61     namespace functional
62     {
63         struct context
64         {
65             BOOST_PROTO_CALLABLE()
66 
67             template <typename Sig>
68             struct result;
69 
70             template <typename This, typename Env, typename Actions>
71             struct result<This(Env, Actions)>
72                 : result<This(Env const &, Actions const &)>
73             {};
74 
75             template <typename This, typename Env, typename Actions>
76             struct result<This(Env &, Actions)>
77                 : result<This(Env &, Actions const &)>
78             {};
79 
80             template <typename This, typename Env, typename Actions>
81             struct result<This(Env, Actions &)>
82                 : result<This(Env const &, Actions &)>
83             {};
84 
85             template <typename This, typename Env, typename Actions>
86             struct result<This(Env &, Actions &)>
87                 : result_of::context<Env &, Actions &>
88             {};
89 
90             template <typename Env, typename Actions>
91             typename result_of::context<Env &, Actions &>::type
operator ()boost::phoenix::functional::context92             operator()(Env & env, Actions & actions) const
93             {
94                 vector2<Env &, Actions &> e = {env, actions};
95                 return e;
96             }
97 
98             template <typename Env, typename Actions>
99             typename result_of::context<Env const &, Actions &>::type
operator ()boost::phoenix::functional::context100             operator()(Env const & env, Actions & actions) const
101             {
102                 vector2<Env const &, Actions &> e = {env, actions};
103                 return e;
104             }
105 
106             template <typename Env, typename Actions>
107             typename result_of::context<Env &, Actions const &>::type
operator ()boost::phoenix::functional::context108             operator()(Env & env, Actions const & actions) const
109             {
110                 vector2<Env &, Actions const &> e = {env, actions};
111                 return e;
112             }
113 
114             template <typename Env, typename Actions>
115             typename result_of::context<Env const &, Actions const &>::type
operator ()boost::phoenix::functional::context116             operator()(Env const & env, Actions const & actions) const
117             {
118                 vector2<Env const&, Actions const &> e = {env, actions};
119                 return e;
120             }
121         };
122 
123         struct make_context
124             : context
125         {};
126 
127         struct env
128         {
129             BOOST_PROTO_CALLABLE()
130 
131             template <typename Sig>
132             struct result;
133 
134             template <typename This, typename Context>
135             struct result<This(Context)>
136                 : result<This(Context const &)>
137             {};
138 
139             template <typename This, typename Context>
140             struct result<This(Context &)>
141                 : result_of::env<Context>
142             {};
143 
144             template <typename Context>
145             typename result_of::env<Context const>::type
operator ()boost::phoenix::functional::env146             operator()(Context const & ctx) const
147             {
148                 return fusion::at_c<0>(ctx);
149             }
150 
151             template <typename Context>
152             typename result_of::env<Context>::type
operator ()boost::phoenix::functional::env153             operator()(Context & ctx) const
154             {
155                 return fusion::at_c<0>(ctx);
156             }
157         };
158 
159         struct actions
160         {
161             BOOST_PROTO_CALLABLE()
162 
163             template <typename Sig>
164             struct result;
165 
166             template <typename This, typename Context>
167             struct result<This(Context)>
168                 : result<This(Context const &)>
169             {};
170 
171             template <typename This, typename Context>
172             struct result<This(Context &)>
173                 : result_of::actions<Context>
174             {};
175 
176             template <typename Context>
177             typename result_of::actions<Context const>::type
operator ()boost::phoenix::functional::actions178             operator()(Context const & ctx) const
179             {
180                 return fusion::at_c<1>(ctx);
181             }
182 
183             template <typename Context>
184             typename result_of::actions<Context>::type
operator ()boost::phoenix::functional::actions185             operator()(Context & ctx) const
186             {
187                 return fusion::at_c<1>(ctx);
188             }
189         };
190 
191     }
192 
193     struct _context
194         : proto::transform<_context>
195     {
196         template <typename Expr, typename State, typename Data>
197         struct impl
198             : proto::transform_impl<Expr, State, Data>
199         {
200             typedef vector2<State, Data> result_type;
201 
operator ()boost::phoenix::_context::impl202             result_type operator()(
203                 typename impl::expr_param
204               , typename impl::state_param s
205               , typename impl::data_param d
206             ) const
207             {
208                 vector2<State, Data> e = {s, d};
209                 return e;
210             }
211         };
212     };
213 
214     template <typename Env, typename Actions>
215     inline
216     typename result_of::context<Env const &, Actions const&>::type const
context(Env const & env,Actions const & actions)217     context(Env const& env, Actions const& actions)
218     {
219         vector2<Env const&, Actions const &> e = {env, actions};
220         return e;
221     }
222 
223     template <typename Env, typename Actions>
224     inline
225     typename result_of::context<Env const &, Actions const&>::type const
make_context(Env const & env,Actions const & actions)226     make_context(Env const& env, Actions const& actions)
227     {
228         return context(env, actions);
229     }
230 
231     template <typename Env, typename Actions>
232     inline
233     typename result_of::context<Env &, Actions const&>::type const
context(Env & env,Actions const & actions)234     context(Env & env, Actions const& actions)
235     {
236         vector2<Env &, Actions const &> e = {env, actions};
237         return e;
238     }
239 
240     template <typename Env, typename Actions>
241     inline
242     typename result_of::context<Env &, Actions const&>::type const
make_context(Env & env,Actions const & actions)243     make_context(Env & env, Actions const& actions)
244     {
245         return context(env, actions);
246     }
247 
248     template <typename Env, typename Actions>
249     inline
250     typename result_of::context<Env const &, Actions &>::type const
context(Env const & env,Actions & actions)251     context(Env const& env, Actions & actions)
252     {
253         vector2<Env const&, Actions &> e = {env, actions};
254         return e;
255     }
256 
257     template <typename Env, typename Actions>
258     inline
259     typename result_of::context<Env const &, Actions &>::type const
make_context(Env const & env,Actions & actions)260     make_context(Env const& env, Actions & actions)
261     {
262         return context(env, actions);
263     }
264 
265     template <typename Env, typename Actions>
266     inline
267     typename result_of::context<Env &, Actions &>::type const
context(Env & env,Actions & actions)268     context(Env & env, Actions & actions)
269     {
270         vector2<Env &, Actions &> e = {env, actions};
271         return e;
272     }
273 
274     template <typename Env, typename Actions>
275     inline
276     typename result_of::context<Env &, Actions &>::type const
make_context(Env & env,Actions & actions)277     make_context(Env & env, Actions & actions)
278     {
279         return context(env, actions);
280     }
281 
282     struct _env
283         : proto::transform<_env>
284     {
285         template <typename Expr, typename State, typename Data>
286         struct impl
287             : proto::transform_impl<Expr, State, Data>
288         {
289             typedef State result_type;
290 
operator ()boost::phoenix::_env::impl291             result_type operator()(
292                 typename impl::expr_param
293               , typename impl::state_param s
294               , typename impl::data_param
295             ) const
296             {
297                 return s;
298             }
299         };
300     };
301 
302     template <typename Expr, typename State>
303     struct _env::impl<Expr, State, proto::empty_env>
304         : proto::transform_impl<Expr, State, proto::empty_env>
305     {
306             typedef
307                 typename fusion::result_of::at_c<
308                     typename boost::remove_reference<State>::type
309                   , 0
310                 >::type
311                 result_type;
312 
operator ()boost::phoenix::_env::impl313             result_type operator()(
314                 typename impl::expr_param
315               , typename impl::state_param s
316               , typename impl::data_param
317             ) const
318             {
319                 return fusion::at_c<0>(s);
320             }
321     };
322 
323     template <typename Expr, typename State>
324     struct _env::impl<Expr, State, unused>
325         : _env::impl<Expr, State, proto::empty_env>
326     {};
327 
328     template <typename Context>
329     inline
330     typename fusion::result_of::at_c<Context, 0>::type
env(Context & ctx)331     env(Context & ctx)
332     {
333         return fusion::at_c<0>(ctx);
334     }
335 
336     template <typename Context>
337     inline
338     typename fusion::result_of::at_c<Context const, 0>::type
env(Context const & ctx)339     env(Context const & ctx)
340     {
341         return fusion::at_c<0>(ctx);
342     }
343 
344     struct _actions
345         : proto::transform<_actions>
346     {
347         template <typename Expr, typename State, typename Data>
348         struct impl
349             : proto::transform_impl<Expr, State, Data>
350         {
351             typedef Data result_type;
352 
operator ()boost::phoenix::_actions::impl353             result_type operator()(
354                 typename impl::expr_param
355               , typename impl::state_param
356               , typename impl::data_param d
357             ) const
358             {
359                 return d;
360             }
361         };
362     };
363 
364     template <typename Expr, typename State>
365     struct _actions::impl<Expr, State, proto::empty_env>
366         : proto::transform_impl<Expr, State, proto::empty_env>
367     {
368             typedef
369                 typename fusion::result_of::at_c<
370                     typename boost::remove_reference<State>::type
371                   , 1
372                 >::type
373                 result_type;
374 
operator ()boost::phoenix::_actions::impl375             result_type operator()(
376                 typename impl::expr_param
377               , typename impl::state_param s
378               , typename impl::data_param
379             ) const
380             {
381                 return fusion::at_c<1>(s);
382             }
383     };
384 
385     template <typename Expr, typename State>
386     struct _actions::impl<Expr, State, unused>
387         : _actions::impl<Expr, State, proto::empty_env>
388     {};
389 
390     template <typename Context>
391     inline
392     typename fusion::result_of::at_c<Context, 1>::type
actions(Context & ctx)393     actions(Context & ctx)
394     {
395         return fusion::at_c<1>(ctx);
396     }
397 
398     template <typename Context>
399     inline
400     typename fusion::result_of::at_c<Context const, 1>::type
actions(Context const & ctx)401     actions(Context const & ctx)
402     {
403         return fusion::at_c<1>(ctx);
404     }
405 
406     namespace result_of
407     {
408         template <
409             BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
410                 BOOST_PHOENIX_LIMIT
411               , typename A
412               , mpl::void_
413             )
414           , typename Dummy = void
415         >
416         struct make_env;
417 
418     #define M0(Z, N, D)                                                         \
419         template <BOOST_PHOENIX_typename_A(N)>                                  \
420         struct make_env<BOOST_PHOENIX_A(N)>                                     \
421         {                                                                       \
422             typedef BOOST_PP_CAT(vector, N)<BOOST_PHOENIX_A(N)> type;           \
423         };                                                                      \
424     /**/
425         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
426     #undef M0
427     }
428 
429     inline
430     result_of::make_env<>::type
make_env()431     make_env()
432     {
433         return result_of::make_env<>::type();
434     }
435 #define M0(Z, N, D)                                                             \
436     template <BOOST_PHOENIX_typename_A(N)>                                      \
437     inline                                                                      \
438     typename result_of::make_env<BOOST_PHOENIX_A_ref(N)>::type                  \
439     make_env(BOOST_PHOENIX_A_ref_a(N))                                          \
440     {                                                                           \
441         typename result_of::make_env<BOOST_PHOENIX_A_ref(N)>::type              \
442             env =                                                               \
443             {                                                                   \
444                 BOOST_PHOENIX_a(N)                                              \
445             };                                                                  \
446         return env;                                                             \
447     }                                                                           \
448     template <BOOST_PHOENIX_typename_A(N)>                                      \
449     inline                                                                      \
450     typename result_of::make_env<BOOST_PHOENIX_A_const_ref(N)>::type            \
451     make_env(BOOST_PHOENIX_A_const_ref_a(N))                                    \
452     {                                                                           \
453         typename result_of::make_env<BOOST_PHOENIX_A_const_ref(N)>::type        \
454             env =                                                               \
455             {                                                                   \
456                 BOOST_PHOENIX_a(N)                                              \
457             };                                                                  \
458         return env;                                                             \
459     }                                                                           \
460     /**/
461         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
462     #undef M0
463 
464     template <typename T, typename Enable = void>
465     struct is_environment : fusion::traits::is_sequence<T> {};
466 }}
467 
468 #endif
469 
470