Update contrib.
1 /*=============================================================================
3 Copyright (c) 2001-2002 Joel de Guzman
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
12 ///////////////////////////////////////////////////////////////////////////////
13 #include <boost/spirit/phoenix/actor.hpp>
14 #include <boost/spirit/phoenix/composite.hpp>
16 ///////////////////////////////////////////////////////////////////////////////
19 ///////////////////////////////////////////////////////////////////////////////
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:
34 // factorial(arg1 * 6)
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).
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
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?".
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().
59 // Here's an example of a simple functor that computes the
60 // factorial of a number:
62 // struct factorial_impl {
64 // template <typename Arg>
65 // struct result { typedef Arg type; };
67 // template <typename Arg>
68 // Arg operator()(Arg n) const
69 // { return (n <= 0) ? 1 : n * this->operator()(n-1); }
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 -).
77 // We can now declare and instantiate a lazy 'factorial' function:
79 // function<factorial_impl> factorial;
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.
88 // does nothing more than return a composite. A second function
89 // call will invoke the actual factorial function. Example:
92 // cout << factorial(arg1)(i);
94 // will print out "24".
96 // Take note that in certain cases (e.g. for functors with state),
97 // an instance may be passed on to the constructor. Example:
99 // function<factorial_impl> factorial(ftor);
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.
109 ///////////////////////////////////////////////////////////////////////////////
110 template <typename OperationT>
114 function(OperationT const& op_) : op(op_) {}
116 actor<composite<OperationT> >
119 template <typename A>
120 typename impl::make_composite<OperationT, A>::type
121 operator()(A const& a) const;
123 template <typename A, typename B>
124 typename impl::make_composite<OperationT, A, B>::type
125 operator()(A const& a, B const& b) const;
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;
131 #if PHOENIX_LIMIT > 3
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;
137 template <typename A, typename B, typename C, typename D, typename E>
138 typename impl::make_composite<
139 OperationT, A, B, C, D, E
142 A const& a, B const& b, C const& c, D const& d, E const& e
146 typename A, typename B, typename C, typename D, typename E,
149 typename impl::make_composite<
150 OperationT, A, B, C, D, E, F
153 A const& a, B const& b, C const& c, D const& d, E const& e,
157 #if PHOENIX_LIMIT > 6
160 typename A, typename B, typename C, typename D, typename E,
161 typename F, typename G
163 typename impl::make_composite<
164 OperationT, A, B, C, D, E, F, G
167 A const& a, B const& b, C const& c, D const& d, E const& e,
168 F const& f, G const& g
172 typename A, typename B, typename C, typename D, typename E,
173 typename F, typename G, typename H
175 typename impl::make_composite<
176 OperationT, A, B, C, D, E, F, G, H
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
184 typename A, typename B, typename C, typename D, typename E,
185 typename F, typename G, typename H, typename I
187 typename impl::make_composite<
188 OperationT, A, B, C, D, E, F, G, H, I
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
195 #if PHOENIX_LIMIT > 9
198 typename A, typename B, typename C, typename D, typename E,
199 typename F, typename G, typename H, typename I, typename J
201 typename impl::make_composite<
202 OperationT, A, B, C, D, E, F, G, H, I, J
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
210 typename A, typename B, typename C, typename D, typename E,
211 typename F, typename G, typename H, typename I, typename J,
214 typename impl::make_composite<
215 OperationT, A, B, C, D, E, F, G, H, I, J, K
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,
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
228 typename impl::make_composite<
229 OperationT, A, B, C, D, E, F, G, H, I, J, K, L
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
237 #if PHOENIX_LIMIT > 12
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
244 typename impl::make_composite<
245 OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
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
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
258 typename impl::make_composite<
259 OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
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
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
272 typename impl::make_composite<
273 OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
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
289 ///////////////////////////////////////////////////////////////////////////////
291 // function class implementation
293 ///////////////////////////////////////////////////////////////////////////////
294 template <typename OperationT>
295 inline actor<composite<OperationT> >
296 function<OperationT>::operator()() const
298 return actor<composite<OperationT> >(op);
301 //////////////////////////////////
302 template <typename OperationT>
303 template <typename A>
304 inline typename impl::make_composite<OperationT, A>::type
305 function<OperationT>::operator()(A const& a) const
307 typedef typename impl::make_composite<OperationT, A>::composite_type ret_t;
311 as_actor<A>::convert(a)
315 //////////////////////////////////
316 template <typename OperationT>
317 template <typename A, typename B>
318 inline typename impl::make_composite<OperationT, A, B>::type
319 function<OperationT>::operator()(A const& a, B const& b) const
322 typename impl::make_composite<OperationT, A, B>::composite_type
327 as_actor<A>::convert(a),
328 as_actor<B>::convert(b)
332 //////////////////////////////////
333 template <typename OperationT>
334 template <typename A, typename B, typename C>
335 inline typename impl::make_composite<OperationT, A, B, C>::type
336 function<OperationT>::operator()(A const& a, B const& b, C const& c) const
339 typename impl::make_composite<OperationT, A, B, C>::composite_type
344 as_actor<A>::convert(a),
345 as_actor<B>::convert(b),
346 as_actor<C>::convert(c)
350 #if PHOENIX_LIMIT > 3
351 //////////////////////////////////
352 template <typename OperationT>
354 typename A, typename B, typename C, typename D
356 inline typename impl::make_composite<
357 OperationT, A, B, C, D
359 function<OperationT>::operator()(
360 A const& a, B const& b, C const& c, D const& d
363 typedef typename impl::make_composite<
364 OperationT, A, B, C, D
365 >::composite_type ret_t;
369 as_actor<A>::convert(a),
370 as_actor<B>::convert(b),
371 as_actor<C>::convert(c),
372 as_actor<D>::convert(d)
376 //////////////////////////////////
377 template <typename OperationT>
379 typename A, typename B, typename C, typename D, typename E
381 inline typename impl::make_composite<
382 OperationT, A, B, C, D, E
384 function<OperationT>::operator()(
385 A const& a, B const& b, C const& c, D const& d, E const& e
388 typedef typename impl::make_composite<
389 OperationT, A, B, C, D, E
390 >::composite_type ret_t;
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)
402 //////////////////////////////////
403 template <typename OperationT>
405 typename A, typename B, typename C, typename D, typename E,
408 inline typename impl::make_composite<
409 OperationT, A, B, C, D, E, F
411 function<OperationT>::operator()(
412 A const& a, B const& b, C const& c, D const& d, E const& e,
416 typedef typename impl::make_composite<
417 OperationT, A, B, C, D, E, F
418 >::composite_type ret_t;
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)
431 #if PHOENIX_LIMIT > 6
433 //////////////////////////////////
434 template <typename OperationT>
436 typename A, typename B, typename C, typename D, typename E,
437 typename F, typename G
439 inline typename impl::make_composite<
440 OperationT, A, B, C, D, E, F, G
442 function<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
447 typedef typename impl::make_composite<
448 OperationT, A, B, C, D, E, F, G
449 >::composite_type ret_t;
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)
463 //////////////////////////////////
464 template <typename OperationT>
466 typename A, typename B, typename C, typename D, typename E,
467 typename F, typename G, typename H
469 inline typename impl::make_composite<
470 OperationT, A, B, C, D, E, F, G, H
472 function<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
477 typedef typename impl::make_composite<
478 OperationT, A, B, C, D, E, F, G, H
479 >::composite_type ret_t;
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)
494 //////////////////////////////////
495 template <typename OperationT>
497 typename A, typename B, typename C, typename D, typename E,
498 typename F, typename G, typename H, typename I
500 inline typename impl::make_composite<
501 OperationT, A, B, C, D, E, F, G, H, I
503 function<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
508 typedef typename impl::make_composite<
509 OperationT, A, B, C, D, E, F, G, H, I
510 >::composite_type ret_t;
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)
526 #if PHOENIX_LIMIT > 9
528 //////////////////////////////////
529 template <typename OperationT>
531 typename A, typename B, typename C, typename D, typename E,
532 typename F, typename G, typename H, typename I, typename J
534 inline typename impl::make_composite<
535 OperationT, A, B, C, D, E, F, G, H, I, J
537 function<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
542 typedef typename impl::make_composite<
543 OperationT, A, B, C, D, E, F, G, H, I, J
544 >::composite_type ret_t;
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)
561 //////////////////////////////////
562 template <typename OperationT>
564 typename A, typename B, typename C, typename D, typename E,
565 typename F, typename G, typename H, typename I, typename J,
568 inline typename impl::make_composite<
569 OperationT, A, B, C, D, E, F, G, H, I, J, K
571 function<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,
577 typedef typename impl::make_composite<
578 OperationT, A, B, C, D, E, F, G, H, I, J, K
579 >::composite_type ret_t;
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)
597 //////////////////////////////////
598 template <typename OperationT>
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
604 inline typename impl::make_composite<
605 OperationT, A, B, C, D, E, F, G, H, I, J, K, L
607 function<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
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;
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)
634 #if PHOENIX_LIMIT > 12
636 //////////////////////////////////
637 template <typename OperationT>
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
643 inline typename impl::make_composite<
644 OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
646 function<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
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;
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)
674 //////////////////////////////////
675 template <typename OperationT>
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
681 inline typename impl::make_composite<
682 OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
684 function<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
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;
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)
713 //////////////////////////////////
714 template <typename OperationT>
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
720 inline typename impl::make_composite<
721 OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
723 function<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
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;
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)
758 ///////////////////////////////////////////////////////////////////////////////
759 } // namespace phoenix