1
/*=============================================================================
3
Copyright (c) 2001-2002 Joel de Guzman
5
Permission to copy, use, modify, sell and distribute this software
6
is granted provided this copyright notice appears in all copies.
7
This software is provided "as is" without express or implied
8
warranty, and with no claim as to its suitability for any purpose.
9
==============================================================================*/
10
#ifndef PHOENIX_ACTOR_HPP
11
#define PHOENIX_ACTOR_HPP
13
///////////////////////////////////////////////////////////////////////////////
14
#include "boost/spirit/phoenix/tuples.hpp"
16
///////////////////////////////////////////////////////////////////////////////
19
// These are forward declared here because we cannot include impl.hpp
20
// or operators.hpp yet but the actor's assignment operator and index
21
// operator are required to be members.
23
//////////////////////////////////
27
//////////////////////////////////
30
template <typename OperationT, typename BaseT, typename B>
36
///////////////////////////////////////////////////////////////////////////
38
// if_t selects type A or B depending on the condition C If C is of
39
// type char[2], B is selected, otherwise A
41
// TODO: This should be part of a common meta-library
43
///////////////////////////////////////////////////////////////////////////
44
template <typename C, typename A, typename B>
45
struct if_t { typedef A type; };
47
template <typename A, typename B>
48
struct if_t<char[2], A, B> { typedef B type; };
51
///////////////////////////////////////////////////////////////////////////////
55
// This class is used to unpack a supplied tuple such, that the members of
56
// this tuple will be handled as if they would be supplied separately.
58
///////////////////////////////////////////////////////////////////////////////
59
template <typename TupleT>
60
struct unpack_tuple : public TupleT {
62
typedef TupleT tuple_t;
65
unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {}
68
///////////////////////////////////////////////////////////////////////////////
72
// This class is a protocol class for all actors. This class is
73
// essentially an interface contract. The actor class does not
74
// really know how how to act on anything but instead relies on the
75
// template parameter BaseT (from which the actor will derive from)
76
// to do the actual action.
78
// An actor is a functor that is capable of accepting arguments up
79
// to a predefined maximum. It is up to the base class to do the
80
// actual processing or possibly to limit the arity (no. of
81
// arguments) passed in. Upon invocation of the functor through a
82
// supplied operator(), the actor funnels the arguments passed in
83
// by the client into a tuple and calls the base eval member
90
// arg3 ---------|---> tupled_args ---> base.eval
94
// actor::operator()(arg0, arg1... argN)
95
// ---> BaseT::eval(tupled_args);
97
// Actor base classes from which this class inherits from are
98
// expected to have a corresponding member function eval compatible
99
// with the conceptual Interface:
101
// template <typename TupleT>
103
// eval(TupleT const& args) const;
105
// where args are the actual arguments passed in by the client
106
// funneled into a tuple (see tuple.hpp for details).
108
// The actor_return_type can be anything. Base classes are free to
109
// return any type, even argument dependent types (types that are
110
// deduced from the types of the arguments). After evaluating the
111
// parameters and doing some computations or actions, the eval
112
// member function concludes by returning something back to the
113
// client. To do this, the forwarding function (the actor's
114
// operator()) needs to know the return type of the eval member
115
// function that it is calling. For this purpose, actor base
116
// classes are required to provide a nested template class:
118
// template <typename TupleT>
121
// This auxiliary class provides the result type information
122
// returned by the eval member function of a base actor class. The
123
// nested template class result should have a typedef 'type' that
124
// reflects the return type of its member function eval. It is
125
// basically a type computer that answers the question "given
126
// arguments packed into a TupleT type, what will be the result
127
// type of the eval member function of ActorT?". The template class
128
// actor_result queries this to extract the return type of an
131
// typedef typename actor_result<ActorT, TupleT>::type
132
// actor_return_type;
134
// where actor_return_type is the actual type returned by ActorT's
135
// eval member function given some arguments in a TupleT.
137
///////////////////////////////////////////////////////////////////////////////
138
template <typename ActorT, typename TupleT>
139
struct actor_result {
141
typedef typename ActorT::template result<TupleT>::type type;
142
typedef typename remove_reference<type>::type plain_type;
145
//////////////////////////////////
146
template <typename BaseT>
147
struct actor : public BaseT {
150
actor(BaseT const& base);
152
typename actor_result<BaseT, tuple<> >::type
155
template <typename A>
156
typename actor_result<BaseT, tuple<A&> >::type
157
operator()(A& a) const;
159
template <typename A, typename B>
160
typename actor_result<BaseT, tuple<A&, B&> >::type
161
operator()(A& a, B& b) const;
163
template <typename A, typename B, typename C>
164
typename actor_result<BaseT, tuple<A&, B&, C&> >::type
165
operator()(A& a, B& b, C& c) const;
167
#if PHOENIX_LIMIT > 3
168
template <typename A, typename B, typename C, typename D>
169
typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
170
operator()(A& a, B& b, C& c, D& d) const;
172
template <typename A, typename B, typename C, typename D, typename E>
173
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
174
operator()(A& a, B& b, C& c, D& d, E& e) const;
177
typename A, typename B, typename C, typename D, typename E,
179
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type
180
operator()(A& a, B& b, C& c, D& d, E& e, F& f) const;
182
#if PHOENIX_LIMIT > 6
185
typename A, typename B, typename C, typename D, typename E,
186
typename F, typename G>
187
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type
188
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const;
191
typename A, typename B, typename C, typename D, typename E,
192
typename F, typename G, typename H>
193
typename actor_result<BaseT,
194
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
196
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
199
typename A, typename B, typename C, typename D, typename E,
200
typename F, typename G, typename H, typename I>
201
typename actor_result<BaseT,
202
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
204
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
206
#if PHOENIX_LIMIT > 9
209
typename A, typename B, typename C, typename D, typename E,
210
typename F, typename G, typename H, typename I, typename J>
211
typename actor_result<BaseT,
212
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
215
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
218
typename A, typename B, typename C, typename D, typename E,
219
typename F, typename G, typename H, typename I, typename J,
221
typename actor_result<BaseT,
222
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
225
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
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>
232
typename actor_result<BaseT,
233
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
236
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
239
#if PHOENIX_LIMIT > 12
242
typename A, typename B, typename C, typename D, typename E,
243
typename F, typename G, typename H, typename I, typename J,
244
typename K, typename L, typename M>
245
typename actor_result<BaseT,
246
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
249
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
250
K& k, L& l, M& m) const;
253
typename A, typename B, typename C, typename D, typename E,
254
typename F, typename G, typename H, typename I, typename J,
255
typename K, typename L, typename M, typename N>
256
typename actor_result<BaseT,
257
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
260
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
261
K& k, L& l, M& m, N& n) const;
264
typename A, typename B, typename C, typename D, typename E,
265
typename F, typename G, typename H, typename I, typename J,
266
typename K, typename L, typename M, typename N, typename O>
267
typename actor_result<BaseT,
268
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
271
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
272
K& k, L& l, M& m, N& n, O& o) const;
279
template <typename TupleT>
280
typename actor_result<BaseT, unpack_tuple<TupleT> >::type
281
operator()(unpack_tuple<TupleT> const &t) const;
283
template <typename B>
284
typename impl::make_binary1<assign_op, BaseT, B>::type
285
operator=(B const& b) const;
287
template <typename B>
288
typename impl::make_binary1<index_op, BaseT, B>::type
289
operator[](B const& b) const;
292
///////////////////////////////////////////////////////////////////////////
296
// as_actor is a meta-program that converts an arbitrary type into
297
// an actor. All participants in the framework must be first-class
298
// actors. This meta-program is used all throughout the framework
299
// whenever an unknown type needs to be converted to an actor.
300
// as_actor specializations are expected to have a typedef 'type'.
301
// This is the destination actor type. A static member function
302
// 'convert' converts an object to this target type.
304
// The meta-program does no conversion if the object to be
305
// converted is already an actor.
307
///////////////////////////////////////////////////////////////////////////
308
template <typename T>
311
//////////////////////////////////
312
template <typename BaseT>
313
struct as_actor<actor<BaseT> > {
315
typedef actor<BaseT> type;
316
static type convert(actor<BaseT> const& x) { return x; }
319
//////////////////////////////////
321
struct as_actor<nil_t> {
324
static nil_t convert(nil_t /*x*/)
328
//////////////////////////////////
330
struct as_actor<void> {
336
///////////////////////////////////////////////////////////////////////////////
338
// actor class implementation
340
///////////////////////////////////////////////////////////////////////////////
341
template <typename BaseT>
342
actor<BaseT>::actor()
345
//////////////////////////////////
346
template <typename BaseT>
347
actor<BaseT>::actor(BaseT const& base)
350
//////////////////////////////////
351
template <typename BaseT>
352
inline typename actor_result<BaseT, tuple<> >::type
353
actor<BaseT>::operator()() const
355
return BaseT::eval(tuple<>());
358
//////////////////////////////////
359
template <typename BaseT>
360
template <typename A>
361
inline typename actor_result<BaseT, tuple<A&> >::type
362
actor<BaseT>::operator()(A& a) const
364
return BaseT::eval(tuple<A&>(a));
367
//////////////////////////////////
368
template <typename BaseT>
369
template <typename A, typename B>
370
inline typename actor_result<BaseT, tuple<A&, B&> >::type
371
actor<BaseT>::operator()(A& a, B& b) const
373
return BaseT::eval(tuple<A&, B&>(a, b));
376
//////////////////////////////////
377
template <typename BaseT>
378
template <typename A, typename B, typename C>
379
inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type
380
actor<BaseT>::operator()(A& a, B& b, C& c) const
382
return BaseT::eval(tuple<A&, B&, C&>(a, b, c));
385
#if PHOENIX_LIMIT > 3
386
//////////////////////////////////
387
template <typename BaseT>
388
template <typename A, typename B, typename C, typename D>
389
inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
390
actor<BaseT>::operator()(A& a, B& b, C& c, D& d) const
392
return BaseT::eval(tuple<A&, B&, C&, D&>(a, b, c, d));
395
//////////////////////////////////
396
template <typename BaseT>
397
template <typename A, typename B, typename C, typename D, typename E>
398
inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
399
actor<BaseT>::operator()(A& a, B& b, C& c, D& d, E& e) const
401
return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a, b, c, d, e));
404
//////////////////////////////////
405
template <typename BaseT>
407
typename A, typename B, typename C, typename D, typename E,
409
inline typename actor_result<BaseT,
410
tuple<A&, B&, C&, D&, E&, F&>
412
actor<BaseT>::operator()(
413
A& a, B& b, C& c, D& d, E& e, F& f
417
tuple<A&, B&, C&, D&, E&, F&>
422
#if PHOENIX_LIMIT > 6
423
//////////////////////////////////
424
template <typename BaseT>
426
typename A, typename B, typename C, typename D, typename E,
427
typename F, typename G>
428
inline typename actor_result<BaseT,
429
tuple<A&, B&, C&, D&, E&, F&, G&>
431
actor<BaseT>::operator()(
432
A& a, B& b, C& c, D& d, E& e, F& f, G& g
436
tuple<A&, B&, C&, D&, E&, F&, G&>
437
(a, b, c, d, e, f, g)
441
//////////////////////////////////
442
template <typename BaseT>
444
typename A, typename B, typename C, typename D, typename E,
445
typename F, typename G, typename H>
446
inline typename actor_result<BaseT,
447
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
449
actor<BaseT>::operator()(
450
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h
454
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
455
(a, b, c, d, e, f, g, h)
459
//////////////////////////////////
460
template <typename BaseT>
462
typename A, typename B, typename C, typename D, typename E,
463
typename F, typename G, typename H, typename I>
464
inline typename actor_result<BaseT,
465
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
467
actor<BaseT>::operator()(
468
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i
472
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
473
(a, b, c, d, e, f, g, h, i)
477
#if PHOENIX_LIMIT > 9
478
//////////////////////////////////
479
template <typename BaseT>
481
typename A, typename B, typename C, typename D, typename E,
482
typename F, typename G, typename H, typename I, typename J>
483
inline typename actor_result<BaseT,
484
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
486
actor<BaseT>::operator()(
487
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j
491
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
492
(a, b, c, d, e, f, g, h, i, j)
496
//////////////////////////////////
497
template <typename BaseT>
499
typename A, typename B, typename C, typename D, typename E,
500
typename F, typename G, typename H, typename I, typename J,
502
inline typename actor_result<BaseT,
503
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
505
actor<BaseT>::operator()(
506
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
511
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
512
(a, b, c, d, e, f, g, h, i, j, k)
516
//////////////////////////////////
517
template <typename BaseT>
519
typename A, typename B, typename C, typename D, typename E,
520
typename F, typename G, typename H, typename I, typename J,
521
typename K, typename L>
522
inline typename actor_result<BaseT,
523
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
525
actor<BaseT>::operator()(
526
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
531
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
532
(a, b, c, d, e, f, g, h, i, j, k, l)
536
#if PHOENIX_LIMIT > 12
537
//////////////////////////////////
538
template <typename BaseT>
540
typename A, typename B, typename C, typename D, typename E,
541
typename F, typename G, typename H, typename I, typename J,
542
typename K, typename L, typename M>
543
inline typename actor_result<BaseT,
544
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
546
actor<BaseT>::operator()(
547
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
552
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
553
(a, b, c, d, e, f, g, h, i, j, k, l, m)
557
//////////////////////////////////
558
template <typename BaseT>
560
typename A, typename B, typename C, typename D, typename E,
561
typename F, typename G, typename H, typename I, typename J,
562
typename K, typename L, typename M, typename N>
563
inline typename actor_result<BaseT,
564
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
566
actor<BaseT>::operator()(
567
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
568
K& k, L& l, M& m, N& n
572
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
573
(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
577
//////////////////////////////////
578
template <typename BaseT>
580
typename A, typename B, typename C, typename D, typename E,
581
typename F, typename G, typename H, typename I, typename J,
582
typename K, typename L, typename M, typename N, typename O>
583
inline typename actor_result<BaseT,
584
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
586
actor<BaseT>::operator()(
587
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
588
K& k, L& l, M& m, N& n, O& o
592
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
593
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
602
//////////////////////////////////
603
template <typename BaseT>
604
template <typename TupleT>
605
typename actor_result<BaseT, unpack_tuple<TupleT> >::type
606
actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const
608
return BaseT::eval(t);
611
///////////////////////////////////////////////////////////////////////////////
612
} // namespace phoenix