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 + -
显示快捷键?