x
Yes
No
Do you want to visit DriveHQ English website?
首页
产品服务
价格
免费试用
下载客户端
关于我们
云文件服务
|
云备份服务
|
FTP服务
|
企业邮箱服务
|
网站托管
|
客户端软件
云文件服务
云备份服务
FTP服务
企业级邮箱服务
网站托管
客户端软件
operators.hpp - Hosted on DriveHQ Cloud IT Platform
返回上层目录
上传
下载
共享
发布
新建文件夹
新建文件
复制
剪切
删除
粘贴
评论
升级服务
路径: \\game3dprogramming\materials\GameFactory\GameFactoryDemo\references\boost_1_35_0\boost\spirit\phoenix\operators.hpp
旋转
特效
属性
历史版本
/*============================================================================= 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
#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 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 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