1 | /*============================================================================= |
---|
2 | Phoenix V1.2.1 |
---|
3 | Copyright (c) 2001-2003 Joel de Guzman |
---|
4 | |
---|
5 | Use, modification and distribution is subject to the Boost Software |
---|
6 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
---|
7 | http://www.boost.org/LICENSE_1_0.txt) |
---|
8 | ==============================================================================*/ |
---|
9 | #include <vector> |
---|
10 | #include <algorithm> |
---|
11 | #include <iostream> |
---|
12 | |
---|
13 | #define PHOENIX_LIMIT 5 |
---|
14 | #include <boost/spirit/phoenix/operators.hpp> |
---|
15 | #include <boost/spirit/phoenix/primitives.hpp> |
---|
16 | #include <boost/spirit/phoenix/composite.hpp> |
---|
17 | #include <boost/spirit/phoenix/special_ops.hpp> |
---|
18 | #include <boost/spirit/phoenix/statements.hpp> |
---|
19 | |
---|
20 | namespace phoenix { |
---|
21 | |
---|
22 | /////////////////////////////////////////////////////////////////////////////// |
---|
23 | // |
---|
24 | // local_tuple |
---|
25 | // |
---|
26 | // This *is a* tuple like the one we see in TupleT in any actor |
---|
27 | // base class' eval member function. local_tuple should look and |
---|
28 | // feel the same as a tupled-args, that's why it is derived from |
---|
29 | // TupleArgsT. It has an added member, locs which is another tuple |
---|
30 | // where the local variables will be stored. locs is mutable to |
---|
31 | // allow read-write access to our locals regardless of |
---|
32 | // local_tuple's constness (The eval member function accepts it as |
---|
33 | // a const argument). |
---|
34 | // |
---|
35 | /////////////////////////////////////////////////////////////////////////////// |
---|
36 | template <typename TupleArgsT, typename TupleLocsT> |
---|
37 | struct local_tuple : public TupleArgsT { |
---|
38 | |
---|
39 | typedef TupleLocsT local_vars_t; |
---|
40 | |
---|
41 | local_tuple(TupleArgsT const& args, TupleLocsT const& locs_) |
---|
42 | : TupleArgsT(args), locs(locs_) {} |
---|
43 | |
---|
44 | mutable TupleLocsT locs; |
---|
45 | }; |
---|
46 | |
---|
47 | /////////////////////////////////////////////////////////////////////////////// |
---|
48 | // |
---|
49 | // local_var_result |
---|
50 | // |
---|
51 | // This is a return type computer. Given a constant integer N and a |
---|
52 | // tuple, get the Nth local variable type. If TupleT is not really |
---|
53 | // a local_tuple, we just return nil_t. Otherwise we get the Nth |
---|
54 | // local variable type. |
---|
55 | // |
---|
56 | /////////////////////////////////////////////////////////////////////////////// |
---|
57 | template <int N, typename TupleT> |
---|
58 | struct local_var_result { |
---|
59 | |
---|
60 | typedef nil_t type; |
---|
61 | }; |
---|
62 | |
---|
63 | ////////////////////////////////// |
---|
64 | template <int N, typename TupleArgsT, typename TupleLocsT> |
---|
65 | struct local_var_result<N, local_tuple<TupleArgsT, TupleLocsT> > { |
---|
66 | |
---|
67 | typedef typename tuple_element<N, TupleLocsT>::type& type; |
---|
68 | }; |
---|
69 | |
---|
70 | /////////////////////////////////////////////////////////////////////////////// |
---|
71 | // |
---|
72 | // local_var |
---|
73 | // |
---|
74 | // This class looks so curiously like the argument class. local_var |
---|
75 | // provides access to the Nth local variable packed in the tuple |
---|
76 | // duo local_tuple above. Note that the member function eval |
---|
77 | // expects a local_tuple argument. Otherwise the expression |
---|
78 | // 'tuple.locs' will fail (compile-time error). local_var |
---|
79 | // primitives only work within the context of a locals_composite |
---|
80 | // (see below). |
---|
81 | // |
---|
82 | // Provided are some predefined local_var actors for 0..N local |
---|
83 | // variable access: loc1..locN. |
---|
84 | // |
---|
85 | /////////////////////////////////////////////////////////////////////////////// |
---|
86 | template <int N> |
---|
87 | struct local_var { |
---|
88 | |
---|
89 | template <typename TupleT> |
---|
90 | struct result { |
---|
91 | |
---|
92 | typedef typename local_var_result<N, TupleT>::type type; |
---|
93 | }; |
---|
94 | |
---|
95 | template <typename TupleT> |
---|
96 | typename local_var_result<N, TupleT>::type |
---|
97 | eval(TupleT const& tuple) const |
---|
98 | { |
---|
99 | return tuple.locs[tuple_index<N>()]; |
---|
100 | } |
---|
101 | }; |
---|
102 | |
---|
103 | ////////////////////////////////// |
---|
104 | actor<local_var<0> > const loc1 = local_var<0>(); |
---|
105 | actor<local_var<1> > const loc2 = local_var<1>(); |
---|
106 | actor<local_var<2> > const loc3 = local_var<2>(); |
---|
107 | actor<local_var<3> > const loc4 = local_var<3>(); |
---|
108 | actor<local_var<4> > const loc5 = local_var<4>(); |
---|
109 | |
---|
110 | /////////////////////////////////////////////////////////////////////////////// |
---|
111 | // |
---|
112 | // locals_composite |
---|
113 | // |
---|
114 | // This class encapsulates an actor and some local variable |
---|
115 | // initializers packed in a tuple. |
---|
116 | // |
---|
117 | // locals_composite is just like a proxy and delegates the actual |
---|
118 | // evaluation to the actor. The actor does the actual work. In the |
---|
119 | // eval member function, before invoking the embedded actor's eval |
---|
120 | // member function, we first stuff an instance of our locals and |
---|
121 | // bundle both 'args' and 'locals' in a local_tuple. This |
---|
122 | // local_tuple instance is created in the stack initializing it |
---|
123 | // with our locals member. We then pass this local_tuple instance |
---|
124 | // as an argument to the actor's eval member function. |
---|
125 | // |
---|
126 | /////////////////////////////////////////////////////////////////////////////// |
---|
127 | template <typename ActorT, typename LocsT> |
---|
128 | struct locals_composite { |
---|
129 | |
---|
130 | typedef locals_composite<ActorT, LocsT> self_t; |
---|
131 | |
---|
132 | template <typename TupleT> |
---|
133 | struct result { typedef typename actor_result<ActorT, TupleT>::type type; }; |
---|
134 | |
---|
135 | locals_composite(ActorT const& actor_, LocsT const& locals_) |
---|
136 | : actor(actor_), locals(locals_) {} |
---|
137 | |
---|
138 | template <typename TupleT> |
---|
139 | typename actor_result<ActorT, TupleT>::type |
---|
140 | eval(TupleT const& args) const |
---|
141 | { |
---|
142 | actor.eval(local_tuple<TupleT, LocsT>(args, locals)); |
---|
143 | } |
---|
144 | |
---|
145 | ActorT actor; |
---|
146 | LocsT locals; |
---|
147 | }; |
---|
148 | |
---|
149 | /////////////////////////////////////////////////////////////////////////////// |
---|
150 | // |
---|
151 | // locals_gen |
---|
152 | // |
---|
153 | // At construction time, this class is given some local var- |
---|
154 | // initializers packed in a tuple. We just store this for later. |
---|
155 | // The operator[] of this class creates the actual locals_composite |
---|
156 | // given an actor. This is responsible for the construct |
---|
157 | // locals<types>[actor]. |
---|
158 | // |
---|
159 | /////////////////////////////////////////////////////////////////////////////// |
---|
160 | template <typename LocsT> |
---|
161 | struct locals_gen { |
---|
162 | |
---|
163 | locals_gen(LocsT const& locals_) |
---|
164 | : locals(locals_) {} |
---|
165 | |
---|
166 | template <typename ActorT> |
---|
167 | actor<locals_composite<typename as_actor<ActorT>::type, LocsT> > |
---|
168 | operator[](ActorT const& actor) |
---|
169 | { |
---|
170 | return locals_composite<typename as_actor<ActorT>::type, LocsT> |
---|
171 | (as_actor<ActorT>::convert(actor), locals); |
---|
172 | } |
---|
173 | |
---|
174 | LocsT locals; |
---|
175 | }; |
---|
176 | |
---|
177 | /////////////////////////////////////////////////////////////////////////////// |
---|
178 | // |
---|
179 | // Front end generator functions. These generators are overloaded for |
---|
180 | // 1..N local variables. locals<T0,... TN>(i0,...iN) generate locals_gen |
---|
181 | // objects (see above). |
---|
182 | // |
---|
183 | /////////////////////////////////////////////////////////////////////////////// |
---|
184 | template <typename T0> |
---|
185 | inline locals_gen<tuple<T0> > |
---|
186 | locals( |
---|
187 | T0 const& _0 = T0() |
---|
188 | ) |
---|
189 | { |
---|
190 | typedef tuple<T0> tuple_t; |
---|
191 | return locals_gen<tuple_t>(tuple_t(_0)); |
---|
192 | } |
---|
193 | |
---|
194 | ////////////////////////////////// |
---|
195 | template <typename T0, typename T1> |
---|
196 | inline locals_gen<tuple<T0, T1> > |
---|
197 | locals( |
---|
198 | T0 const& _0 = T0(), |
---|
199 | T1 const& _1 = T1() |
---|
200 | ) |
---|
201 | { |
---|
202 | typedef tuple<T0, T1> tuple_t; |
---|
203 | return locals_gen<tuple_t>(tuple_t(_0, _1)); |
---|
204 | } |
---|
205 | |
---|
206 | ////////////////////////////////// |
---|
207 | template <typename T0, typename T1, typename T2> |
---|
208 | inline locals_gen<tuple<T0, T1, T2> > |
---|
209 | locals( |
---|
210 | T0 const& _0 = T0(), |
---|
211 | T1 const& _1 = T1(), |
---|
212 | T2 const& _2 = T2() |
---|
213 | ) |
---|
214 | { |
---|
215 | typedef tuple<T0, T1, T2> tuple_t; |
---|
216 | return locals_gen<tuple_t>(tuple_t(_0, _1, _2)); |
---|
217 | } |
---|
218 | |
---|
219 | ////////////////////////////////// |
---|
220 | template <typename T0, typename T1, typename T2, typename T3> |
---|
221 | inline locals_gen<tuple<T0, T1, T2, T3> > |
---|
222 | locals( |
---|
223 | T0 const& _0 = T0(), |
---|
224 | T1 const& _1 = T1(), |
---|
225 | T2 const& _2 = T2(), |
---|
226 | T3 const& _3 = T3() |
---|
227 | ) |
---|
228 | { |
---|
229 | typedef tuple<T0, T1, T2, T3> tuple_t; |
---|
230 | return locals_gen<tuple_t>(tuple_t(_0, _1, _2, _3)); |
---|
231 | } |
---|
232 | |
---|
233 | ////////////////////////////////// |
---|
234 | template <typename T0, typename T1, typename T2, typename T3, typename T4> |
---|
235 | inline locals_gen<tuple<T0, T1, T2, T3, T4> > |
---|
236 | locals( |
---|
237 | T0 const& _0 = T0(), |
---|
238 | T1 const& _1 = T1(), |
---|
239 | T2 const& _2 = T2(), |
---|
240 | T3 const& _3 = T3(), |
---|
241 | T4 const& _4 = T4() |
---|
242 | ) |
---|
243 | { |
---|
244 | typedef tuple<T0, T1, T2, T3> tuple_t; |
---|
245 | return locals_gen<tuple_t>(tuple_t(_0, _1, _2, _3, _4)); |
---|
246 | } |
---|
247 | |
---|
248 | /////////////////////////////////////////////////////////////////////////////// |
---|
249 | } |
---|
250 | |
---|
251 | ////////////////////////////////// |
---|
252 | using namespace std; |
---|
253 | using namespace phoenix; |
---|
254 | |
---|
255 | ////////////////////////////////// |
---|
256 | int |
---|
257 | main() |
---|
258 | { |
---|
259 | int init[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; |
---|
260 | vector<int> c(init, init + 10); |
---|
261 | typedef vector<int>::iterator iterator; |
---|
262 | |
---|
263 | for_each(c.begin(), c.end(), |
---|
264 | locals<int, char const*>(0, "...That's all\n") |
---|
265 | [ |
---|
266 | for_(loc1 = 0, loc1 < arg1, ++loc1) |
---|
267 | [ |
---|
268 | cout << loc1 << ", " |
---|
269 | ], |
---|
270 | cout << loc2 |
---|
271 | ] |
---|
272 | ); |
---|
273 | |
---|
274 | return 0; |
---|
275 | } |
---|