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

Revision 857, 23.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Phoenix V1.2.1
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_FUNCTIONS_HPP
10#define PHOENIX_FUNCTIONS_HPP
11
12///////////////////////////////////////////////////////////////////////////////
13#include <boost/spirit/phoenix/actor.hpp>
14#include <boost/spirit/phoenix/composite.hpp>
15
16///////////////////////////////////////////////////////////////////////////////
17namespace phoenix {
18
19///////////////////////////////////////////////////////////////////////////////
20//
21//  function class
22//
23//      Lazy functions
24//
25//      This class provides a mechanism for lazily evaluating functions.
26//      Syntactically, a lazy function looks like an ordinary C/C++
27//      function. The function call looks the same. However, unlike
28//      ordinary functions, the actual function execution is deferred.
29//      (see actor.hpp, primitives.hpp and composite.hpp for an
30//      overview). For example here are sample factorial function calls:
31//
32//          factorial(4)
33//          factorial(arg1)
34//          factorial(arg1 * 6)
35//
36//      These functions are automatically lazily bound unlike ordinary
37//      function pointers or functor objects that need to be explicitly
38//      bound through the bind function (see binders.hpp).
39//
40//      A lazy function works in conjunction with a user defined functor
41//      (as usual with a member operator()). Only special forms of
42//      functor objects are allowed. This is required to enable true
43//      polymorphism (STL style monomorphic functors and function
44//      pointers can still be used through the bind facility in
45//      binders.hpp).
46//
47//      This special functor is expected to have a nested template class
48//      result<A...TN> (where N is the number of arguments of its
49//      member operator()). The nested template class result should have
50//      a typedef 'type' that reflects the return type of its member
51//      operator(). This is essentially a type computer that answers the
52//      metaprogramming question "Given arguments of type A...TN, what
53//      will be the operator()'s return type?".
54//
55//      There is a special case for functors that accept no arguments.
56//      Such nullary functors are only required to define a typedef
57//      result_type that reflects the return type of its operator().
58//
59//      Here's an example of a simple functor that computes the
60//      factorial of a number:
61//
62//          struct factorial_impl {
63//
64//              template <typename Arg>
65//              struct result { typedef Arg type; };
66//
67//              template <typename Arg>
68//              Arg operator()(Arg n) const
69//              { return (n <= 0) ? 1 : n * this->operator()(n-1); }
70//          };
71//
72//      As can be seen, the functor can be polymorphic. Its arguments
73//      and return type are not fixed to a particular type. The example
74//      above for example, can handle any type as long as it can carry
75//      out the required operations (i.e. <=, * and -).
76//
77//      We can now declare and instantiate a lazy 'factorial' function:
78//
79//          function<factorial_impl> factorial;
80//
81//      Invoking a lazy function 'factorial' does not immediately
82//      execute the functor factorial_impl. Instead, a composite (see
83//      composite.hpp) object is created and returned to the caller.
84//      Example:
85//
86//          factorial(arg1)
87//
88//      does nothing more than return a composite. A second function
89//      call will invoke the actual factorial function. Example:
90//
91//          int i = 4;
92//          cout << factorial(arg1)(i);
93//
94//      will print out "24".
95//
96//      Take note that in certain cases (e.g. for functors with state),
97//      an instance may be passed on to the constructor. Example:
98//
99//          function<factorial_impl> factorial(ftor);
100//
101//      where ftor is an instance of factorial_impl (this is not
102//      necessary in this case since factorial is a simple stateless
103//      functor). Take care though when using functors with state
104//      because the functors are taken in by value. It is best to keep
105//      the data manipulated by a functor outside the functor itself and
106//      keep a reference to this data inside the functor. Also, it is
107//      best to keep functors as small as possible.
108//
109///////////////////////////////////////////////////////////////////////////////
110template <typename OperationT>
111struct function {
112
113    function() : op() {}
114    function(OperationT const& op_) : op(op_) {}
115
116    actor<composite<OperationT> >
117    operator()() const;
118
119    template <typename A>
120    typename impl::make_composite<OperationT, A>::type
121    operator()(A const& a) const;
122
123    template <typename A, typename B>
124    typename impl::make_composite<OperationT, A, B>::type
125    operator()(A const& a, B const& b) const;
126
127    template <typename A, typename B, typename C>
128    typename impl::make_composite<OperationT, A, B, C>::type
129    operator()(A const& a, B const& b, C const& c) const;
130
131#if PHOENIX_LIMIT > 3
132
133    template <typename A, typename B, typename C, typename D>
134    typename impl::make_composite<OperationT, A, B, C, D>::type
135    operator()(A const& a, B const& b, C const& c, D const& d) const;
136
137    template <typename A, typename B, typename C, typename D, typename E>
138    typename impl::make_composite<
139        OperationT, A, B, C, D, E
140    >::type
141    operator()(
142        A const& a, B const& b, C const& c, D const& d, E const& e
143    ) const;
144
145    template <
146        typename A, typename B, typename C, typename D, typename E,
147        typename F
148    >
149    typename impl::make_composite<
150        OperationT, A, B, C, D, E, F
151    >::type
152    operator()(
153        A const& a, B const& b, C const& c, D const& d, E const& e,
154        F const& f
155    ) const;
156
157#if PHOENIX_LIMIT > 6
158
159    template <
160        typename A, typename B, typename C, typename D, typename E,
161        typename F, typename G
162    >
163    typename impl::make_composite<
164        OperationT, A, B, C, D, E, F, G
165    >::type
166    operator()(
167        A const& a, B const& b, C const& c, D const& d, E const& e,
168        F const& f, G const& g
169    ) const;
170
171    template <
172        typename A, typename B, typename C, typename D, typename E,
173        typename F, typename G, typename H
174    >
175    typename impl::make_composite<
176        OperationT, A, B, C, D, E, F, G, H
177    >::type
178    operator()(
179        A const& a, B const& b, C const& c, D const& d, E const& e,
180        F const& f, G const& g, H const& h
181    ) const;
182
183    template <
184        typename A, typename B, typename C, typename D, typename E,
185        typename F, typename G, typename H, typename I
186    >
187    typename impl::make_composite<
188        OperationT, A, B, C, D, E, F, G, H, I
189    >::type
190    operator()(
191        A const& a, B const& b, C const& c, D const& d, E const& e,
192        F const& f, G const& g, H const& h, I const& i
193    ) const;
194
195#if PHOENIX_LIMIT > 9
196
197    template <
198        typename A, typename B, typename C, typename D, typename E,
199        typename F, typename G, typename H, typename I, typename J
200    >
201    typename impl::make_composite<
202        OperationT, A, B, C, D, E, F, G, H, I, J
203    >::type
204    operator()(
205        A const& a, B const& b, C const& c, D const& d, E const& e,
206        F const& f, G const& g, H const& h, I const& i, J const& j
207    ) const;
208
209    template <
210        typename A, typename B, typename C, typename D, typename E,
211        typename F, typename G, typename H, typename I, typename J,
212        typename K
213    >
214    typename impl::make_composite<
215        OperationT, A, B, C, D, E, F, G, H, I, J, K
216    >::type
217    operator()(
218        A const& a, B const& b, C const& c, D const& d, E const& e,
219        F const& f, G const& g, H const& h, I const& i, J const& j,
220        K const& k
221    ) const;
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
227    >
228    typename impl::make_composite<
229        OperationT, A, B, C, D, E, F, G, H, I, J, K, L
230    >::type
231    operator()(
232        A const& a, B const& b, C const& c, D const& d, E const& e,
233        F const& f, G const& g, H const& h, I const& i, J const& j,
234        K const& k, L const& l
235    ) const;
236
237#if PHOENIX_LIMIT > 12
238
239    template <
240        typename A, typename B, typename C, typename D, typename E,
241        typename F, typename G, typename H, typename I, typename J,
242        typename K, typename L, typename M
243    >
244    typename impl::make_composite<
245        OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
246    >::type
247    operator()(
248        A const& a, B const& b, C const& c, D const& d, E const& e,
249        F const& f, G const& g, H const& h, I const& i, J const& j,
250        K const& k, L const& l, M const& m
251    ) const;
252
253    template <
254        typename A, typename B, typename C, typename D, typename E,
255        typename F, typename G, typename H, typename I, typename J,
256        typename K, typename L, typename M, typename N
257    >
258    typename impl::make_composite<
259        OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
260    >::type
261    operator()(
262        A const& a, B const& b, C const& c, D const& d, E const& e,
263        F const& f, G const& g, H const& h, I const& i, J const& j,
264        K const& k, L const& l, M const& m, N const& n
265    ) const;
266
267    template <
268        typename A, typename B, typename C, typename D, typename E,
269        typename F, typename G, typename H, typename I, typename J,
270        typename K, typename L, typename M, typename N, typename O
271    >
272    typename impl::make_composite<
273        OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
274    >::type
275    operator()(
276        A const& a, B const& b, C const& c, D const& d, E const& e,
277        F const& f, G const& g, H const& h, I const& i, J const& j,
278        K const& k, L const& l, M const& m, N const& n, O const& o
279    ) const;
280
281#endif
282#endif
283#endif
284#endif
285
286    OperationT op;
287};
288
289///////////////////////////////////////////////////////////////////////////////
290//
291//  function class implementation
292//
293///////////////////////////////////////////////////////////////////////////////
294template <typename OperationT>
295inline actor<composite<OperationT> >
296function<OperationT>::operator()() const
297{
298    return actor<composite<OperationT> >(op);
299}
300
301//////////////////////////////////
302template <typename OperationT>
303template <typename A>
304inline typename impl::make_composite<OperationT, A>::type
305function<OperationT>::operator()(A const& a) const
306{
307    typedef typename impl::make_composite<OperationT, A>::composite_type ret_t;
308    return ret_t
309    (
310        op,
311        as_actor<A>::convert(a)
312    );
313}
314
315//////////////////////////////////
316template <typename OperationT>
317template <typename A, typename B>
318inline typename impl::make_composite<OperationT, A, B>::type
319function<OperationT>::operator()(A const& a, B const& b) const
320{
321    typedef
322        typename impl::make_composite<OperationT, A, B>::composite_type
323        ret_t;
324       
325    return ret_t(
326        op,
327        as_actor<A>::convert(a),
328        as_actor<B>::convert(b)
329    );
330}
331
332//////////////////////////////////
333template <typename OperationT>
334template <typename A, typename B, typename C>
335inline typename impl::make_composite<OperationT, A, B, C>::type
336function<OperationT>::operator()(A const& a, B const& b, C const& c) const
337{
338    typedef
339        typename impl::make_composite<OperationT, A, B, C>::composite_type
340        ret_t;
341       
342    return ret_t(
343        op,
344        as_actor<A>::convert(a),
345        as_actor<B>::convert(b),
346        as_actor<C>::convert(c)
347    );
348}
349
350#if PHOENIX_LIMIT > 3
351//////////////////////////////////
352template <typename OperationT>
353template <
354    typename A, typename B, typename C, typename D
355>
356inline typename impl::make_composite<
357    OperationT, A, B, C, D
358>::type
359function<OperationT>::operator()(
360    A const& a, B const& b, C const& c, D const& d
361) const
362{
363    typedef typename impl::make_composite<
364            OperationT, A, B, C, D
365        >::composite_type ret_t;
366       
367    return ret_t(
368        op,
369        as_actor<A>::convert(a),
370        as_actor<B>::convert(b),
371        as_actor<C>::convert(c),
372        as_actor<D>::convert(d)
373    );
374}
375
376//////////////////////////////////
377template <typename OperationT>
378template <
379    typename A, typename B, typename C, typename D, typename E
380>
381inline typename impl::make_composite<
382    OperationT, A, B, C, D, E
383>::type
384function<OperationT>::operator()(
385    A const& a, B const& b, C const& c, D const& d, E const& e
386) const
387{
388    typedef typename impl::make_composite<
389            OperationT, A, B, C, D, E
390        >::composite_type ret_t;
391
392    return ret_t(
393        op,
394        as_actor<A>::convert(a),
395        as_actor<B>::convert(b),
396        as_actor<C>::convert(c),
397        as_actor<D>::convert(d),
398        as_actor<E>::convert(e)
399    );
400}
401
402//////////////////////////////////
403template <typename OperationT>
404template <
405    typename A, typename B, typename C, typename D, typename E,
406    typename F
407>
408inline typename impl::make_composite<
409    OperationT, A, B, C, D, E, F
410>::type
411function<OperationT>::operator()(
412    A const& a, B const& b, C const& c, D const& d, E const& e,
413    F const& f
414) const
415{
416    typedef typename impl::make_composite<
417            OperationT, A, B, C, D, E, F
418        >::composite_type ret_t;
419
420    return ret_t(
421        op,
422        as_actor<A>::convert(a),
423        as_actor<B>::convert(b),
424        as_actor<C>::convert(c),
425        as_actor<D>::convert(d),
426        as_actor<E>::convert(e),
427        as_actor<F>::convert(f)
428    );
429}
430
431#if PHOENIX_LIMIT > 6
432
433//////////////////////////////////
434template <typename OperationT>
435template <
436    typename A, typename B, typename C, typename D, typename E,
437    typename F, typename G
438>
439inline typename impl::make_composite<
440    OperationT, A, B, C, D, E, F, G
441>::type
442function<OperationT>::operator()(
443    A const& a, B const& b, C const& c, D const& d, E const& e,
444    F const& f, G const& g
445) const
446{
447    typedef typename impl::make_composite<
448            OperationT, A, B, C, D, E, F, G
449        >::composite_type ret_t;
450
451    return ret_t(
452        op,
453        as_actor<A>::convert(a),
454        as_actor<B>::convert(b),
455        as_actor<C>::convert(c),
456        as_actor<D>::convert(d),
457        as_actor<E>::convert(e),
458        as_actor<F>::convert(f),
459        as_actor<G>::convert(g)
460    );
461}
462
463//////////////////////////////////
464template <typename OperationT>
465template <
466    typename A, typename B, typename C, typename D, typename E,
467    typename F, typename G, typename H
468>
469inline typename impl::make_composite<
470    OperationT, A, B, C, D, E, F, G, H
471>::type
472function<OperationT>::operator()(
473    A const& a, B const& b, C const& c, D const& d, E const& e,
474    F const& f, G const& g, H const& h
475) const
476{
477    typedef typename impl::make_composite<
478            OperationT, A, B, C, D, E, F, G, H
479        >::composite_type ret_t;
480       
481    return ret_t(
482        op,
483        as_actor<A>::convert(a),
484        as_actor<B>::convert(b),
485        as_actor<C>::convert(c),
486        as_actor<D>::convert(d),
487        as_actor<E>::convert(e),
488        as_actor<F>::convert(f),
489        as_actor<G>::convert(g),
490        as_actor<H>::convert(h)
491    );
492}
493
494//////////////////////////////////
495template <typename OperationT>
496template <
497    typename A, typename B, typename C, typename D, typename E,
498    typename F, typename G, typename H, typename I
499>
500inline typename impl::make_composite<
501    OperationT, A, B, C, D, E, F, G, H, I
502>::type
503function<OperationT>::operator()(
504    A const& a, B const& b, C const& c, D const& d, E const& e,
505    F const& f, G const& g, H const& h, I const& i
506) const
507{
508    typedef typename impl::make_composite<
509            OperationT, A, B, C, D, E, F, G, H, I
510        >::composite_type ret_t;
511       
512    return ret_t(
513        op,
514        as_actor<A>::convert(a),
515        as_actor<B>::convert(b),
516        as_actor<C>::convert(c),
517        as_actor<D>::convert(d),
518        as_actor<E>::convert(e),
519        as_actor<F>::convert(f),
520        as_actor<G>::convert(g),
521        as_actor<H>::convert(h),
522        as_actor<I>::convert(i)
523    );
524}
525
526#if PHOENIX_LIMIT > 9
527
528//////////////////////////////////
529template <typename OperationT>
530template <
531    typename A, typename B, typename C, typename D, typename E,
532    typename F, typename G, typename H, typename I, typename J
533>
534inline typename impl::make_composite<
535    OperationT, A, B, C, D, E, F, G, H, I, J
536>::type
537function<OperationT>::operator()(
538    A const& a, B const& b, C const& c, D const& d, E const& e,
539    F const& f, G const& g, H const& h, I const& i, J const& j
540) const
541{
542    typedef typename impl::make_composite<
543            OperationT, A, B, C, D, E, F, G, H, I, J
544        >::composite_type ret_t;
545       
546    return ret_t(
547        op,
548        as_actor<A>::convert(a),
549        as_actor<B>::convert(b),
550        as_actor<C>::convert(c),
551        as_actor<D>::convert(d),
552        as_actor<E>::convert(e),
553        as_actor<F>::convert(f),
554        as_actor<G>::convert(g),
555        as_actor<H>::convert(h),
556        as_actor<I>::convert(i),
557        as_actor<J>::convert(j)
558    );
559}
560
561//////////////////////////////////
562template <typename OperationT>
563template <
564    typename A, typename B, typename C, typename D, typename E,
565    typename F, typename G, typename H, typename I, typename J,
566    typename K
567>
568inline typename impl::make_composite<
569    OperationT, A, B, C, D, E, F, G, H, I, J, K
570>::type
571function<OperationT>::operator()(
572    A const& a, B const& b, C const& c, D const& d, E const& e,
573    F const& f, G const& g, H const& h, I const& i, J const& j,
574    K const& k
575) const
576{
577    typedef typename impl::make_composite<
578            OperationT, A, B, C, D, E, F, G, H, I, J, K
579        >::composite_type ret_t;
580       
581    return ret_t(
582        op,
583        as_actor<A>::convert(a),
584        as_actor<B>::convert(b),
585        as_actor<C>::convert(c),
586        as_actor<D>::convert(d),
587        as_actor<E>::convert(e),
588        as_actor<F>::convert(f),
589        as_actor<G>::convert(g),
590        as_actor<H>::convert(h),
591        as_actor<I>::convert(i),
592        as_actor<J>::convert(j),
593        as_actor<K>::convert(k)
594    );
595}
596
597//////////////////////////////////
598template <typename OperationT>
599template <
600    typename A, typename B, typename C, typename D, typename E,
601    typename F, typename G, typename H, typename I, typename J,
602    typename K, typename L
603>
604inline typename impl::make_composite<
605    OperationT, A, B, C, D, E, F, G, H, I, J, K, L
606>::type
607function<OperationT>::operator()(
608    A const& a, B const& b, C const& c, D const& d, E const& e,
609    F const& f, G const& g, H const& h, I const& i, J const& j,
610    K const& k, L const& l
611) const
612{
613    typedef typename impl::make_composite<
614            OperationT, A, B, C, D, E, F, G, H, I, J, K, L
615        >::composite_type ret_t;
616       
617    return ret_t(
618        op,
619        as_actor<A>::convert(a),
620        as_actor<B>::convert(b),
621        as_actor<C>::convert(c),
622        as_actor<D>::convert(d),
623        as_actor<E>::convert(e),
624        as_actor<F>::convert(f),
625        as_actor<G>::convert(g),
626        as_actor<H>::convert(h),
627        as_actor<I>::convert(i),
628        as_actor<J>::convert(j),
629        as_actor<K>::convert(k),
630        as_actor<L>::convert(l)
631    );
632}
633
634#if PHOENIX_LIMIT > 12
635
636//////////////////////////////////
637template <typename OperationT>
638template <
639    typename A, typename B, typename C, typename D, typename E,
640    typename F, typename G, typename H, typename I, typename J,
641    typename K, typename L, typename M
642>
643inline typename impl::make_composite<
644    OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
645>::type
646function<OperationT>::operator()(
647    A const& a, B const& b, C const& c, D const& d, E const& e,
648    F const& f, G const& g, H const& h, I const& i, J const& j,
649    K const& k, L const& l, M const& m
650) const
651{
652    typedef typename impl::make_composite<
653            OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
654        >::composite_type ret_t;
655       
656    return ret_t(
657        op,
658        as_actor<A>::convert(a),
659        as_actor<B>::convert(b),
660        as_actor<C>::convert(c),
661        as_actor<D>::convert(d),
662        as_actor<E>::convert(e),
663        as_actor<F>::convert(f),
664        as_actor<G>::convert(g),
665        as_actor<H>::convert(h),
666        as_actor<I>::convert(i),
667        as_actor<J>::convert(j),
668        as_actor<K>::convert(k),
669        as_actor<L>::convert(l),
670        as_actor<M>::convert(m)
671    );
672}
673
674//////////////////////////////////
675template <typename OperationT>
676template <
677    typename A, typename B, typename C, typename D, typename E,
678    typename F, typename G, typename H, typename I, typename J,
679    typename K, typename L, typename M, typename N
680>
681inline typename impl::make_composite<
682    OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
683>::type
684function<OperationT>::operator()(
685    A const& a, B const& b, C const& c, D const& d, E const& e,
686    F const& f, G const& g, H const& h, I const& i, J const& j,
687    K const& k, L const& l, M const& m, N const& n
688) const
689{
690    typedef typename impl::make_composite<
691            OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
692        >::composite_type ret_t;
693
694    return ret_t(
695        op,
696        as_actor<A>::convert(a),
697        as_actor<B>::convert(b),
698        as_actor<C>::convert(c),
699        as_actor<D>::convert(d),
700        as_actor<E>::convert(e),
701        as_actor<F>::convert(f),
702        as_actor<G>::convert(g),
703        as_actor<H>::convert(h),
704        as_actor<I>::convert(i),
705        as_actor<J>::convert(j),
706        as_actor<K>::convert(k),
707        as_actor<L>::convert(l),
708        as_actor<M>::convert(m),
709        as_actor<N>::convert(n)
710    );
711}
712
713//////////////////////////////////
714template <typename OperationT>
715template <
716    typename A, typename B, typename C, typename D, typename E,
717    typename F, typename G, typename H, typename I, typename J,
718    typename K, typename L, typename M, typename N, typename O
719>
720inline typename impl::make_composite<
721    OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
722>::type
723function<OperationT>::operator()(
724    A const& a, B const& b, C const& c, D const& d, E const& e,
725    F const& f, G const& g, H const& h, I const& i, J const& j,
726    K const& k, L const& l, M const& m, N const& n, O const& o
727) const
728{
729    typedef typename impl::make_composite<
730            OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
731        >::composite_type ret_t;
732       
733    return ret_t(
734        op,
735        as_actor<A>::convert(a),
736        as_actor<B>::convert(b),
737        as_actor<C>::convert(c),
738        as_actor<D>::convert(d),
739        as_actor<E>::convert(e),
740        as_actor<F>::convert(f),
741        as_actor<G>::convert(g),
742        as_actor<H>::convert(h),
743        as_actor<I>::convert(i),
744        as_actor<J>::convert(j),
745        as_actor<K>::convert(k),
746        as_actor<L>::convert(l),
747        as_actor<M>::convert(m),
748        as_actor<N>::convert(n),
749        as_actor<O>::convert(o)
750    );
751}
752
753#endif
754#endif
755#endif
756#endif
757
758///////////////////////////////////////////////////////////////////////////////
759}   //  namespace phoenix
760
761#endif
Note: See TracBrowser for help on using the repository browser.