]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | |
92 | 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 | |
100 | 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 | |
108 | 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 | |
116 | 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 | |
146 | 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 | |
153 | 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 | |
178 | 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 | |
185 | 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 | ||
202 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | ||
291 | 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 | ||
313 | 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 | |
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 | |
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 | ||
353 | 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 | ||
375 | 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 | |
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 | |
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 | |
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 |