1 /*==============================================================================
2 Copyright (c) 2005-2010 Joel de Guzman
3 Copyright (c) 2010-2011 Thomas Heller
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
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>
21 namespace boost { namespace phoenix
27 template <typename Env, typename Actions>
30 typedef vector2<Env, Actions> type;
33 template <typename Env, typename Actions>
35 : context<Env, Actions>
38 template <typename Context>
42 typename fusion::result_of::at_c<
43 typename boost::remove_reference<Context>::type
49 template <typename Context>
53 typename fusion::result_of::at_c<
54 typename boost::remove_reference<Context>::type
65 BOOST_PROTO_CALLABLE()
67 template <typename Sig>
70 template <typename This, typename Env, typename Actions>
71 struct result<This(Env, Actions)>
72 : result<This(Env const &, Actions const &)>
75 template <typename This, typename Env, typename Actions>
76 struct result<This(Env &, Actions)>
77 : result<This(Env &, Actions const &)>
80 template <typename This, typename Env, typename Actions>
81 struct result<This(Env, Actions &)>
82 : result<This(Env const &, Actions &)>
85 template <typename This, typename Env, typename Actions>
86 struct result<This(Env &, Actions &)>
87 : result_of::context<Env &, Actions &>
90 template <typename Env, typename Actions>
91 typename result_of::context<Env &, Actions &>::type
92 operator()(Env & env, Actions & actions) const
94 vector2<Env &, Actions &> e = {env, actions};
98 template <typename Env, typename Actions>
99 typename result_of::context<Env const &, Actions &>::type
100 operator()(Env const & env, Actions & actions) const
102 vector2<Env const &, Actions &> e = {env, actions};
106 template <typename Env, typename Actions>
107 typename result_of::context<Env &, Actions const &>::type
108 operator()(Env & env, Actions const & actions) const
110 vector2<Env &, Actions const &> e = {env, actions};
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
118 vector2<Env const&, Actions const &> e = {env, actions};
129 BOOST_PROTO_CALLABLE()
131 template <typename Sig>
134 template <typename This, typename Context>
135 struct result<This(Context)>
136 : result<This(Context const &)>
139 template <typename This, typename Context>
140 struct result<This(Context &)>
141 : result_of::env<Context>
144 template <typename Context>
145 typename result_of::env<Context const>::type
146 operator()(Context const & ctx) const
148 return fusion::at_c<0>(ctx);
151 template <typename Context>
152 typename result_of::env<Context>::type
153 operator()(Context & ctx) const
155 return fusion::at_c<0>(ctx);
161 BOOST_PROTO_CALLABLE()
163 template <typename Sig>
166 template <typename This, typename Context>
167 struct result<This(Context)>
168 : result<This(Context const &)>
171 template <typename This, typename Context>
172 struct result<This(Context &)>
173 : result_of::actions<Context>
176 template <typename Context>
177 typename result_of::actions<Context const>::type
178 operator()(Context const & ctx) const
180 return fusion::at_c<1>(ctx);
183 template <typename Context>
184 typename result_of::actions<Context>::type
185 operator()(Context & ctx) const
187 return fusion::at_c<1>(ctx);
194 : proto::transform<_context>
196 template <typename Expr, typename State, typename Data>
198 : proto::transform_impl<Expr, State, Data>
200 typedef vector2<State, Data> result_type;
202 result_type operator()(
203 typename impl::expr_param
204 , typename impl::state_param s
205 , typename impl::data_param d
208 vector2<State, Data> e = {s, d};
214 template <typename Env, typename Actions>
216 typename result_of::context<Env const &, Actions const&>::type const
217 context(Env const& env, Actions const& actions)
219 vector2<Env const&, Actions const &> e = {env, actions};
223 template <typename Env, typename Actions>
225 typename result_of::context<Env const &, Actions const&>::type const
226 make_context(Env const& env, Actions const& actions)
228 return context(env, actions);
231 template <typename Env, typename Actions>
233 typename result_of::context<Env &, Actions const&>::type const
234 context(Env & env, Actions const& actions)
236 vector2<Env &, Actions const &> e = {env, actions};
240 template <typename Env, typename Actions>
242 typename result_of::context<Env &, Actions const&>::type const
243 make_context(Env & env, Actions const& actions)
245 return context(env, actions);
248 template <typename Env, typename Actions>
250 typename result_of::context<Env const &, Actions &>::type const
251 context(Env const& env, Actions & actions)
253 vector2<Env const&, Actions &> e = {env, actions};
257 template <typename Env, typename Actions>
259 typename result_of::context<Env const &, Actions &>::type const
260 make_context(Env const& env, Actions & actions)
262 return context(env, actions);
265 template <typename Env, typename Actions>
267 typename result_of::context<Env &, Actions &>::type const
268 context(Env & env, Actions & actions)
270 vector2<Env &, Actions &> e = {env, actions};
274 template <typename Env, typename Actions>
276 typename result_of::context<Env &, Actions &>::type const
277 make_context(Env & env, Actions & actions)
279 return context(env, actions);
283 : proto::transform<_env>
285 template <typename Expr, typename State, typename Data>
287 : proto::transform_impl<Expr, State, Data>
289 typedef State result_type;
291 result_type operator()(
292 typename impl::expr_param
293 , typename impl::state_param s
294 , typename impl::data_param
302 template <typename Expr, typename State>
303 struct _env::impl<Expr, State, proto::empty_env>
304 : proto::transform_impl<Expr, State, proto::empty_env>
307 typename fusion::result_of::at_c<
308 typename boost::remove_reference<State>::type
313 result_type operator()(
314 typename impl::expr_param
315 , typename impl::state_param s
316 , typename impl::data_param
319 return fusion::at_c<0>(s);
323 template <typename Expr, typename State>
324 struct _env::impl<Expr, State, unused>
325 : _env::impl<Expr, State, proto::empty_env>
328 template <typename Context>
330 typename fusion::result_of::at_c<Context, 0>::type
333 return fusion::at_c<0>(ctx);
336 template <typename Context>
338 typename fusion::result_of::at_c<Context const, 0>::type
339 env(Context const & ctx)
341 return fusion::at_c<0>(ctx);
345 : proto::transform<_actions>
347 template <typename Expr, typename State, typename Data>
349 : proto::transform_impl<Expr, State, Data>
351 typedef Data result_type;
353 result_type operator()(
354 typename impl::expr_param
355 , typename impl::state_param
356 , typename impl::data_param d
364 template <typename Expr, typename State>
365 struct _actions::impl<Expr, State, proto::empty_env>
366 : proto::transform_impl<Expr, State, proto::empty_env>
369 typename fusion::result_of::at_c<
370 typename boost::remove_reference<State>::type
375 result_type operator()(
376 typename impl::expr_param
377 , typename impl::state_param s
378 , typename impl::data_param
381 return fusion::at_c<1>(s);
385 template <typename Expr, typename State>
386 struct _actions::impl<Expr, State, unused>
387 : _actions::impl<Expr, State, proto::empty_env>
390 template <typename Context>
392 typename fusion::result_of::at_c<Context, 1>::type
393 actions(Context & ctx)
395 return fusion::at_c<1>(ctx);
398 template <typename Context>
400 typename fusion::result_of::at_c<Context const, 1>::type
401 actions(Context const & ctx)
403 return fusion::at_c<1>(ctx);
409 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
414 , typename Dummy = void
418 #define M0(Z, N, D) \
419 template <BOOST_PHOENIX_typename_A(N)> \
420 struct make_env<BOOST_PHOENIX_A(N)> \
422 typedef BOOST_PP_CAT(vector, N)<BOOST_PHOENIX_A(N)> type; \
425 BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
430 result_of::make_env<>::type
433 return result_of::make_env<>::type();
435 #define M0(Z, N, D) \
436 template <BOOST_PHOENIX_typename_A(N)> \
438 typename result_of::make_env<BOOST_PHOENIX_A_ref(N)>::type \
439 make_env(BOOST_PHOENIX_A_ref_a(N)) \
441 typename result_of::make_env<BOOST_PHOENIX_A_ref(N)>::type \
448 template <BOOST_PHOENIX_typename_A(N)> \
450 typename result_of::make_env<BOOST_PHOENIX_A_const_ref(N)>::type \
451 make_env(BOOST_PHOENIX_A_const_ref_a(N)) \
453 typename result_of::make_env<BOOST_PHOENIX_A_const_ref(N)>::type \
461 BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
464 template <typename T, typename Enable = void>
465 struct is_environment : fusion::traits::is_sequence<T> {};