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