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>
14 ///////////////////////////////////////////////////////////////////////////////
17 // These are forward declared here because we cannot include impl.hpp
18 // or operators.hpp yet but the actor's assignment operator and index
19 // operator are required to be members.
21 //////////////////////////////////
25 //////////////////////////////////
28 template <typename OperationT, typename BaseT, typename B>
32 ///////////////////////////////////////////////////////////////////////////////
36 // This class is used to unpack a supplied tuple such, that the members of
37 // this tuple will be handled as if they would be supplied separately.
39 ///////////////////////////////////////////////////////////////////////////////
40 template <typename TupleT>
41 struct unpack_tuple : public TupleT {
43 typedef TupleT tuple_t;
46 unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {}
49 ///////////////////////////////////////////////////////////////////////////////
53 // This class is a protocol class for all actors. This class is
54 // essentially an interface contract. The actor class does not
55 // really know how how to act on anything but instead relies on the
56 // template parameter BaseT (from which the actor will derive from)
57 // to do the actual action.
59 // An actor is a functor that is capable of accepting arguments up
60 // to a predefined maximum. It is up to the base class to do the
61 // actual processing or possibly to limit the arity (no. of
62 // arguments) passed in. Upon invocation of the functor through a
63 // supplied operator(), the actor funnels the arguments passed in
64 // by the client into a tuple and calls the base eval member
71 // arg2 ---------|---> tupled_args ---> base.eval
75 // actor::operator()(arg0, arg1... argN)
76 // ---> BaseT::eval(tupled_args);
78 // Actor base classes from which this class inherits from are
79 // expected to have a corresponding member function eval compatible
80 // with the conceptual Interface:
82 // template <typename TupleT>
84 // eval(TupleT const& args) const;
86 // where args are the actual arguments passed in by the client
87 // funneled into a tuple (see tuple.hpp for details).
89 // The actor_return_type can be anything. Base classes are free to
90 // return any type, even argument dependent types (types that are
91 // deduced from the types of the arguments). After evaluating the
92 // parameters and doing some computations or actions, the eval
93 // member function concludes by returning something back to the
94 // client. To do this, the forwarding function (the actor's
95 // operator()) needs to know the return type of the eval member
96 // function that it is calling. For this purpose, actor base
97 // classes are required to provide a nested template class:
99 // template <typename TupleT>
102 // This auxiliary class provides the result type information
103 // returned by the eval member function of a base actor class. The
104 // nested template class result should have a typedef 'type' that
105 // reflects the return type of its member function eval. It is
106 // basically a type computer that answers the question "given
107 // arguments packed into a TupleT type, what will be the result
108 // type of the eval member function of ActorT?". The template class
109 // actor_result queries this to extract the return type of an
112 // typedef typename actor_result<ActorT, TupleT>::type
113 // actor_return_type;
115 // where actor_return_type is the actual type returned by ActorT's
116 // eval member function given some arguments in a TupleT.
118 ///////////////////////////////////////////////////////////////////////////////
119 template <typename ActorT, typename TupleT>
120 struct actor_result {
122 typedef typename ActorT::template result<TupleT>::type type;
123 typedef typename remove_reference<type>::type plain_type;
126 //////////////////////////////////
127 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
128 #pragma warning(push)
129 #pragma warning(disable:4512) //assignment operator could not be generated
132 template <typename BaseT>
133 struct actor : public BaseT {
136 actor(BaseT const& base);
138 typename actor_result<BaseT, tuple<> >::type
141 template <typename A>
142 typename actor_result<BaseT, tuple<A&> >::type
143 operator()(A& a) const;
145 template <typename A, typename B>
146 typename actor_result<BaseT, tuple<A&, B&> >::type
147 operator()(A& a, B& b) const;
149 template <typename A, typename B, typename C>
150 typename actor_result<BaseT, tuple<A&, B&, C&> >::type
151 operator()(A& a, B& b, C& c) const;
153 #if PHOENIX_LIMIT > 3
154 template <typename A, typename B, typename C, typename D>
155 typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
156 operator()(A& a, B& b, C& c, D& d) const;
158 template <typename A, typename B, typename C, typename D, typename E>
159 typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
160 operator()(A& a, B& b, C& c, D& d, E& e) const;
163 typename A, typename B, typename C, typename D, typename E,
165 typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type
166 operator()(A& a, B& b, C& c, D& d, E& e, F& f) const;
168 #if PHOENIX_LIMIT > 6
171 typename A, typename B, typename C, typename D, typename E,
172 typename F, typename G>
173 typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type
174 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const;
177 typename A, typename B, typename C, typename D, typename E,
178 typename F, typename G, typename H>
179 typename actor_result<BaseT,
180 tuple<A&, B&, C&, D&, E&, F&, G&, H&>
182 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
185 typename A, typename B, typename C, typename D, typename E,
186 typename F, typename G, typename H, typename I>
187 typename actor_result<BaseT,
188 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
190 operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
192 #if PHOENIX_LIMIT > 9
195 typename A, typename B, typename C, typename D, typename E,
196 typename F, typename G, typename H, typename I, typename J>
197 typename actor_result<BaseT,
198 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
201 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
204 typename A, typename B, typename C, typename D, typename E,
205 typename F, typename G, typename H, typename I, typename J,
207 typename actor_result<BaseT,
208 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
211 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
215 typename A, typename B, typename C, typename D, typename E,
216 typename F, typename G, typename H, typename I, typename J,
217 typename K, typename L>
218 typename actor_result<BaseT,
219 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
222 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
225 #if PHOENIX_LIMIT > 12
228 typename A, typename B, typename C, typename D, typename E,
229 typename F, typename G, typename H, typename I, typename J,
230 typename K, typename L, typename M>
231 typename actor_result<BaseT,
232 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
235 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
236 K& k, L& l, M& m) const;
239 typename A, typename B, typename C, typename D, typename E,
240 typename F, typename G, typename H, typename I, typename J,
241 typename K, typename L, typename M, typename N>
242 typename actor_result<BaseT,
243 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
246 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
247 K& k, L& l, M& m, N& n) const;
250 typename A, typename B, typename C, typename D, typename E,
251 typename F, typename G, typename H, typename I, typename J,
252 typename K, typename L, typename M, typename N, typename O>
253 typename actor_result<BaseT,
254 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
257 A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
258 K& k, L& l, M& m, N& n, O& o) const;
265 template <typename TupleT>
266 typename actor_result<BaseT, unpack_tuple<TupleT> >::type
267 operator()(unpack_tuple<TupleT> const &t) const;
269 template <typename B>
270 typename impl::make_binary1<assign_op, BaseT, B>::type
271 operator=(B const& b) const;
273 template <typename B>
274 typename impl::make_binary1<index_op, BaseT, B>::type
275 operator[](B const& b) const;
278 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
282 ///////////////////////////////////////////////////////////////////////////
286 // as_actor is a meta-program that converts an arbitrary type into
287 // an actor. All participants in the framework must be first-class
288 // actors. This meta-program is used all throughout the framework
289 // whenever an unknown type needs to be converted to an actor.
290 // as_actor specializations are expected to have a typedef 'type'.
291 // This is the destination actor type. A static member function
292 // 'convert' converts an object to this target type.
294 // The meta-program does no conversion if the object to be
295 // converted is already an actor.
297 ///////////////////////////////////////////////////////////////////////////
298 template <typename T>
301 //////////////////////////////////
302 template <typename BaseT>
303 struct as_actor<actor<BaseT> > {
305 typedef actor<BaseT> type;
306 static type convert(actor<BaseT> const& x) { return x; }
309 //////////////////////////////////
311 struct as_actor<nil_t> {
314 static nil_t convert(nil_t /*x*/)
318 //////////////////////////////////
320 struct as_actor<void> {
326 ///////////////////////////////////////////////////////////////////////////////
328 // actor class implementation
330 ///////////////////////////////////////////////////////////////////////////////
331 template <typename BaseT>
332 actor<BaseT>::actor()
335 //////////////////////////////////
336 template <typename BaseT>
337 actor<BaseT>::actor(BaseT const& base)
340 //////////////////////////////////
341 template <typename BaseT>
342 inline typename actor_result<BaseT, tuple<> >::type
343 actor<BaseT>::operator()() const
345 return BaseT::eval(tuple<>());
348 //////////////////////////////////
349 template <typename BaseT>
350 template <typename A>
351 inline typename actor_result<BaseT, tuple<A&> >::type
352 actor<BaseT>::operator()(A& a_) const
354 return BaseT::eval(tuple<A&>(a_));
357 //////////////////////////////////
358 template <typename BaseT>
359 template <typename A, typename B>
360 inline typename actor_result<BaseT, tuple<A&, B&> >::type
361 actor<BaseT>::operator()(A& a_, B& b_) const
363 return BaseT::eval(tuple<A&, B&>(a_, b_));
366 //////////////////////////////////
367 template <typename BaseT>
368 template <typename A, typename B, typename C>
369 inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type
370 actor<BaseT>::operator()(A& a_, B& b_, C& c_) const
372 return BaseT::eval(tuple<A&, B&, C&>(a_, b_, c_));
375 #if PHOENIX_LIMIT > 3
376 //////////////////////////////////
377 template <typename BaseT>
378 template <typename A, typename B, typename C, typename D>
379 inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
380 actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_) const
382 return BaseT::eval(tuple<A&, B&, C&, D&>(a_, b_, c_, d_));
385 //////////////////////////////////
386 template <typename BaseT>
387 template <typename A, typename B, typename C, typename D, typename E>
388 inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
389 actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_, E& e_) const
391 return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a_, b_, c_, d_, e_));
394 //////////////////////////////////
395 template <typename BaseT>
397 typename A, typename B, typename C, typename D, typename E,
399 inline typename actor_result<BaseT,
400 tuple<A&, B&, C&, D&, E&, F&>
402 actor<BaseT>::operator()(
403 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_
407 tuple<A&, B&, C&, D&, E&, F&>
408 (a_, b_, c_, d_, e_, f_)
412 #if PHOENIX_LIMIT > 6
413 //////////////////////////////////
414 template <typename BaseT>
416 typename A, typename B, typename C, typename D, typename E,
417 typename F, typename G>
418 inline typename actor_result<BaseT,
419 tuple<A&, B&, C&, D&, E&, F&, G&>
421 actor<BaseT>::operator()(
422 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_
426 tuple<A&, B&, C&, D&, E&, F&, G&>
427 (a_, b_, c_, d_, e_, f_, g_)
431 //////////////////////////////////
432 template <typename BaseT>
434 typename A, typename B, typename C, typename D, typename E,
435 typename F, typename G, typename H>
436 inline typename actor_result<BaseT,
437 tuple<A&, B&, C&, D&, E&, F&, G&, H&>
439 actor<BaseT>::operator()(
440 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_
444 tuple<A&, B&, C&, D&, E&, F&, G&, H&>
445 (a_, b_, c_, d_, e_, f_, g_, h_)
449 //////////////////////////////////
450 template <typename BaseT>
452 typename A, typename B, typename C, typename D, typename E,
453 typename F, typename G, typename H, typename I>
454 inline typename actor_result<BaseT,
455 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
457 actor<BaseT>::operator()(
458 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_
462 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
463 (a_, b_, c_, d_, e_, f_, g_, h_, i_)
467 #if PHOENIX_LIMIT > 9
468 //////////////////////////////////
469 template <typename BaseT>
471 typename A, typename B, typename C, typename D, typename E,
472 typename F, typename G, typename H, typename I, typename J>
473 inline typename actor_result<BaseT,
474 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
476 actor<BaseT>::operator()(
477 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_
481 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
482 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_)
486 //////////////////////////////////
487 template <typename BaseT>
489 typename A, typename B, typename C, typename D, typename E,
490 typename F, typename G, typename H, typename I, typename J,
492 inline typename actor_result<BaseT,
493 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
495 actor<BaseT>::operator()(
496 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
501 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
502 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_)
506 //////////////////////////////////
507 template <typename BaseT>
509 typename A, typename B, typename C, typename D, typename E,
510 typename F, typename G, typename H, typename I, typename J,
511 typename K, typename L>
512 inline typename actor_result<BaseT,
513 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
515 actor<BaseT>::operator()(
516 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
521 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
522 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_)
526 #if PHOENIX_LIMIT > 12
527 //////////////////////////////////
528 template <typename BaseT>
530 typename A, typename B, typename C, typename D, typename E,
531 typename F, typename G, typename H, typename I, typename J,
532 typename K, typename L, typename M>
533 inline typename actor_result<BaseT,
534 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
536 actor<BaseT>::operator()(
537 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
542 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
543 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_)
547 //////////////////////////////////
548 template <typename BaseT>
550 typename A, typename B, typename C, typename D, typename E,
551 typename F, typename G, typename H, typename I, typename J,
552 typename K, typename L, typename M, typename N>
553 inline typename actor_result<BaseT,
554 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
556 actor<BaseT>::operator()(
557 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
558 K& k_, L& l_, M& m_, N& n_
562 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
563 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_)
567 //////////////////////////////////
568 template <typename BaseT>
570 typename A, typename B, typename C, typename D, typename E,
571 typename F, typename G, typename H, typename I, typename J,
572 typename K, typename L, typename M, typename N, typename O>
573 inline typename actor_result<BaseT,
574 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
576 actor<BaseT>::operator()(
577 A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
578 K& k_, L& l_, M& m_, N& n_, O& o_
582 tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
583 (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_)
592 //////////////////////////////////
593 template <typename BaseT>
594 template <typename TupleT>
595 typename actor_result<BaseT, unpack_tuple<TupleT> >::type
596 actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const
598 return BaseT::eval(t);
601 ///////////////////////////////////////////////////////////////////////////////
602 } // namespace phoenix