operators.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 2,101 行 · 第 1/5 页

HPP
2,101
字号
/*=============================================================================    Phoenix V1.2.1    Copyright (c) 2001-2002 Joel de Guzman  Distributed under 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 <cwctype>#endif#if defined(__BORLANDC__) || (defined(__ICL) && __ICL >= 700)#define CREF const&#else#define CREF#endif#include <climits>#include <boost/spirit/home/classic/phoenix/actor.hpp>#include <boost/spirit/home/classic/phoenix/composite.hpp>#include <boost/config.hpp>#include <boost/mpl/if.hpp>///////////////////////////////////////////////////////////////////////////////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<value<T> > (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<argument<N> > class (see primitives.hpp). The right//      operand <3> is implicitly converted to an actor<value<int> >.//      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 tagsstruct 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 tagsstruct 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<TagT, T>////      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 <typename TagT, typename T>struct unary_operator;//////////////////////////////////template <typename T>struct unary_operator<negative_op, T> {    typedef T const result_type;    static result_type eval(T const& v)    { return -v; }};//////////////////////////////////template <typename T>struct unary_operator<positive_op, T> {    typedef T const result_type;    static result_type eval(T const& v)    { return +v; }};//////////////////////////////////template <typename T>struct unary_operator<logical_not_op, T> {    typedef T const result_type;    static result_type eval(T const& v)    { return !v; }};//////////////////////////////////template <typename T>struct unary_operator<invert_op, T> {    typedef T const result_type;    static result_type eval(T const& v)    { return ~v; }};//////////////////////////////////template <typename T>struct unary_operator<reference_op, T> {    typedef T* result_type;    static result_type eval(T& v)    { return &v; }};//////////////////////////////////template <typename T>struct unary_operator<dereference_op, T*> {    typedef T& result_type;    static result_type eval(T* v)    { return *v; }};//////////////////////////////////template <typename T>struct unary_operator<dereference_op, T* const> {    typedef T& result_type;    static result_type eval(T* const v)    { return *v; }};//////////////////////////////////template <>struct unary_operator<dereference_op, nil_t> {    //  G++ eager template instantiation    //  somehow requires this.    typedef nil_t result_type;};//////////////////////////////////#ifndef __BORLANDC__template <>struct unary_operator<dereference_op, nil_t const> {    //  G++ eager template instantiation    //  somehow requires this.    typedef nil_t result_type;};#endif//////////////////////////////////template <typename T>struct unary_operator<pre_incr_op, T> {    typedef T& result_type;    static result_type eval(T& v)    { return ++v; }};//////////////////////////////////template <typename T>struct unary_operator<pre_decr_op, T> {    typedef T& result_type;    static result_type eval(T& v)    { return --v; }};//////////////////////////////////template <typename T>struct unary_operator<post_incr_op, T> {    typedef T const result_type;    static result_type eval(T& v)    { T t(v); ++v; return t; }};//////////////////////////////////template <typename T>struct unary_operator<post_decr_op, T> {    typedef T const result_type;    static result_type eval(T& v)    { T t(v); --v; return t; }};///////////////////////////////////////////////////////////////////////////////////  rank<T>////      rank<T> class has a static int constant 'value' that defines the//      absolute rank of a type. rank<T> 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 <typename T>struct rank { static int const value = INT_MAX; };template <> struct rank<void>               { static int const value = 0; };template <> struct rank<bool>               { static int const value = 10; };template <> struct rank<char>               { static int const value = 20; };template <> struct rank<signed char>        { static int const value = 20; };template <> struct rank<unsigned char>      { static int const value = 30; };#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)template <> struct rank<wchar_t>            { static int const value = 40; };#endif // !defined(BOOST_NO_INTRINSIC_WCHAR_T)template <> struct rank<short>              { static int const value = 50; };template <> struct rank<unsigned short>     { static int const value = 60; };template <> struct rank<int>                { static int const value = 70; };template <> struct rank<unsigned int>       { static int const value = 80; };template <> struct rank<long>               { static int const value = 90; };template <> struct rank<unsigned long>      { static int const value = 100; };#ifdef BOOST_HAS_LONG_LONGtemplate <> struct rank< ::boost::long_long_type>          { static int const value = 110; };template <> struct rank< ::boost::ulong_long_type> { static int const value = 120; };#endiftemplate <> struct rank<float>              { static int const value = 130; };template <> struct rank<double>             { static int const value = 140; };template <> struct rank<long double>        { static int const value = 150; };template <typename T> struct rank<T*>{ static int const value = 160; };template <typename T> struct rank<T* const>{ static int const value = 160; };template <typename T, int N> struct rank<T[N]>{ static int const value = 160; };///////////////////////////////////////////////////////////////////////////////////  higher_rank<T0, T1>////      Chooses the type (T0 or T1) with the higher rank./////////////////////////////////////////////////////////////////////////////////template <typename T0, typename T1>struct higher_rank {    typedef typename boost::mpl::if_c<        rank<T0>::value < rank<T1>::value,        T1, T0>::type type;};///////////////////////////////////////////////////////////////////////////////////  binary_operator<TagT, T0, T1>////      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,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?