]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample10.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / classic / phoenix / example / fundamental / sample10.cpp
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/include/phoenix1_operators.hpp>
15 #include <boost/spirit/include/phoenix1_primitives.hpp>
16 #include <boost/spirit/include/phoenix1_composite.hpp>
17 #include <boost/spirit/include/phoenix1_special_ops.hpp>
18 #include <boost/spirit/include/phoenix1_statements.hpp>
19 #include <boost/spirit/include/phoenix1_functions.hpp>
20
21 namespace phoenix {
22
23 ///////////////////////////////////////////////////////////////////////////////
24 //
25 // local_tuple
26 //
27 // This *is a* tuple like the one we see in TupleT in any actor
28 // base class' eval member function. local_tuple should look and
29 // feel the same as a tupled-args, that's why it is derived from
30 // TupleArgsT. It has an added member, locs which is another tuple
31 // where the local variables will be stored. locs is mutable to
32 // allow read-write access to our locals regardless of
33 // local_tuple's constness (The eval member function accepts it as
34 // a const argument).
35 //
36 ///////////////////////////////////////////////////////////////////////////////
37 template <typename TupleArgsT, typename TupleLocsT>
38 struct local_tuple : public TupleArgsT {
39
40 local_tuple(TupleArgsT const& args, TupleLocsT const& locs_)
41 : TupleArgsT(args), locs(locs_) {}
42
43 mutable TupleLocsT locs;
44 };
45
46 ///////////////////////////////////////////////////////////////////////////////
47 //
48 // local_var_result
49 //
50 // This is a return type computer. Given a constant integer N, a
51 // parent index and a tuple, get the Nth local variable type. The
52 // parent index is an integer specifying which parent scope to
53 // access; 0==current scope, 1==parent scope, 2==parent's parent
54 // scope etc.
55 //
56 // This is a metaprogram with partial specializations. There is a
57 // general case, a special case for local_tuples and a terminating
58 // special case for local_tuples.
59 //
60 // General case: If TupleT is not really a local_tuple, we just return nil_t.
61 //
62 // local_tuples case:
63 // Parent index is 0: We get the Nth local variable.
64 // Otherwise: We subclass from local_tuples<N, Parent-1, TupleArgsT>
65 //
66 ///////////////////////////////////////////////////////////////////////////////
67 template <int N, int Parent, typename TupleT>
68 struct local_var_result {
69
70 typedef nil_t type;
71 };
72
73 //////////////////////////////////
74 template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
75 struct local_var_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
76 : public local_var_result<N, Parent-1, TupleArgsT> {};
77
78 //////////////////////////////////
79 template <int N, typename TupleArgsT, typename TupleLocsT>
80 struct local_var_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {
81
82 typedef typename tuple_element<N, TupleLocsT>::type& type;
83
84 static type get(local_tuple<TupleArgsT, TupleLocsT> const& tuple)
85 { return tuple.locs[tuple_index<N>()]; }
86 };
87
88 ///////////////////////////////////////////////////////////////////////////////
89 //
90 // local_var
91 //
92 // This class looks so curiously like the argument class. local_var
93 // provides access to the Nth local variable packed in the tuple
94 // duo local_tuple above. Parent specifies the Nth parent scope.
95 // 0==current scope, 1==parent scope, 2==parent's parent scope etc.
96 // The member function parent<N>() may be called to provide access
97 // to outer scopes.
98 //
99 // Note that the member function eval expects a local_tuple
100 // argument. Otherwise there will be acompile-time error. local_var
101 // primitives only work within the context of a context_composite
102 // (see below).
103 //
104 // Provided are some predefined local_var actors for 0..N local
105 // variable access: lvar1..locN.
106 //
107 ///////////////////////////////////////////////////////////////////////////////
108 template <int N, int Parent = 0>
109 struct local_var {
110
111 typedef local_var<N, Parent> self_t;
112
113 template <typename TupleT>
114 struct result {
115
116 typedef typename local_var_result<N, Parent, TupleT>::type type;
117 };
118
119 template <typename TupleT>
120 typename actor_result<self_t, TupleT>::type
121 eval(TupleT const& tuple) const
122 {
123 return local_var_result<N, Parent, TupleT>::get(tuple);
124 }
125
126 template <int PIndex>
127 actor<local_var<N, Parent+PIndex> >
128 parent() const
129 {
130 return local_var<N, Parent+PIndex>();
131 }
132 };
133
134 //////////////////////////////////
135 namespace locals {
136
137 actor<local_var<0> > const result = local_var<0>();
138 actor<local_var<1> > const lvar1 = local_var<1>();
139 actor<local_var<2> > const lvar2 = local_var<2>();
140 actor<local_var<3> > const lvar3 = local_var<3>();
141 actor<local_var<4> > const lvar4 = local_var<4>();
142 }
143
144
145
146
147
148
149
150
151
152 ///////////////////////////////////////////////////////////////////////////////
153 template <int N, int Parent, typename TupleT>
154 struct local_func_result {
155
156 typedef nil_t type;
157 };
158
159 //////////////////////////////////
160 template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
161 struct local_func_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
162 : public local_func_result<N, Parent-1, TupleArgsT> {};
163
164 //////////////////////////////////
165 template <int N, typename TupleArgsT, typename TupleLocsT>
166 struct local_func_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {
167
168 typedef typename actor_result<
169 typename tuple_element<N, TupleLocsT>::type,
170 local_tuple<TupleArgsT, TupleLocsT>
171 >::type type;
172
173 template <typename ArgsT>
174 static type eval(local_tuple<ArgsT, TupleLocsT> const& tuple)
175 { return tuple.locs[tuple_index<N>()].eval(tuple); }
176 };
177
178
179
180
181
182
183
184
185 template <
186 int N, int Parent,
187 typename A0 = nil_t,
188 typename A1 = nil_t,
189 typename A2 = nil_t,
190 typename A3 = nil_t,
191 typename A4 = nil_t
192 >
193 struct local_function_actor;
194
195 //////////////////////////////////
196 template <int N, int Parent>
197 struct local_function_base {
198
199 template <typename TupleT>
200 struct result {
201
202 typedef typename local_func_result<N, Parent, TupleT>::type type;
203 };
204 };
205
206 //////////////////////////////////
207 template <int N, int Parent>
208 struct local_function_actor<N, Parent, nil_t, nil_t, nil_t, nil_t, nil_t>
209 : public local_function_base<N, Parent> {
210
211 template <typename TupleArgsT, typename TupleLocsT>
212 typename local_func_result<
213 N, Parent, local_tuple<TupleArgsT, TupleLocsT> >::type
214 eval(local_tuple<TupleArgsT, TupleLocsT> const& args) const
215 {
216 typedef local_tuple<TupleArgsT, TupleLocsT> local_tuple_t;
217 typedef tuple<> tuple_t;
218 tuple_t local_args;
219
220 local_tuple<tuple_t, TupleLocsT> local_context(local_args, args.locs);
221 return local_func_result<
222 N, Parent, local_tuple_t>
223 ::eval(local_context);
224 }
225 };
226
227 //////////////////////////////////
228 template <int N, int Parent,
229 typename A0>
230 struct local_function_actor<N, Parent, A0, nil_t, nil_t, nil_t, nil_t>
231 : public local_function_base<N, Parent> {
232
233 local_function_actor(
234 A0 const& _0)
235 : a0(_0) {}
236
237 template <typename TupleArgsT, typename TupleLocsT>
238 typename local_func_result<
239 N, Parent, local_tuple<TupleArgsT, TupleLocsT> >::type
240 eval(local_tuple<TupleArgsT, TupleLocsT> const& args) const
241 {
242 typedef local_tuple<TupleArgsT, TupleLocsT> local_tuple_t;
243 typename actor_result<A0, local_tuple_t>::type r0 = a0.eval(args);
244
245 typedef tuple<
246 typename actor_result<A0, local_tuple_t>::type
247 > tuple_t;
248 tuple_t local_args(r0);
249
250 local_tuple<tuple_t, TupleLocsT> local_context(local_args, args.locs);
251 return local_func_result<
252 N, Parent, local_tuple_t>
253 ::eval(local_context);
254 }
255
256 A0 a0; // actors
257 };
258
259 namespace impl {
260
261 template <
262 int N, int Parent,
263 typename T0 = nil_t,
264 typename T1 = nil_t,
265 typename T2 = nil_t,
266 typename T3 = nil_t,
267 typename T4 = nil_t
268 >
269 struct make_local_function_actor {
270
271 typedef local_function_actor<
272 N, Parent,
273 typename as_actor<T0>::type,
274 typename as_actor<T1>::type,
275 typename as_actor<T2>::type,
276 typename as_actor<T3>::type,
277 typename as_actor<T4>::type
278 > composite_type;
279
280 typedef actor<composite_type> type;
281 };
282 }
283
284
285
286 template <int N, int Parent = 0>
287 struct local_function {
288
289 actor<local_function_actor<N, Parent> >
290 operator()() const
291 {
292 return local_function_actor<N, Parent>();
293 }
294
295 template <typename T0>
296 typename impl::make_local_function_actor<N, Parent, T0>::type
297 operator()(T0 const& _0) const
298 {
299 return impl::make_local_function_actor<N, Parent, T0>::composite_type(_0);
300 }
301
302 template <int PIndex>
303 local_function<N, Parent+PIndex>
304 parent() const
305 {
306 return local_function<N, Parent+PIndex>();
307 }
308 };
309
310 //////////////////////////////////
311 namespace locals {
312
313 local_function<1> const lfun1 = local_function<1>();
314 local_function<2> const lfun2 = local_function<2>();
315 local_function<3> const lfun3 = local_function<3>();
316 local_function<4> const lfun4 = local_function<4>();
317 }
318
319
320
321
322
323
324 ///////////////////////////////////////////////////////////////////////////////
325 //
326 // context_composite
327 //
328 // This class encapsulates an actor and some local variable
329 // initializers packed in a tuple.
330 //
331 // context_composite is just like a proxy and delegates the actual
332 // evaluation to the actor. The actor does the actual work. In the
333 // eval member function, before invoking the embedded actor's eval
334 // member function, we first stuff an instance of our locals and
335 // bundle both 'args' and 'locals' in a local_tuple. This
336 // local_tuple instance is created in the stack initializing it
337 // with our locals member. We then pass this local_tuple instance
338 // as an argument to the actor's eval member function.
339 //
340 ///////////////////////////////////////////////////////////////////////////////
341 template <typename ActorT, typename LocsT>
342 struct context_composite {
343
344 typedef context_composite<ActorT, LocsT> self_t;
345
346 template <typename TupleT>
347 struct result { typedef typename tuple_element<0, LocsT>::type type; };
348
349 context_composite(ActorT const& actor_, LocsT const& locals_)
350 : actor(actor_), locals(locals_) {}
351
352 template <typename TupleT>
353 typename tuple_element<0, LocsT>::type
354 eval(TupleT const& args) const
355 {
356 local_tuple<TupleT, LocsT> local_context(args, locals);
357 actor.eval(local_context);
358 return local_context.locs[tuple_index<0>()];
359 }
360
361 ActorT actor;
362 LocsT locals;
363 };
364
365 ///////////////////////////////////////////////////////////////////////////////
366 //
367 // context_gen
368 //
369 // At construction time, this class is given some local var-
370 // initializers packed in a tuple. We just store this for later.
371 // The operator[] of this class creates the actual context_composite
372 // given an actor. This is responsible for the construct
373 // context<types>[actor].
374 //
375 ///////////////////////////////////////////////////////////////////////////////
376 template <typename LocsT>
377 struct context_gen {
378
379 context_gen(LocsT const& locals_)
380 : locals(locals_) {}
381
382 template <typename ActorT>
383 actor<context_composite<typename as_actor<ActorT>::type, LocsT> >
384 operator[](ActorT const& actor)
385 {
386 return context_composite<typename as_actor<ActorT>::type, LocsT>
387 (as_actor<ActorT>::convert(actor), locals);
388 }
389
390 LocsT locals;
391 };
392
393 ///////////////////////////////////////////////////////////////////////////////
394 //
395 // Front end generator functions. These generators are overloaded for
396 // 1..N local variables. context<T0,... TN>(i0,...iN) generate
397 // context_gen objects (see above).
398 //
399 ///////////////////////////////////////////////////////////////////////////////
400 template <typename T0>
401 inline context_gen<tuple<T0> >
402 context()
403 {
404 typedef tuple<T0> tuple_t;
405 return context_gen<tuple_t>(tuple_t(T0()));
406 }
407
408 //////////////////////////////////
409 template <typename T0, typename T1>
410 inline context_gen<tuple<T0, T1> >
411 context(
412 T1 const& _1 = T1()
413 )
414 {
415 typedef tuple<T0, T1> tuple_t;
416 return context_gen<tuple_t>(tuple_t(T0(), _1));
417 }
418
419 //////////////////////////////////
420 template <typename T0, typename T1, typename T2>
421 inline context_gen<tuple<T0, T1, T2> >
422 context(
423 T1 const& _1 = T1(),
424 T2 const& _2 = T2()
425 )
426 {
427 typedef tuple<T0, T1, T2> tuple_t;
428 return context_gen<tuple_t>(tuple_t(T0(), _1, _2));
429 }
430
431 //////////////////////////////////
432 template <typename T0, typename T1, typename T2, typename T3>
433 inline context_gen<tuple<T0, T1, T2, T3> >
434 context(
435 T1 const& _1 = T1(),
436 T2 const& _2 = T2(),
437 T3 const& _3 = T3()
438 )
439 {
440 typedef tuple<T0, T1, T2, T3> tuple_t;
441 return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3));
442 }
443
444 //////////////////////////////////
445 template <typename T0, typename T1, typename T2, typename T3, typename T4>
446 inline context_gen<tuple<T0, T1, T2, T3, T4> >
447 context(
448 T1 const& _1 = T1(),
449 T2 const& _2 = T2(),
450 T3 const& _3 = T3(),
451 T4 const& _4 = T4()
452 )
453 {
454 typedef tuple<T0, T1, T2, T3, T4> tuple_t;
455 return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3, _4));
456 }
457
458
459
460
461
462
463
464
465
466
467
468
469 ///////////////////////////////////////////////////////////////////////////////
470 }
471
472 //////////////////////////////////
473 using namespace std;
474 using namespace phoenix;
475 using namespace phoenix::locals;
476
477 //////////////////////////////////
478 int
479 main()
480 {
481 int _10 = 10;
482
483 #ifndef __BORLANDC__
484
485 context<nil_t>
486 (
487 1000, // lvar1: local int variable
488 cout << arg1 << '\n', // lfun2: local function w/ 1 argument (arg1)
489 lvar1 * 2, // lfun3: local function that accesses local variable lvar1
490 lfun2(2 * arg1) // lfun4: local function that calls local function lfun2
491 )
492 [
493 lfun2(arg1 + 2000),
494 lfun2(val(5000) * 2),
495 lfun2(lvar1 + lfun3()),
496 lfun4(val(55)),
497 cout << lvar1 << '\n',
498 cout << lfun3() << '\n',
499 cout << val("bye bye\n")
500 ]
501
502 (_10);
503
504 #else // Borland does not like local variables w/ local functions
505 // we can have local variables (see sample 7..9) *OR*
506 // local functions (this: sample 10) but not both
507 // Sigh... Borland :-{
508
509 context<nil_t>
510 (
511 12345,
512 cout << arg1 << '\n'
513 )
514 [
515 lfun2(arg1 + 687),
516 lfun2(val(9999) * 2),
517 cout << val("bye bye\n")
518 ]
519
520 (_10);
521
522 #endif
523
524 return 0;
525 }