operator_return_type_traits.hpp

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

HPP
943
字号
  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 actiontemplate<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_STREAMStemplate<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;};#elsetemplate <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// ostreamtemplate<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;};// istreamtemplate<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 typestemplate <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 happytemplate<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 detailtemplate<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) && defined(_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>#elsenamespace std {  template <class T, class Allocator> class deque;}#endifnamespace 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;}#endifnamespace 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; };  // dequetemplate<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;};  // vectortemplate<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_stringtemplate<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 + =
减小字号Ctrl + -
显示快捷键?