1 /*=============================================================================
3 Copyright (c) 2001-2002 Joel de Guzman
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
11 ///////////////////////////////////////////////////////////////////////////////
12 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
13 #include <boost/type_traits/remove_reference.hpp>
15 ///////////////////////////////////////////////////////////////////////////////
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.
22 //////////////////////////////////
26 //////////////////////////////////
29 template <typename OperationT, typename BaseT, typename B>
33 ///////////////////////////////////////////////////////////////////////////////
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.
40 ///////////////////////////////////////////////////////////////////////////////
41 template <typename TupleT>
42 struct unpack_tuple : public TupleT {
44 typedef TupleT tuple_t;
47 unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {}
50 ///////////////////////////////////////////////////////////////////////////////
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.
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
72 // arg2 ---------|---> tupled_args ---> base.eval
76 // actor::operator()(arg0, arg1... argN)
77 // ---> BaseT::eval(tupled_args);
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:
83 // template <typename TupleT>
85 // eval(TupleT const& args) const;
87 // where args are the actual arguments passed in by the client
88 // funneled into a tuple (see tuple.hpp for details).
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:
100 // template <typename TupleT>
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
113 // typedef typename actor_result<ActorT, TupleT>::type
114 // actor_return_type;
116 // where actor_return_type is the actual type returned by ActorT's
117 // eval member function given some arguments in a TupleT.
119 ///////////////////////////////////////////////////////////////////////////////
120 template <typename ActorT, typename TupleT>
121 struct actor_result {
123 typedef typename ActorT::template result<TupleT>::type type;
124 typedef typename boost::remove_reference<type>::type plain_type;
127 //////////////////////////////////
128 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
129 #pragma warning(push)
130 #pragma warning(disable:4512) //assignment operator could not be generated
133 template <typename BaseT>
134 struct actor : public BaseT {
137 actor(BaseT const& base);
139 typename actor_result<BaseT, tuple<> >::type
142 template <typename A>
143 typename actor_result<BaseT, tuple<A&> >::type
144 operator()(A& a) const;
146 template <typename A, typename B>
147 typename actor_result<BaseT, tuple<A&, B&> >::type
148 operator()(A& a, B& b) const;
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;
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;
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;
164 typename A, typename B, typename C, typename D, typename E,
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;
169 #if PHOENIX_LIMIT > 6
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;
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&>
183 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
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&>
191 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
193 #if PHOENIX_LIMIT > 9
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&>
202 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
205 typename A, typename B, typename C, typename D, typename E,
206 typename F, typename G, typename H, typename I, typename J,
208 typename actor_result<BaseT,
209 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
212 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
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&>
223 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
226 #if PHOENIX_LIMIT > 12
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&>
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;
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&>
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;
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&>
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;
266 template <typename TupleT>
267 typename actor_result<BaseT, unpack_tuple<TupleT> >::type
268 operator()(unpack_tuple<TupleT> const &t) const;
270 template <typename B>
271 typename impl::make_binary1<assign_op, BaseT, B>::type
272 operator=(B const& b) const;
274 template <typename B>
275 typename impl::make_binary1<index_op, BaseT, B>::type
276 operator[](B const& b) const;
279 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
283 ///////////////////////////////////////////////////////////////////////////
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.
295 // The meta-program does no conversion if the object to be
296 // converted is already an actor.
298 ///////////////////////////////////////////////////////////////////////////
299 template <typename T>
302 //////////////////////////////////
303 template <typename BaseT>
304 struct as_actor<actor<BaseT> > {
306 typedef actor<BaseT> type;
307 static type convert(actor<BaseT> const& x) { return x; }
310 //////////////////////////////////
312 struct as_actor<nil_t> {
315 static nil_t convert(nil_t /*x*/)
319 //////////////////////////////////
321 struct as_actor<void> {
327 ///////////////////////////////////////////////////////////////////////////////
329 // actor class implementation
331 ///////////////////////////////////////////////////////////////////////////////
332 template <typename BaseT>
333 actor<BaseT>::actor()
336 //////////////////////////////////
337 template <typename BaseT>
338 actor<BaseT>::actor(BaseT const& base)
341 //////////////////////////////////
342 template <typename BaseT>
343 inline typename actor_result<BaseT, tuple<> >::type
344 actor<BaseT>::operator()() const
346 return BaseT::eval(tuple<>());
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
355 return BaseT::eval(tuple<A&>(a_));
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
364 return BaseT::eval(tuple<A&, B&>(a_, b_));
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
373 return BaseT::eval(tuple<A&, B&, C&>(a_, b_, c_));
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
383 return BaseT::eval(tuple<A&, B&, C&, D&>(a_, b_, c_, d_));
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
392 return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a_, b_, c_, d_, e_));
395 //////////////////////////////////
396 template <typename BaseT>
398 typename A, typename B, typename C, typename D, typename E,
400 inline typename actor_result<BaseT,
401 tuple<A&, B&, C&, D&, E&, F&>
403 actor<BaseT>::operator()(
404 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_
408 tuple<A&, B&, C&, D&, E&, F&>
409 (a_, b_, c_, d_, e_, f_)
413 #if PHOENIX_LIMIT > 6
414 //////////////////////////////////
415 template <typename BaseT>
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&>
422 actor<BaseT>::operator()(
423 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_
427 tuple<A&, B&, C&, D&, E&, F&, G&>
428 (a_, b_, c_, d_, e_, f_, g_)
432 //////////////////////////////////
433 template <typename BaseT>
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&>
440 actor<BaseT>::operator()(
441 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_
445 tuple<A&, B&, C&, D&, E&, F&, G&, H&>
446 (a_, b_, c_, d_, e_, f_, g_, h_)
450 //////////////////////////////////
451 template <typename BaseT>
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&>
458 actor<BaseT>::operator()(
459 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_
463 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
464 (a_, b_, c_, d_, e_, f_, g_, h_, i_)
468 #if PHOENIX_LIMIT > 9
469 //////////////////////////////////
470 template <typename BaseT>
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&>
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_
482 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
483 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_)
487 //////////////////////////////////
488 template <typename BaseT>
490 typename A, typename B, typename C, typename D, typename E,
491 typename F, typename G, typename H, typename I, typename J,
493 inline typename actor_result<BaseT,
494 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
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_,
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_)
507 //////////////////////////////////
508 template <typename BaseT>
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&>
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_,
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_)
527 #if PHOENIX_LIMIT > 12
528 //////////////////////////////////
529 template <typename BaseT>
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&>
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_,
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_)
548 //////////////////////////////////
549 template <typename BaseT>
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&>
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_
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_)
568 //////////////////////////////////
569 template <typename BaseT>
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&>
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_
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_)
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
599 return BaseT::eval(t);
602 ///////////////////////////////////////////////////////////////////////////////
603 } // namespace phoenix