Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2007 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2004 Daniel Wallin
|
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 PHOENIX_SCOPE_LAMBDA_HPP
|
Chris@16
|
9 #define PHOENIX_SCOPE_LAMBDA_HPP
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/spirit/home/phoenix/core/limits.hpp>
|
Chris@16
|
12 #include <boost/spirit/home/phoenix/core/composite.hpp>
|
Chris@16
|
13 #include <boost/spirit/home/phoenix/scope/scoped_environment.hpp>
|
Chris@16
|
14 #include <boost/spirit/home/phoenix/scope/detail/local_variable.hpp>
|
Chris@16
|
15 #include <boost/spirit/home/phoenix/detail/local_reference.hpp>
|
Chris@16
|
16 #include <boost/spirit/home/phoenix/core/actor.hpp>
|
Chris@16
|
17 #include <boost/fusion/include/transform.hpp>
|
Chris@16
|
18 #include <boost/fusion/include/as_vector.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 namespace boost { namespace phoenix
|
Chris@16
|
21 {
|
Chris@16
|
22 template <typename Base, typename OuterEnv, typename Locals, typename Map>
|
Chris@16
|
23 struct lambda_eval : Base
|
Chris@16
|
24 {
|
Chris@16
|
25 template <typename Env>
|
Chris@16
|
26 struct result
|
Chris@16
|
27 {
|
Chris@16
|
28 typedef typename Base::template
|
Chris@16
|
29 result<scoped_environment<Env, OuterEnv, Locals, Map> >::type
|
Chris@16
|
30 result_type;
|
Chris@16
|
31
|
Chris@16
|
32 typedef typename
|
Chris@16
|
33 detail::unwrap_local_reference<result_type>::type
|
Chris@16
|
34 type;
|
Chris@16
|
35 };
|
Chris@16
|
36
|
Chris@16
|
37 lambda_eval(
|
Chris@16
|
38 Base const& base
|
Chris@16
|
39 , OuterEnv const& outer_env
|
Chris@16
|
40 , Locals const& locals)
|
Chris@16
|
41 : Base(base)
|
Chris@16
|
42 , outer_env(outer_env)
|
Chris@16
|
43 , locals(locals) {}
|
Chris@16
|
44
|
Chris@16
|
45 template <typename Env>
|
Chris@16
|
46 typename result<Env>::type
|
Chris@16
|
47 eval(Env const& env) const
|
Chris@16
|
48 {
|
Chris@16
|
49 typedef typename result<Env>::type RT;
|
Chris@16
|
50 return RT(Base::eval(
|
Chris@16
|
51 scoped_environment<Env, OuterEnv, Locals, Map>(
|
Chris@16
|
52 env, outer_env, locals)));
|
Chris@16
|
53 }
|
Chris@16
|
54
|
Chris@16
|
55 OuterEnv outer_env;
|
Chris@16
|
56 mutable Locals locals;
|
Chris@16
|
57 };
|
Chris@16
|
58
|
Chris@16
|
59 template <typename Base, typename Vars, typename Map>
|
Chris@16
|
60 struct lambda_actor
|
Chris@16
|
61 {
|
Chris@16
|
62 typedef typename
|
Chris@16
|
63 mpl::fold<
|
Chris@16
|
64 Vars
|
Chris@16
|
65 , mpl::false_
|
Chris@16
|
66 , detail::compute_no_nullary
|
Chris@16
|
67 >::type
|
Chris@16
|
68 no_nullary;
|
Chris@16
|
69
|
Chris@16
|
70 template <typename Env>
|
Chris@16
|
71 struct result
|
Chris@16
|
72 {
|
Chris@16
|
73 typedef typename
|
Chris@16
|
74 fusion::result_of::as_vector<
|
Chris@16
|
75 typename fusion::result_of::transform<
|
Chris@16
|
76 Vars
|
Chris@16
|
77 , detail::initialize_local<Env>
|
Chris@16
|
78 >::type
|
Chris@16
|
79 >::type
|
Chris@16
|
80 locals_type;
|
Chris@16
|
81
|
Chris@16
|
82 typedef actor<lambda_eval<Base, Env, locals_type, Map> > type;
|
Chris@16
|
83 };
|
Chris@16
|
84
|
Chris@16
|
85 lambda_actor(Base const& f, Vars const& vars)
|
Chris@16
|
86 : f(f), vars(vars) {}
|
Chris@16
|
87
|
Chris@16
|
88 template <typename Env>
|
Chris@16
|
89 typename result<Env>::type
|
Chris@16
|
90 eval(Env const& env) const
|
Chris@16
|
91 {
|
Chris@16
|
92 typedef typename result<Env>::type result_type;
|
Chris@16
|
93
|
Chris@16
|
94 return result_type(
|
Chris@16
|
95 f, env, fusion::as_vector(
|
Chris@16
|
96 fusion::transform(
|
Chris@16
|
97 vars
|
Chris@16
|
98 , detail::initialize_local<Env>(env)
|
Chris@16
|
99 )));
|
Chris@16
|
100 }
|
Chris@16
|
101
|
Chris@16
|
102 Base f;
|
Chris@16
|
103 Vars vars;
|
Chris@16
|
104 };
|
Chris@16
|
105
|
Chris@16
|
106 template <typename Vars, typename Map>
|
Chris@16
|
107 struct lambda_actor_gen
|
Chris@16
|
108 {
|
Chris@16
|
109 template <typename Base>
|
Chris@16
|
110 actor<lambda_actor<Base, Vars, Map> > const
|
Chris@16
|
111 operator[](actor<Base> const& f) const
|
Chris@16
|
112 {
|
Chris@16
|
113 return lambda_actor<Base, Vars, Map>(f, vars);
|
Chris@16
|
114 }
|
Chris@16
|
115
|
Chris@16
|
116 lambda_actor_gen(Vars const& vars)
|
Chris@16
|
117 : vars(vars) {}
|
Chris@16
|
118
|
Chris@16
|
119 Vars vars;
|
Chris@16
|
120 };
|
Chris@16
|
121
|
Chris@16
|
122 template <typename Key>
|
Chris@16
|
123 struct local_variable; // forward
|
Chris@16
|
124 struct assign_eval; // forward
|
Chris@16
|
125
|
Chris@16
|
126 struct lambda_gen
|
Chris@16
|
127 : lambda_actor_gen<
|
Chris@16
|
128 fusion::vector<>
|
Chris@16
|
129 , detail::map_local_index_to_tuple<> >
|
Chris@16
|
130 {
|
Chris@16
|
131 typedef
|
Chris@16
|
132 lambda_actor_gen<
|
Chris@16
|
133 fusion::vector<>
|
Chris@16
|
134 , detail::map_local_index_to_tuple<> >
|
Chris@16
|
135 base_type;
|
Chris@16
|
136
|
Chris@16
|
137 lambda_gen()
|
Chris@16
|
138 : base_type(fusion::vector<>())
|
Chris@16
|
139 {
|
Chris@16
|
140 }
|
Chris@16
|
141
|
Chris@16
|
142 template <typename K0, typename V0>
|
Chris@16
|
143 lambda_actor_gen<
|
Chris@16
|
144 fusion::vector<V0>
|
Chris@16
|
145 , detail::map_local_index_to_tuple<K0>
|
Chris@16
|
146 >
|
Chris@16
|
147 operator()(
|
Chris@16
|
148 actor<composite<assign_eval, fusion::vector<local_variable<K0>, V0> > > const& a0
|
Chris@16
|
149 ) const
|
Chris@16
|
150 {
|
Chris@16
|
151 return fusion::vector<V0>(fusion::at_c<1>(a0));
|
Chris@16
|
152 }
|
Chris@16
|
153
|
Chris@16
|
154 template <typename K0, typename K1, typename V0, typename V1>
|
Chris@16
|
155 lambda_actor_gen<
|
Chris@16
|
156 fusion::vector<V0, V1>
|
Chris@16
|
157 , detail::map_local_index_to_tuple<K0, K1>
|
Chris@16
|
158 >
|
Chris@16
|
159 operator()(
|
Chris@16
|
160 actor<composite<assign_eval, fusion::vector<local_variable<K0>, V0> > > const& a0
|
Chris@16
|
161 , actor<composite<assign_eval, fusion::vector<local_variable<K1>, V1> > > const& a1
|
Chris@16
|
162 ) const
|
Chris@16
|
163 {
|
Chris@16
|
164 return fusion::vector<V0, V1>(fusion::at_c<1>(a0), fusion::at_c<1>(a1));
|
Chris@16
|
165 }
|
Chris@16
|
166
|
Chris@16
|
167 // Bring in the rest...
|
Chris@16
|
168 #define PHOENIX_LOCAL_GEN_NAME lambda_actor_gen
|
Chris@16
|
169 #include <boost/spirit/home/phoenix/scope/detail/local_gen.hpp>
|
Chris@16
|
170 #undef PHOENIX_LOCAL_GEN_NAME
|
Chris@16
|
171 };
|
Chris@16
|
172
|
Chris@16
|
173 lambda_gen const lambda = lambda_gen();
|
Chris@16
|
174 }}
|
Chris@16
|
175
|
Chris@16
|
176 #endif
|