⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 operator_return_type_traits.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
  typedef typename
    return_type_2_arithmetic_phase_3<
      typename promote_to_int<A>::type, 
      typename promote_to_int<B>::type
    >::type type;
};

// specialization for unsigned int.
// We only have to do these two specialization because the value promotion will
// take care of the other cases.
// The unsigned int promotion rule is this:
// unsigned int to long if a long can hold all values of unsigned int,
// otherwise go to unsigned long.

// struct so I don't have to type this twice.
struct promotion_of_unsigned_int
{
        typedef
        detail::IF<sizeof(long) <= sizeof(unsigned int),        
                unsigned long,
                long>::RET type; 
};

template<>
struct return_type_2_arithmetic_phase_2<unsigned int, long>
{
        typedef promotion_of_unsigned_int::type type;
};
template<>
struct return_type_2_arithmetic_phase_2<long, unsigned int>
{
        typedef promotion_of_unsigned_int::type type;
};


template<class A, class B> struct return_type_2_arithmetic_phase_3 { 
   enum { promote_code_A_value = promote_code<A>::value,
         promote_code_B_value = promote_code<B>::value }; // enums for KCC
  typedef typename
    detail::IF<
      promote_code_A_value == -1 || promote_code_B_value == -1,
      detail::return_type_deduction_failure<return_type_2_arithmetic_phase_3>,
      typename detail::IF<
        ((int)promote_code_A_value > (int)promote_code_B_value), 
        A, 
        B
      >::RET
    >::RET type;                    
};

} // namespace detail

// --  bitwise actions -------------------------------------------
// note: for integral types deuduction is similar to arithmetic actions. 

// drop any qualifiers from the argument types within arithmetic action
template<class A, class B, class Act> 
struct return_type_2<bitwise_action<Act>, A, B>
{

  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<bitwise_action<Act>, plain_A, plain_B>::type type1;
  
  // if user defined return type, do not enter type deductions
  typedef typename 
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value, 
      return_type_2<arithmetic_action<plus_action>, A, B>,
      plain_return_type_2<bitwise_action<Act>, plain_A, plain_B>
    >::type type;

  // plus_action is just a random pick, has to be a concrete instance

  // TODO: This check is only valid for built-in types, overloaded types might
  // accept floating point operators

  // bitwise operators not defined for floating point types
  // these test are not strictly needed here, since the error will be caught in
  // the apply function
  BOOST_STATIC_ASSERT(!(boost::is_float<plain_A>::value && boost::is_float<plain_B>::value));

};

namespace detail {

#ifdef BOOST_NO_TEMPLATED_STREAMS

template<class A, class B>
struct leftshift_type {

  typedef typename detail::IF<
    boost::is_convertible<
      typename boost::remove_reference<A>::type*,
      std::ostream*
    >::value,
    std::ostream&, 
    typename detail::remove_reference_and_cv<A>::type
  >::RET type;
};

template<class A, class B>
struct rightshift_type {

  typedef typename detail::IF<

    boost::is_convertible<
      typename boost::remove_reference<A>::type*,
      std::istream*
    >::value, 
    std::istream&,
    typename detail::remove_reference_and_cv<A>::type
  >::RET type;
};

#else

template <class T> struct get_ostream_type {
  typedef std::basic_ostream<typename T::char_type, 
                             typename T::traits_type>& type;
};

template <class T> struct get_istream_type {
  typedef std::basic_istream<typename T::char_type, 
                             typename T::traits_type>& type;
};

template<class A, class B>
struct leftshift_type {
private:
  typedef typename boost::remove_reference<A>::type plainA;
public:
  typedef typename detail::IF_type<
    is_instance_of_2<plainA, std::basic_ostream>::value, 
    get_ostream_type<plainA>, //reference to the stream 
    detail::remove_reference_and_cv<A>
  >::type type;
};

template<class A, class B>
struct rightshift_type {
private:
  typedef typename boost::remove_reference<A>::type plainA;
public:
  typedef typename detail::IF_type<
    is_instance_of_2<plainA, std::basic_istream>::value, 
    get_istream_type<plainA>, //reference to the stream 
    detail::remove_reference_and_cv<A>
  >::type type;
};


#endif

} // end detail

// ostream
template<class A, class B> 
struct return_type_2<bitwise_action<leftshift_action>, A, B>
{
  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<bitwise_action<leftshift_action>, plain_A, plain_B>::type type1;
  
  // if user defined return type, do not enter type deductions
  typedef typename 
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value, 
      detail::leftshift_type<A, B>,
      plain_return_type_2<bitwise_action<leftshift_action>, plain_A, plain_B>
    >::type type;
};

// istream
template<class A, class B> 
struct return_type_2<bitwise_action<rightshift_action>, A, B>
{
  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<bitwise_action<rightshift_action>, plain_A, plain_B>::type type1;
  
  // if user defined return type, do not enter type deductions
  typedef typename 
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value, 
      detail::rightshift_type<A, B>,
      plain_return_type_2<bitwise_action<rightshift_action>, plain_A, plain_B>
    >::type type;
};

// -- logical actions ----------------------------------------
// always bool
// NOTE: this may not be true for some weird user-defined types,
template<class A, class B, class Act> 
struct plain_return_type_2<logical_action<Act>, A, B> { 
  typedef bool type; 
};

template<class A, class B, class Act> 
struct return_type_2<logical_action<Act>, A, B> { 

  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<logical_action<Act>, plain_A, plain_B>::type type;
  
};


// -- relational actions ----------------------------------------
// always bool
// NOTE: this may not be true for some weird user-defined types,
template<class A, class B, class Act> 
struct plain_return_type_2<relational_action<Act>, A, B> { 
  typedef bool type; 
};

template<class A, class B, class Act> 
struct return_type_2<relational_action<Act>, A, B> { 

  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<relational_action<Act>, plain_A, plain_B>::type type; 
};

// Assingment actions -----------------------------------------------
// return type is the type of the first argument as reference

// note that cv-qualifiers are preserved.
// Yes, assignment operator can be const!

// NOTE: this may not be true for some weird user-defined types,

template<class A, class B, class Act> 
struct return_type_2<arithmetic_assignment_action<Act>, A, B> { 

  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<
      arithmetic_assignment_action<Act>, plain_A, plain_B
    >::type type1;
  
  typedef typename 
    detail::IF<
      boost::is_same<type1, detail::unspecified>::value, 
      typename boost::add_reference<A>::type,
      type1
    >::RET type;
};

template<class A, class B, class Act> 
struct return_type_2<bitwise_assignment_action<Act>, A, B> { 

  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<
      bitwise_assignment_action<Act>, plain_A, plain_B
    >::type type1;
  
  typedef typename 
    detail::IF<
      boost::is_same<type1, detail::unspecified>::value, 
      typename boost::add_reference<A>::type,
      type1
    >::RET type;
};

template<class A, class B> 
struct return_type_2<other_action<assignment_action>, A, B> { 
  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<
      other_action<assignment_action>, plain_A, plain_B
    >::type type1;
  
  typedef typename 
    detail::IF<
      boost::is_same<type1, detail::unspecified>::value, 
      typename boost::add_reference<A>::type,
      type1
    >::RET type;
};

// -- other actions ----------------------------------------

// comma action ----------------------------------
// Note: this may not be true for some weird user-defined types,

// NOTE! This only tries the plain_return_type_2 layer and gives
// detail::unspecified as default. If no such specialization is found, the 
// type rule in the spcecialization of the return_type_2_prot is used
// to give the type of the right argument (which can be a reference too)
// (The built in operator, can return a l- or rvalue).
template<class A, class B> 
struct return_type_2<other_action<comma_action>, A, B> { 

  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename 
    plain_return_type_2<
      other_action<comma_action>, plain_A, plain_B
    >::type type;
  };

// subscript action -----------------------------------------------


namespace detail {
  // A and B are nonreference types
template <class A, class B> struct subscript_type {
  typedef detail::unspecified type; 
};

template <class A, class B> struct subscript_type<A*, B> {
  typedef A& type;
};
template <class A, class B> struct subscript_type<A* const, B> {
  typedef A& type;
};
template <class A, class B> struct subscript_type<A* volatile, B> {
  typedef A& type;
};
template <class A, class B> struct subscript_type<A* const volatile, B> {
  typedef A& type;
};


template<class A, class B, int N> struct subscript_type<A[N], B> { 
  typedef A& type; 
};

  // these 3 specializations are needed to make gcc <3 happy
template<class A, class B, int N> struct subscript_type<const A[N], B> { 
  typedef const A& type; 
};
template<class A, class B, int N> struct subscript_type<volatile A[N], B> { 
  typedef volatile A& type; 
};
template<class A, class B, int N> struct subscript_type<const volatile A[N], B> { 
  typedef const volatile A& type; 
};

} // end detail

template<class A, class B>
struct return_type_2<other_action<subscript_action>, A, B> {

  typedef typename detail::remove_reference_and_cv<A>::type plain_A;
  typedef typename detail::remove_reference_and_cv<B>::type plain_B;

  typedef typename boost::remove_reference<A>::type nonref_A;
  typedef typename boost::remove_reference<B>::type nonref_B;

  typedef typename 
    plain_return_type_2<
      other_action<subscript_action>, plain_A, plain_B
    >::type type1;
  
  typedef typename 
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value, 
      detail::subscript_type<nonref_A, nonref_B>,
      plain_return_type_2<other_action<subscript_action>, plain_A, plain_B>
    >::type type;

};


} // namespace lambda
} // namespace boost


// Forward declarations are incompatible with the libstdc++ debug mode.
#if BOOST_WORKAROUND(__GNUC__, >= 3) && _GLIBCXX_DEBUG
#include <string>
#include <vector>
#include <map>
#include <deque>
#else

// The GCC 2.95.x uses a non-conformant deque
#if BOOST_WORKAROUND(__GNUC__, == 2) && __GNUC_MINOR__ <= 96
#include <deque>
#else

namespace std {
  template <class T, class Allocator> class deque;
}

#endif

namespace std {
 template <class Char, class Traits, class Allocator> class basic_string;
 template <class T, class Allocator> class vector;
 template <class Key, class T, class Cmp, class Allocator> class map;
 template <class Key, class T, class Cmp, class Allocator> class multimap;
}

#endif



namespace boost { 
namespace lambda {

template<class Key, class T, class Cmp, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, std::map<Key, T, Cmp, Allocator>, B> { 
  typedef T& type;
  // T == std::map<Key, T, Cmp, Allocator>::mapped_type; 
};

template<class Key, class T, class Cmp, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, std::multimap<Key, T, Cmp, Allocator>, B> { 
  typedef T& type;
  // T == std::map<Key, T, Cmp, Allocator>::mapped_type; 
};

  // deque
template<class T, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, std::deque<T, Allocator>, B> { 
  typedef typename std::deque<T, Allocator>::reference type;
};
template<class T, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, const std::deque<T, Allocator>, B> { 
  typedef typename std::deque<T, Allocator>::const_reference type;
};

  // vector
template<class T, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, std::vector<T, Allocator>, B> { 
  typedef typename std::vector<T, Allocator>::reference type;
};
template<class T, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, const std::vector<T, Allocator>, B> { 
  typedef typename std::vector<T, Allocator>::const_reference type;
};

  // basic_string
template<class Char, class Traits, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, std::basic_string<Char, Traits, Allocator>, B> { 
  typedef typename std::basic_string<Char, Traits, Allocator>::reference type;
};
template<class Char, class Traits, class Allocator, class B> 
struct plain_return_type_2<other_action<subscript_action>, const std::basic_string<Char, Traits, Allocator>, B> { 
  typedef typename std::basic_string<Char, Traits, Allocator>::const_reference type;
};


} // namespace lambda
} // namespace boost

#endif


⌨️ 快捷键说明

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