1 /*=============================================================================
3 Copyright (c) 2001-2002 Joel de Guzman
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_OPERATORS_HPP
9 #define PHOENIX_OPERATORS_HPP
11 ///////////////////////////////////////////////////////////////////////////////
12 #if !defined(BOOST_NO_CWCTYPE)
16 #if defined(__BORLANDC__) || (defined(__ICL) && __ICL >= 700)
23 #include <boost/spirit/home/classic/phoenix/actor.hpp>
24 #include <boost/spirit/home/classic/phoenix/composite.hpp>
25 #include <boost/config.hpp>
26 #include <boost/mpl/if.hpp>
28 ///////////////////////////////////////////////////////////////////////////////
31 ///////////////////////////////////////////////////////////////////////////////
37 // This class provides a mechanism for lazily evaluating operators.
38 // Syntactically, a lazy operator looks like an ordinary C/C++
39 // infix, prefix or postfix operator. The operator application
40 // looks the same. However, unlike ordinary operators, the actual
41 // operator execution is deferred. (see actor.hpp, primitives.hpp
42 // and composite.hpp for an overview). Samples:
49 // T1 set of classes implement all the C++ free operators. Like
50 // lazy functions (see functions.hpp), lazy operators are not
51 // immediately executed when invoked. Instead, a composite (see
52 // composite.hpp) object is created and returned to the caller.
55 // (arg1 + arg2) * arg3
57 // does nothing more than return a composite. T1 second function
58 // call will evaluate the actual operators. Example:
60 // int i = 4, j = 5, k = 6;
61 // cout << ((arg1 + arg2) * arg3)(i, j, k);
63 // will print out "54".
65 // Arbitrarily complex expressions can be lazily evaluated
66 // following three simple rules:
68 // 1) Lazy evaluated binary operators apply when at least one
69 // of the operands is an actor object (see actor.hpp and
70 // primitives.hpp). Consequently, if an operand is not an actor
71 // object, it is implicitly converted to an object of type
72 // actor<value<T> > (where T is the original type of the
75 // 2) Lazy evaluated unary operators apply only to operands
76 // which are actor objects.
78 // 3) The result of a lazy operator is a composite actor object
79 // that can in turn apply to rule 1.
85 // is a lazy expression involving the operator+. Following rule 1,
86 // lazy evaluation is triggered since arg1 is an instance of an
87 // actor<argument<N> > class (see primitives.hpp). The right
88 // operand <3> is implicitly converted to an actor<value<int> >.
89 // The result of this binary + expression is a composite object,
92 // Take note that although at least one of the operands must be a
93 // valid actor class in order for lazy evaluation to take effect,
94 // if this is not the case and we still want to lazily evaluate an
95 // expression, we can use var(x), val(x) or cref(x) to transform
96 // the operand into a valid action object (see primitives.hpp).
101 // Supported operators:
105 // prefix: ~, !, -, +, ++, --, & (reference), * (dereference)
110 // =, [], +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
111 // +, -, *, /, %, &, |, ^, <<, >>
112 // ==, !=, <, >, <=, >=
115 // Each operator has a special tag type associated with it. For
116 // example the binary + operator has a plus_op tag type associated
117 // with it. This is used to specialize either the unary_operator or
118 // binary_operator template classes (see unary_operator and
119 // binary_operator below). Specializations of these unary_operator
120 // and binary_operator are the actual workhorses that implement the
121 // operations. The behavior of each lazy operator depends on these
122 // unary_operator and binary_operator specializations. 'preset'
123 // specializations conform to the canonical operator rules modeled
124 // by the behavior of integers and pointers:
126 // Prefix -, + and ~ accept constant arguments and return an
129 // The ! accept constant arguments and returns a boolean
132 // The & (address-of), * (dereference) both return a reference
135 // Prefix ++ returns a reference to its mutable argument after
136 // it is incremented.
138 // Postfix ++ returns the mutable argument by value before it
141 // The += and its family accept mutable right hand side (rhs)
142 // operand and return a reference to the rhs operand.
144 // Infix + and its family accept constant arguments and return
145 // an object by value.
147 // The == and its family accept constant arguments and return a
150 // Operators && and || accept constant arguments and return a
151 // boolean result and are short circuit evaluated as expected.
153 ///////////////////////////////////////////////////////////////////////////////
155 ///////////////////////////////////////////////////////////////////////////////
159 // Each C++ operator has a corresponding tag type. This is
160 // used as a means for specializing the unary_operator and
161 // binary_operator (see below). The tag also serves as the
162 // lazy operator type compatible as a composite operation
163 // see (composite.hpp).
165 ///////////////////////////////////////////////////////////////////////////////
167 // Unary operator tags
169 struct negative_op; struct positive_op;
170 struct logical_not_op; struct invert_op;
171 struct reference_op; struct dereference_op;
172 struct pre_incr_op; struct pre_decr_op;
173 struct post_incr_op; struct post_decr_op;
175 // Binary operator tags
177 struct assign_op; struct index_op;
178 struct plus_assign_op; struct minus_assign_op;
179 struct times_assign_op; struct divide_assign_op; struct mod_assign_op;
180 struct and_assign_op; struct or_assign_op; struct xor_assign_op;
181 struct shift_l_assign_op; struct shift_r_assign_op;
183 struct plus_op; struct minus_op;
184 struct times_op; struct divide_op; struct mod_op;
185 struct and_op; struct or_op; struct xor_op;
186 struct shift_l_op; struct shift_r_op;
188 struct eq_op; struct not_eq_op;
189 struct lt_op; struct lt_eq_op;
190 struct gt_op; struct gt_eq_op;
191 struct logical_and_op; struct logical_or_op;
193 ///////////////////////////////////////////////////////////////////////////////
195 // unary_operator<TagT, T>
197 // The unary_operator class implements most of the C++ unary
198 // operators. Each specialization is basically a simple static eval
199 // function plus a result_type typedef that determines the return
200 // type of the eval function.
202 // TagT is one of the unary operator tags above and T is the data
203 // type (argument) involved in the operation.
205 // Only the behavior of C/C++ built-in types are taken into account
206 // in the specializations provided below. For user-defined types,
207 // these specializations may still be used provided that the
208 // operator overloads of such types adhere to the standard behavior
209 // of built-in types.
211 // T1 separate special_ops.hpp file implements more stl savvy
212 // specializations. Other more specialized unary_operator
213 // implementations may be defined by the client for specific
214 // unary operator tags/data types.
216 ///////////////////////////////////////////////////////////////////////////////
217 template <typename TagT, typename T>
218 struct unary_operator;
220 //////////////////////////////////
221 template <typename T>
222 struct unary_operator<negative_op, T> {
224 typedef T const result_type;
225 static result_type eval(T const& v)
229 //////////////////////////////////
230 template <typename T>
231 struct unary_operator<positive_op, T> {
233 typedef T const result_type;
234 static result_type eval(T const& v)
238 //////////////////////////////////
239 template <typename T>
240 struct unary_operator<logical_not_op, T> {
242 typedef T const result_type;
243 static result_type eval(T const& v)
247 //////////////////////////////////
248 template <typename T>
249 struct unary_operator<invert_op, T> {
251 typedef T const result_type;
252 static result_type eval(T const& v)
256 //////////////////////////////////
257 template <typename T>
258 struct unary_operator<reference_op, T> {
260 typedef T* result_type;
261 static result_type eval(T& v)
265 //////////////////////////////////
266 template <typename T>
267 struct unary_operator<dereference_op, T*> {
269 typedef T& result_type;
270 static result_type eval(T* v)
274 //////////////////////////////////
275 template <typename T>
276 struct unary_operator<dereference_op, T* const> {
278 typedef T& result_type;
279 static result_type eval(T* const v)
283 //////////////////////////////////
285 struct unary_operator<dereference_op, nil_t> {
287 // G++ eager template instantiation
288 // somehow requires this.
289 typedef nil_t result_type;
292 //////////////////////////////////
295 struct unary_operator<dereference_op, nil_t const> {
297 // G++ eager template instantiation
298 // somehow requires this.
299 typedef nil_t result_type;
303 //////////////////////////////////
304 template <typename T>
305 struct unary_operator<pre_incr_op, T> {
307 typedef T& result_type;
308 static result_type eval(T& v)
312 //////////////////////////////////
313 template <typename T>
314 struct unary_operator<pre_decr_op, T> {
316 typedef T& result_type;
317 static result_type eval(T& v)
321 //////////////////////////////////
322 template <typename T>
323 struct unary_operator<post_incr_op, T> {
325 typedef T const result_type;
326 static result_type eval(T& v)
327 { T t(v); ++v; return t; }
330 //////////////////////////////////
331 template <typename T>
332 struct unary_operator<post_decr_op, T> {
334 typedef T const result_type;
335 static result_type eval(T& v)
336 { T t(v); --v; return t; }
339 ///////////////////////////////////////////////////////////////////////////////
343 // rank<T> class has a static int constant 'value' that defines the
344 // absolute rank of a type. rank<T> is used to choose the result
345 // type of binary operators such as +. The type with the higher
346 // rank wins and is used as the operator's return type. T1 generic
347 // user defined type has a very high rank and always wins when
348 // compared against a user defined type. If this is not desireable,
349 // one can write a rank specialization for the type.
351 // Take note that ranks 0..9999 are reserved for the framework.
353 ///////////////////////////////////////////////////////////////////////////////
354 template <typename T>
355 struct rank { static int const value = INT_MAX; };
357 template <> struct rank<void> { static int const value = 0; };
358 template <> struct rank<bool> { static int const value = 10; };
360 template <> struct rank<char> { static int const value = 20; };
361 template <> struct rank<signed char> { static int const value = 20; };
362 template <> struct rank<unsigned char> { static int const value = 30; };
363 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
364 template <> struct rank<wchar_t> { static int const value = 40; };
365 #endif // !defined(BOOST_NO_INTRINSIC_WCHAR_T)
367 template <> struct rank<short> { static int const value = 50; };
368 template <> struct rank<unsigned short> { static int const value = 60; };
370 template <> struct rank<int> { static int const value = 70; };
371 template <> struct rank<unsigned int> { static int const value = 80; };
373 template <> struct rank<long> { static int const value = 90; };
374 template <> struct rank<unsigned long> { static int const value = 100; };
376 #ifdef BOOST_HAS_LONG_LONG
377 template <> struct rank< ::boost::long_long_type> { static int const value = 110; };
378 template <> struct rank< ::boost::ulong_long_type> { static int const value = 120; };
381 template <> struct rank<float> { static int const value = 130; };
382 template <> struct rank<double> { static int const value = 140; };
383 template <> struct rank<long double> { static int const value = 150; };
385 template <typename T> struct rank<T*>
386 { static int const value = 160; };
388 template <typename T> struct rank<T* const>
389 { static int const value = 160; };
391 template <typename T, int N> struct rank<T[N]>
392 { static int const value = 160; };
394 ///////////////////////////////////////////////////////////////////////////////
396 // higher_rank<T0, T1>
398 // Chooses the type (T0 or T1) with the higher rank.
400 ///////////////////////////////////////////////////////////////////////////////
401 template <typename T0, typename T1>
403 typedef typename boost::mpl::if_c<
404 rank<T0>::value < rank<T1>::value,
408 ///////////////////////////////////////////////////////////////////////////////
410 // binary_operator<TagT, T0, T1>
412 // The binary_operator class implements most of the C++ binary
413 // operators. Each specialization is basically a simple static eval
414 // function plus a result_type typedef that determines the return
415 // type of the eval function.
417 // TagT is one of the binary operator tags above T0 and T1 are the
418 // (arguments') data types involved in the operation.
420 // Only the behavior of C/C++ built-in types are taken into account
421 // in the specializations provided below. For user-defined types,
422 // these specializations may still be used provided that the
423 // operator overloads of such types adhere to the standard behavior
424 // of built-in types.
426 // T1 separate special_ops.hpp file implements more stl savvy
427 // specializations. Other more specialized unary_operator
428 // implementations may be defined by the client for specific
429 // unary operator tags/data types.
431 // All binary_operator except the logical_and_op and logical_or_op
432 // have an eval static function that carries out the actual operation.
433 // The logical_and_op and logical_or_op d are special because these
434 // two operators are short-circuit evaluated.
436 ///////////////////////////////////////////////////////////////////////////////
437 template <typename TagT, typename T0, typename T1>
438 struct binary_operator;
440 //////////////////////////////////
441 template <typename T0, typename T1>
442 struct binary_operator<assign_op, T0, T1> {
444 typedef T0& result_type;
445 static result_type eval(T0& lhs, T1 const& rhs)
446 { return lhs = rhs; }
449 //////////////////////////////////
450 template <typename T1>
451 struct binary_operator<index_op, nil_t, T1> {
453 // G++ eager template instantiation
454 // somehow requires this.
455 typedef nil_t result_type;
458 //////////////////////////////////
459 template <typename T0, typename T1>
460 struct binary_operator<index_op, T0*, T1> {
462 typedef T0& result_type;
463 static result_type eval(T0* ptr, T1 const& index)
464 { return ptr[index]; }
467 //////////////////////////////////
468 template <typename T0, typename T1>
469 struct binary_operator<index_op, T0* const, T1> {
471 typedef T0& result_type;
472 static result_type eval(T0* const ptr, T1 const& index)
473 { return ptr[index]; }
476 //////////////////////////////////
477 template <typename T0, int N, typename T1>
478 struct binary_operator<index_op, T0[N], T1> {
480 typedef T0& result_type;
481 static result_type eval(T0* ptr, T1 const& index)
482 { return ptr[index]; }
485 //////////////////////////////////
486 template <typename T0, typename T1>
487 struct binary_operator<plus_assign_op, T0, T1> {
489 typedef T0& result_type;
490 static result_type eval(T0& lhs, T1 const& rhs)
491 { return lhs += rhs; }
494 //////////////////////////////////
495 template <typename T0, typename T1>
496 struct binary_operator<minus_assign_op, T0, T1> {
498 typedef T0& result_type;
499 static result_type eval(T0& lhs, T1 const& rhs)
500 { return lhs -= rhs; }
503 //////////////////////////////////
504 template <typename T0, typename T1>
505 struct binary_operator<times_assign_op, T0, T1> {
507 typedef T0& result_type;
508 static result_type eval(T0& lhs, T1 const& rhs)
509 { return lhs *= rhs; }
512 //////////////////////////////////
513 template <typename T0, typename T1>
514 struct binary_operator<divide_assign_op, T0, T1> {
516 typedef T0& result_type;
517 static result_type eval(T0& lhs, T1 const& rhs)
518 { return lhs /= rhs; }
521 //////////////////////////////////
522 template <typename T0, typename T1>
523 struct binary_operator<mod_assign_op, T0, T1> {
525 typedef T0& result_type;
526 static result_type eval(T0& lhs, T1 const& rhs)
527 { return lhs %= rhs; }
530 //////////////////////////////////
531 template <typename T0, typename T1>
532 struct binary_operator<and_assign_op, T0, T1> {
534 typedef T0& result_type;
535 static result_type eval(T0& lhs, T1 const& rhs)
536 { return lhs &= rhs; }
539 //////////////////////////////////
540 template <typename T0, typename T1>
541 struct binary_operator<or_assign_op, T0, T1> {
543 typedef T0& result_type;
544 static result_type eval(T0& lhs, T1 const& rhs)
545 { return lhs |= rhs; }
548 //////////////////////////////////
549 template <typename T0, typename T1>
550 struct binary_operator<xor_assign_op, T0, T1> {
552 typedef T0& result_type;
553 static result_type eval(T0& lhs, T1 const& rhs)
554 { return lhs ^= rhs; }
557 //////////////////////////////////
558 template <typename T0, typename T1>
559 struct binary_operator<shift_l_assign_op, T0, T1> {
561 typedef T0& result_type;
562 static result_type eval(T0& lhs, T1 const& rhs)
563 { return lhs <<= rhs; }
566 //////////////////////////////////
567 template <typename T0, typename T1>
568 struct binary_operator<shift_r_assign_op, T0, T1> {
570 typedef T0& result_type;
571 static result_type eval(T0& lhs, T1 const& rhs)
572 { return lhs >>= rhs; }
575 //////////////////////////////////
576 template <typename T0, typename T1>
577 struct binary_operator<plus_op, T0, T1> {
579 typedef typename higher_rank<T0, T1>::type const result_type;
580 static result_type eval(T0 const& lhs, T1 const& rhs)
581 { return lhs + rhs; }
584 //////////////////////////////////
585 template <typename T0, typename T1>
586 struct binary_operator<minus_op, T0, T1> {
588 typedef typename higher_rank<T0, T1>::type const result_type;
589 static result_type eval(T0 const& lhs, T1 const& rhs)
590 { return lhs - rhs; }
593 //////////////////////////////////
594 template <typename T0, typename T1>
595 struct binary_operator<times_op, T0, T1> {
597 typedef typename higher_rank<T0, T1>::type const result_type;
598 static result_type eval(T0 const& lhs, T1 const& rhs)
599 { return lhs * rhs; }
602 //////////////////////////////////
603 template <typename T0, typename T1>
604 struct binary_operator<divide_op, T0, T1> {
606 typedef typename higher_rank<T0, T1>::type const result_type;
607 static result_type eval(T0 const& lhs, T1 const& rhs)
608 { return lhs / rhs; }
611 //////////////////////////////////
612 template <typename T0, typename T1>
613 struct binary_operator<mod_op, T0, T1> {
615 typedef typename higher_rank<T0, T1>::type const result_type;
616 static result_type eval(T0 const& lhs, T1 const& rhs)
617 { return lhs % rhs; }
620 //////////////////////////////////
621 template <typename T0, typename T1>
622 struct binary_operator<and_op, T0, T1> {
624 typedef typename higher_rank<T0, T1>::type const result_type;
625 static result_type eval(T0 const& lhs, T1 const& rhs)
626 { return lhs & rhs; }
629 //////////////////////////////////
630 template <typename T0, typename T1>
631 struct binary_operator<or_op, T0, T1> {
633 typedef typename higher_rank<T0, T1>::type const result_type;
634 static result_type eval(T0 const& lhs, T1 const& rhs)
635 { return lhs | rhs; }
638 //////////////////////////////////
639 template <typename T0, typename T1>
640 struct binary_operator<xor_op, T0, T1> {
642 typedef typename higher_rank<T0, T1>::type const result_type;
643 static result_type eval(T0 const& lhs, T1 const& rhs)
644 { return lhs ^ rhs; }
647 //////////////////////////////////
648 template <typename T0, typename T1>
649 struct binary_operator<shift_l_op, T0, T1> {
651 typedef T0 const result_type;
652 static result_type eval(T0 const& lhs, T1 const& rhs)
653 { return lhs << rhs; }
656 //////////////////////////////////
657 template <typename T0, typename T1>
658 struct binary_operator<shift_r_op, T0, T1> {
660 typedef T0 const result_type;
661 static result_type eval(T0 const& lhs, T1 const& rhs)
662 { return lhs >> rhs; }
665 //////////////////////////////////
666 template <typename T0, typename T1>
667 struct binary_operator<eq_op, T0, T1> {
669 typedef bool result_type;
670 static result_type eval(T0 const& lhs, T1 const& rhs)
671 { return lhs == rhs; }
674 //////////////////////////////////
675 template <typename T0, typename T1>
676 struct binary_operator<not_eq_op, T0, T1> {
678 typedef bool result_type;
679 static result_type eval(T0 const& lhs, T1 const& rhs)
680 { return lhs != rhs; }
683 //////////////////////////////////
684 template <typename T0, typename T1>
685 struct binary_operator<lt_op, T0, T1> {
687 typedef bool result_type;
688 static result_type eval(T0 const& lhs, T1 const& rhs)
689 { return lhs < rhs; }
692 //////////////////////////////////
693 template <typename T0, typename T1>
694 struct binary_operator<lt_eq_op, T0, T1> {
696 typedef bool result_type;
697 static result_type eval(T0 const& lhs, T1 const& rhs)
698 { return lhs <= rhs; }
701 //////////////////////////////////
702 template <typename T0, typename T1>
703 struct binary_operator<gt_op, T0, T1> {
705 typedef bool result_type;
706 static result_type eval(T0 const& lhs, T1 const& rhs)
707 { return lhs > rhs; }
710 //////////////////////////////////
711 template <typename T0, typename T1>
712 struct binary_operator<gt_eq_op, T0, T1> {
714 typedef bool result_type;
715 static result_type eval(T0 const& lhs, T1 const& rhs)
716 { return lhs >= rhs; }
719 //////////////////////////////////
720 template <typename T0, typename T1>
721 struct binary_operator<logical_and_op, T0, T1> {
723 typedef bool result_type;
724 // no eval function, see comment above.
727 //////////////////////////////////
728 template <typename T0, typename T1>
729 struct binary_operator<logical_or_op, T0, T1> {
731 typedef bool result_type;
732 // no eval function, see comment above.
735 ///////////////////////////////////////////////////////////////////////////////
737 // negative lazy operator (prefix -)
739 ///////////////////////////////////////////////////////////////////////////////
742 template <typename T0>
745 typedef typename unary_operator<negative_op, T0>::result_type type;
748 template <typename T0>
749 typename unary_operator<negative_op, T0>::result_type
750 operator()(T0& _0) const
751 { return unary_operator<negative_op, T0>::eval(_0); }
754 //////////////////////////////////
755 template <typename BaseT>
756 inline typename impl::make_unary<negative_op, BaseT>::type
757 operator-(actor<BaseT> const& _0)
759 return impl::make_unary<negative_op, BaseT>::construct(_0);
762 ///////////////////////////////////////////////////////////////////////////////
764 // positive lazy operator (prefix +)
766 ///////////////////////////////////////////////////////////////////////////////
769 template <typename T0>
772 typedef typename unary_operator<positive_op, T0>::result_type type;
775 template <typename T0>
776 typename unary_operator<positive_op, T0>::result_type
777 operator()(T0& _0) const
778 { return unary_operator<positive_op, T0>::eval(_0); }
781 //////////////////////////////////
782 template <typename BaseT>
783 inline typename impl::make_unary<positive_op, BaseT>::type
784 operator+(actor<BaseT> const& _0)
786 return impl::make_unary<positive_op, BaseT>::construct(_0);
789 ///////////////////////////////////////////////////////////////////////////////
791 // logical not lazy operator (prefix !)
793 ///////////////////////////////////////////////////////////////////////////////
794 struct logical_not_op {
796 template <typename T0>
799 typedef typename unary_operator<logical_not_op, T0>::result_type type;
802 template <typename T0>
803 typename unary_operator<logical_not_op, T0>::result_type
804 operator()(T0& _0) const
805 { return unary_operator<logical_not_op, T0>::eval(_0); }
808 //////////////////////////////////
809 template <typename BaseT>
810 inline typename impl::make_unary<logical_not_op, BaseT>::type
811 operator!(actor<BaseT> const& _0)
813 return impl::make_unary<logical_not_op, BaseT>::construct(_0);
816 ///////////////////////////////////////////////////////////////////////////////
818 // invert lazy operator (prefix ~)
820 ///////////////////////////////////////////////////////////////////////////////
823 template <typename T0>
826 typedef typename unary_operator<invert_op, T0>::result_type type;
829 template <typename T0>
830 typename unary_operator<invert_op, T0>::result_type
831 operator()(T0& _0) const
832 { return unary_operator<invert_op, T0>::eval(_0); }
835 //////////////////////////////////
836 template <typename BaseT>
837 inline typename impl::make_unary<invert_op, BaseT>::type
838 operator~(actor<BaseT> const& _0)
840 return impl::make_unary<invert_op, BaseT>::construct(_0);
843 ///////////////////////////////////////////////////////////////////////////////
845 // reference lazy operator (prefix &)
847 ///////////////////////////////////////////////////////////////////////////////
848 struct reference_op {
850 template <typename T0>
853 typedef typename unary_operator<reference_op, T0>::result_type type;
856 template <typename T0>
857 typename unary_operator<reference_op, T0>::result_type
858 operator()(T0& _0) const
859 { return unary_operator<reference_op, T0>::eval(_0); }
862 //////////////////////////////////
863 template <typename BaseT>
864 inline typename impl::make_unary<reference_op, BaseT>::type
865 operator&(actor<BaseT> const& _0)
867 return impl::make_unary<reference_op, BaseT>::construct(_0);
870 ///////////////////////////////////////////////////////////////////////////////
872 // dereference lazy operator (prefix *)
874 ///////////////////////////////////////////////////////////////////////////////
875 struct dereference_op {
877 template <typename T0>
880 typedef typename unary_operator<dereference_op, T0>::result_type type;
883 template <typename T0>
884 typename unary_operator<dereference_op, T0>::result_type
885 operator()(T0& _0) const
886 { return unary_operator<dereference_op, T0>::eval(_0); }
889 //////////////////////////////////
890 template <typename BaseT>
891 inline typename impl::make_unary<dereference_op, BaseT>::type
892 operator*(actor<BaseT> const& _0)
894 return impl::make_unary<dereference_op, BaseT>::construct(_0);
897 ///////////////////////////////////////////////////////////////////////////////
899 // pre increment lazy operator (prefix ++)
901 ///////////////////////////////////////////////////////////////////////////////
904 template <typename T0>
907 typedef typename unary_operator<pre_incr_op, T0>::result_type type;
910 template <typename T0>
911 typename unary_operator<pre_incr_op, T0>::result_type
912 operator()(T0& _0) const
913 { return unary_operator<pre_incr_op, T0>::eval(_0); }
916 //////////////////////////////////
917 template <typename BaseT>
918 inline typename impl::make_unary<pre_incr_op, BaseT>::type
919 operator++(actor<BaseT> const& _0)
921 return impl::make_unary<pre_incr_op, BaseT>::construct(_0);
924 ///////////////////////////////////////////////////////////////////////////////
926 // pre decrement lazy operator (prefix --)
928 ///////////////////////////////////////////////////////////////////////////////
931 template <typename T0>
934 typedef typename unary_operator<pre_decr_op, T0>::result_type type;
937 template <typename T0>
938 typename unary_operator<pre_decr_op, T0>::result_type
939 operator()(T0& _0) const
940 { return unary_operator<pre_decr_op, T0>::eval(_0); }
943 //////////////////////////////////
944 template <typename BaseT>
945 inline typename impl::make_unary<pre_decr_op, BaseT>::type
946 operator--(actor<BaseT> const& _0)
948 return impl::make_unary<pre_decr_op, BaseT>::construct(_0);
951 ///////////////////////////////////////////////////////////////////////////////
953 // post increment lazy operator (postfix ++)
955 ///////////////////////////////////////////////////////////////////////////////
956 struct post_incr_op {
958 template <typename T0>
961 typedef typename unary_operator<post_incr_op, T0>::result_type type;
964 template <typename T0>
965 typename unary_operator<post_incr_op, T0>::result_type
966 operator()(T0& _0) const
967 { return unary_operator<post_incr_op, T0>::eval(_0); }
970 //////////////////////////////////
971 template <typename BaseT>
972 inline typename impl::make_unary<post_incr_op, BaseT>::type
973 operator++(actor<BaseT> const& _0, int)
975 return impl::make_unary<post_incr_op, BaseT>::construct(_0);
978 ///////////////////////////////////////////////////////////////////////////////
980 // post decrement lazy operator (postfix --)
982 ///////////////////////////////////////////////////////////////////////////////
983 struct post_decr_op {
985 template <typename T0>
988 typedef typename unary_operator<post_decr_op, T0>::result_type type;
991 template <typename T0>
992 typename unary_operator<post_decr_op, T0>::result_type
993 operator()(T0& _0) const
994 { return unary_operator<post_decr_op, T0>::eval(_0); }
997 //////////////////////////////////
998 template <typename BaseT>
999 inline typename impl::make_unary<post_decr_op, BaseT>::type
1000 operator--(actor<BaseT> const& _0, int)
1002 return impl::make_unary<post_decr_op, BaseT>::construct(_0);
1005 ///////////////////////////////////////////////////////////////////////////////
1007 // assignment lazy operator (infix =)
1008 // The acual lazy operator is a member of the actor class.
1010 ///////////////////////////////////////////////////////////////////////////////
1013 template <typename T0, typename T1>
1016 typedef typename binary_operator<assign_op, T0, T1>
1020 template <typename T0, typename T1>
1021 typename binary_operator<assign_op, T0, T1>::result_type
1022 operator()(T0& _0, T1& _1) const
1023 { return binary_operator<assign_op, T0, T1>::eval(_0, _1); }
1026 //////////////////////////////////
1027 template <typename BaseT>
1028 template <typename B>
1029 inline typename impl::make_binary1<assign_op, BaseT, B>::type
1030 actor<BaseT>::operator=(B const& _1) const
1032 return impl::make_binary1<assign_op, BaseT, B>::construct(*this, _1);
1035 ///////////////////////////////////////////////////////////////////////////////
1037 // index lazy operator (array index [])
1038 // The acual lazy operator is a member of the actor class.
1040 ///////////////////////////////////////////////////////////////////////////////
1043 template <typename T0, typename T1>
1046 typedef typename binary_operator<index_op, T0, T1>
1050 template <typename T0, typename T1>
1051 typename binary_operator<index_op, T0, T1>::result_type
1052 operator()(T0& _0, T1& _1) const
1053 { return binary_operator<index_op, T0, T1>::eval(_0, _1); }
1056 //////////////////////////////////
1057 template <typename BaseT>
1058 template <typename B>
1059 inline typename impl::make_binary1<index_op, BaseT, B>::type
1060 actor<BaseT>::operator[](B const& _1) const
1062 return impl::make_binary1<index_op, BaseT, B>::construct(*this, _1);
1065 ///////////////////////////////////////////////////////////////////////////////
1067 // plus assign lazy operator (infix +=)
1069 ///////////////////////////////////////////////////////////////////////////////
1070 struct plus_assign_op {
1072 template <typename T0, typename T1>
1075 typedef typename binary_operator<plus_assign_op, T0, T1>
1079 template <typename T0, typename T1>
1080 typename binary_operator<plus_assign_op, T0, T1>::result_type
1081 operator()(T0& _0, T1& _1) const
1082 { return binary_operator<plus_assign_op, T0, T1>::eval(_0, _1); }
1085 //////////////////////////////////
1086 template <typename BaseT, typename T1>
1087 inline typename impl::make_binary1<plus_assign_op, BaseT, T1>::type
1088 operator+=(actor<BaseT> const& _0, T1 CREF _1)
1090 return impl::make_binary1<plus_assign_op, BaseT, T1>::construct(_0, _1);
1093 ///////////////////////////////////////////////////////////////////////////////
1095 // minus assign lazy operator (infix -=)
1097 ///////////////////////////////////////////////////////////////////////////////
1098 struct minus_assign_op {
1100 template <typename T0, typename T1>
1103 typedef typename binary_operator<minus_assign_op, T0, T1>
1107 template <typename T0, typename T1>
1108 typename binary_operator<minus_assign_op, T0, T1>::result_type
1109 operator()(T0& _0, T1& _1) const
1110 { return binary_operator<minus_assign_op, T0, T1>::eval(_0, _1); }
1113 //////////////////////////////////
1114 template <typename BaseT, typename T1>
1115 inline typename impl::make_binary1<minus_assign_op, BaseT, T1>::type
1116 operator-=(actor<BaseT> const& _0, T1 CREF _1)
1118 return impl::make_binary1<minus_assign_op, BaseT, T1>::construct(_0, _1);
1121 ///////////////////////////////////////////////////////////////////////////////
1123 // times assign lazy operator (infix *=)
1125 ///////////////////////////////////////////////////////////////////////////////
1126 struct times_assign_op {
1128 template <typename T0, typename T1>
1131 typedef typename binary_operator<times_assign_op, T0, T1>
1135 template <typename T0, typename T1>
1136 typename binary_operator<times_assign_op, T0, T1>::result_type
1137 operator()(T0& _0, T1& _1) const
1138 { return binary_operator<times_assign_op, T0, T1>::eval(_0, _1); }
1141 //////////////////////////////////
1142 template <typename BaseT, typename T1>
1143 inline typename impl::make_binary1<times_assign_op, BaseT, T1>::type
1144 operator*=(actor<BaseT> const& _0, T1 CREF _1)
1146 return impl::make_binary1<times_assign_op, BaseT, T1>::construct(_0, _1);
1149 ///////////////////////////////////////////////////////////////////////////////
1151 // divide assign lazy operator (infix /=)
1153 ///////////////////////////////////////////////////////////////////////////////
1154 struct divide_assign_op {
1156 template <typename T0, typename T1>
1159 typedef typename binary_operator<divide_assign_op, T0, T1>
1163 template <typename T0, typename T1>
1164 typename binary_operator<divide_assign_op, T0, T1>::result_type
1165 operator()(T0& _0, T1& _1) const
1166 { return binary_operator<divide_assign_op, T0, T1>::eval(_0, _1); }
1169 //////////////////////////////////
1170 template <typename BaseT, typename T1>
1171 inline typename impl::make_binary1<divide_assign_op, BaseT, T1>::type
1172 operator/=(actor<BaseT> const& _0, T1 CREF _1)
1174 return impl::make_binary1<divide_assign_op, BaseT, T1>::construct(_0, _1);
1177 ///////////////////////////////////////////////////////////////////////////////
1179 // mod assign lazy operator (infix %=)
1181 ///////////////////////////////////////////////////////////////////////////////
1182 struct mod_assign_op {
1184 template <typename T0, typename T1>
1187 typedef typename binary_operator<mod_assign_op, T0, T1>
1191 template <typename T0, typename T1>
1192 typename binary_operator<mod_assign_op, T0, T1>::result_type
1193 operator()(T0& _0, T1& _1) const
1194 { return binary_operator<mod_assign_op, T0, T1>::eval(_0, _1); }
1197 //////////////////////////////////
1198 template <typename BaseT, typename T1>
1199 inline typename impl::make_binary1<mod_assign_op, BaseT, T1>::type
1200 operator%=(actor<BaseT> const& _0, T1 CREF _1)
1202 return impl::make_binary1<mod_assign_op, BaseT, T1>::construct(_0, _1);
1205 ///////////////////////////////////////////////////////////////////////////////
1207 // and assign lazy operator (infix &=)
1209 ///////////////////////////////////////////////////////////////////////////////
1210 struct and_assign_op {
1212 template <typename T0, typename T1>
1215 typedef typename binary_operator<and_assign_op, T0, T1>
1219 template <typename T0, typename T1>
1220 typename binary_operator<and_assign_op, T0, T1>::result_type
1221 operator()(T0& _0, T1& _1) const
1222 { return binary_operator<and_assign_op, T0, T1>::eval(_0, _1); }
1225 //////////////////////////////////
1226 template <typename BaseT, typename T1>
1227 inline typename impl::make_binary1<and_assign_op, BaseT, T1>::type
1228 operator&=(actor<BaseT> const& _0, T1 CREF _1)
1230 return impl::make_binary1<and_assign_op, BaseT, T1>::construct(_0, _1);
1233 ///////////////////////////////////////////////////////////////////////////////
1235 // or assign lazy operator (infix |=)
1237 ///////////////////////////////////////////////////////////////////////////////
1238 struct or_assign_op {
1240 template <typename T0, typename T1>
1243 typedef typename binary_operator<or_assign_op, T0, T1>
1247 template <typename T0, typename T1>
1248 typename binary_operator<or_assign_op, T0, T1>::result_type
1249 operator()(T0& _0, T1& _1) const
1250 { return binary_operator<or_assign_op, T0, T1>::eval(_0, _1); }
1253 //////////////////////////////////
1254 template <typename BaseT, typename T1>
1255 inline typename impl::make_binary1<or_assign_op, BaseT, T1>::type
1256 operator|=(actor<BaseT> const& _0, T1 CREF _1)
1258 return impl::make_binary1<or_assign_op, BaseT, T1>::construct(_0, _1);
1261 ///////////////////////////////////////////////////////////////////////////////
1263 // xor assign lazy operator (infix ^=)
1265 ///////////////////////////////////////////////////////////////////////////////
1266 struct xor_assign_op {
1268 template <typename T0, typename T1>
1271 typedef typename binary_operator<xor_assign_op, T0, T1>
1275 template <typename T0, typename T1>
1276 typename binary_operator<xor_assign_op, T0, T1>::result_type
1277 operator()(T0& _0, T1& _1) const
1278 { return binary_operator<xor_assign_op, T0, T1>::eval(_0, _1); }
1281 //////////////////////////////////
1282 template <typename BaseT, typename T1>
1283 inline typename impl::make_binary1<xor_assign_op, BaseT, T1>::type
1284 operator^=(actor<BaseT> const& _0, T1 CREF _1)
1286 return impl::make_binary1<xor_assign_op, BaseT, T1>::construct(_0, _1);
1289 ///////////////////////////////////////////////////////////////////////////////
1291 // shift left assign lazy operator (infix <<=)
1293 ///////////////////////////////////////////////////////////////////////////////
1294 struct shift_l_assign_op {
1296 template <typename T0, typename T1>
1299 typedef typename binary_operator<shift_l_assign_op, T0, T1>
1303 template <typename T0, typename T1>
1304 typename binary_operator<shift_l_assign_op, T0, T1>::result_type
1305 operator()(T0& _0, T1& _1) const
1306 { return binary_operator<shift_l_assign_op, T0, T1>::eval(_0, _1); }
1309 //////////////////////////////////
1310 template <typename BaseT, typename T1>
1311 inline typename impl::make_binary1<shift_l_assign_op, BaseT, T1>::type
1312 operator<<=(actor<BaseT> const& _0, T1 CREF _1)
1314 return impl::make_binary1<shift_l_assign_op, BaseT, T1>::construct(_0, _1);
1317 ///////////////////////////////////////////////////////////////////////////////
1319 // shift right assign lazy operator (infix >>=)
1321 ///////////////////////////////////////////////////////////////////////////////
1322 struct shift_r_assign_op {
1324 template <typename T0, typename T1>
1327 typedef typename binary_operator<shift_r_assign_op, T0, T1>
1331 template <typename T0, typename T1>
1332 typename binary_operator<shift_r_assign_op, T0, T1>::result_type
1333 operator()(T0& _0, T1& _1) const
1334 { return binary_operator<shift_r_assign_op, T0, T1>::eval(_0, _1); }
1337 //////////////////////////////////
1338 template <typename BaseT, typename T1>
1339 inline typename impl::make_binary1<shift_r_assign_op, BaseT, T1>::type
1340 operator>>=(actor<BaseT> const& _0, T1 CREF _1)
1342 return impl::make_binary1<shift_r_assign_op, BaseT, T1>::construct(_0, _1);
1345 ///////////////////////////////////////////////////////////////////////////////
1347 // plus lazy operator (infix +)
1349 ///////////////////////////////////////////////////////////////////////////////
1352 template <typename T0, typename T1>
1355 typedef typename binary_operator<plus_op, T0, T1>
1359 template <typename T0, typename T1>
1360 typename binary_operator<plus_op, T0, T1>::result_type
1361 operator()(T0& _0, T1& _1) const
1362 { return binary_operator<plus_op, T0, T1>::eval(_0, _1); }
1365 //////////////////////////////////
1366 template <typename BaseT, typename T1>
1367 inline typename impl::make_binary1<plus_op, BaseT, T1>::type
1368 operator+(actor<BaseT> const& _0, T1 CREF _1)
1370 return impl::make_binary1<plus_op, BaseT, T1>::construct(_0, _1);
1373 //////////////////////////////////
1374 template <typename T0, typename BaseT>
1375 inline typename impl::make_binary2<plus_op, T0, BaseT>::type
1376 operator+(T0 CREF _0, actor<BaseT> const& _1)
1378 return impl::make_binary2<plus_op, T0, BaseT>::construct(_0, _1);
1381 //////////////////////////////////
1382 template <typename BaseT0, typename BaseT1>
1383 inline typename impl::make_binary3<plus_op, BaseT0, BaseT1>::type
1384 operator+(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1386 return impl::make_binary3<plus_op, BaseT0, BaseT1>::construct(_0, _1);
1389 ///////////////////////////////////////////////////////////////////////////////
1391 // minus lazy operator (infix -)
1393 ///////////////////////////////////////////////////////////////////////////////
1396 template <typename T0, typename T1>
1399 typedef typename binary_operator<minus_op, T0, T1>
1403 template <typename T0, typename T1>
1404 typename binary_operator<minus_op, T0, T1>::result_type
1405 operator()(T0& _0, T1& _1) const
1406 { return binary_operator<minus_op, T0, T1>::eval(_0, _1); }
1409 //////////////////////////////////
1410 template <typename BaseT, typename T1>
1411 inline typename impl::make_binary1<minus_op, BaseT, T1>::type
1412 operator-(actor<BaseT> const& _0, T1 CREF _1)
1414 return impl::make_binary1<minus_op, BaseT, T1>::construct(_0, _1);
1417 //////////////////////////////////
1418 template <typename T0, typename BaseT>
1419 inline typename impl::make_binary2<minus_op, T0, BaseT>::type
1420 operator-(T0 CREF _0, actor<BaseT> const& _1)
1422 return impl::make_binary2<minus_op, T0, BaseT>::construct(_0, _1);
1425 //////////////////////////////////
1426 template <typename BaseT0, typename BaseT1>
1427 inline typename impl::make_binary3<minus_op, BaseT0, BaseT1>::type
1428 operator-(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1430 return impl::make_binary3<minus_op, BaseT0, BaseT1>::construct(_0, _1);
1433 ///////////////////////////////////////////////////////////////////////////////
1435 // times lazy operator (infix *)
1437 ///////////////////////////////////////////////////////////////////////////////
1440 template <typename T0, typename T1>
1443 typedef typename binary_operator<times_op, T0, T1>
1447 template <typename T0, typename T1>
1448 typename binary_operator<times_op, T0, T1>::result_type
1449 operator()(T0& _0, T1& _1) const
1450 { return binary_operator<times_op, T0, T1>::eval(_0, _1); }
1453 //////////////////////////////////
1454 template <typename BaseT, typename T1>
1455 inline typename impl::make_binary1<times_op, BaseT, T1>::type
1456 operator*(actor<BaseT> const& _0, T1 CREF _1)
1458 return impl::make_binary1<times_op, BaseT, T1>::construct(_0, _1);
1461 //////////////////////////////////
1462 template <typename T0, typename BaseT>
1463 inline typename impl::make_binary2<times_op, T0, BaseT>::type
1464 operator*(T0 CREF _0, actor<BaseT> const& _1)
1466 return impl::make_binary2<times_op, T0, BaseT>::construct(_0, _1);
1469 //////////////////////////////////
1470 template <typename BaseT0, typename BaseT1>
1471 inline typename impl::make_binary3<times_op, BaseT0, BaseT1>::type
1472 operator*(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1474 return impl::make_binary3<times_op, BaseT0, BaseT1>::construct(_0, _1);
1477 ///////////////////////////////////////////////////////////////////////////////
1479 // divide lazy operator (infix /)
1481 ///////////////////////////////////////////////////////////////////////////////
1484 template <typename T0, typename T1>
1487 typedef typename binary_operator<divide_op, T0, T1>
1491 template <typename T0, typename T1>
1492 typename binary_operator<divide_op, T0, T1>::result_type
1493 operator()(T0& _0, T1& _1) const
1494 { return binary_operator<divide_op, T0, T1>::eval(_0, _1); }
1497 //////////////////////////////////
1498 template <typename BaseT, typename T1>
1499 inline typename impl::make_binary1<divide_op, BaseT, T1>::type
1500 operator/(actor<BaseT> const& _0, T1 CREF _1)
1502 return impl::make_binary1<divide_op, BaseT, T1>::construct(_0, _1);
1505 //////////////////////////////////
1506 template <typename T0, typename BaseT>
1507 inline typename impl::make_binary2<divide_op, T0, BaseT>::type
1508 operator/(T0 CREF _0, actor<BaseT> const& _1)
1510 return impl::make_binary2<divide_op, T0, BaseT>::construct(_0, _1);
1513 //////////////////////////////////
1514 template <typename BaseT0, typename BaseT1>
1515 inline typename impl::make_binary3<divide_op, BaseT0, BaseT1>::type
1516 operator/(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1518 return impl::make_binary3<divide_op, BaseT0, BaseT1>::construct(_0, _1);
1521 ///////////////////////////////////////////////////////////////////////////////
1523 // mod lazy operator (infix %)
1525 ///////////////////////////////////////////////////////////////////////////////
1528 template <typename T0, typename T1>
1531 typedef typename binary_operator<mod_op, T0, T1>
1535 template <typename T0, typename T1>
1536 typename binary_operator<mod_op, T0, T1>::result_type
1537 operator()(T0& _0, T1& _1) const
1538 { return binary_operator<mod_op, T0, T1>::eval(_0, _1); }
1541 //////////////////////////////////
1542 template <typename BaseT, typename T1>
1543 inline typename impl::make_binary1<mod_op, BaseT, T1>::type
1544 operator%(actor<BaseT> const& _0, T1 CREF _1)
1546 return impl::make_binary1<mod_op, BaseT, T1>::construct(_0, _1);
1549 //////////////////////////////////
1550 template <typename T0, typename BaseT>
1551 inline typename impl::make_binary2<mod_op, T0, BaseT>::type
1552 operator%(T0 CREF _0, actor<BaseT> const& _1)
1554 return impl::make_binary2<mod_op, T0, BaseT>::construct(_0, _1);
1557 //////////////////////////////////
1558 template <typename BaseT0, typename BaseT1>
1559 inline typename impl::make_binary3<mod_op, BaseT0, BaseT1>::type
1560 operator%(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1562 return impl::make_binary3<mod_op, BaseT0, BaseT1>::construct(_0, _1);
1565 ///////////////////////////////////////////////////////////////////////////////
1567 // and lazy operator (infix &)
1569 ///////////////////////////////////////////////////////////////////////////////
1572 template <typename T0, typename T1>
1575 typedef typename binary_operator<and_op, T0, T1>
1579 template <typename T0, typename T1>
1580 typename binary_operator<and_op, T0, T1>::result_type
1581 operator()(T0& _0, T1& _1) const
1582 { return binary_operator<and_op, T0, T1>::eval(_0, _1); }
1585 //////////////////////////////////
1586 template <typename BaseT, typename T1>
1587 inline typename impl::make_binary1<and_op, BaseT, T1>::type
1588 operator&(actor<BaseT> const& _0, T1 CREF _1)
1590 return impl::make_binary1<and_op, BaseT, T1>::construct(_0, _1);
1593 //////////////////////////////////
1594 template <typename T0, typename BaseT>
1595 inline typename impl::make_binary2<and_op, T0, BaseT>::type
1596 operator&(T0 CREF _0, actor<BaseT> const& _1)
1598 return impl::make_binary2<and_op, T0, BaseT>::construct(_0, _1);
1601 //////////////////////////////////
1602 template <typename BaseT0, typename BaseT1>
1603 inline typename impl::make_binary3<and_op, BaseT0, BaseT1>::type
1604 operator&(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1606 return impl::make_binary3<and_op, BaseT0, BaseT1>::construct(_0, _1);
1609 ///////////////////////////////////////////////////////////////////////////////
1611 // or lazy operator (infix |)
1613 ///////////////////////////////////////////////////////////////////////////////
1616 template <typename T0, typename T1>
1619 typedef typename binary_operator<or_op, T0, T1>
1623 template <typename T0, typename T1>
1624 typename binary_operator<or_op, T0, T1>::result_type
1625 operator()(T0& _0, T1& _1) const
1626 { return binary_operator<or_op, T0, T1>::eval(_0, _1); }
1629 //////////////////////////////////
1630 template <typename BaseT, typename T1>
1631 inline typename impl::make_binary1<or_op, BaseT, T1>::type
1632 operator|(actor<BaseT> const& _0, T1 CREF _1)
1634 return impl::make_binary1<or_op, BaseT, T1>::construct(_0, _1);
1637 //////////////////////////////////
1638 template <typename T0, typename BaseT>
1639 inline typename impl::make_binary2<or_op, T0, BaseT>::type
1640 operator|(T0 CREF _0, actor<BaseT> const& _1)
1642 return impl::make_binary2<or_op, T0, BaseT>::construct(_0, _1);
1645 //////////////////////////////////
1646 template <typename BaseT0, typename BaseT1>
1647 inline typename impl::make_binary3<or_op, BaseT0, BaseT1>::type
1648 operator|(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1650 return impl::make_binary3<or_op, BaseT0, BaseT1>::construct(_0, _1);
1653 ///////////////////////////////////////////////////////////////////////////////
1655 // xor lazy operator (infix ^)
1657 ///////////////////////////////////////////////////////////////////////////////
1660 template <typename T0, typename T1>
1663 typedef typename binary_operator<xor_op, T0, T1>
1667 template <typename T0, typename T1>
1668 typename binary_operator<xor_op, T0, T1>::result_type
1669 operator()(T0& _0, T1& _1) const
1670 { return binary_operator<xor_op, T0, T1>::eval(_0, _1); }
1673 //////////////////////////////////
1674 template <typename BaseT, typename T1>
1675 inline typename impl::make_binary1<xor_op, BaseT, T1>::type
1676 operator^(actor<BaseT> const& _0, T1 CREF _1)
1678 return impl::make_binary1<xor_op, BaseT, T1>::construct(_0, _1);
1681 //////////////////////////////////
1682 template <typename T0, typename BaseT>
1683 inline typename impl::make_binary2<xor_op, T0, BaseT>::type
1684 operator^(T0 CREF _0, actor<BaseT> const& _1)
1686 return impl::make_binary2<xor_op, T0, BaseT>::construct(_0, _1);
1689 //////////////////////////////////
1690 template <typename BaseT0, typename BaseT1>
1691 inline typename impl::make_binary3<xor_op, BaseT0, BaseT1>::type
1692 operator^(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1694 return impl::make_binary3<xor_op, BaseT0, BaseT1>::construct(_0, _1);
1697 ///////////////////////////////////////////////////////////////////////////////
1699 // shift left lazy operator (infix <<)
1701 ///////////////////////////////////////////////////////////////////////////////
1704 template <typename T0, typename T1>
1707 typedef typename binary_operator<shift_l_op, T0, T1>
1711 template <typename T0, typename T1>
1712 typename binary_operator<shift_l_op, T0, T1>::result_type
1713 operator()(T0& _0, T1& _1) const
1714 { return binary_operator<shift_l_op, T0, T1>::eval(_0, _1); }
1717 //////////////////////////////////
1718 template <typename BaseT, typename T1>
1719 inline typename impl::make_binary1<shift_l_op, BaseT, T1>::type
1720 operator<<(actor<BaseT> const& _0, T1 CREF _1)
1722 return impl::make_binary1<shift_l_op, BaseT, T1>::construct(_0, _1);
1725 //////////////////////////////////
1726 template <typename T0, typename BaseT>
1727 inline typename impl::make_binary2<shift_l_op, T0, BaseT>::type
1728 operator<<(T0 CREF _0, actor<BaseT> const& _1)
1730 return impl::make_binary2<shift_l_op, T0, BaseT>::construct(_0, _1);
1733 //////////////////////////////////
1734 template <typename BaseT0, typename BaseT1>
1735 inline typename impl::make_binary3<shift_l_op, BaseT0, BaseT1>::type
1736 operator<<(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1738 return impl::make_binary3<shift_l_op, BaseT0, BaseT1>::construct(_0, _1);
1741 ///////////////////////////////////////////////////////////////////////////////
1743 // shift right lazy operator (infix >>)
1745 ///////////////////////////////////////////////////////////////////////////////
1748 template <typename T0, typename T1>
1751 typedef typename binary_operator<shift_r_op, T0, T1>
1755 template <typename T0, typename T1>
1756 typename binary_operator<shift_r_op, T0, T1>::result_type
1757 operator()(T0& _0, T1& _1) const
1758 { return binary_operator<shift_r_op, T0, T1>::eval(_0, _1); }
1761 //////////////////////////////////
1762 template <typename BaseT, typename T1>
1763 inline typename impl::make_binary1<shift_r_op, BaseT, T1>::type
1764 operator>>(actor<BaseT> const& _0, T1 CREF _1)
1766 return impl::make_binary1<shift_r_op, BaseT, T1>::construct(_0, _1);
1769 //////////////////////////////////
1770 template <typename T0, typename BaseT>
1771 inline typename impl::make_binary2<shift_r_op, T0, BaseT>::type
1772 operator>>(T0 CREF _0, actor<BaseT> const& _1)
1774 return impl::make_binary2<shift_r_op, T0, BaseT>::construct(_0, _1);
1777 //////////////////////////////////
1778 template <typename BaseT0, typename BaseT1>
1779 inline typename impl::make_binary3<shift_r_op, BaseT0, BaseT1>::type
1780 operator>>(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1782 return impl::make_binary3<shift_r_op, BaseT0, BaseT1>::construct(_0, _1);
1785 ///////////////////////////////////////////////////////////////////////////////
1787 // equal lazy operator (infix ==)
1789 ///////////////////////////////////////////////////////////////////////////////
1792 template <typename T0, typename T1>
1795 typedef typename binary_operator<eq_op, T0, T1>
1799 template <typename T0, typename T1>
1800 typename binary_operator<eq_op, T0, T1>::result_type
1801 operator()(T0& _0, T1& _1) const
1802 { return binary_operator<eq_op, T0, T1>::eval(_0, _1); }
1805 //////////////////////////////////
1806 template <typename BaseT, typename T1>
1807 inline typename impl::make_binary1<eq_op, BaseT, T1>::type
1808 operator==(actor<BaseT> const& _0, T1 CREF _1)
1810 return impl::make_binary1<eq_op, BaseT, T1>::construct(_0, _1);
1813 //////////////////////////////////
1814 template <typename T0, typename BaseT>
1815 inline typename impl::make_binary2<eq_op, T0, BaseT>::type
1816 operator==(T0 CREF _0, actor<BaseT> const& _1)
1818 return impl::make_binary2<eq_op, T0, BaseT>::construct(_0, _1);
1821 //////////////////////////////////
1822 template <typename BaseT0, typename BaseT1>
1823 inline typename impl::make_binary3<eq_op, BaseT0, BaseT1>::type
1824 operator==(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1826 return impl::make_binary3<eq_op, BaseT0, BaseT1>::construct(_0, _1);
1829 ///////////////////////////////////////////////////////////////////////////////
1831 // not equal lazy operator (infix !=)
1833 ///////////////////////////////////////////////////////////////////////////////
1836 template <typename T0, typename T1>
1839 typedef typename binary_operator<not_eq_op, T0, T1>
1843 template <typename T0, typename T1>
1844 typename binary_operator<not_eq_op, T0, T1>::result_type
1845 operator()(T0& _0, T1& _1) const
1846 { return binary_operator<not_eq_op, T0, T1>::eval(_0, _1); }
1849 //////////////////////////////////
1850 template <typename BaseT, typename T1>
1851 inline typename impl::make_binary1<not_eq_op, BaseT, T1>::type
1852 operator!=(actor<BaseT> const& _0, T1 CREF _1)
1854 return impl::make_binary1<not_eq_op, BaseT, T1>::construct(_0, _1);
1857 //////////////////////////////////
1858 template <typename T0, typename BaseT>
1859 inline typename impl::make_binary2<not_eq_op, T0, BaseT>::type
1860 operator!=(T0 CREF _0, actor<BaseT> const& _1)
1862 return impl::make_binary2<not_eq_op, T0, BaseT>::construct(_0, _1);
1865 //////////////////////////////////
1866 template <typename BaseT0, typename BaseT1>
1867 inline typename impl::make_binary3<not_eq_op, BaseT0, BaseT1>::type
1868 operator!=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1870 return impl::make_binary3<not_eq_op, BaseT0, BaseT1>::construct(_0, _1);
1873 ///////////////////////////////////////////////////////////////////////////////
1875 // less than lazy operator (infix <)
1877 ///////////////////////////////////////////////////////////////////////////////
1880 template <typename T0, typename T1>
1883 typedef typename binary_operator<lt_op, T0, T1>
1887 template <typename T0, typename T1>
1888 typename binary_operator<lt_op, T0, T1>::result_type
1889 operator()(T0& _0, T1& _1) const
1890 { return binary_operator<lt_op, T0, T1>::eval(_0, _1); }
1893 //////////////////////////////////
1894 template <typename BaseT, typename T1>
1895 inline typename impl::make_binary1<lt_op, BaseT, T1>::type
1896 operator<(actor<BaseT> const& _0, T1 CREF _1)
1898 return impl::make_binary1<lt_op, BaseT, T1>::construct(_0, _1);
1901 //////////////////////////////////
1902 template <typename T0, typename BaseT>
1903 inline typename impl::make_binary2<lt_op, T0, BaseT>::type
1904 operator<(T0 CREF _0, actor<BaseT> const& _1)
1906 return impl::make_binary2<lt_op, T0, BaseT>::construct(_0, _1);
1909 //////////////////////////////////
1910 template <typename BaseT0, typename BaseT1>
1911 inline typename impl::make_binary3<lt_op, BaseT0, BaseT1>::type
1912 operator<(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1914 return impl::make_binary3<lt_op, BaseT0, BaseT1>::construct(_0, _1);
1917 ///////////////////////////////////////////////////////////////////////////////
1919 // less than equal lazy operator (infix <=)
1921 ///////////////////////////////////////////////////////////////////////////////
1924 template <typename T0, typename T1>
1927 typedef typename binary_operator<lt_eq_op, T0, T1>
1931 template <typename T0, typename T1>
1932 typename binary_operator<lt_eq_op, T0, T1>::result_type
1933 operator()(T0& _0, T1& _1) const
1934 { return binary_operator<lt_eq_op, T0, T1>::eval(_0, _1); }
1937 //////////////////////////////////
1938 template <typename BaseT, typename T1>
1939 inline typename impl::make_binary1<lt_eq_op, BaseT, T1>::type
1940 operator<=(actor<BaseT> const& _0, T1 CREF _1)
1942 return impl::make_binary1<lt_eq_op, BaseT, T1>::construct(_0, _1);
1945 //////////////////////////////////
1946 template <typename T0, typename BaseT>
1947 inline typename impl::make_binary2<lt_eq_op, T0, BaseT>::type
1948 operator<=(T0 CREF _0, actor<BaseT> const& _1)
1950 return impl::make_binary2<lt_eq_op, T0, BaseT>::construct(_0, _1);
1953 //////////////////////////////////
1954 template <typename BaseT0, typename BaseT1>
1955 inline typename impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::type
1956 operator<=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1958 return impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
1961 ///////////////////////////////////////////////////////////////////////////////
1963 // greater than lazy operator (infix >)
1965 ///////////////////////////////////////////////////////////////////////////////
1968 template <typename T0, typename T1>
1971 typedef typename binary_operator<gt_op, T0, T1>
1975 template <typename T0, typename T1>
1976 typename binary_operator<gt_op, T0, T1>::result_type
1977 operator()(T0& _0, T1& _1) const
1978 { return binary_operator<gt_op, T0, T1>::eval(_0, _1); }
1981 //////////////////////////////////
1982 template <typename BaseT, typename T1>
1983 inline typename impl::make_binary1<gt_op, BaseT, T1>::type
1984 operator>(actor<BaseT> const& _0, T1 CREF _1)
1986 return impl::make_binary1<gt_op, BaseT, T1>::construct(_0, _1);
1989 //////////////////////////////////
1990 template <typename T0, typename BaseT>
1991 inline typename impl::make_binary2<gt_op, T0, BaseT>::type
1992 operator>(T0 CREF _0, actor<BaseT> const& _1)
1994 return impl::make_binary2<gt_op, T0, BaseT>::construct(_0, _1);
1997 //////////////////////////////////
1998 template <typename BaseT0, typename BaseT1>
1999 inline typename impl::make_binary3<gt_op, BaseT0, BaseT1>::type
2000 operator>(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2002 return impl::make_binary3<gt_op, BaseT0, BaseT1>::construct(_0, _1);
2005 ///////////////////////////////////////////////////////////////////////////////
2007 // greater than equal lazy operator (infix >=)
2009 ///////////////////////////////////////////////////////////////////////////////
2012 template <typename T0, typename T1>
2015 typedef typename binary_operator<gt_eq_op, T0, T1>
2019 template <typename T0, typename T1>
2020 typename binary_operator<gt_eq_op, T0, T1>::result_type
2021 operator()(T0& _0, T1& _1) const
2022 { return binary_operator<gt_eq_op, T0, T1>::eval(_0, _1); }
2025 //////////////////////////////////
2026 template <typename BaseT, typename T1>
2027 inline typename impl::make_binary1<gt_eq_op, BaseT, T1>::type
2028 operator>=(actor<BaseT> const& _0, T1 CREF _1)
2030 return impl::make_binary1<gt_eq_op, BaseT, T1>::construct(_0, _1);
2033 //////////////////////////////////
2034 template <typename T0, typename BaseT>
2035 inline typename impl::make_binary2<gt_eq_op, T0, BaseT>::type
2036 operator>=(T0 CREF _0, actor<BaseT> const& _1)
2038 return impl::make_binary2<gt_eq_op, T0, BaseT>::construct(_0, _1);
2041 //////////////////////////////////
2042 template <typename BaseT0, typename BaseT1>
2043 inline typename impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::type
2044 operator>=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2046 return impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
2049 ///////////////////////////////////////////////////////////////////////////////
2051 // logical and lazy operator (infix &&)
2053 // The logical_and_composite class and its corresponding generators are
2054 // provided to allow short-circuit evaluation of the operator's
2057 ///////////////////////////////////////////////////////////////////////////////
2058 template <typename A0, typename A1>
2059 struct logical_and_composite {
2061 typedef logical_and_composite<A0, A1> self_t;
2063 template <typename TupleT>
2066 typedef typename binary_operator<logical_and_op,
2067 typename actor_result<A0, TupleT>::plain_type,
2068 typename actor_result<A1, TupleT>::plain_type
2069 >::result_type type;
2072 logical_and_composite(A0 const& _0, A1 const& _1)
2075 template <typename TupleT>
2076 typename actor_result<self_t, TupleT>::type
2077 eval(TupleT const& args) const
2079 return a0.eval(args) && a1.eval(args);
2082 A0 a0; A1 a1; // actors
2085 #if !(defined(__ICL) && __ICL <= 500)
2086 //////////////////////////////////
2087 template <typename BaseT, typename T1>
2088 inline actor<logical_and_composite
2089 <actor<BaseT>, typename as_actor<T1>::type> >
2090 operator&&(actor<BaseT> const& _0, T1 CREF _1)
2092 return logical_and_composite
2093 <actor<BaseT>, typename as_actor<T1>::type>
2094 (_0, as_actor<T1>::convert(_1));
2097 //////////////////////////////////
2098 template <typename T0, typename BaseT>
2099 inline actor<logical_and_composite
2100 <typename as_actor<T0>::type, actor<BaseT> > >
2101 operator&&(T0 CREF _0, actor<BaseT> const& _1)
2103 return logical_and_composite
2104 <typename as_actor<T0>::type, actor<BaseT> >
2105 (as_actor<T0>::convert(_0), _1);
2108 //////////////////////////////////
2109 template <typename BaseT0, typename BaseT1>
2110 inline actor<logical_and_composite
2111 <actor<BaseT0>, actor<BaseT1> > >
2112 operator&&(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2114 return logical_and_composite
2115 <actor<BaseT0>, actor<BaseT1> >
2119 //////////////////////////////////
2120 template <typename T0, typename T1>
2121 inline actor<logical_and_composite
2122 <typename as_actor<T0>::type, typename as_actor<T1>::type> >
2123 operator&&(T0 CREF _0, T1 CREF _1)
2125 return logical_and_composite
2126 <typename as_actor<T0>::type, typename as_actor<T1>::type>
2127 (as_actor<T0>::convert(_0), as_actor<T1>::convert(_1));
2129 #endif // !(__ICL && __ICL <= 500)
2131 ///////////////////////////////////////////////////////////////////////////////
2133 // logical or lazy operator (infix ||)
2135 // The logical_or_composite class and its corresponding generators are
2136 // provided to allow short-circuit evaluation of the operator's
2139 ///////////////////////////////////////////////////////////////////////////////
2140 template <typename A0, typename A1>
2141 struct logical_or_composite {
2143 typedef logical_or_composite<A0, A1> self_t;
2145 template <typename TupleT>
2148 typedef typename binary_operator<logical_or_op,
2149 typename actor_result<A0, TupleT>::plain_type,
2150 typename actor_result<A1, TupleT>::plain_type
2151 >::result_type type;
2154 logical_or_composite(A0 const& _0, A1 const& _1)
2157 template <typename TupleT>
2158 typename actor_result<self_t, TupleT>::type
2159 eval(TupleT const& args) const
2161 return a0.eval(args) || a1.eval(args);
2164 A0 a0; A1 a1; // actors
2167 //////////////////////////////////
2168 template <typename BaseT, typename T1>
2169 inline actor<logical_or_composite
2170 <actor<BaseT>, typename as_actor<T1>::type> >
2171 operator||(actor<BaseT> const& _0, T1 CREF _1)
2173 return logical_or_composite
2174 <actor<BaseT>, typename as_actor<T1>::type>
2175 (_0, as_actor<T1>::convert(_1));
2178 //////////////////////////////////
2179 template <typename T0, typename BaseT>
2180 inline actor<logical_or_composite
2181 <typename as_actor<T0>::type, actor<BaseT> > >
2182 operator||(T0 CREF _0, actor<BaseT> const& _1)
2184 return logical_or_composite
2185 <typename as_actor<T0>::type, actor<BaseT> >
2186 (as_actor<T0>::convert(_0), _1);
2189 //////////////////////////////////
2190 template <typename BaseT0, typename BaseT1>
2191 inline actor<logical_or_composite
2192 <actor<BaseT0>, actor<BaseT1> > >
2193 operator||(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2195 return logical_or_composite
2196 <actor<BaseT0>, actor<BaseT1> >
2200 } // namespace phoenix