Chris@16: /*============================================================================= Chris@16: Phoenix V1.2.1 Chris@16: Copyright (c) 2001-2002 Joel de Guzman Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #ifndef PHOENIX_OPERATORS_HPP Chris@16: #define PHOENIX_OPERATORS_HPP Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: #if !defined(BOOST_NO_CWCTYPE) Chris@16: #include Chris@16: #endif Chris@16: Chris@16: #if defined(__BORLANDC__) || (defined(__ICL) && __ICL >= 700) Chris@16: #define CREF const& Chris@16: #else Chris@16: #define CREF Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace phoenix { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Operators Chris@16: // Chris@16: // Lazy operators Chris@16: // Chris@16: // This class provides a mechanism for lazily evaluating operators. Chris@16: // Syntactically, a lazy operator looks like an ordinary C/C++ Chris@16: // infix, prefix or postfix operator. The operator application Chris@16: // looks the same. However, unlike ordinary operators, the actual Chris@16: // operator execution is deferred. (see actor.hpp, primitives.hpp Chris@16: // and composite.hpp for an overview). Samples: Chris@16: // Chris@16: // arg1 + arg2 Chris@16: // 1 + arg1 * arg2 Chris@16: // 1 / -arg1 Chris@16: // arg1 < 150 Chris@16: // Chris@16: // T1 set of classes implement all the C++ free operators. Like Chris@16: // lazy functions (see functions.hpp), lazy operators are not Chris@16: // immediately executed when invoked. Instead, a composite (see Chris@16: // composite.hpp) object is created and returned to the caller. Chris@16: // Example: Chris@16: // Chris@16: // (arg1 + arg2) * arg3 Chris@16: // Chris@16: // does nothing more than return a composite. T1 second function Chris@16: // call will evaluate the actual operators. Example: Chris@16: // Chris@16: // int i = 4, j = 5, k = 6; Chris@16: // cout << ((arg1 + arg2) * arg3)(i, j, k); Chris@16: // Chris@16: // will print out "54". Chris@16: // Chris@16: // Arbitrarily complex expressions can be lazily evaluated Chris@16: // following three simple rules: Chris@16: // Chris@16: // 1) Lazy evaluated binary operators apply when at least one Chris@16: // of the operands is an actor object (see actor.hpp and Chris@16: // primitives.hpp). Consequently, if an operand is not an actor Chris@16: // object, it is implicitly converted to an object of type Chris@16: // actor > (where T is the original type of the Chris@16: // operand). Chris@16: // Chris@16: // 2) Lazy evaluated unary operators apply only to operands Chris@16: // which are actor objects. Chris@16: // Chris@16: // 3) The result of a lazy operator is a composite actor object Chris@16: // that can in turn apply to rule 1. Chris@16: // Chris@16: // Example: Chris@16: // Chris@16: // arg1 + 3 Chris@16: // Chris@16: // is a lazy expression involving the operator+. Following rule 1, Chris@16: // lazy evaluation is triggered since arg1 is an instance of an Chris@16: // actor > class (see primitives.hpp). The right Chris@16: // operand <3> is implicitly converted to an actor >. Chris@16: // The result of this binary + expression is a composite object, Chris@16: // following rule 3. Chris@16: // Chris@16: // Take note that although at least one of the operands must be a Chris@16: // valid actor class in order for lazy evaluation to take effect, Chris@16: // if this is not the case and we still want to lazily evaluate an Chris@16: // expression, we can use var(x), val(x) or cref(x) to transform Chris@16: // the operand into a valid action object (see primitives.hpp). Chris@16: // Example: Chris@16: // Chris@16: // val(1) << 3; Chris@16: // Chris@16: // Supported operators: Chris@16: // Chris@16: // Unary operators: Chris@16: // Chris@16: // prefix: ~, !, -, +, ++, --, & (reference), * (dereference) Chris@16: // postfix: ++, -- Chris@16: // Chris@16: // Binary operators: Chris@16: // Chris@16: // =, [], +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= Chris@16: // +, -, *, /, %, &, |, ^, <<, >> Chris@16: // ==, !=, <, >, <=, >= Chris@16: // &&, || Chris@16: // Chris@16: // Each operator has a special tag type associated with it. For Chris@16: // example the binary + operator has a plus_op tag type associated Chris@16: // with it. This is used to specialize either the unary_operator or Chris@16: // binary_operator template classes (see unary_operator and Chris@16: // binary_operator below). Specializations of these unary_operator Chris@16: // and binary_operator are the actual workhorses that implement the Chris@16: // operations. The behavior of each lazy operator depends on these Chris@16: // unary_operator and binary_operator specializations. 'preset' Chris@16: // specializations conform to the canonical operator rules modeled Chris@16: // by the behavior of integers and pointers: Chris@16: // Chris@16: // Prefix -, + and ~ accept constant arguments and return an Chris@16: // object by value. Chris@16: // Chris@16: // The ! accept constant arguments and returns a boolean Chris@16: // result. Chris@16: // Chris@16: // The & (address-of), * (dereference) both return a reference Chris@16: // to an object. Chris@16: // Chris@16: // Prefix ++ returns a reference to its mutable argument after Chris@16: // it is incremented. Chris@16: // Chris@16: // Postfix ++ returns the mutable argument by value before it Chris@16: // is incremented. Chris@16: // Chris@16: // The += and its family accept mutable right hand side (rhs) Chris@16: // operand and return a reference to the rhs operand. Chris@16: // Chris@16: // Infix + and its family accept constant arguments and return Chris@16: // an object by value. Chris@16: // Chris@16: // The == and its family accept constant arguments and return a Chris@16: // boolean result. Chris@16: // Chris@16: // Operators && and || accept constant arguments and return a Chris@16: // boolean result and are short circuit evaluated as expected. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Operator tags Chris@16: // Chris@16: // Each C++ operator has a corresponding tag type. This is Chris@16: // used as a means for specializing the unary_operator and Chris@16: // binary_operator (see below). The tag also serves as the Chris@16: // lazy operator type compatible as a composite operation Chris@16: // see (composite.hpp). Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: // Unary operator tags Chris@16: Chris@16: struct negative_op; struct positive_op; Chris@16: struct logical_not_op; struct invert_op; Chris@16: struct reference_op; struct dereference_op; Chris@16: struct pre_incr_op; struct pre_decr_op; Chris@16: struct post_incr_op; struct post_decr_op; Chris@16: Chris@16: // Binary operator tags Chris@16: Chris@16: struct assign_op; struct index_op; Chris@16: struct plus_assign_op; struct minus_assign_op; Chris@16: struct times_assign_op; struct divide_assign_op; struct mod_assign_op; Chris@16: struct and_assign_op; struct or_assign_op; struct xor_assign_op; Chris@16: struct shift_l_assign_op; struct shift_r_assign_op; Chris@16: Chris@16: struct plus_op; struct minus_op; Chris@16: struct times_op; struct divide_op; struct mod_op; Chris@16: struct and_op; struct or_op; struct xor_op; Chris@16: struct shift_l_op; struct shift_r_op; Chris@16: Chris@16: struct eq_op; struct not_eq_op; Chris@16: struct lt_op; struct lt_eq_op; Chris@16: struct gt_op; struct gt_eq_op; Chris@16: struct logical_and_op; struct logical_or_op; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // unary_operator Chris@16: // Chris@16: // The unary_operator class implements most of the C++ unary Chris@16: // operators. Each specialization is basically a simple static eval Chris@16: // function plus a result_type typedef that determines the return Chris@16: // type of the eval function. Chris@16: // Chris@16: // TagT is one of the unary operator tags above and T is the data Chris@16: // type (argument) involved in the operation. Chris@16: // Chris@16: // Only the behavior of C/C++ built-in types are taken into account Chris@16: // in the specializations provided below. For user-defined types, Chris@16: // these specializations may still be used provided that the Chris@16: // operator overloads of such types adhere to the standard behavior Chris@16: // of built-in types. Chris@16: // Chris@16: // T1 separate special_ops.hpp file implements more stl savvy Chris@16: // specializations. Other more specialized unary_operator Chris@16: // implementations may be defined by the client for specific Chris@16: // unary operator tags/data types. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct unary_operator; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T const result_type; Chris@16: static result_type eval(T const& v) Chris@16: { return -v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T const result_type; Chris@16: static result_type eval(T const& v) Chris@16: { return +v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T const result_type; Chris@16: static result_type eval(T const& v) Chris@16: { return !v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T const result_type; Chris@16: static result_type eval(T const& v) Chris@16: { return ~v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T* result_type; Chris@16: static result_type eval(T& v) Chris@16: { return &v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T& result_type; Chris@16: static result_type eval(T* v) Chris@16: { return *v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T& result_type; Chris@16: static result_type eval(T* const v) Chris@16: { return *v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template <> Chris@16: struct unary_operator { Chris@16: Chris@16: // G++ eager template instantiation Chris@16: // somehow requires this. Chris@16: typedef nil_t result_type; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: #ifndef __BORLANDC__ Chris@16: template <> Chris@16: struct unary_operator { Chris@16: Chris@16: // G++ eager template instantiation Chris@16: // somehow requires this. Chris@16: typedef nil_t result_type; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T& result_type; Chris@16: static result_type eval(T& v) Chris@16: { return ++v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T& result_type; Chris@16: static result_type eval(T& v) Chris@16: { return --v; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T const result_type; Chris@16: static result_type eval(T& v) Chris@16: { T t(v); ++v; return t; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct unary_operator { Chris@16: Chris@16: typedef T const result_type; Chris@16: static result_type eval(T& v) Chris@16: { T t(v); --v; return t; } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // rank Chris@16: // Chris@16: // rank class has a static int constant 'value' that defines the Chris@16: // absolute rank of a type. rank is used to choose the result Chris@16: // type of binary operators such as +. The type with the higher Chris@16: // rank wins and is used as the operator's return type. T1 generic Chris@16: // user defined type has a very high rank and always wins when Chris@16: // compared against a user defined type. If this is not desireable, Chris@16: // one can write a rank specialization for the type. Chris@16: // Chris@16: // Take note that ranks 0..9999 are reserved for the framework. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct rank { static int const value = INT_MAX; }; Chris@16: Chris@16: template <> struct rank { static int const value = 0; }; Chris@16: template <> struct rank { static int const value = 10; }; Chris@16: Chris@16: template <> struct rank { static int const value = 20; }; Chris@16: template <> struct rank { static int const value = 20; }; Chris@16: template <> struct rank { static int const value = 30; }; Chris@16: #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) Chris@16: template <> struct rank { static int const value = 40; }; Chris@16: #endif // !defined(BOOST_NO_INTRINSIC_WCHAR_T) Chris@16: Chris@16: template <> struct rank { static int const value = 50; }; Chris@16: template <> struct rank { static int const value = 60; }; Chris@16: Chris@16: template <> struct rank { static int const value = 70; }; Chris@16: template <> struct rank { static int const value = 80; }; Chris@16: Chris@16: template <> struct rank { static int const value = 90; }; Chris@16: template <> struct rank { static int const value = 100; }; Chris@16: Chris@16: #ifdef BOOST_HAS_LONG_LONG Chris@16: template <> struct rank< ::boost::long_long_type> { static int const value = 110; }; Chris@16: template <> struct rank< ::boost::ulong_long_type> { static int const value = 120; }; Chris@16: #endif Chris@16: Chris@16: template <> struct rank { static int const value = 130; }; Chris@16: template <> struct rank { static int const value = 140; }; Chris@16: template <> struct rank { static int const value = 150; }; Chris@16: Chris@16: template struct rank Chris@16: { static int const value = 160; }; Chris@16: Chris@16: template struct rank Chris@16: { static int const value = 160; }; Chris@16: Chris@16: template struct rank Chris@16: { static int const value = 160; }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // higher_rank Chris@16: // Chris@16: // Chooses the type (T0 or T1) with the higher rank. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct higher_rank { Chris@16: typedef typename boost::mpl::if_c< Chris@16: rank::value < rank::value, Chris@16: T1, T0>::type type; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // binary_operator Chris@16: // Chris@16: // The binary_operator class implements most of the C++ binary Chris@16: // operators. Each specialization is basically a simple static eval Chris@16: // function plus a result_type typedef that determines the return Chris@16: // type of the eval function. Chris@16: // Chris@16: // TagT is one of the binary operator tags above T0 and T1 are the Chris@16: // (arguments') data types involved in the operation. Chris@16: // Chris@16: // Only the behavior of C/C++ built-in types are taken into account Chris@16: // in the specializations provided below. For user-defined types, Chris@16: // these specializations may still be used provided that the Chris@16: // operator overloads of such types adhere to the standard behavior Chris@16: // of built-in types. Chris@16: // Chris@16: // T1 separate special_ops.hpp file implements more stl savvy Chris@16: // specializations. Other more specialized unary_operator Chris@16: // implementations may be defined by the client for specific Chris@16: // unary operator tags/data types. Chris@16: // Chris@16: // All binary_operator except the logical_and_op and logical_or_op Chris@16: // have an eval static function that carries out the actual operation. Chris@16: // The logical_and_op and logical_or_op d are special because these Chris@16: // two operators are short-circuit evaluated. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct binary_operator; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs = rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: // G++ eager template instantiation Chris@16: // somehow requires this. Chris@16: typedef nil_t result_type; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0* ptr, T1 const& index) Chris@16: { return ptr[index]; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0* const ptr, T1 const& index) Chris@16: { return ptr[index]; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0* ptr, T1 const& index) Chris@16: { return ptr[index]; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs += rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs -= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs *= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs /= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs %= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs &= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs |= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs ^= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs <<= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0& result_type; Chris@16: static result_type eval(T0& lhs, T1 const& rhs) Chris@16: { return lhs >>= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs + rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs - rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs * rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs / rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs % rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs & rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs | rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef typename higher_rank::type const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs ^ rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0 const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs << rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef T0 const result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs >> rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs == rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs != rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs < rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs <= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs > rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: static result_type eval(T0 const& lhs, T1 const& rhs) Chris@16: { return lhs >= rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: // no eval function, see comment above. Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator { Chris@16: Chris@16: typedef bool result_type; Chris@16: // no eval function, see comment above. Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // negative lazy operator (prefix -) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct negative_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator-(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // positive lazy operator (prefix +) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct positive_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator+(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // logical not lazy operator (prefix !) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct logical_not_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator!(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // invert lazy operator (prefix ~) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct invert_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator~(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // reference lazy operator (prefix &) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct reference_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator&(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // dereference lazy operator (prefix *) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct dereference_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator*(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // pre increment lazy operator (prefix ++) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct pre_incr_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator++(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // pre decrement lazy operator (prefix --) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct pre_decr_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator--(actor const& _0) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // post increment lazy operator (postfix ++) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct post_incr_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator++(actor const& _0, int) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // post decrement lazy operator (postfix --) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct post_decr_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename unary_operator::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unary_operator::result_type Chris@16: operator()(T0& _0) const Chris@16: { return unary_operator::eval(_0); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_unary::type Chris@16: operator--(actor const& _0, int) Chris@16: { Chris@16: return impl::make_unary::construct(_0); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // assignment lazy operator (infix =) Chris@16: // The acual lazy operator is a member of the actor class. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: actor::operator=(B const& _1) const Chris@16: { Chris@16: return impl::make_binary1::construct(*this, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // index lazy operator (array index []) Chris@16: // The acual lazy operator is a member of the actor class. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct index_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: actor::operator[](B const& _1) const Chris@16: { Chris@16: return impl::make_binary1::construct(*this, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // plus assign lazy operator (infix +=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct plus_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator+=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // minus assign lazy operator (infix -=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct minus_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator-=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // times assign lazy operator (infix *=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct times_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator*=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // divide assign lazy operator (infix /=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct divide_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator/=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // mod assign lazy operator (infix %=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct mod_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator%=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // and assign lazy operator (infix &=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct and_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator&=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // or assign lazy operator (infix |=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct or_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator|=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // xor assign lazy operator (infix ^=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct xor_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator^=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // shift left assign lazy operator (infix <<=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct shift_l_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator<<=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // shift right assign lazy operator (infix >>=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct shift_r_assign_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator>>=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // plus lazy operator (infix +) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct plus_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator+(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator+(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator+(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // minus lazy operator (infix -) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct minus_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator-(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator-(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator-(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // times lazy operator (infix *) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct times_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator*(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator*(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator*(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // divide lazy operator (infix /) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct divide_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator/(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator/(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator/(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // mod lazy operator (infix %) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct mod_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator%(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator%(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator%(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // and lazy operator (infix &) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct and_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator&(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator&(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator&(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // or lazy operator (infix |) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct or_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator|(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator|(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator|(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // xor lazy operator (infix ^) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct xor_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator^(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator^(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator^(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // shift left lazy operator (infix <<) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct shift_l_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator<<(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator<<(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator<<(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // shift right lazy operator (infix >>) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct shift_r_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator>>(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator>>(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator>>(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // equal lazy operator (infix ==) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct eq_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator==(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator==(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator==(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // not equal lazy operator (infix !=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct not_eq_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator!=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator!=(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator!=(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // less than lazy operator (infix <) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct lt_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator<(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator<(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator<(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // less than equal lazy operator (infix <=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct lt_eq_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator<=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator<=(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator<=(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // greater than lazy operator (infix >) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct gt_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator>(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator>(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator>(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // greater than equal lazy operator (infix >=) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct gt_eq_op { Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator Chris@16: ::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename binary_operator::result_type Chris@16: operator()(T0& _0, T1& _1) const Chris@16: { return binary_operator::eval(_0, _1); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator>=(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary2::type Chris@16: operator>=(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary2::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3::type Chris@16: operator>=(actor const& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3::construct(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // logical and lazy operator (infix &&) Chris@16: // Chris@16: // The logical_and_composite class and its corresponding generators are Chris@16: // provided to allow short-circuit evaluation of the operator's Chris@16: // operands. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct logical_and_composite { Chris@16: Chris@16: typedef logical_and_composite self_t; Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator::plain_type, Chris@16: typename actor_result::plain_type Chris@16: >::result_type type; Chris@16: }; Chris@16: Chris@16: logical_and_composite(A0 const& _0, A1 const& _1) Chris@16: : a0(_0), a1(_1) {} Chris@16: Chris@16: template Chris@16: typename actor_result::type Chris@16: eval(TupleT const& args) const Chris@16: { Chris@16: return a0.eval(args) && a1.eval(args); Chris@16: } Chris@16: Chris@16: A0 a0; A1 a1; // actors Chris@16: }; Chris@16: Chris@16: #if !(defined(__ICL) && __ICL <= 500) Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor, typename as_actor::type> > Chris@16: operator&&(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return logical_and_composite Chris@16: , typename as_actor::type> Chris@16: (_0, as_actor::convert(_1)); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor::type, actor > > Chris@16: operator&&(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return logical_and_composite Chris@16: ::type, actor > Chris@16: (as_actor::convert(_0), _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor, actor > > Chris@16: operator&&(actor const& _0, actor const& _1) Chris@16: { Chris@16: return logical_and_composite Chris@16: , actor > Chris@16: (_0, _1); Chris@16: } Chris@16: #else Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor::type, typename as_actor::type> > Chris@16: operator&&(T0 CREF _0, T1 CREF _1) Chris@16: { Chris@16: return logical_and_composite Chris@16: ::type, typename as_actor::type> Chris@16: (as_actor::convert(_0), as_actor::convert(_1)); Chris@16: } Chris@16: #endif // !(__ICL && __ICL <= 500) Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // logical or lazy operator (infix ||) Chris@16: // Chris@16: // The logical_or_composite class and its corresponding generators are Chris@16: // provided to allow short-circuit evaluation of the operator's Chris@16: // operands. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct logical_or_composite { Chris@16: Chris@16: typedef logical_or_composite self_t; Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef typename binary_operator::plain_type, Chris@16: typename actor_result::plain_type Chris@16: >::result_type type; Chris@16: }; Chris@16: Chris@16: logical_or_composite(A0 const& _0, A1 const& _1) Chris@16: : a0(_0), a1(_1) {} Chris@16: Chris@16: template Chris@16: typename actor_result::type Chris@16: eval(TupleT const& args) const Chris@16: { Chris@16: return a0.eval(args) || a1.eval(args); Chris@16: } Chris@16: Chris@16: A0 a0; A1 a1; // actors Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor, typename as_actor::type> > Chris@16: operator||(actor const& _0, T1 CREF _1) Chris@16: { Chris@16: return logical_or_composite Chris@16: , typename as_actor::type> Chris@16: (_0, as_actor::convert(_1)); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor::type, actor > > Chris@16: operator||(T0 CREF _0, actor const& _1) Chris@16: { Chris@16: return logical_or_composite Chris@16: ::type, actor > Chris@16: (as_actor::convert(_0), _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor, actor > > Chris@16: operator||(actor const& _0, actor const& _1) Chris@16: { Chris@16: return logical_or_composite Chris@16: , actor > Chris@16: (_0, _1); Chris@16: } Chris@16: Chris@16: } // namespace phoenix Chris@16: Chris@16: #undef CREF Chris@16: #endif