1 /*=============================================================================
2     Phoenix V1.2.1
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_COMPOSITE_HPP
9 #define PHOENIX_COMPOSITE_HPP
10 
11 ///////////////////////////////////////////////////////////////////////////////
12 #include <boost/spirit/home/classic/phoenix/actor.hpp>
13 
14 ///////////////////////////////////////////////////////////////////////////////
15 namespace phoenix {
16 
17 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
18 #pragma warning(push)
19 #pragma warning(disable:4512) //assignment operator could not be generated
20 #endif
21 
22 ///////////////////////////////////////////////////////////////////////////////
23 //
24 //  composite class
25 //
26 //      A composite is an actor base class composed of zero or more
27 //      actors (see actor.hpp) and an operation. A composite is itself
28 //      an actor superclass and conforms to its conceptual interface.
29 //      Its eval member function un-funnels the tupled actual arguments
30 //      from the tuple by invoking each of the actors' eval member
31 //      function. The results of each are then passed on as arguments to
32 //      the operation. Specializations are provided to handle different
33 //      numbers of actors.
34 //
35 //      Schematically:
36 //
37 //          actor0.eval(tupled_args) --> arg0 --> |
38 //          actor1.eval(tupled_args) --> arg1 --> |
39 //          actor2.eval(tupled_args) --> arg3 --> | --> operation(arg0...argN)
40 //            ...                                 |
41 //          actorN.eval(tupled_args) --> argN --> |
42 //
43 //      The operation can be any suitable functor that can accept the
44 //      arguments passed in by the composite. The operation is expected
45 //      to have a member operator() that carries out the actual
46 //      operation. There should be a one to one correspondence between
47 //      actors of the composite and the arguments of the operation's
48 //      member operator().
49 //
50 //      The operation is also expected to have a nested template class
51 //      result<T0...TN>. The nested template class result should have a
52 //      typedef 'type' that reflects the return type of its member
53 //      operator(). This is essentially a type computer that answers the
54 //      metaprogramming question "Given arguments of type T0...TN, what
55 //      will be its operator()'s return type?".
56 //
57 //      There is a special case for operations that accept no arguments.
58 //      Such nullary operations are only required to define a typedef
59 //      result_type that reflects the return type of its operator().
60 //
61 //      Here's an example of a simple operation that squares a number:
62 //
63 //          struct square {
64 //
65 //              template <typename ArgT>
66 //              struct result { typedef ArgT type; };
67 //
68 //              template <typename ArgT>
69 //              ArgT operator()(ArgT n) const { return n * n; }
70 //          };
71 //
72 //      As can be seen, operations can be polymorphic. Its arguments and
73 //      return type are not fixed to a particular type. The example
74 //      above for example, can handle any ArgT type as long as it has a
75 //      multiplication operator.
76 //
77 //      Composites are not created directly. Instead, there are meta-
78 //      programs provided that indirectly create composites. See
79 //      operators.hpp, binders.hpp and functions.hpp for examples.
80 //
81 ///////////////////////////////////////////////////////////////////////////////
82 template <
83     typename OperationT
84     ,   typename A = nil_t
85     ,   typename B = nil_t
86     ,   typename C = nil_t
87 
88 #if PHOENIX_LIMIT > 3
89     ,   typename D = nil_t
90     ,   typename E = nil_t
91     ,   typename F = nil_t
92 
93 #if PHOENIX_LIMIT > 6
94     ,   typename G = nil_t
95     ,   typename H = nil_t
96     ,   typename I = nil_t
97 
98 #if PHOENIX_LIMIT > 9
99     ,   typename J = nil_t
100     ,   typename K = nil_t
101     ,   typename L = nil_t
102 
103 #if PHOENIX_LIMIT > 12
104     ,   typename M = nil_t
105     ,   typename N = nil_t
106     ,   typename O = nil_t
107 
108 #endif
109 #endif
110 #endif
111 #endif
112 
113     ,   typename NU = nil_t  // Not used
114 >
115 struct composite;
116 
117 ///////////////////////////////////////////////////////////////////////////////
118 //
119 //  composite <0 actor> class
120 //
121 ///////////////////////////////////////////////////////////////////////////////
122 template <typename OperationT, typename TupleT>
123 struct composite0_result {
124 
125     typedef typename OperationT::result_type type;
126 };
127 
128 //////////////////////////////////
129 template <typename OperationT>
130 struct composite<OperationT,
131     nil_t, nil_t, nil_t,
132 #if PHOENIX_LIMIT > 3
133     nil_t, nil_t, nil_t,
134 #if PHOENIX_LIMIT > 6
135     nil_t, nil_t, nil_t,
136 #if PHOENIX_LIMIT > 9
137     nil_t, nil_t, nil_t,
138 #if PHOENIX_LIMIT > 12
139     nil_t, nil_t, nil_t,
140 #endif
141 #endif
142 #endif
143 #endif
144     nil_t   //  Unused
145 > {
146 
147     typedef composite<OperationT> self_t;
148 
149     template <typename TupleT>
150     struct result {
151 
152         typedef typename composite0_result<
153             OperationT, TupleT
154         >::type type;
155     };
156 
compositephoenix::composite157     composite(OperationT const& op_)
158     :   op(op_) {}
159 
160     template <typename TupleT>
161     typename OperationT::result_type
evalphoenix::composite162     eval(TupleT const& /*args*/) const
163     {
164         return op();
165     }
166 
167     mutable OperationT op; //  operation
168 };
169 
170 ///////////////////////////////////////////////////////////////////////////////
171 //
172 //  composite <1 actor> class
173 //
174 ///////////////////////////////////////////////////////////////////////////////
175 template <typename OperationT, typename TupleT,
176     typename A>
177 struct composite1_result {
178 
179     typedef typename OperationT::template result<
180         typename actor_result<A, TupleT>::plain_type
181     >::type type;
182 };
183 
184 //////////////////////////////////
185 template <typename OperationT,
186     typename A>
187 struct composite<OperationT,
188     A, nil_t, nil_t,
189 #if PHOENIX_LIMIT > 3
190     nil_t, nil_t, nil_t,
191 #if PHOENIX_LIMIT > 6
192     nil_t, nil_t, nil_t,
193 #if PHOENIX_LIMIT > 9
194     nil_t, nil_t, nil_t,
195 #if PHOENIX_LIMIT > 12
196     nil_t, nil_t, nil_t,
197 #endif
198 #endif
199 #endif
200 #endif
201     nil_t   //  Unused
202 > {
203 
204     typedef composite<OperationT, A> self_t;
205 
206     template <typename TupleT>
207     struct result {
208 
209         typedef typename composite1_result<
210             OperationT, TupleT, A
211         >::type type;
212     };
213 
compositephoenix::composite214     composite(OperationT const& op_,
215         A const& a_)
216     :   op(op_), a(a_) {}
217 
218     template <typename TupleT>
219     typename actor_result<self_t, TupleT>::type
evalphoenix::composite220     eval(TupleT const& args) const
221     {
222         typename actor_result<A, TupleT>::type ra = a.eval(args);
223         return op(ra);
224     }
225 
226     mutable OperationT op; //  operation
227     A a; //  actors
228 };
229 
230 ///////////////////////////////////////////////////////////////////////////////
231 //
232 //  composite <2 actors> class
233 //
234 ///////////////////////////////////////////////////////////////////////////////
235 template <typename OperationT, typename TupleT,
236     typename A, typename B>
237 struct composite2_result {
238 
239     typedef typename OperationT::template result<
240         typename actor_result<A, TupleT>::plain_type,
241         typename actor_result<B, TupleT>::plain_type
242     >::type type;
243 };
244 
245 //////////////////////////////////
246 template <typename OperationT,
247     typename A, typename B>
248 struct composite<OperationT,
249     A, B, nil_t,
250 #if PHOENIX_LIMIT > 3
251     nil_t, nil_t, nil_t,
252 #if PHOENIX_LIMIT > 6
253     nil_t, nil_t, nil_t,
254 #if PHOENIX_LIMIT > 9
255     nil_t, nil_t, nil_t,
256 #if PHOENIX_LIMIT > 12
257     nil_t, nil_t, nil_t,
258 #endif
259 #endif
260 #endif
261 #endif
262     nil_t   //  Unused
263 > {
264 
265     typedef composite<OperationT, A, B> self_t;
266 
267     template <typename TupleT>
268     struct result {
269 
270         typedef typename composite2_result<
271             OperationT, TupleT, A, B
272         >::type type;
273     };
274 
compositephoenix::composite275     composite(OperationT const& op_,
276         A const& a_, B const& b_)
277     :   op(op_), a(a_), b(b_) {}
278 
279     template <typename TupleT>
280     typename actor_result<self_t, TupleT>::type
evalphoenix::composite281     eval(TupleT const& args) const
282     {
283         typename actor_result<A, TupleT>::type ra = a.eval(args);
284         typename actor_result<B, TupleT>::type rb = b.eval(args);
285         return op(ra, rb);
286     }
287 
288     mutable OperationT op; //  operation
289     A a; B b; //  actors
290 };
291 
292 ///////////////////////////////////////////////////////////////////////////////
293 //
294 //  composite <3 actors> class
295 //
296 ///////////////////////////////////////////////////////////////////////////////
297 template <typename OperationT, typename TupleT,
298     typename A, typename B, typename C>
299 struct composite3_result {
300 
301     typedef typename OperationT::template result<
302         typename actor_result<A, TupleT>::plain_type,
303         typename actor_result<B, TupleT>::plain_type,
304         typename actor_result<C, TupleT>::plain_type
305     >::type type;
306 };
307 
308 //////////////////////////////////
309 template <typename OperationT,
310     typename A, typename B, typename C>
311 struct composite<OperationT,
312     A, B, C,
313 #if PHOENIX_LIMIT > 3
314     nil_t, nil_t, nil_t,
315 #if PHOENIX_LIMIT > 6
316     nil_t, nil_t, nil_t,
317 #if PHOENIX_LIMIT > 9
318     nil_t, nil_t, nil_t,
319 #if PHOENIX_LIMIT > 12
320     nil_t, nil_t, nil_t,
321 #endif
322 #endif
323 #endif
324 #endif
325     nil_t   //  Unused
326 > {
327 
328     typedef composite<OperationT, A, B, C> self_t;
329 
330     template <typename TupleT>
331     struct result {
332 
333         typedef typename composite3_result<
334             OperationT, TupleT, A, B, C
335         >::type type;
336     };
337 
compositephoenix::composite338     composite(OperationT const& op_,
339         A const& a_, B const& b_, C const& c_)
340     :   op(op_), a(a_), b(b_), c(c_) {}
341 
342     template <typename TupleT>
343     typename actor_result<self_t, TupleT>::type
evalphoenix::composite344     eval(TupleT const& args) const
345     {
346         typename actor_result<A, TupleT>::type ra = a.eval(args);
347         typename actor_result<B, TupleT>::type rb = b.eval(args);
348         typename actor_result<C, TupleT>::type rc = c.eval(args);
349         return op(ra, rb, rc);
350     }
351 
352     mutable OperationT op; //  operation
353     A a; B b; C c; //  actors
354 };
355 
356 #if PHOENIX_LIMIT > 3
357 ///////////////////////////////////////////////////////////////////////////////
358 //
359 //  composite <4 actors> class
360 //
361 ///////////////////////////////////////////////////////////////////////////////
362 template <typename OperationT, typename TupleT,
363     typename A, typename B, typename C, typename D>
364 struct composite4_result {
365 
366     typedef typename OperationT::template result<
367         typename actor_result<A, TupleT>::plain_type,
368         typename actor_result<B, TupleT>::plain_type,
369         typename actor_result<C, TupleT>::plain_type,
370         typename actor_result<D, TupleT>::plain_type
371     >::type type;
372 };
373 
374 //////////////////////////////////
375 template <typename OperationT,
376     typename A, typename B, typename C, typename D>
377 struct composite<OperationT,
378     A, B, C, D, nil_t, nil_t,
379 #if PHOENIX_LIMIT > 6
380     nil_t, nil_t, nil_t,
381 #if PHOENIX_LIMIT > 9
382     nil_t, nil_t, nil_t,
383 #if PHOENIX_LIMIT > 12
384     nil_t, nil_t, nil_t,
385 #endif
386 #endif
387 #endif
388     nil_t   //  Unused
389 > {
390 
391     typedef composite<OperationT, A, B, C, D> self_t;
392 
393     template <typename TupleT>
394     struct result {
395 
396         typedef typename composite4_result<
397             OperationT, TupleT, A, B, C, D
398         >::type type;
399     };
400 
compositephoenix::composite401     composite(OperationT const& op_,
402         A const& a_, B const& b_, C const& c_, D const& d_)
403     :   op(op_), a(a_), b(b_), c(c_), d(d_) {}
404 
405     template <typename TupleT>
406     typename actor_result<self_t, TupleT>::type
evalphoenix::composite407     eval(TupleT const& args) const
408     {
409         typename actor_result<A, TupleT>::type ra = a.eval(args);
410         typename actor_result<B, TupleT>::type rb = b.eval(args);
411         typename actor_result<C, TupleT>::type rc = c.eval(args);
412         typename actor_result<D, TupleT>::type rd = d.eval(args);
413         return op(ra, rb, rc, rd);
414     }
415 
416     mutable OperationT op; //  operation
417     A a; B b; C c; D d; //  actors
418 };
419 
420 ///////////////////////////////////////////////////////////////////////////////
421 //
422 //  composite <5 actors> class
423 //
424 ///////////////////////////////////////////////////////////////////////////////
425 template <typename OperationT, typename TupleT,
426     typename A, typename B, typename C, typename D, typename E>
427 struct composite5_result {
428 
429     typedef typename OperationT::template result<
430         typename actor_result<A, TupleT>::plain_type,
431         typename actor_result<B, TupleT>::plain_type,
432         typename actor_result<C, TupleT>::plain_type,
433         typename actor_result<D, TupleT>::plain_type,
434         typename actor_result<E, TupleT>::plain_type
435     >::type type;
436 };
437 
438 //////////////////////////////////
439 template <typename OperationT,
440     typename A, typename B, typename C, typename D, typename E>
441 struct composite<OperationT,
442     A, B, C, D, E, nil_t,
443 #if PHOENIX_LIMIT > 6
444     nil_t, nil_t, nil_t,
445 #if PHOENIX_LIMIT > 9
446     nil_t, nil_t, nil_t,
447 #if PHOENIX_LIMIT > 12
448     nil_t, nil_t, nil_t,
449 #endif
450 #endif
451 #endif
452     nil_t   //  Unused
453 > {
454 
455     typedef composite<OperationT, A, B, C, D, E> self_t;
456 
457     template <typename TupleT>
458     struct result {
459 
460         typedef typename composite5_result<
461             OperationT, TupleT, A, B, C, D, E
462         >::type type;
463     };
464 
compositephoenix::composite465     composite(OperationT const& op_,
466         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_)
467     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_) {}
468 
469     template <typename TupleT>
470     typename actor_result<self_t, TupleT>::type
evalphoenix::composite471     eval(TupleT const& args) const
472     {
473         typename actor_result<A, TupleT>::type ra = a.eval(args);
474         typename actor_result<B, TupleT>::type rb = b.eval(args);
475         typename actor_result<C, TupleT>::type rc = c.eval(args);
476         typename actor_result<D, TupleT>::type rd = d.eval(args);
477         typename actor_result<E, TupleT>::type re = e.eval(args);
478         return op(ra, rb, rc, rd, re);
479     }
480 
481     mutable OperationT op; //  operation
482     A a; B b; C c; D d; E e; //  actors
483 };
484 
485 ///////////////////////////////////////////////////////////////////////////////
486 //
487 //  composite <6 actors> class
488 //
489 ///////////////////////////////////////////////////////////////////////////////
490 template <typename OperationT, typename TupleT,
491     typename A, typename B, typename C, typename D, typename E,
492     typename F>
493 struct composite6_result {
494 
495     typedef typename OperationT::template result<
496         typename actor_result<A, TupleT>::plain_type,
497         typename actor_result<B, TupleT>::plain_type,
498         typename actor_result<C, TupleT>::plain_type,
499         typename actor_result<D, TupleT>::plain_type,
500         typename actor_result<E, TupleT>::plain_type,
501         typename actor_result<F, TupleT>::plain_type
502     >::type type;
503 };
504 
505 //////////////////////////////////
506 template <typename OperationT,
507     typename A, typename B, typename C, typename D, typename E,
508     typename F>
509 struct composite<OperationT,
510     A, B, C, D, E, F,
511 #if PHOENIX_LIMIT > 6
512     nil_t, nil_t, nil_t,
513 #if PHOENIX_LIMIT > 9
514     nil_t, nil_t, nil_t,
515 #if PHOENIX_LIMIT > 12
516     nil_t, nil_t, nil_t,
517 #endif
518 #endif
519 #endif
520     nil_t   //  Unused
521 > {
522 
523     typedef composite<OperationT, A, B, C, D, E, F> self_t;
524 
525     template <typename TupleT>
526     struct result {
527 
528         typedef typename composite6_result<
529             OperationT, TupleT, A, B, C, D, E, F
530         >::type type;
531     };
532 
compositephoenix::composite533     composite(OperationT const& op_,
534         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
535         F const& f_)
536     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
537         f(f_) {}
538 
539     template <typename TupleT>
540     typename actor_result<self_t, TupleT>::type
evalphoenix::composite541     eval(TupleT const& args) const
542     {
543         typename actor_result<A, TupleT>::type ra = a.eval(args);
544         typename actor_result<B, TupleT>::type rb = b.eval(args);
545         typename actor_result<C, TupleT>::type rc = c.eval(args);
546         typename actor_result<D, TupleT>::type rd = d.eval(args);
547         typename actor_result<E, TupleT>::type re = e.eval(args);
548         typename actor_result<F, TupleT>::type rf = f.eval(args);
549         return op(ra, rb, rc, rd, re, rf);
550     }
551 
552     mutable OperationT op; //  operation
553     A a; B b; C c; D d; E e; F f; //  actors
554 };
555 
556 #if PHOENIX_LIMIT > 6
557 ///////////////////////////////////////////////////////////////////////////////
558 //
559 //  composite <7 actors> class
560 //
561 ///////////////////////////////////////////////////////////////////////////////
562 template <typename OperationT, typename TupleT,
563     typename A, typename B, typename C, typename D, typename E,
564     typename F, typename G>
565 struct composite7_result {
566 
567     typedef typename OperationT::template result<
568         typename actor_result<A, TupleT>::plain_type,
569         typename actor_result<B, TupleT>::plain_type,
570         typename actor_result<C, TupleT>::plain_type,
571         typename actor_result<D, TupleT>::plain_type,
572         typename actor_result<E, TupleT>::plain_type,
573         typename actor_result<F, TupleT>::plain_type,
574         typename actor_result<G, TupleT>::plain_type
575     >::type type;
576 };
577 
578 //////////////////////////////////
579 template <typename OperationT,
580     typename A, typename B, typename C, typename D, typename E,
581     typename F, typename G>
582 struct composite<OperationT,
583     A, B, C, D, E, F, G, nil_t, nil_t,
584 #if PHOENIX_LIMIT > 9
585     nil_t, nil_t, nil_t,
586 #if PHOENIX_LIMIT > 12
587     nil_t, nil_t, nil_t,
588 #endif
589 #endif
590     nil_t   //  Unused
591 > {
592 
593     typedef composite<OperationT, A, B, C, D, E, F, G> self_t;
594 
595     template <typename TupleT>
596     struct result {
597 
598         typedef typename composite7_result<
599             OperationT, TupleT, A, B, C, D, E, F, G
600         >::type type;
601     };
602 
compositephoenix::composite603     composite(OperationT const& op_,
604         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
605         F const& f_, G const& g_)
606     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
607         f(f_), g(g_) {}
608 
609     template <typename TupleT>
610     typename actor_result<self_t, TupleT>::type
evalphoenix::composite611     eval(TupleT const& args) const
612     {
613         typename actor_result<A, TupleT>::type ra = a.eval(args);
614         typename actor_result<B, TupleT>::type rb = b.eval(args);
615         typename actor_result<C, TupleT>::type rc = c.eval(args);
616         typename actor_result<D, TupleT>::type rd = d.eval(args);
617         typename actor_result<E, TupleT>::type re = e.eval(args);
618         typename actor_result<F, TupleT>::type rf = f.eval(args);
619         typename actor_result<G, TupleT>::type rg = g.eval(args);
620         return op(ra, rb, rc, rd, re, rf, rg);
621     }
622 
623     mutable OperationT op; //  operation
624     A a; B b; C c; D d; E e; F f; G g; //  actors
625 };
626 
627 ///////////////////////////////////////////////////////////////////////////////
628 //
629 //  composite <8 actors> class
630 //
631 ///////////////////////////////////////////////////////////////////////////////
632 template <typename OperationT, typename TupleT,
633     typename A, typename B, typename C, typename D, typename E,
634     typename F, typename G, typename H>
635 struct composite8_result {
636 
637     typedef typename OperationT::template result<
638         typename actor_result<A, TupleT>::plain_type,
639         typename actor_result<B, TupleT>::plain_type,
640         typename actor_result<C, TupleT>::plain_type,
641         typename actor_result<D, TupleT>::plain_type,
642         typename actor_result<E, TupleT>::plain_type,
643         typename actor_result<F, TupleT>::plain_type,
644         typename actor_result<G, TupleT>::plain_type,
645         typename actor_result<H, TupleT>::plain_type
646     >::type type;
647 };
648 
649 //////////////////////////////////
650 template <typename OperationT,
651     typename A, typename B, typename C, typename D, typename E,
652     typename F, typename G, typename H>
653 struct composite<OperationT,
654     A, B, C, D, E, F, G, H, nil_t,
655 #if PHOENIX_LIMIT > 9
656     nil_t, nil_t, nil_t,
657 #if PHOENIX_LIMIT > 12
658     nil_t, nil_t, nil_t,
659 #endif
660 #endif
661     nil_t   //  Unused
662 > {
663 
664     typedef composite<OperationT, A, B, C, D, E, F, G, H> self_t;
665 
666     template <typename TupleT>
667     struct result {
668 
669         typedef typename composite8_result<
670             OperationT, TupleT, A, B, C, D, E, F, G, H
671         >::type type;
672     };
673 
compositephoenix::composite674     composite(OperationT const& op_,
675         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
676         F const& f_, G const& g_, H const& h_)
677     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
678         f(f_), g(g_), h(h_) {}
679 
680     template <typename TupleT>
681     typename actor_result<self_t, TupleT>::type
evalphoenix::composite682     eval(TupleT const& args) const
683     {
684         typename actor_result<A, TupleT>::type ra = a.eval(args);
685         typename actor_result<B, TupleT>::type rb = b.eval(args);
686         typename actor_result<C, TupleT>::type rc = c.eval(args);
687         typename actor_result<D, TupleT>::type rd = d.eval(args);
688         typename actor_result<E, TupleT>::type re = e.eval(args);
689         typename actor_result<F, TupleT>::type rf = f.eval(args);
690         typename actor_result<G, TupleT>::type rg = g.eval(args);
691         typename actor_result<H, TupleT>::type rh = h.eval(args);
692         return op(ra, rb, rc, rd, re, rf, rg, rh);
693     }
694 
695     mutable OperationT op; //  operation
696     A a; B b; C c; D d; E e; F f; G g; H h; //  actors
697 };
698 
699 ///////////////////////////////////////////////////////////////////////////////
700 //
701 //  composite <9 actors> class
702 //
703 ///////////////////////////////////////////////////////////////////////////////
704 template <typename OperationT, typename TupleT,
705     typename A, typename B, typename C, typename D, typename E,
706     typename F, typename G, typename H, typename I>
707 struct composite9_result {
708 
709     typedef typename OperationT::template result<
710         typename actor_result<A, TupleT>::plain_type,
711         typename actor_result<B, TupleT>::plain_type,
712         typename actor_result<C, TupleT>::plain_type,
713         typename actor_result<D, TupleT>::plain_type,
714         typename actor_result<E, TupleT>::plain_type,
715         typename actor_result<F, TupleT>::plain_type,
716         typename actor_result<G, TupleT>::plain_type,
717         typename actor_result<H, TupleT>::plain_type,
718         typename actor_result<I, TupleT>::plain_type
719     >::type type;
720 };
721 
722 //////////////////////////////////
723 template <typename OperationT,
724     typename A, typename B, typename C, typename D, typename E,
725     typename F, typename G, typename H, typename I>
726 struct composite<OperationT,
727     A, B, C, D, E, F, G, H, I,
728 #if PHOENIX_LIMIT > 9
729     nil_t, nil_t, nil_t,
730 #if PHOENIX_LIMIT > 12
731     nil_t, nil_t, nil_t,
732 #endif
733 #endif
734     nil_t   //  Unused
735 > {
736 
737     typedef composite<OperationT, A, B, C, D, E, F, G, H, I> self_t;
738 
739     template <typename TupleT>
740     struct result {
741 
742         typedef typename composite9_result<
743             OperationT, TupleT, A, B, C, D, E, F, G, H, I
744         >::type type;
745     };
746 
compositephoenix::composite747     composite(OperationT const& op_,
748         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
749         F const& f_, G const& g_, H const& h_, I const& i_)
750     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
751         f(f_), g(g_), h(h_), i(i_) {}
752 
753     template <typename TupleT>
754     typename actor_result<self_t, TupleT>::type
evalphoenix::composite755     eval(TupleT const& args) const
756     {
757         typename actor_result<A, TupleT>::type ra = a.eval(args);
758         typename actor_result<B, TupleT>::type rb = b.eval(args);
759         typename actor_result<C, TupleT>::type rc = c.eval(args);
760         typename actor_result<D, TupleT>::type rd = d.eval(args);
761         typename actor_result<E, TupleT>::type re = e.eval(args);
762         typename actor_result<F, TupleT>::type rf = f.eval(args);
763         typename actor_result<G, TupleT>::type rg = g.eval(args);
764         typename actor_result<H, TupleT>::type rh = h.eval(args);
765         typename actor_result<I, TupleT>::type ri = i.eval(args);
766         return op(ra, rb, rc, rd, re, rf, rg, rh, ri);
767     }
768 
769     mutable OperationT op; //  operation
770     A a; B b; C c; D d; E e; F f; G g; H h; I i; //  actors
771 };
772 
773 #if PHOENIX_LIMIT > 9
774 ///////////////////////////////////////////////////////////////////////////////
775 //
776 //  composite <10 actors> class
777 //
778 ///////////////////////////////////////////////////////////////////////////////
779 template <typename OperationT, typename TupleT,
780     typename A, typename B, typename C, typename D, typename E,
781     typename F, typename G, typename H, typename I, typename J>
782 struct composite10_result {
783 
784     typedef typename OperationT::template result<
785         typename actor_result<A, TupleT>::plain_type,
786         typename actor_result<B, TupleT>::plain_type,
787         typename actor_result<C, TupleT>::plain_type,
788         typename actor_result<D, TupleT>::plain_type,
789         typename actor_result<E, TupleT>::plain_type,
790         typename actor_result<F, TupleT>::plain_type,
791         typename actor_result<G, TupleT>::plain_type,
792         typename actor_result<H, TupleT>::plain_type,
793         typename actor_result<I, TupleT>::plain_type,
794         typename actor_result<J, TupleT>::plain_type
795     >::type type;
796 };
797 
798 //////////////////////////////////
799 template <typename OperationT,
800     typename A, typename B, typename C, typename D, typename E,
801     typename F, typename G, typename H, typename I, typename J>
802 struct composite<OperationT,
803     A, B, C, D, E, F, G, H, I, J, nil_t, nil_t,
804 #if PHOENIX_LIMIT > 12
805     nil_t, nil_t, nil_t,
806 #endif
807     nil_t   //  Unused
808 > {
809 
810     typedef composite<OperationT, A, B, C, D, E, F, G, H, I, J> self_t;
811 
812     template <typename TupleT>
813     struct result {
814 
815         typedef typename composite10_result<
816             OperationT, TupleT, A, B, C, D, E, F, G, H, I, J
817         >::type type;
818     };
819 
compositephoenix::composite820     composite(OperationT const& op_,
821         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
822         F const& f_, G const& g_, H const& h_, I const& i_, J const& j_)
823     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
824         f(f_), g(g_), h(h_), i(i_), j(j_) {}
825 
826     template <typename TupleT>
827     typename actor_result<self_t, TupleT>::type
evalphoenix::composite828     eval(TupleT const& args) const
829     {
830         typename actor_result<A, TupleT>::type ra = a.eval(args);
831         typename actor_result<B, TupleT>::type rb = b.eval(args);
832         typename actor_result<C, TupleT>::type rc = c.eval(args);
833         typename actor_result<D, TupleT>::type rd = d.eval(args);
834         typename actor_result<E, TupleT>::type re = e.eval(args);
835         typename actor_result<F, TupleT>::type rf = f.eval(args);
836         typename actor_result<G, TupleT>::type rg = g.eval(args);
837         typename actor_result<H, TupleT>::type rh = h.eval(args);
838         typename actor_result<I, TupleT>::type ri = i.eval(args);
839         typename actor_result<J, TupleT>::type rj = j.eval(args);
840         return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj);
841     }
842 
843     mutable OperationT op; //  operation
844     A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; //  actors
845 };
846 
847 ///////////////////////////////////////////////////////////////////////////////
848 //
849 //  composite <11 actors> class
850 //
851 ///////////////////////////////////////////////////////////////////////////////
852 template <typename OperationT, typename TupleT,
853     typename A, typename B, typename C, typename D, typename E,
854     typename F, typename G, typename H, typename I, typename J,
855     typename K>
856 struct composite11_result {
857 
858     typedef typename OperationT::template result<
859         typename actor_result<A, TupleT>::plain_type,
860         typename actor_result<B, TupleT>::plain_type,
861         typename actor_result<C, TupleT>::plain_type,
862         typename actor_result<D, TupleT>::plain_type,
863         typename actor_result<E, TupleT>::plain_type,
864         typename actor_result<F, TupleT>::plain_type,
865         typename actor_result<G, TupleT>::plain_type,
866         typename actor_result<H, TupleT>::plain_type,
867         typename actor_result<I, TupleT>::plain_type,
868         typename actor_result<J, TupleT>::plain_type,
869         typename actor_result<K, TupleT>::plain_type
870     >::type type;
871 };
872 
873 //////////////////////////////////
874 template <typename OperationT,
875     typename A, typename B, typename C, typename D, typename E,
876     typename F, typename G, typename H, typename I, typename J,
877     typename K>
878 struct composite<OperationT,
879     A, B, C, D, E, F, G, H, I, J, K, nil_t,
880 #if PHOENIX_LIMIT > 12
881     nil_t, nil_t, nil_t,
882 #endif
883     nil_t   //  Unused
884 > {
885 
886     typedef composite<OperationT,
887         A, B, C, D, E, F, G, H, I, J, K> self_t;
888 
889     template <typename TupleT>
890     struct result {
891 
892         typedef typename composite11_result<
893             OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K
894         >::type type;
895     };
896 
compositephoenix::composite897     composite(OperationT const& op_,
898         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
899         F const& f_, G const& g_, H const& h_, I const& i_, J const& j_,
900         K const& k_)
901     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
902         f(f_), g(g_), h(h_), i(i_), j(j_),
903         k(k_) {}
904 
905     template <typename TupleT>
906     typename actor_result<self_t, TupleT>::type
evalphoenix::composite907     eval(TupleT const& args) const
908     {
909         typename actor_result<A, TupleT>::type ra = a.eval(args);
910         typename actor_result<B, TupleT>::type rb = b.eval(args);
911         typename actor_result<C, TupleT>::type rc = c.eval(args);
912         typename actor_result<D, TupleT>::type rd = d.eval(args);
913         typename actor_result<E, TupleT>::type re = e.eval(args);
914         typename actor_result<F, TupleT>::type rf = f.eval(args);
915         typename actor_result<G, TupleT>::type rg = g.eval(args);
916         typename actor_result<H, TupleT>::type rh = h.eval(args);
917         typename actor_result<I, TupleT>::type ri = i.eval(args);
918         typename actor_result<J, TupleT>::type rj = j.eval(args);
919         typename actor_result<K, TupleT>::type rk = k.eval(args);
920         return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk);
921     }
922 
923     mutable OperationT op; //  operation
924     A a; B b; C c; D d; E e; F f; G g; H h; I i; J j;
925     K k;//  actors
926 };
927 
928 ///////////////////////////////////////////////////////////////////////////////
929 //
930 //  composite <12 actors> class
931 //
932 ///////////////////////////////////////////////////////////////////////////////
933 template <typename OperationT, typename TupleT,
934     typename A, typename B, typename C, typename D, typename E,
935     typename F, typename G, typename H, typename I, typename J,
936     typename K, typename L>
937 struct composite12_result {
938 
939     typedef typename OperationT::template result<
940         typename actor_result<A, TupleT>::plain_type,
941         typename actor_result<B, TupleT>::plain_type,
942         typename actor_result<C, TupleT>::plain_type,
943         typename actor_result<D, TupleT>::plain_type,
944         typename actor_result<E, TupleT>::plain_type,
945         typename actor_result<F, TupleT>::plain_type,
946         typename actor_result<G, TupleT>::plain_type,
947         typename actor_result<H, TupleT>::plain_type,
948         typename actor_result<I, TupleT>::plain_type,
949         typename actor_result<J, TupleT>::plain_type,
950         typename actor_result<K, TupleT>::plain_type,
951         typename actor_result<L, TupleT>::plain_type
952     >::type type;
953 };
954 
955 //////////////////////////////////
956 template <typename OperationT,
957     typename A, typename B, typename C, typename D, typename E,
958     typename F, typename G, typename H, typename I, typename J,
959     typename K, typename L>
960 struct composite<OperationT,
961     A, B, C, D, E, F, G, H, I, J, K, L,
962 #if PHOENIX_LIMIT > 12
963     nil_t, nil_t, nil_t,
964 #endif
965     nil_t   //  Unused
966 > {
967 
968     typedef composite<OperationT,
969         A, B, C, D, E, F, G, H, I, J, K, L> self_t;
970 
971     template <typename TupleT>
972     struct result {
973 
974         typedef typename composite12_result<
975             OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L
976         >::type type;
977     };
978 
compositephoenix::composite979     composite(OperationT const& op_,
980         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
981         F const& f_, G const& g_, H const& h_, I const& i_, J const& j_,
982         K const& k_, L const& l_)
983     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
984         f(f_), g(g_), h(h_), i(i_), j(j_),
985         k(k_), l(l_) {}
986 
987     template <typename TupleT>
988     typename actor_result<self_t, TupleT>::type
evalphoenix::composite989     eval(TupleT const& args) const
990     {
991         typename actor_result<A, TupleT>::type ra = a.eval(args);
992         typename actor_result<B, TupleT>::type rb = b.eval(args);
993         typename actor_result<C, TupleT>::type rc = c.eval(args);
994         typename actor_result<D, TupleT>::type rd = d.eval(args);
995         typename actor_result<E, TupleT>::type re = e.eval(args);
996         typename actor_result<F, TupleT>::type rf = f.eval(args);
997         typename actor_result<G, TupleT>::type rg = g.eval(args);
998         typename actor_result<H, TupleT>::type rh = h.eval(args);
999         typename actor_result<I, TupleT>::type ri = i.eval(args);
1000         typename actor_result<J, TupleT>::type rj = j.eval(args);
1001         typename actor_result<K, TupleT>::type rk = k.eval(args);
1002         typename actor_result<L, TupleT>::type rl = l.eval(args);
1003         return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl);
1004     }
1005 
1006     mutable OperationT op; //  operation
1007     A a; B b; C c; D d; E e; F f; G g; H h; I i; J j;
1008     K k; L l;//  actors
1009 };
1010 
1011 #if PHOENIX_LIMIT > 12
1012 ///////////////////////////////////////////////////////////////////////////////
1013 //
1014 //  composite <13 actors> class
1015 //
1016 ///////////////////////////////////////////////////////////////////////////////
1017 template <typename OperationT, typename TupleT,
1018     typename A, typename B, typename C, typename D, typename E,
1019     typename F, typename G, typename H, typename I, typename J,
1020     typename K, typename L, typename M>
1021 struct composite13_result {
1022 
1023     typedef typename OperationT::template result<
1024         typename actor_result<A, TupleT>::plain_type,
1025         typename actor_result<B, TupleT>::plain_type,
1026         typename actor_result<C, TupleT>::plain_type,
1027         typename actor_result<D, TupleT>::plain_type,
1028         typename actor_result<E, TupleT>::plain_type,
1029         typename actor_result<F, TupleT>::plain_type,
1030         typename actor_result<G, TupleT>::plain_type,
1031         typename actor_result<H, TupleT>::plain_type,
1032         typename actor_result<I, TupleT>::plain_type,
1033         typename actor_result<J, TupleT>::plain_type,
1034         typename actor_result<K, TupleT>::plain_type,
1035         typename actor_result<L, TupleT>::plain_type,
1036         typename actor_result<M, TupleT>::plain_type
1037     >::type type;
1038 };
1039 
1040 //////////////////////////////////
1041 template <typename OperationT,
1042     typename A, typename B, typename C, typename D, typename E,
1043     typename F, typename G, typename H, typename I, typename J,
1044     typename K, typename L, typename M>
1045 struct composite<OperationT,
1046     A, B, C, D, E, F, G, H, I, J, K, L, M, nil_t, nil_t, nil_t
1047 > {
1048 
1049     typedef composite<OperationT,
1050         A, B, C, D, E, F, G, H, I, J, K, L, M> self_t;
1051 
1052     template <typename TupleT>
1053     struct result {
1054 
1055         typedef typename composite13_result<
1056             OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L, M
1057         >::type type;
1058     };
1059 
compositephoenix::composite1060     composite(OperationT const& op_,
1061         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
1062         F const& f_, G const& g_, H const& h_, I const& i_, J const& j_,
1063         K const& k_, L const& l_, M const& m_)
1064     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
1065         f(f_), g(g_), h(h_), i(i_), j(j_),
1066         k(k_), l(l_), m(m_) {}
1067 
1068     template <typename TupleT>
1069     typename actor_result<self_t, TupleT>::type
evalphoenix::composite1070     eval(TupleT const& args) const
1071     {
1072         typename actor_result<A, TupleT>::type ra = a.eval(args);
1073         typename actor_result<B, TupleT>::type rb = b.eval(args);
1074         typename actor_result<C, TupleT>::type rc = c.eval(args);
1075         typename actor_result<D, TupleT>::type rd = d.eval(args);
1076         typename actor_result<E, TupleT>::type re = e.eval(args);
1077         typename actor_result<F, TupleT>::type rf = f.eval(args);
1078         typename actor_result<G, TupleT>::type rg = g.eval(args);
1079         typename actor_result<H, TupleT>::type rh = h.eval(args);
1080         typename actor_result<I, TupleT>::type ri = i.eval(args);
1081         typename actor_result<J, TupleT>::type rj = j.eval(args);
1082         typename actor_result<K, TupleT>::type rk = k.eval(args);
1083         typename actor_result<L, TupleT>::type rl = l.eval(args);
1084         typename actor_result<M, TupleT>::type rm = m.eval(args);
1085         return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl, rm);
1086     }
1087 
1088     mutable OperationT op; //  operation
1089     A a; B b; C c; D d; E e; F f; G g; H h; I i; J j;
1090     K k; L l; M m; //  actors
1091 };
1092 
1093 ///////////////////////////////////////////////////////////////////////////////
1094 //
1095 //  composite <14 actors> class
1096 //
1097 ///////////////////////////////////////////////////////////////////////////////
1098 template <typename OperationT, typename TupleT,
1099     typename A, typename B, typename C, typename D, typename E,
1100     typename F, typename G, typename H, typename I, typename J,
1101     typename K, typename L, typename M, typename N>
1102 struct composite14_result {
1103 
1104     typedef typename OperationT::template result<
1105         typename actor_result<A, TupleT>::plain_type,
1106         typename actor_result<B, TupleT>::plain_type,
1107         typename actor_result<C, TupleT>::plain_type,
1108         typename actor_result<D, TupleT>::plain_type,
1109         typename actor_result<E, TupleT>::plain_type,
1110         typename actor_result<F, TupleT>::plain_type,
1111         typename actor_result<G, TupleT>::plain_type,
1112         typename actor_result<H, TupleT>::plain_type,
1113         typename actor_result<I, TupleT>::plain_type,
1114         typename actor_result<J, TupleT>::plain_type,
1115         typename actor_result<K, TupleT>::plain_type,
1116         typename actor_result<L, TupleT>::plain_type,
1117         typename actor_result<M, TupleT>::plain_type,
1118         typename actor_result<N, TupleT>::plain_type
1119     >::type type;
1120 };
1121 
1122 //////////////////////////////////
1123 template <typename OperationT,
1124     typename A, typename B, typename C, typename D, typename E,
1125     typename F, typename G, typename H, typename I, typename J,
1126     typename K, typename L, typename M, typename N>
1127 struct composite<OperationT,
1128     A, B, C, D, E, F, G, H, I, J, K, L, M, N, nil_t, nil_t
1129 > {
1130 
1131     typedef composite<OperationT,
1132         A, B, C, D, E, F, G, H, I, J, K, L, M, N> self_t;
1133 
1134     template <typename TupleT>
1135     struct result {
1136 
1137         typedef typename composite14_result<
1138             OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
1139         >::type type;
1140     };
1141 
compositephoenix::composite1142     composite(OperationT const& op_,
1143         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
1144         F const& f_, G const& g_, H const& h_, I const& i_, J const& j_,
1145         K const& k_, L const& l_, M const& m_, N const& n_)
1146     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
1147         f(f_), g(g_), h(h_), i(i_), j(j_),
1148         k(k_), l(l_), m(m_), n(n_) {}
1149 
1150     template <typename TupleT>
1151     typename actor_result<self_t, TupleT>::type
evalphoenix::composite1152     eval(TupleT const& args) const
1153     {
1154         typename actor_result<A, TupleT>::type ra = a.eval(args);
1155         typename actor_result<B, TupleT>::type rb = b.eval(args);
1156         typename actor_result<C, TupleT>::type rc = c.eval(args);
1157         typename actor_result<D, TupleT>::type rd = d.eval(args);
1158         typename actor_result<E, TupleT>::type re = e.eval(args);
1159         typename actor_result<F, TupleT>::type rf = f.eval(args);
1160         typename actor_result<G, TupleT>::type rg = g.eval(args);
1161         typename actor_result<H, TupleT>::type rh = h.eval(args);
1162         typename actor_result<I, TupleT>::type ri = i.eval(args);
1163         typename actor_result<J, TupleT>::type rj = j.eval(args);
1164         typename actor_result<K, TupleT>::type rk = k.eval(args);
1165         typename actor_result<L, TupleT>::type rl = l.eval(args);
1166         typename actor_result<M, TupleT>::type rm = m.eval(args);
1167         typename actor_result<N, TupleT>::type rn = n.eval(args);
1168         return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl, rm, rn);
1169     }
1170 
1171     mutable OperationT op; //  operation
1172     A a; B b; C c; D d; E e; F f; G g; H h; I i; J j;
1173     K k; L l; M m; N n; //  actors
1174 };
1175 
1176 ///////////////////////////////////////////////////////////////////////////////
1177 //
1178 //  composite <15 actors> class
1179 //
1180 ///////////////////////////////////////////////////////////////////////////////
1181 template <typename OperationT, typename TupleT,
1182     typename A, typename B, typename C, typename D, typename E,
1183     typename F, typename G, typename H, typename I, typename J,
1184     typename K, typename L, typename M, typename N, typename O>
1185 struct composite15_result {
1186 
1187     typedef typename OperationT::template result<
1188         typename actor_result<A, TupleT>::plain_type,
1189         typename actor_result<B, TupleT>::plain_type,
1190         typename actor_result<C, TupleT>::plain_type,
1191         typename actor_result<D, TupleT>::plain_type,
1192         typename actor_result<E, TupleT>::plain_type,
1193         typename actor_result<F, TupleT>::plain_type,
1194         typename actor_result<G, TupleT>::plain_type,
1195         typename actor_result<H, TupleT>::plain_type,
1196         typename actor_result<I, TupleT>::plain_type,
1197         typename actor_result<J, TupleT>::plain_type,
1198         typename actor_result<K, TupleT>::plain_type,
1199         typename actor_result<L, TupleT>::plain_type,
1200         typename actor_result<M, TupleT>::plain_type,
1201         typename actor_result<N, TupleT>::plain_type,
1202         typename actor_result<O, TupleT>::plain_type
1203     >::type type;
1204 };
1205 
1206 //////////////////////////////////
1207 template <typename OperationT,
1208     typename A, typename B, typename C, typename D, typename E,
1209     typename F, typename G, typename H, typename I, typename J,
1210     typename K, typename L, typename M, typename N, typename O>
1211 struct composite<OperationT,
1212     A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, nil_t
1213 > {
1214 
1215     typedef composite<OperationT,
1216         A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> self_t;
1217 
1218     template <typename TupleT>
1219     struct result {
1220 
1221         typedef typename composite15_result<
1222             OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
1223         >::type type;
1224     };
1225 
compositephoenix::composite1226     composite(OperationT const& op_,
1227         A const& a_, B const& b_, C const& c_, D const& d_, E const& e_,
1228         F const& f_, G const& g_, H const& h_, I const& i_, J const& j_,
1229         K const& k_, L const& l_, M const& m_, N const& n_, O const& o_)
1230     :   op(op_), a(a_), b(b_), c(c_), d(d_), e(e_),
1231         f(f_), g(g_), h(h_), i(i_), j(j_),
1232         k(k_), l(l_), m(m_), n(n_), o(o_) {}
1233 
1234     template <typename TupleT>
1235     typename actor_result<self_t, TupleT>::type
evalphoenix::composite1236     eval(TupleT const& args) const
1237     {
1238         typename actor_result<A, TupleT>::type ra = a.eval(args);
1239         typename actor_result<B, TupleT>::type rb = b.eval(args);
1240         typename actor_result<C, TupleT>::type rc = c.eval(args);
1241         typename actor_result<D, TupleT>::type rd = d.eval(args);
1242         typename actor_result<E, TupleT>::type re = e.eval(args);
1243         typename actor_result<F, TupleT>::type rf = f.eval(args);
1244         typename actor_result<G, TupleT>::type rg = g.eval(args);
1245         typename actor_result<H, TupleT>::type rh = h.eval(args);
1246         typename actor_result<I, TupleT>::type ri = i.eval(args);
1247         typename actor_result<J, TupleT>::type rj = j.eval(args);
1248         typename actor_result<K, TupleT>::type rk = k.eval(args);
1249         typename actor_result<L, TupleT>::type rl = l.eval(args);
1250         typename actor_result<M, TupleT>::type rm = m.eval(args);
1251         typename actor_result<N, TupleT>::type rn = n.eval(args);
1252         typename actor_result<O, TupleT>::type ro = o.eval(args);
1253         return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl, rm, rn, ro);
1254     }
1255 
1256     mutable OperationT op; //  operation
1257     A a; B b; C c; D d; E e; F f; G g; H h; I i; J j;
1258     K k; L l; M m; N n; O o; //  actors
1259 };
1260 
1261 #endif
1262 #endif
1263 #endif
1264 #endif
1265 
1266 namespace impl {
1267 
1268     ///////////////////////////////////////////////////////////////////////////
1269     //
1270     //      make_composite is basically a type computer that answers the
1271     //      question "Given types T0..TN, what composite type should I
1272     //      create <composite_type> and if I were to generate an actual
1273     //      composite, what type <type> should I return?"
1274     //
1275     ///////////////////////////////////////////////////////////////////////////
1276     template <
1277         typename OperationT
1278         ,   typename A = nil_t
1279         ,   typename B = nil_t
1280         ,   typename C = nil_t
1281 
1282 #if PHOENIX_LIMIT > 3
1283         ,   typename D = nil_t
1284         ,   typename E = nil_t
1285         ,   typename F = nil_t
1286 
1287 #if PHOENIX_LIMIT > 6
1288         ,   typename G = nil_t
1289         ,   typename H = nil_t
1290         ,   typename I = nil_t
1291 
1292 #if PHOENIX_LIMIT > 9
1293         ,   typename J = nil_t
1294         ,   typename K = nil_t
1295         ,   typename L = nil_t
1296 
1297 #if PHOENIX_LIMIT > 12
1298         ,   typename M = nil_t
1299         ,   typename N = nil_t
1300         ,   typename O = nil_t
1301 
1302 #endif
1303 #endif
1304 #endif
1305 #endif
1306     >
1307     struct make_composite {
1308 
1309         typedef composite<OperationT
1310             ,   typename as_actor<A>::type
1311             ,   typename as_actor<B>::type
1312             ,   typename as_actor<C>::type
1313 
1314 #if PHOENIX_LIMIT > 3
1315             ,   typename as_actor<D>::type
1316             ,   typename as_actor<E>::type
1317             ,   typename as_actor<F>::type
1318 
1319 #if PHOENIX_LIMIT > 6
1320             ,   typename as_actor<G>::type
1321             ,   typename as_actor<H>::type
1322             ,   typename as_actor<I>::type
1323 
1324 #if PHOENIX_LIMIT > 9
1325             ,   typename as_actor<J>::type
1326             ,   typename as_actor<K>::type
1327             ,   typename as_actor<L>::type
1328 
1329 #if PHOENIX_LIMIT > 12
1330             ,   typename as_actor<M>::type
1331             ,   typename as_actor<N>::type
1332             ,   typename as_actor<O>::type
1333 
1334 #endif
1335 #endif
1336 #endif
1337 #endif
1338         > composite_type;
1339 
1340         typedef actor<composite_type> type;
1341     };
1342 
1343     ///////////////////////////////////////////////////////////////////////////
1344     //
1345     //      make_unary, make_binary, make_binary1, make_binary2 and
1346     //      make_binary3 utilities are provided here for easy creation of
1347     //      unary and binary composites.
1348     //
1349     ///////////////////////////////////////////////////////////////////////////
1350 
1351     //////////////////////////////////  input is an actor
1352     template <typename OperationT, typename BaseT>
1353     struct make_unary {
1354 
1355         typedef typename make_composite
1356             <OperationT, actor<BaseT> >::type type;
1357 
1358         static type
constructphoenix::impl::make_unary1359         construct(actor<BaseT> const& _0)
1360         {
1361             typedef typename make_composite
1362                     <OperationT, actor<BaseT> >::composite_type
1363                 ret_t;
1364 
1365             return ret_t(OperationT(), _0);
1366         }
1367     };
1368 
1369     //////////////////////////////////  LHS is an actor, RHS is unknown
1370     template <typename OperationT, typename BaseT, typename B>
1371     struct make_binary1 {
1372 
1373         typedef typename make_composite
1374             <OperationT, actor<BaseT>, B>::type type;
1375 
1376         static type
constructphoenix::impl::make_binary11377         construct(actor<BaseT> const& _0, B const& _1)
1378         {
1379             typedef typename make_composite
1380                     <OperationT, actor<BaseT>, B>::composite_type
1381                 ret_t;
1382 
1383             return ret_t(OperationT(), _0, as_actor<B>::convert(_1));
1384         }
1385     };
1386 
1387     //////////////////////////////////  LHS is unknown, RHS is an actor
1388     template <typename OperationT, typename A, typename BaseT>
1389     struct make_binary2 {
1390 
1391         typedef typename make_composite
1392             <OperationT, A, actor<BaseT> >::type type;
1393 
1394         static type
constructphoenix::impl::make_binary21395         construct(A const& _0, actor<BaseT> const& _1)
1396         {
1397             typedef typename make_composite
1398                     <OperationT, A, actor<BaseT> >::composite_type
1399                 ret_t;
1400 
1401             return ret_t(OperationT(), as_actor<A>::convert(_0), _1);
1402         }
1403     };
1404 
1405     //////////////////////////////////  Both LHS and RHS are actors
1406     template <typename OperationT, typename BaseA, typename BaseB>
1407     struct make_binary3 {
1408 
1409         typedef typename make_composite
1410             <OperationT, actor<BaseA>, actor<BaseB> >::type type;
1411 
1412         static type
constructphoenix::impl::make_binary31413         construct(actor<BaseA> const& _0, actor<BaseB> const& _1)
1414         {
1415             typedef typename make_composite
1416                     <OperationT, actor<BaseA>, actor<BaseB> >::composite_type
1417                 ret_t;
1418 
1419             return ret_t(OperationT(), _0, _1);
1420         }
1421     };
1422 
1423 }   // namespace impl
1424 
1425 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
1426 #pragma warning(pop)
1427 #endif
1428 
1429 }   //  namespace phoenix
1430 
1431 #endif
1432