]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/classic/phoenix/actor.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / spirit / home / classic / phoenix / actor.hpp
1 /*=============================================================================
2 Phoenix v1.2
3 Copyright (c) 2001-2002 Joel de Guzman
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 PHOENIX_ACTOR_HPP
9 #define PHOENIX_ACTOR_HPP
10
11 ///////////////////////////////////////////////////////////////////////////////
12 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
13 #include <boost/type_traits/remove_reference.hpp>
14
15 ///////////////////////////////////////////////////////////////////////////////
16 namespace phoenix {
17
18 // These are forward declared here because we cannot include impl.hpp
19 // or operators.hpp yet but the actor's assignment operator and index
20 // operator are required to be members.
21
22 //////////////////////////////////
23 struct assign_op;
24 struct index_op;
25
26 //////////////////////////////////
27 namespace impl {
28
29 template <typename OperationT, typename BaseT, typename B>
30 struct make_binary1;
31 }
32
33 ///////////////////////////////////////////////////////////////////////////////
34 //
35 // unpack_tuple class
36 //
37 // This class is used to unpack a supplied tuple such, that the members of
38 // this tuple will be handled as if they would be supplied separately.
39 //
40 ///////////////////////////////////////////////////////////////////////////////
41 template <typename TupleT>
42 struct unpack_tuple : public TupleT {
43
44 typedef TupleT tuple_t;
45
46 unpack_tuple() {}
47 unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {}
48 };
49
50 ///////////////////////////////////////////////////////////////////////////////
51 //
52 // actor class
53 //
54 // This class is a protocol class for all actors. This class is
55 // essentially an interface contract. The actor class does not
56 // really know how how to act on anything but instead relies on the
57 // template parameter BaseT (from which the actor will derive from)
58 // to do the actual action.
59 //
60 // An actor is a functor that is capable of accepting arguments up
61 // to a predefined maximum. It is up to the base class to do the
62 // actual processing or possibly to limit the arity (no. of
63 // arguments) passed in. Upon invocation of the functor through a
64 // supplied operator(), the actor funnels the arguments passed in
65 // by the client into a tuple and calls the base eval member
66 // function.
67 //
68 // Schematically:
69 //
70 // arg0 ---------|
71 // arg1 ---------|
72 // arg2 ---------|---> tupled_args ---> base.eval
73 // ... |
74 // argN ---------|
75 //
76 // actor::operator()(arg0, arg1... argN)
77 // ---> BaseT::eval(tupled_args);
78 //
79 // Actor base classes from which this class inherits from are
80 // expected to have a corresponding member function eval compatible
81 // with the conceptual Interface:
82 //
83 // template <typename TupleT>
84 // actor_return_type
85 // eval(TupleT const& args) const;
86 //
87 // where args are the actual arguments passed in by the client
88 // funneled into a tuple (see tuple.hpp for details).
89 //
90 // The actor_return_type can be anything. Base classes are free to
91 // return any type, even argument dependent types (types that are
92 // deduced from the types of the arguments). After evaluating the
93 // parameters and doing some computations or actions, the eval
94 // member function concludes by returning something back to the
95 // client. To do this, the forwarding function (the actor's
96 // operator()) needs to know the return type of the eval member
97 // function that it is calling. For this purpose, actor base
98 // classes are required to provide a nested template class:
99 //
100 // template <typename TupleT>
101 // struct result;
102 //
103 // This auxiliary class provides the result type information
104 // returned by the eval member function of a base actor class. The
105 // nested template class result should have a typedef 'type' that
106 // reflects the return type of its member function eval. It is
107 // basically a type computer that answers the question "given
108 // arguments packed into a TupleT type, what will be the result
109 // type of the eval member function of ActorT?". The template class
110 // actor_result queries this to extract the return type of an
111 // actor. Example:
112 //
113 // typedef typename actor_result<ActorT, TupleT>::type
114 // actor_return_type;
115 //
116 // where actor_return_type is the actual type returned by ActorT's
117 // eval member function given some arguments in a TupleT.
118 //
119 ///////////////////////////////////////////////////////////////////////////////
120 template <typename ActorT, typename TupleT>
121 struct actor_result {
122
123 typedef typename ActorT::template result<TupleT>::type type;
124 typedef typename boost::remove_reference<type>::type plain_type;
125 };
126
127 //////////////////////////////////
128 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
129 #pragma warning(push)
130 #pragma warning(disable:4512) //assignment operator could not be generated
131 #endif
132
133 template <typename BaseT>
134 struct actor : public BaseT {
135
136 actor();
137 actor(BaseT const& base);
138
139 typename actor_result<BaseT, tuple<> >::type
140 operator()() const;
141
142 template <typename A>
143 typename actor_result<BaseT, tuple<A&> >::type
144 operator()(A& a) const;
145
146 template <typename A, typename B>
147 typename actor_result<BaseT, tuple<A&, B&> >::type
148 operator()(A& a, B& b) const;
149
150 template <typename A, typename B, typename C>
151 typename actor_result<BaseT, tuple<A&, B&, C&> >::type
152 operator()(A& a, B& b, C& c) const;
153
154 #if PHOENIX_LIMIT > 3
155 template <typename A, typename B, typename C, typename D>
156 typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
157 operator()(A& a, B& b, C& c, D& d) const;
158
159 template <typename A, typename B, typename C, typename D, typename E>
160 typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
161 operator()(A& a, B& b, C& c, D& d, E& e) const;
162
163 template <
164 typename A, typename B, typename C, typename D, typename E,
165 typename F>
166 typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type
167 operator()(A& a, B& b, C& c, D& d, E& e, F& f) const;
168
169 #if PHOENIX_LIMIT > 6
170
171 template <
172 typename A, typename B, typename C, typename D, typename E,
173 typename F, typename G>
174 typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type
175 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const;
176
177 template <
178 typename A, typename B, typename C, typename D, typename E,
179 typename F, typename G, typename H>
180 typename actor_result<BaseT,
181 tuple<A&, B&, C&, D&, E&, F&, G&, H&>
182 >::type
183 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
184
185 template <
186 typename A, typename B, typename C, typename D, typename E,
187 typename F, typename G, typename H, typename I>
188 typename actor_result<BaseT,
189 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
190 >::type
191 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
192
193 #if PHOENIX_LIMIT > 9
194
195 template <
196 typename A, typename B, typename C, typename D, typename E,
197 typename F, typename G, typename H, typename I, typename J>
198 typename actor_result<BaseT,
199 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
200 >::type
201 operator()(
202 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
203
204 template <
205 typename A, typename B, typename C, typename D, typename E,
206 typename F, typename G, typename H, typename I, typename J,
207 typename K>
208 typename actor_result<BaseT,
209 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
210 >::type
211 operator()(
212 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
213 K& k) const;
214
215 template <
216 typename A, typename B, typename C, typename D, typename E,
217 typename F, typename G, typename H, typename I, typename J,
218 typename K, typename L>
219 typename actor_result<BaseT,
220 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
221 >::type
222 operator()(
223 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
224 K& k, L& l) const;
225
226 #if PHOENIX_LIMIT > 12
227
228 template <
229 typename A, typename B, typename C, typename D, typename E,
230 typename F, typename G, typename H, typename I, typename J,
231 typename K, typename L, typename M>
232 typename actor_result<BaseT,
233 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
234 >::type
235 operator()(
236 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
237 K& k, L& l, M& m) const;
238
239 template <
240 typename A, typename B, typename C, typename D, typename E,
241 typename F, typename G, typename H, typename I, typename J,
242 typename K, typename L, typename M, typename N>
243 typename actor_result<BaseT,
244 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
245 >::type
246 operator()(
247 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
248 K& k, L& l, M& m, N& n) const;
249
250 template <
251 typename A, typename B, typename C, typename D, typename E,
252 typename F, typename G, typename H, typename I, typename J,
253 typename K, typename L, typename M, typename N, typename O>
254 typename actor_result<BaseT,
255 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
256 >::type
257 operator()(
258 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
259 K& k, L& l, M& m, N& n, O& o) const;
260
261 #endif
262 #endif
263 #endif
264 #endif
265
266 template <typename TupleT>
267 typename actor_result<BaseT, unpack_tuple<TupleT> >::type
268 operator()(unpack_tuple<TupleT> const &t) const;
269
270 template <typename B>
271 typename impl::make_binary1<assign_op, BaseT, B>::type
272 operator=(B const& b) const;
273
274 template <typename B>
275 typename impl::make_binary1<index_op, BaseT, B>::type
276 operator[](B const& b) const;
277 };
278
279 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
280 #pragma warning(pop)
281 #endif
282
283 ///////////////////////////////////////////////////////////////////////////
284 //
285 // as_actor
286 //
287 // as_actor is a meta-program that converts an arbitrary type into
288 // an actor. All participants in the framework must be first-class
289 // actors. This meta-program is used all throughout the framework
290 // whenever an unknown type needs to be converted to an actor.
291 // as_actor specializations are expected to have a typedef 'type'.
292 // This is the destination actor type. A static member function
293 // 'convert' converts an object to this target type.
294 //
295 // The meta-program does no conversion if the object to be
296 // converted is already an actor.
297 //
298 ///////////////////////////////////////////////////////////////////////////
299 template <typename T>
300 struct as_actor;
301
302 //////////////////////////////////
303 template <typename BaseT>
304 struct as_actor<actor<BaseT> > {
305
306 typedef actor<BaseT> type;
307 static type convert(actor<BaseT> const& x) { return x; }
308 };
309
310 //////////////////////////////////
311 template <>
312 struct as_actor<nil_t> {
313
314 typedef nil_t type;
315 static nil_t convert(nil_t /*x*/)
316 { return nil_t(); }
317 };
318
319 //////////////////////////////////
320 template <>
321 struct as_actor<void> {
322
323 typedef void type;
324 // ERROR!!!
325 };
326
327 ///////////////////////////////////////////////////////////////////////////////
328 //
329 // actor class implementation
330 //
331 ///////////////////////////////////////////////////////////////////////////////
332 template <typename BaseT>
333 actor<BaseT>::actor()
334 : BaseT() {}
335
336 //////////////////////////////////
337 template <typename BaseT>
338 actor<BaseT>::actor(BaseT const& base)
339 : BaseT(base) {}
340
341 //////////////////////////////////
342 template <typename BaseT>
343 inline typename actor_result<BaseT, tuple<> >::type
344 actor<BaseT>::operator()() const
345 {
346 return BaseT::eval(tuple<>());
347 }
348
349 //////////////////////////////////
350 template <typename BaseT>
351 template <typename A>
352 inline typename actor_result<BaseT, tuple<A&> >::type
353 actor<BaseT>::operator()(A& a_) const
354 {
355 return BaseT::eval(tuple<A&>(a_));
356 }
357
358 //////////////////////////////////
359 template <typename BaseT>
360 template <typename A, typename B>
361 inline typename actor_result<BaseT, tuple<A&, B&> >::type
362 actor<BaseT>::operator()(A& a_, B& b_) const
363 {
364 return BaseT::eval(tuple<A&, B&>(a_, b_));
365 }
366
367 //////////////////////////////////
368 template <typename BaseT>
369 template <typename A, typename B, typename C>
370 inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type
371 actor<BaseT>::operator()(A& a_, B& b_, C& c_) const
372 {
373 return BaseT::eval(tuple<A&, B&, C&>(a_, b_, c_));
374 }
375
376 #if PHOENIX_LIMIT > 3
377 //////////////////////////////////
378 template <typename BaseT>
379 template <typename A, typename B, typename C, typename D>
380 inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
381 actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_) const
382 {
383 return BaseT::eval(tuple<A&, B&, C&, D&>(a_, b_, c_, d_));
384 }
385
386 //////////////////////////////////
387 template <typename BaseT>
388 template <typename A, typename B, typename C, typename D, typename E>
389 inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
390 actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_, E& e_) const
391 {
392 return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a_, b_, c_, d_, e_));
393 }
394
395 //////////////////////////////////
396 template <typename BaseT>
397 template <
398 typename A, typename B, typename C, typename D, typename E,
399 typename F>
400 inline typename actor_result<BaseT,
401 tuple<A&, B&, C&, D&, E&, F&>
402 >::type
403 actor<BaseT>::operator()(
404 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_
405 ) const
406 {
407 return BaseT::eval(
408 tuple<A&, B&, C&, D&, E&, F&>
409 (a_, b_, c_, d_, e_, f_)
410 );
411 }
412
413 #if PHOENIX_LIMIT > 6
414 //////////////////////////////////
415 template <typename BaseT>
416 template <
417 typename A, typename B, typename C, typename D, typename E,
418 typename F, typename G>
419 inline typename actor_result<BaseT,
420 tuple<A&, B&, C&, D&, E&, F&, G&>
421 >::type
422 actor<BaseT>::operator()(
423 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_
424 ) const
425 {
426 return BaseT::eval(
427 tuple<A&, B&, C&, D&, E&, F&, G&>
428 (a_, b_, c_, d_, e_, f_, g_)
429 );
430 }
431
432 //////////////////////////////////
433 template <typename BaseT>
434 template <
435 typename A, typename B, typename C, typename D, typename E,
436 typename F, typename G, typename H>
437 inline typename actor_result<BaseT,
438 tuple<A&, B&, C&, D&, E&, F&, G&, H&>
439 >::type
440 actor<BaseT>::operator()(
441 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_
442 ) const
443 {
444 return BaseT::eval(
445 tuple<A&, B&, C&, D&, E&, F&, G&, H&>
446 (a_, b_, c_, d_, e_, f_, g_, h_)
447 );
448 }
449
450 //////////////////////////////////
451 template <typename BaseT>
452 template <
453 typename A, typename B, typename C, typename D, typename E,
454 typename F, typename G, typename H, typename I>
455 inline typename actor_result<BaseT,
456 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
457 >::type
458 actor<BaseT>::operator()(
459 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_
460 ) const
461 {
462 return BaseT::eval(
463 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
464 (a_, b_, c_, d_, e_, f_, g_, h_, i_)
465 );
466 }
467
468 #if PHOENIX_LIMIT > 9
469 //////////////////////////////////
470 template <typename BaseT>
471 template <
472 typename A, typename B, typename C, typename D, typename E,
473 typename F, typename G, typename H, typename I, typename J>
474 inline typename actor_result<BaseT,
475 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
476 >::type
477 actor<BaseT>::operator()(
478 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_
479 ) const
480 {
481 return BaseT::eval(
482 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
483 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_)
484 );
485 }
486
487 //////////////////////////////////
488 template <typename BaseT>
489 template <
490 typename A, typename B, typename C, typename D, typename E,
491 typename F, typename G, typename H, typename I, typename J,
492 typename K>
493 inline typename actor_result<BaseT,
494 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
495 >::type
496 actor<BaseT>::operator()(
497 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
498 K& k_
499 ) const
500 {
501 return BaseT::eval(
502 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
503 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_)
504 );
505 }
506
507 //////////////////////////////////
508 template <typename BaseT>
509 template <
510 typename A, typename B, typename C, typename D, typename E,
511 typename F, typename G, typename H, typename I, typename J,
512 typename K, typename L>
513 inline typename actor_result<BaseT,
514 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
515 >::type
516 actor<BaseT>::operator()(
517 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
518 K& k_, L& l_
519 ) const
520 {
521 return BaseT::eval(
522 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
523 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_)
524 );
525 }
526
527 #if PHOENIX_LIMIT > 12
528 //////////////////////////////////
529 template <typename BaseT>
530 template <
531 typename A, typename B, typename C, typename D, typename E,
532 typename F, typename G, typename H, typename I, typename J,
533 typename K, typename L, typename M>
534 inline typename actor_result<BaseT,
535 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
536 >::type
537 actor<BaseT>::operator()(
538 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
539 K& k_, L& l_, M& m_
540 ) const
541 {
542 return BaseT::eval(
543 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
544 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_)
545 );
546 }
547
548 //////////////////////////////////
549 template <typename BaseT>
550 template <
551 typename A, typename B, typename C, typename D, typename E,
552 typename F, typename G, typename H, typename I, typename J,
553 typename K, typename L, typename M, typename N>
554 inline typename actor_result<BaseT,
555 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
556 >::type
557 actor<BaseT>::operator()(
558 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
559 K& k_, L& l_, M& m_, N& n_
560 ) const
561 {
562 return BaseT::eval(
563 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
564 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_)
565 );
566 }
567
568 //////////////////////////////////
569 template <typename BaseT>
570 template <
571 typename A, typename B, typename C, typename D, typename E,
572 typename F, typename G, typename H, typename I, typename J,
573 typename K, typename L, typename M, typename N, typename O>
574 inline typename actor_result<BaseT,
575 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
576 >::type
577 actor<BaseT>::operator()(
578 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
579 K& k_, L& l_, M& m_, N& n_, O& o_
580 ) const
581 {
582 return BaseT::eval(
583 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
584 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_)
585 );
586 }
587
588 #endif
589 #endif
590 #endif
591 #endif
592
593 //////////////////////////////////
594 template <typename BaseT>
595 template <typename TupleT>
596 typename actor_result<BaseT, unpack_tuple<TupleT> >::type
597 actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const
598 {
599 return BaseT::eval(t);
600 }
601
602 ///////////////////////////////////////////////////////////////////////////////
603 } // namespace phoenix
604
605 #endif