diff --git a/include/boost/type_traits/common_type.hpp b/include/boost/type_traits/common_type.hpp index 6dc955e..954c723 100644 --- a/include/boost/type_traits/common_type.hpp +++ b/include/boost/type_traits/common_type.hpp @@ -1,163 +1,87 @@ -// common_type.hpp ---------------------------------------------------------// - -// Copyright 2008 Howard Hinnant -// Copyright 2008 Beman Dawes +#ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED +// +// Copyright 2015 Peter Dimov +// // Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// -#ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP -#define BOOST_TYPE_TRAITS_COMMON_TYPE_HPP - -#include -#include - -#if defined(__SUNPRO_CC) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) -# define BOOST_COMMON_TYPE_DONT_USE_TYPEOF -#endif -#if defined(__IBMCPP__) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) -# define BOOST_COMMON_TYPE_DONT_USE_TYPEOF -#endif - -#if defined(__GNUC__) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) -// All supported GCC versions (and emulations thereof) support __typeof__ -#define BOOST_COMMON_TYPE_USE_TYPEOF -#endif - -//----------------------------------------------------------------------------// -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_COMMON_TYPE_ARITY) -#define BOOST_COMMON_TYPE_ARITY 3 -#endif - -//----------------------------------------------------------------------------// -#if !defined(BOOST_NO_CXX11_DECLTYPE) -#include -#elif defined(BOOST_COMMON_TYPE_USE_TYPEOF) -#include -#elif defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) -#include -#include -#else -#include // boost wonders never cease! -#include -#include -#endif - -#include #include +#include -//----------------------------------------------------------------------------// -// // -// C++03 implementation of // -// 20.9.7.6 Other transformations [meta.trans.other] // -// Written by Howard Hinnant // -// Adapted for Boost by Beman Dawes, Vicente Botet and Jeffrey Hellrung // -// // -//----------------------------------------------------------------------------// - -namespace boost { - - namespace type_traits_detail { - - template - struct std_decay: boost::remove_cv< - typename boost::decay::type> {}; - - } - -// prototype -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - struct common_type; -#else // or no specialization - template - struct common_type - { - public: - typedef typename common_type::type, V>::type type; - }; +#if defined(BOOST_NO_CXX11_DECLTYPE) +#include #endif +namespace boost +{ + +// variadic common_type -// 1 arg - template #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - struct common_type + +template struct common_type +{ +}; + +template +struct common_type: common_type::type, T...> +{ +}; + #else - struct common_type -#endif - { - BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "The template arguments to common_type must be complete types"); - public: - typedef typename type_traits_detail::std_decay::type type; - }; +template< + class T1 = void, class T2 = void, class T3 = void, + class T4 = void, class T5 = void, class T6 = void, + class T7 = void, class T8 = void, class T9 = void +> +struct common_type: common_type::type, T3, T4, T5, T6, T7, T8, T9> +{ +}; -// 2 args -namespace type_traits_detail { +#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - struct common_type_2 - { - private: - BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "The template arguments to common_type must be complete types"); - BOOST_STATIC_ASSERT_MSG(sizeof(U) > 0, "The template arguments to common_type must be complete types"); +// one argument + +template struct common_type: boost::decay +{ +}; + +// two arguments + +namespace type_traits_detail +{ + +// binary common_type #if !defined(BOOST_NO_CXX11_DECLTYPE) - public: - typedef typename std_decay() ? declval() : declval())>::type type; -#elif defined(BOOST_COMMON_TYPE_USE_TYPEOF) - static typename add_rvalue_reference::type declval_T(); // workaround gcc bug; not required by std - static typename add_rvalue_reference::type declval_U(); // workaround gcc bug; not required by std - static typename add_rvalue_reference::type declval_b(); - public: - typedef typename std_decay<__typeof__(declval_b() ? declval_T() : declval_U())>::type type; -#elif defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) - public: - typedef typename detail_type_traits_common_type::common_type_impl< - typename remove_cv::type, - typename remove_cv::type - >::type type; -#else - static typename add_rvalue_reference::type declval_T(); // workaround gcc bug; not required by std - static typename add_rvalue_reference::type declval_U(); // workaround gcc bug; not required by std - static typename add_rvalue_reference::type declval_b(); - public: - typedef typename std_decay::type type; -#endif -#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 3 - public: - void public_dummy_function_just_to_silence_warning(); -#endif - }; +template struct common_type_impl: boost::decay()? boost::declval(): boost::declval() )> +{ +}; - template - struct common_type_2 - { - typedef typename type_traits_detail::std_decay::type type; - }; - } +#endif // #if !defined(BOOST_NO_CXX11_DECLTYPE) -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - struct common_type -#else - template - struct common_type -#endif - : public type_traits_detail::common_type_2 - { }; +// decay helper +template::type, class T2d = typename boost::decay::type> struct common_type_decay_helper: boost::common_type +{ +}; -// 3 or more args -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - struct common_type { - public: - typedef typename common_type::type, V...>::type type; - }; -#endif -} // namespace boost +template struct common_type_decay_helper: common_type_impl +{ +}; -#endif // BOOST_TYPE_TRAITS_COMMON_TYPE_HPP +} // type_traits_detail + +template struct common_type: type_traits_detail::common_type_decay_helper +{ +}; + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED diff --git a/include/boost/type_traits/copy_cv.hpp b/include/boost/type_traits/copy_cv.hpp new file mode 100644 index 0000000..1605ca3 --- /dev/null +++ b/include/boost/type_traits/copy_cv.hpp @@ -0,0 +1,34 @@ +#ifndef BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED + +// +// Copyright 2015 Peter Dimov +// +// 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 +// + +#include +#include +#include +#include +#include + +namespace boost +{ + +template struct copy_cv +{ +private: + + typedef typename boost::conditional::value, typename boost::add_const::type, T>::type CT; + +public: + + typedef typename boost::conditional::value, typename boost::add_volatile::type, CT>::type type; +}; + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED diff --git a/include/boost/type_traits/detail/common_arithmetic_type.hpp b/include/boost/type_traits/detail/common_arithmetic_type.hpp new file mode 100644 index 0000000..9e9a4cb --- /dev/null +++ b/include/boost/type_traits/detail/common_arithmetic_type.hpp @@ -0,0 +1,212 @@ +#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED + +// +// Copyright 2015 Peter Dimov +// +// 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 +// + +#include + +namespace boost +{ + +namespace type_traits_detail +{ + +template struct arithmetic_type; + +// Types bool, char, char16_t, char32_t, wchar_t, +// and the signed and unsigned integer types are +// collectively called integral types + +template<> struct arithmetic_type<1> +{ + typedef bool type; + typedef char (&result_type) [1]; +}; + +template<> struct arithmetic_type<2> +{ + typedef char type; + typedef char (&result_type) [2]; +}; + +template<> struct arithmetic_type<3> +{ + typedef wchar_t type; + typedef char (&result_type) [3]; +}; + +// There are five standard signed integer types: +// “signed char”, “short int”, “int”, “long int”, and “long long int”. + +template<> struct arithmetic_type<4> +{ + typedef signed char type; + typedef char (&result_type) [4]; +}; + +template<> struct arithmetic_type<5> +{ + typedef short type; + typedef char (&result_type) [5]; +}; + +template<> struct arithmetic_type<6> +{ + typedef int type; + typedef char (&result_type) [6]; +}; + +template<> struct arithmetic_type<7> +{ + typedef long type; + typedef char (&result_type) [7]; +}; + +template<> struct arithmetic_type<8> +{ + typedef boost::long_long_type type; + typedef char (&result_type) [8]; +}; + +// For each of the standard signed integer types, there exists a corresponding +// (but different) standard unsigned integer type: “unsigned char”, “unsigned short int”, +// “unsigned int”, “unsigned long int”, and “unsigned long long int” + +template<> struct arithmetic_type<9> +{ + typedef unsigned char type; + typedef char (&result_type) [9]; +}; + +template<> struct arithmetic_type<10> +{ + typedef unsigned short type; + typedef char (&result_type) [10]; +}; + +template<> struct arithmetic_type<11> +{ + typedef unsigned int type; + typedef char (&result_type) [11]; +}; + +template<> struct arithmetic_type<12> +{ + typedef unsigned long type; + typedef char (&result_type) [12]; +}; + +template<> struct arithmetic_type<13> +{ + typedef boost::ulong_long_type type; + typedef char (&result_type) [13]; +}; + +// There are three floating point types: float, double, and long double. + +template<> struct arithmetic_type<14> +{ + typedef float type; + typedef char (&result_type) [14]; +}; + +template<> struct arithmetic_type<15> +{ + typedef double type; + typedef char (&result_type) [15]; +}; + +template<> struct arithmetic_type<16> +{ + typedef long double type; + typedef char (&result_type) [16]; +}; + +#if !defined( BOOST_NO_CXX11_CHAR16_T ) + +template<> struct arithmetic_type<17> +{ + typedef char16_t type; + typedef char (&result_type) [17]; +}; + +#endif + +#if !defined( BOOST_NO_CXX11_CHAR32_T ) + +template<> struct arithmetic_type<18> +{ + typedef char32_t type; + typedef char (&result_type) [18]; +}; + +#endif + +#if defined( BOOST_HAS_INT128 ) + +template<> struct arithmetic_type<19> +{ + typedef __int128 type; + typedef char (&result_type) [19]; +}; + +template<> struct arithmetic_type<20> +{ + typedef unsigned __int128 type; + typedef char (&result_type) [20]; +}; + +#endif + +template class common_arithmetic_type +{ +private: + + static arithmetic_type<1>::result_type select( arithmetic_type<1>::type ); + static arithmetic_type<2>::result_type select( arithmetic_type<2>::type ); + static arithmetic_type<3>::result_type select( arithmetic_type<3>::type ); + static arithmetic_type<4>::result_type select( arithmetic_type<4>::type ); + static arithmetic_type<5>::result_type select( arithmetic_type<5>::type ); + static arithmetic_type<6>::result_type select( arithmetic_type<6>::type ); + static arithmetic_type<7>::result_type select( arithmetic_type<7>::type ); + static arithmetic_type<8>::result_type select( arithmetic_type<8>::type ); + static arithmetic_type<9>::result_type select( arithmetic_type<9>::type ); + static arithmetic_type<10>::result_type select( arithmetic_type<10>::type ); + static arithmetic_type<11>::result_type select( arithmetic_type<11>::type ); + static arithmetic_type<12>::result_type select( arithmetic_type<12>::type ); + static arithmetic_type<13>::result_type select( arithmetic_type<13>::type ); + static arithmetic_type<14>::result_type select( arithmetic_type<14>::type ); + static arithmetic_type<15>::result_type select( arithmetic_type<15>::type ); + static arithmetic_type<16>::result_type select( arithmetic_type<16>::type ); + +#if !defined( BOOST_NO_CXX11_CHAR16_T ) + static arithmetic_type<17>::result_type select( arithmetic_type<17>::type ); +#endif + +#if !defined( BOOST_NO_CXX11_CHAR32_T ) + static arithmetic_type<18>::result_type select( arithmetic_type<18>::type ); +#endif + +#if defined( BOOST_HAS_INT128 ) + static arithmetic_type<19>::result_type select( arithmetic_type<19>::type ); + static arithmetic_type<20>::result_type select( arithmetic_type<20>::type ); +#endif + + static bool cond(); + +public: + + typedef typename arithmetic_type< sizeof(select( cond()? T(): U() )) >::type type; +}; + +} // namespace type_traits_detail + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED diff --git a/include/boost/type_traits/detail/common_type_imp.hpp b/include/boost/type_traits/detail/common_type_imp.hpp deleted file mode 100644 index 84de8b4..0000000 --- a/include/boost/type_traits/detail/common_type_imp.hpp +++ /dev/null @@ -1,333 +0,0 @@ -/******************************************************************************* - * boost/type_traits/detail/common_type_imp.hpp - * - * Copyright 2010, Jeffrey Hellrung. - * 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) - * - * struct boost::common_type - * - * common_type::type is the type of the expression - * b() ? x() : y() - * where b() returns a bool, x() has return type T, and y() has return type U. - * See - * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm#common_type - * - * Note that this evaluates to void if one or both of T and U is void. - ******************************************************************************/ - -#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMP_HPP -#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMP_HPP - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost -{ - -namespace detail_type_traits_common_type -{ - -/******************************************************************************* - * struct propagate_cv< From, To > - * - * This metafunction propagates cv-qualifiers on type From to type To. - ******************************************************************************/ - -template< class From, class To > -struct propagate_cv -{ typedef To type; }; -template< class From, class To > -struct propagate_cv< const From, To > -{ typedef To const type; }; -template< class From, class To > -struct propagate_cv< volatile From, To > -{ typedef To volatile type; }; -template< class From, class To > -struct propagate_cv< const volatile From, To > -{ typedef To const volatile type; }; - -/******************************************************************************* - * struct is_integral_or_enum - * - * This metafunction determines if T is an integral type which can be made - * signed or unsigned. - ******************************************************************************/ - -template< class T > -struct is_integral_or_enum - : public mpl::or_< is_integral, is_enum > -{ }; -template<> -struct is_integral_or_enum< bool > - : public false_type -{ }; - -/******************************************************************************* - * struct make_unsigned_soft - * struct make_signed_soft - * - * These metafunction are identical to make_unsigned and make_signed, - * respectively, except for special-casing bool. - ******************************************************************************/ - -template< class T > -struct make_unsigned_soft - : public make_unsigned -{ }; -template<> -struct make_unsigned_soft< bool > -{ typedef bool type; }; - -template< class T > -struct make_signed_soft - : public make_signed -{ }; -template<> -struct make_signed_soft< bool > -{ typedef bool type; }; - -/******************************************************************************* - * struct sizeof_t - * typedef ... yes_type - * typedef ... no_type - * - * These types are integral players in the use of the "sizeof trick", i.e., we - * can distinguish overload selection by inspecting the size of the return type - * of the overload. - ******************************************************************************/ - -template< std::size_t N > struct sizeof_t { char _dummy[N]; }; -typedef sizeof_t<1> yes_type; -typedef sizeof_t<2> no_type; -BOOST_MPL_ASSERT_RELATION( sizeof( yes_type ), ==, 1 ); -BOOST_MPL_ASSERT_RELATION( sizeof( no_type ), ==, 2 ); - -/******************************************************************************* - * rvalue_test(T&) -> no_type - * rvalue_test(...) -> yes_type - * - * These overloads are used to determine the rvalue-ness of an expression. - ******************************************************************************/ - -template< class T > no_type rvalue_test(T&); -yes_type rvalue_test(...); - -/******************************************************************************* - * struct conversion_test_overloads< Sequence > - * - * This struct has multiple overloads of the static member function apply, each - * one taking a single parameter of a type within the Boost.MPL sequence - * Sequence. Each such apply overload has a return type with sizeof equal to - * one plus the index of the parameter type within Sequence. Thus, we can - * deduce the type T of an expression as long as we can generate a finite set of - * candidate types containing T via these apply overloads and the "sizeof - * trick". - ******************************************************************************/ - -template< class First, class Last, std::size_t Index > -struct conversion_test_overloads_iterate - : public conversion_test_overloads_iterate< - typename mpl::next< First >::type, Last, Index + 1 - > -{ - using conversion_test_overloads_iterate< - typename mpl::next< First >::type, Last, Index + 1 - >::apply; - static sizeof_t< Index + 1 > - apply(typename mpl::deref< First >::type); -}; - -template< class Last, std::size_t Index > -struct conversion_test_overloads_iterate< Last, Last, Index > -{ static sizeof_t< Index + 1 > apply(...); }; - -template< class Sequence > -struct conversion_test_overloads - : public conversion_test_overloads_iterate< - typename mpl::begin< Sequence >::type, - typename mpl::end< Sequence >::type, - 0 - > -{ }; - -/******************************************************************************* - * struct select< Sequence, Index > - * - * select is synonymous with mpl::at_c unless Index equals the size of the - * Boost.MPL Sequence, in which case this evaluates to void. - ******************************************************************************/ - -template< - class Sequence, int Index, - int N = mpl::size< Sequence >::value -> -struct select - : public mpl::at_c< Sequence, Index > -{ }; -template< class Sequence, int N > -struct select< Sequence, N, N > -{ typedef void type; }; - -/******************************************************************************* - * class deduce_common_type< T, U, NominalCandidates > - * struct nominal_candidates - * struct common_type_dispatch_on_rvalueness - * struct common_type_impl - * - * These classes and structs implement the logic behind common_type, which goes - * roughly as follows. Let C be the type of the conditional expression - * declval< bool >() ? declval() : declval() - * if C is an rvalue, then: - * let T' and U' be T and U stripped of reference- and cv-qualifiers - * if T' and U' are pointer types, say, T' = V* and U' = W*, then: - * define the set of NominalCandidates to be - * { V*, W*, V'*, W'* } - * where V' is V with whatever cv-qualifiers are on W, and W' is W - * with whatever cv-qualifiers are on V - * else if T' and U' are both integral or enum types, then: - * define the set of NominalCandidates to be - * { - * unsigned_soft(T'), - * unsigned_soft(U'), - * signed_soft(T'), - * signed_soft(U'), - * T', - * U', - * unsigned int, - * int - * } - * where unsigned_soft(X) is make_unsigned_soft::type and - * signed_soft(X) is make_signed_soft::type (these are all - * generally necessary to cover the various integral promotion cases) - * else - * define the set of NominalCandidates to be - * { T', U' } - * else - * let V and W be T and U stripped of reference-qualifiers - * define the set of NominalCandidates to be - * { V&, W&, V'&, W'& } - * where V' is V with whatever cv-qualifiers are on W, and W' is W with - * whatever cv-qualifiers are on V - * define the set of Candidates to be equal to the set of NominalCandidates with - * duplicates removed, and use this set of Candidates to determine C using the - * conversion_test_overloads struct - ******************************************************************************/ - -template< class T, class U, class NominalCandidates > -class deduce_common_type -{ - typedef typename mpl::copy< - NominalCandidates, - mpl::inserter< - mpl::vector0<>, - mpl::if_< - mpl::contains< mpl::_1, mpl::_2 >, - mpl::_1, - mpl::push_back< mpl::_1, mpl::_2 > - > - > - >::type candidate_types; - static const int best_candidate_index = - sizeof( conversion_test_overloads< candidate_types >::apply( - declval< bool >() ? declval() : declval() - ) ) - 1; -public: - typedef typename select< candidate_types, best_candidate_index >::type type; -}; - -template< - class T, class U, - class V = typename remove_cv< typename remove_reference::type >::type, - class W = typename remove_cv< typename remove_reference::type >::type, - bool = is_integral_or_enum::value && is_integral_or_enum::value -> -struct nominal_candidates -{ typedef mpl::vector2 type; }; - -template< class T, class U, class V, class W > -struct nominal_candidates< T, U, V, W, true > -{ - typedef boost::mpl::vector8< - typename make_unsigned_soft::type, - typename make_unsigned_soft::type, - typename make_signed_soft::type, - typename make_signed_soft::type, - V, W, unsigned int, int - > type; -}; - -template< class T, class U, class V, class W > -struct nominal_candidates< T, U, V*, W*, false > -{ - typedef mpl::vector4< - V*, W*, - typename propagate_cv::type *, - typename propagate_cv::type * - > type; -}; - -template -struct common_type_dispatch_on_rvalueness - : public deduce_common_type< T, U, typename nominal_candidates::type > -{ }; - -template< class T, class U > -struct common_type_dispatch_on_rvalueness< T, U, false > -{ -private: - typedef typename remove_reference::type unrefed_T_type; - typedef typename remove_reference::type unrefed_U_type; -public: - typedef typename deduce_common_type< - T, U, - mpl::vector4< - unrefed_T_type &, - unrefed_U_type &, - typename propagate_cv< unrefed_U_type, unrefed_T_type >::type &, - typename propagate_cv< unrefed_T_type, unrefed_U_type >::type & - > - >::type type; -}; - -template< class T, class U > -struct common_type_impl - : public common_type_dispatch_on_rvalueness() ? declval() : declval() ) ) == sizeof( yes_type ) > -{ }; - -template< class T > struct common_type_impl< T, void > { typedef void type; }; -template< class T > struct common_type_impl< void, T > { typedef void type; }; -template<> struct common_type_impl< void, void > { typedef void type; }; - -} // namespace detail_type_traits_common_type - - -} // namespace boost - -#endif // BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP - diff --git a/include/boost/type_traits/detail/common_type_impl.hpp b/include/boost/type_traits/detail/common_type_impl.hpp new file mode 100644 index 0000000..93f4c1b --- /dev/null +++ b/include/boost/type_traits/detail/common_type_impl.hpp @@ -0,0 +1,112 @@ +#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP_INCLUDED + +// +// Copyright 2015 Peter Dimov +// +// 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 +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +namespace type_traits_detail +{ + +// the arguments to common_type_impl have already been passed through decay<> + +template struct common_type_impl; + +// same type + +template struct common_type_impl +{ + typedef T type; +}; + +// one of the operands is a class type, try conversions in both directions + +template struct ct_class +{ + BOOST_STATIC_CONSTANT( bool, ct = boost::is_class::value || boost::is_union::value ); + BOOST_STATIC_CONSTANT( bool, cu = boost::is_class::value || boost::is_union::value ); + + BOOST_STATIC_CONSTANT( bool, value = ct || cu ); +}; + +template struct common_type_impl3; + +template struct common_type_class: public boost::conditional< + + boost::is_convertible::value && !boost::is_convertible::value, + boost::tp_identity, + + typename boost::conditional< + + boost::is_convertible::value && !boost::is_convertible::value, + boost::tp_identity, + + common_type_impl3 + >::type +>::type +{ +}; + +template struct common_type_impl: public boost::conditional< + ct_class::value, + common_type_class, + common_type_impl3 >::type +{ +}; + +// pointers + +template struct common_type_impl4; + +template struct common_type_impl3: public boost::conditional< + boost::is_pointer::value || boost::is_pointer::value, + composite_pointer_type, + common_type_impl4 >::type +{ +}; + +// pointers to members + +template struct common_type_impl5; + +template struct common_type_impl4: public boost::conditional< + boost::is_member_pointer::value || boost::is_member_pointer::value, + composite_member_pointer_type, + common_type_impl5 >::type +{ +}; + +// arithmetic types (including class types w/ conversions to arithmetic and enums) + +template struct common_type_impl5: public common_arithmetic_type +{ +}; + +} // namespace type_traits_detail + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP_INCLUDED diff --git a/include/boost/type_traits/detail/composite_member_pointer_type.hpp b/include/boost/type_traits/detail/composite_member_pointer_type.hpp new file mode 100644 index 0000000..ecb4b68 --- /dev/null +++ b/include/boost/type_traits/detail/composite_member_pointer_type.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED + +// +// Copyright 2015 Peter Dimov +// +// 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 +// + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +namespace type_traits_detail +{ + +template struct composite_member_pointer_type; + +// nullptr_t + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) + +template struct composite_member_pointer_type +{ + typedef T C::* type; +}; + +template struct composite_member_pointer_type +{ + typedef T C::* type; +}; + +template<> struct composite_member_pointer_type +{ + typedef decltype(nullptr) type; +}; + +#else + +template struct composite_member_pointer_type +{ + typedef T C::* type; +}; + +template struct composite_member_pointer_type +{ + typedef T C::* type; +}; + +template<> struct composite_member_pointer_type +{ + typedef std::nullptr_t type; +}; + +#endif + +#endif // !defined( BOOST_NO_CXX11_NULLPTR ) + +template struct common_member_class; + +template struct common_member_class +{ + typedef C type; +}; + +template struct common_member_class +{ + typedef typename boost::conditional< + + boost::is_base_of::value, + C2, + typename boost::conditional::value, C1, void>::type + + >::type type; +}; + +template struct composite_member_pointer_type +{ +private: + + typedef typename composite_pointer_type::type CPT; + typedef typename boost::remove_pointer::type CT; + + typedef typename common_member_class::type CB; + +public: + + typedef CT CB::* type; +}; + +} // namespace type_traits_detail + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED diff --git a/include/boost/type_traits/detail/composite_pointer_type.hpp b/include/boost/type_traits/detail/composite_pointer_type.hpp new file mode 100644 index 0000000..7e3757f --- /dev/null +++ b/include/boost/type_traits/detail/composite_pointer_type.hpp @@ -0,0 +1,145 @@ +#ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED + +// +// Copyright 2015 Peter Dimov +// +// 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 +// + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +namespace type_traits_detail +{ + +template struct composite_pointer_type; + +// same type + +template struct composite_pointer_type +{ + typedef T* type; +}; + +// nullptr_t + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) + +template struct composite_pointer_type +{ + typedef T* type; +}; + +template struct composite_pointer_type +{ + typedef T* type; +}; + +template<> struct composite_pointer_type +{ + typedef decltype(nullptr) type; +}; + +#else + +template struct composite_pointer_type +{ + typedef T* type; +}; + +template struct composite_pointer_type +{ + typedef T* type; +}; + +template<> struct composite_pointer_type +{ + typedef std::nullptr_t type; +}; + +#endif + +#endif // !defined( BOOST_NO_CXX11_NULLPTR ) + +namespace detail +{ + +template struct has_common_pointee +{ +private: + + typedef typename boost::remove_cv::type T2; + typedef typename boost::remove_cv::type U2; + +public: + + BOOST_STATIC_CONSTANT( bool, value = + (boost::is_same::value) + || boost::is_void::value + || boost::is_void::value + || (boost::is_base_of::value) + || (boost::is_base_of::value) ); +}; + +template struct common_pointee +{ +private: + + typedef typename boost::remove_cv::type T2; + typedef typename boost::remove_cv::type U2; + +public: + + typedef typename boost::conditional< + + boost::is_same::value || boost::is_void::value || boost::is_base_of::value, + typename boost::copy_cv::type, + typename boost::copy_cv::type + + >::type type; +}; + +template struct composite_pointer_impl +{ +private: + + typedef typename boost::remove_cv::type T2; + typedef typename boost::remove_cv::type U2; + +public: + + typedef typename boost::copy_cv::type const, T>::type, U>::type type; +}; + +} // detail + +template struct composite_pointer_type +{ + typedef typename boost::conditional< + + detail::has_common_pointee::value, + detail::common_pointee, + detail::composite_pointer_impl + + >::type::type * type; +}; + +} // namespace type_traits_detail + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED diff --git a/include/boost/type_traits/tp_identity.hpp b/include/boost/type_traits/tp_identity.hpp new file mode 100644 index 0000000..bf96810 --- /dev/null +++ b/include/boost/type_traits/tp_identity.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_TYPE_TRAITS_TP_IDENTITY_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_TP_IDENTITY_HPP_INCLUDED + +// +// Copyright 2015 Peter Dimov +// +// 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 +// + +namespace boost +{ + +template struct tp_identity +{ + typedef T type; +}; + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_TP_IDENTITY_HPP_INCLUDED