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