source: NonGTP/Boost/boost/spirit/phoenix/actor.hpp @ 857

Revision 857, 19.2 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Phoenix v1.2
3    Copyright (c) 2001-2002 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#ifndef PHOENIX_ACTOR_HPP
10#define PHOENIX_ACTOR_HPP
11
12///////////////////////////////////////////////////////////////////////////////
13#include <boost/spirit/phoenix/tuples.hpp>
14
15///////////////////////////////////////////////////////////////////////////////
16namespace 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//////////////////////////////////
23struct assign_op;
24struct index_op;
25
26//////////////////////////////////
27namespace 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///////////////////////////////////////////////////////////////////////////////
41template <typename TupleT>
42struct 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///////////////////////////////////////////////////////////////////////////////
120template <typename ActorT, typename TupleT>
121struct actor_result {
122
123    typedef typename ActorT::template result<TupleT>::type type;
124    typedef typename remove_reference<type>::type plain_type;
125};
126
127//////////////////////////////////
128template <typename BaseT>
129struct actor : public BaseT {
130
131    actor();
132    actor(BaseT const& base);
133
134    typename actor_result<BaseT, tuple<> >::type
135    operator()() const;
136
137    template <typename A>
138    typename actor_result<BaseT, tuple<A&> >::type
139    operator()(A& a) const;
140
141    template <typename A, typename B>
142    typename actor_result<BaseT, tuple<A&, B&> >::type
143    operator()(A& a, B& b) const;
144
145    template <typename A, typename B, typename C>
146    typename actor_result<BaseT, tuple<A&, B&, C&> >::type
147    operator()(A& a, B& b, C& c) const;
148
149#if PHOENIX_LIMIT > 3
150    template <typename A, typename B, typename C, typename D>
151    typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
152    operator()(A& a, B& b, C& c, D& d) const;
153
154    template <typename A, typename B, typename C, typename D, typename E>
155    typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
156    operator()(A& a, B& b, C& c, D& d, E& e) const;
157
158    template <
159        typename A, typename B, typename C, typename D, typename E,
160        typename F>
161    typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type
162    operator()(A& a, B& b, C& c, D& d, E& e, F& f) const;
163
164#if PHOENIX_LIMIT > 6
165
166    template <
167        typename A, typename B, typename C, typename D, typename E,
168        typename F, typename G>
169    typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type
170    operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const;
171
172    template <
173        typename A, typename B, typename C, typename D, typename E,
174        typename F, typename G, typename H>
175    typename actor_result<BaseT,
176        tuple<A&, B&, C&, D&, E&, F&, G&, H&>
177    >::type
178    operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
179
180    template <
181        typename A, typename B, typename C, typename D, typename E,
182        typename F, typename G, typename H, typename I>
183    typename actor_result<BaseT,
184        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
185    >::type
186    operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
187
188#if PHOENIX_LIMIT > 9
189
190    template <
191        typename A, typename B, typename C, typename D, typename E,
192        typename F, typename G, typename H, typename I, typename J>
193    typename actor_result<BaseT,
194        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
195    >::type
196    operator()(
197        A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
198
199    template <
200        typename A, typename B, typename C, typename D, typename E,
201        typename F, typename G, typename H, typename I, typename J,
202        typename K>
203    typename actor_result<BaseT,
204        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
205    >::type
206    operator()(
207        A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
208        K& k) const;
209
210    template <
211        typename A, typename B, typename C, typename D, typename E,
212        typename F, typename G, typename H, typename I, typename J,
213        typename K, typename L>
214    typename actor_result<BaseT,
215        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
216    >::type
217    operator()(
218        A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
219        K& k, L& l) const;
220
221#if PHOENIX_LIMIT > 12
222
223    template <
224        typename A, typename B, typename C, typename D, typename E,
225        typename F, typename G, typename H, typename I, typename J,
226        typename K, typename L, typename M>
227    typename actor_result<BaseT,
228        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
229    >::type
230    operator()(
231        A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
232        K& k, L& l, M& m) const;
233
234    template <
235        typename A, typename B, typename C, typename D, typename E,
236        typename F, typename G, typename H, typename I, typename J,
237        typename K, typename L, typename M, typename N>
238    typename actor_result<BaseT,
239        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
240    >::type
241    operator()(
242        A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
243        K& k, L& l, M& m, N& n) const;
244
245    template <
246        typename A, typename B, typename C, typename D, typename E,
247        typename F, typename G, typename H, typename I, typename J,
248        typename K, typename L, typename M, typename N, typename O>
249    typename actor_result<BaseT,
250        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
251    >::type
252    operator()(
253        A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
254        K& k, L& l, M& m, N& n, O& o) const;
255
256#endif
257#endif
258#endif
259#endif
260
261    template <typename TupleT>
262    typename actor_result<BaseT, unpack_tuple<TupleT> >::type
263    operator()(unpack_tuple<TupleT> const &t) const;
264   
265    template <typename B>
266    typename impl::make_binary1<assign_op, BaseT, B>::type
267    operator=(B const& b) const;
268
269    template <typename B>
270    typename impl::make_binary1<index_op, BaseT, B>::type
271    operator[](B const& b) const;
272};
273
274///////////////////////////////////////////////////////////////////////////
275//
276//  as_actor
277//
278//      as_actor is a meta-program that converts an arbitrary type into
279//      an actor. All participants in the framework must be first-class
280//      actors. This meta-program is used all throughout the framework
281//      whenever an unknown type needs to be converted to an actor.
282//      as_actor specializations are expected to have a typedef 'type'.
283//      This is the destination actor type. A static member function
284//      'convert' converts an object to this target type.
285//
286//      The meta-program does no conversion if the object to be
287//      converted is already an actor.
288//
289///////////////////////////////////////////////////////////////////////////
290template <typename T>
291struct as_actor;
292
293//////////////////////////////////
294template <typename BaseT>
295struct as_actor<actor<BaseT> > {
296
297    typedef actor<BaseT> type;
298    static type convert(actor<BaseT> const& x) { return x; }
299};
300
301//////////////////////////////////
302template <>
303struct as_actor<nil_t> {
304
305    typedef nil_t type;
306    static nil_t convert(nil_t /*x*/)
307    { return nil_t(); }
308};
309
310//////////////////////////////////
311template <>
312struct as_actor<void> {
313
314    typedef void type;
315    //  ERROR!!!
316};
317
318///////////////////////////////////////////////////////////////////////////////
319//
320//  actor class implementation
321//
322///////////////////////////////////////////////////////////////////////////////
323template <typename BaseT>
324actor<BaseT>::actor()
325:   BaseT() {}
326
327//////////////////////////////////
328template <typename BaseT>
329actor<BaseT>::actor(BaseT const& base)
330:   BaseT(base) {}
331
332//////////////////////////////////
333template <typename BaseT>
334inline typename actor_result<BaseT, tuple<> >::type
335actor<BaseT>::operator()() const
336{
337    return BaseT::eval(tuple<>());
338}
339
340//////////////////////////////////
341template <typename BaseT>
342template <typename A>
343inline typename actor_result<BaseT, tuple<A&> >::type
344actor<BaseT>::operator()(A& a) const
345{
346    return BaseT::eval(tuple<A&>(a));
347}
348
349//////////////////////////////////
350template <typename BaseT>
351template <typename A, typename B>
352inline typename actor_result<BaseT, tuple<A&, B&> >::type
353actor<BaseT>::operator()(A& a, B& b) const
354{
355    return BaseT::eval(tuple<A&, B&>(a, b));
356}
357
358//////////////////////////////////
359template <typename BaseT>
360template <typename A, typename B, typename C>
361inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type
362actor<BaseT>::operator()(A& a, B& b, C& c) const
363{
364    return BaseT::eval(tuple<A&, B&, C&>(a, b, c));
365}
366
367#if PHOENIX_LIMIT > 3
368//////////////////////////////////
369template <typename BaseT>
370template <typename A, typename B, typename C, typename D>
371inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
372actor<BaseT>::operator()(A& a, B& b, C& c, D& d) const
373{
374    return BaseT::eval(tuple<A&, B&, C&, D&>(a, b, c, d));
375}
376
377//////////////////////////////////
378template <typename BaseT>
379template <typename A, typename B, typename C, typename D, typename E>
380inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
381actor<BaseT>::operator()(A& a, B& b, C& c, D& d, E& e) const
382{
383    return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a, b, c, d, e));
384}
385
386//////////////////////////////////
387template <typename BaseT>
388template <
389    typename A, typename B, typename C, typename D, typename E,
390    typename F>
391inline typename actor_result<BaseT,
392    tuple<A&, B&, C&, D&, E&, F&>
393>::type
394actor<BaseT>::operator()(
395    A& a, B& b, C& c, D& d, E& e, F& f
396) const
397{
398    return BaseT::eval(
399        tuple<A&, B&, C&, D&, E&, F&>
400        (a, b, c, d, e, f)
401    );
402}
403
404#if PHOENIX_LIMIT > 6
405//////////////////////////////////
406template <typename BaseT>
407template <
408    typename A, typename B, typename C, typename D, typename E,
409    typename F, typename G>
410inline typename actor_result<BaseT,
411    tuple<A&, B&, C&, D&, E&, F&, G&>
412>::type
413actor<BaseT>::operator()(
414    A& a, B& b, C& c, D& d, E& e, F& f, G& g
415) const
416{
417    return BaseT::eval(
418        tuple<A&, B&, C&, D&, E&, F&, G&>
419        (a, b, c, d, e, f, g)
420    );
421}
422
423//////////////////////////////////
424template <typename BaseT>
425template <
426    typename A, typename B, typename C, typename D, typename E,
427    typename F, typename G, typename H>
428inline typename actor_result<BaseT,
429    tuple<A&, B&, C&, D&, E&, F&, G&, H&>
430>::type
431actor<BaseT>::operator()(
432    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h
433) const
434{
435    return BaseT::eval(
436        tuple<A&, B&, C&, D&, E&, F&, G&, H&>
437        (a, b, c, d, e, f, g, h)
438    );
439}
440
441//////////////////////////////////
442template <typename BaseT>
443template <
444    typename A, typename B, typename C, typename D, typename E,
445    typename F, typename G, typename H, typename I>
446inline typename actor_result<BaseT,
447    tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
448>::type
449actor<BaseT>::operator()(
450    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i
451) const
452{
453    return BaseT::eval(
454        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
455        (a, b, c, d, e, f, g, h, i)
456    );
457}
458
459#if PHOENIX_LIMIT > 9
460//////////////////////////////////
461template <typename BaseT>
462template <
463    typename A, typename B, typename C, typename D, typename E,
464    typename F, typename G, typename H, typename I, typename J>
465inline typename actor_result<BaseT,
466    tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
467>::type
468actor<BaseT>::operator()(
469    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j
470) const
471{
472    return BaseT::eval(
473        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
474        (a, b, c, d, e, f, g, h, i, j)
475    );
476}
477
478//////////////////////////////////
479template <typename BaseT>
480template <
481    typename A, typename B, typename C, typename D, typename E,
482    typename F, typename G, typename H, typename I, typename J,
483    typename K>
484inline typename actor_result<BaseT,
485    tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
486>::type
487actor<BaseT>::operator()(
488    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
489    K& k
490) const
491{
492    return BaseT::eval(
493        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
494        (a, b, c, d, e, f, g, h, i, j, k)
495    );
496}
497
498//////////////////////////////////
499template <typename BaseT>
500template <
501    typename A, typename B, typename C, typename D, typename E,
502    typename F, typename G, typename H, typename I, typename J,
503    typename K, typename L>
504inline typename actor_result<BaseT,
505    tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
506>::type
507actor<BaseT>::operator()(
508    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
509    K& k, L& l
510) const
511{
512    return BaseT::eval(
513        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
514        (a, b, c, d, e, f, g, h, i, j, k, l)
515    );
516}
517
518#if PHOENIX_LIMIT > 12
519//////////////////////////////////
520template <typename BaseT>
521template <
522    typename A, typename B, typename C, typename D, typename E,
523    typename F, typename G, typename H, typename I, typename J,
524    typename K, typename L, typename M>
525inline typename actor_result<BaseT,
526    tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
527>::type
528actor<BaseT>::operator()(
529    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
530    K& k, L& l, M& m
531) const
532{
533    return BaseT::eval(
534        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
535        (a, b, c, d, e, f, g, h, i, j, k, l, m)
536    );
537}
538
539//////////////////////////////////
540template <typename BaseT>
541template <
542    typename A, typename B, typename C, typename D, typename E,
543    typename F, typename G, typename H, typename I, typename J,
544    typename K, typename L, typename M, typename N>
545inline typename actor_result<BaseT,
546    tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
547>::type
548actor<BaseT>::operator()(
549    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
550    K& k, L& l, M& m, N& n
551) const
552{
553    return BaseT::eval(
554        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
555        (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
556    );
557}
558
559//////////////////////////////////
560template <typename BaseT>
561template <
562    typename A, typename B, typename C, typename D, typename E,
563    typename F, typename G, typename H, typename I, typename J,
564    typename K, typename L, typename M, typename N, typename O>
565inline typename actor_result<BaseT,
566    tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
567>::type
568actor<BaseT>::operator()(
569    A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
570    K& k, L& l, M& m, N& n, O& o
571) const
572{
573    return BaseT::eval(
574        tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
575        (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
576    );
577}
578
579#endif
580#endif
581#endif
582#endif
583
584//////////////////////////////////
585template <typename BaseT>
586template <typename TupleT>
587typename actor_result<BaseT, unpack_tuple<TupleT> >::type
588actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const
589{
590    return BaseT::eval(t);
591}
592
593///////////////////////////////////////////////////////////////////////////////
594}   //  namespace phoenix
595
596#endif
Note: See TracBrowser for help on using the repository browser.