From ad1ddddaf4a1229832601f16eecd62d2084b0a2b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2015 19:12:55 +0300 Subject: [PATCH 01/14] New implementation of common_type. --- include/boost/type_traits/common_type.hpp | 208 ++++------- include/boost/type_traits/copy_cv.hpp | 34 ++ .../detail/common_arithmetic_type.hpp | 212 +++++++++++ .../type_traits/detail/common_type_imp.hpp | 333 ------------------ .../type_traits/detail/common_type_impl.hpp | 112 ++++++ .../detail/composite_member_pointer_type.hpp | 105 ++++++ .../detail/composite_pointer_type.hpp | 145 ++++++++ include/boost/type_traits/tp_identity.hpp | 22 ++ 8 files changed, 696 insertions(+), 475 deletions(-) create mode 100644 include/boost/type_traits/copy_cv.hpp create mode 100644 include/boost/type_traits/detail/common_arithmetic_type.hpp delete mode 100644 include/boost/type_traits/detail/common_type_imp.hpp create mode 100644 include/boost/type_traits/detail/common_type_impl.hpp create mode 100644 include/boost/type_traits/detail/composite_member_pointer_type.hpp create mode 100644 include/boost/type_traits/detail/composite_pointer_type.hpp create mode 100644 include/boost/type_traits/tp_identity.hpp 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 From 2b957cfd55429a1e900a25497cb145a91ee63adb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2015 19:19:55 +0300 Subject: [PATCH 02/14] Add missing include of boost/config.hpp. --- include/boost/type_traits/common_type.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/type_traits/common_type.hpp b/include/boost/type_traits/common_type.hpp index 954c723..cf733f3 100644 --- a/include/boost/type_traits/common_type.hpp +++ b/include/boost/type_traits/common_type.hpp @@ -9,6 +9,7 @@ // http://www.boost.org/LICENSE_1_0.txt // +#include #include #include From 5fcc741db4cc1cc0e8bbd4506e7edf9213128069 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2015 21:10:51 +0300 Subject: [PATCH 03/14] Add copy_cv documentation. --- doc/copy_cv.qbk | 39 +++++++++++++++++++++++++++++++++++++++ doc/transform_traits.qbk | 3 +++ doc/type_traits.qbk | 3 +++ 3 files changed, 45 insertions(+) create mode 100644 doc/copy_cv.qbk diff --git a/doc/copy_cv.qbk b/doc/copy_cv.qbk new file mode 100644 index 0000000..9f733a0 --- /dev/null +++ b/doc/copy_cv.qbk @@ -0,0 +1,39 @@ +[/ + 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). +] + +[section:copy_cv copy_cv] + + template + struct copy_cv + { + typedef __below type; + }; + +__type [^T /cv/], where /cv/ are the cv-qualifiers of `U`. + +__header ` #include ` or ` #include ` + +[table Examples + +[ [Expression] [Result Type]] + +[[`copy_cv::type`][`int`]] + +[[`copy_cv::type`][`int const`]] + +[[`copy_cv::type`][`int const`]] + +[[`copy_cv::type`][`int const volatile`]] + +[[`copy_cv::type`] [`int&`]] + +[[`copy_cv::type`] [`int* volatile`]] + +] + +[endsect] + diff --git a/doc/transform_traits.qbk b/doc/transform_traits.qbk index 980ebe4..b96d071 100644 --- a/doc/transform_traits.qbk +++ b/doc/transform_traits.qbk @@ -80,6 +80,9 @@ result of applying the transformation to the template argument `T`. template struct __remove_volatile; + template + struct __copy_cv; + [h4 Broken Compiler Workarounds:] For all of these templates support for partial specialization of class templates is diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 3965809..7924a72 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -132,6 +132,8 @@ [def __decay [link boost_typetraits.reference.decay decay]] [def __is_complex [link boost_typetraits.reference.is_complex is_complex]] +[def __copy_cv [link boost_typetraits.reference.copy_cv copy_cv]] + A printer-friendly [@http://sourceforge.net/projects/boost/files/boost-docs/ PDF version of this manual is also available]. @@ -183,6 +185,7 @@ that is the result of the transformation. [include alignment_of.qbk] [include conditional.qbk] [include common_type.qbk] +[include copy_cv.qbk] [include decay.qbk] [include extent.qbk] [include floating_point_promotion.qbk] From 3d3463b639ef1f4a89ef7ebffc37e00df702e33c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2015 22:18:49 +0300 Subject: [PATCH 04/14] Rename tp_identity to type_identity; add copy_cv.hpp and type_identity.hpp to type_traits.hpp. --- include/boost/type_traits.hpp | 2 ++ include/boost/type_traits/detail/common_type_impl.hpp | 6 +++--- .../boost/type_traits/detail/composite_pointer_type.hpp | 1 - .../type_traits/{tp_identity.hpp => type_identity.hpp} | 8 ++++---- 4 files changed, 9 insertions(+), 8 deletions(-) rename include/boost/type_traits/{tp_identity.hpp => type_identity.hpp} (56%) diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp index 4c9d8eb..0ada915 100644 --- a/include/boost/type_traits.hpp +++ b/include/boost/type_traits.hpp @@ -21,6 +21,7 @@ #include "boost/type_traits/alignment_of.hpp" #include "boost/type_traits/common_type.hpp" #include "boost/type_traits/conditional.hpp" +#include "boost/type_traits/copy_cv.hpp" #include "boost/type_traits/decay.hpp" #include "boost/type_traits/extent.hpp" #include "boost/type_traits/floating_point_promotion.hpp" @@ -91,6 +92,7 @@ #include "boost/type_traits/remove_pointer.hpp" #include "boost/type_traits/remove_reference.hpp" #include "boost/type_traits/remove_volatile.hpp" +#include "boost/type_traits/type_identity.hpp" #include "boost/type_traits/type_with_alignment.hpp" #if !(defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) #include "boost/type_traits/integral_promotion.hpp" diff --git a/include/boost/type_traits/detail/common_type_impl.hpp b/include/boost/type_traits/detail/common_type_impl.hpp index 93f4c1b..c9587b9 100644 --- a/include/boost/type_traits/detail/common_type_impl.hpp +++ b/include/boost/type_traits/detail/common_type_impl.hpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -57,12 +57,12 @@ template struct common_type_impl3; template struct common_type_class: public boost::conditional< boost::is_convertible::value && !boost::is_convertible::value, - boost::tp_identity, + boost::type_identity, typename boost::conditional< boost::is_convertible::value && !boost::is_convertible::value, - boost::tp_identity, + boost::type_identity, common_type_impl3 >::type diff --git a/include/boost/type_traits/detail/composite_pointer_type.hpp b/include/boost/type_traits/detail/composite_pointer_type.hpp index 7e3757f..c807954 100644 --- a/include/boost/type_traits/detail/composite_pointer_type.hpp +++ b/include/boost/type_traits/detail/composite_pointer_type.hpp @@ -10,7 +10,6 @@ // #include -#include #include #include #include diff --git a/include/boost/type_traits/tp_identity.hpp b/include/boost/type_traits/type_identity.hpp similarity index 56% rename from include/boost/type_traits/tp_identity.hpp rename to include/boost/type_traits/type_identity.hpp index bf96810..6d2dd5b 100644 --- a/include/boost/type_traits/tp_identity.hpp +++ b/include/boost/type_traits/type_identity.hpp @@ -1,5 +1,5 @@ -#ifndef BOOST_TYPE_TRAITS_TP_IDENTITY_HPP_INCLUDED -#define BOOST_TYPE_TRAITS_TP_IDENTITY_HPP_INCLUDED +#ifndef BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED // // Copyright 2015 Peter Dimov @@ -12,11 +12,11 @@ namespace boost { -template struct tp_identity +template struct type_identity { typedef T type; }; } // namespace boost -#endif // #ifndef BOOST_TYPE_TRAITS_TP_IDENTITY_HPP_INCLUDED +#endif // #ifndef BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED From d0dbb24fafcabde6347cfc8fd4c599b8b3991ad9 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 00:01:09 +0300 Subject: [PATCH 05/14] Move copy_cv to its alphabetical place. --- doc/transform_traits.qbk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/transform_traits.qbk b/doc/transform_traits.qbk index b96d071..9a7757c 100644 --- a/doc/transform_traits.qbk +++ b/doc/transform_traits.qbk @@ -41,6 +41,9 @@ result of applying the transformation to the template argument `T`. template struct __common_type; + template + struct __copy_cv; + template struct __decay; @@ -80,9 +83,6 @@ result of applying the transformation to the template argument `T`. template struct __remove_volatile; - template - struct __copy_cv; - [h4 Broken Compiler Workarounds:] For all of these templates support for partial specialization of class templates is From 2a645db56ce7f486560db0647d3deadd36565aef Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 00:09:40 +0300 Subject: [PATCH 06/14] Add documentation for type_identity as well. --- doc/transform_traits.qbk | 3 +++ doc/type_identity.qbk | 31 +++++++++++++++++++++++++++++++ doc/type_traits.qbk | 2 ++ 3 files changed, 36 insertions(+) create mode 100644 doc/type_identity.qbk diff --git a/doc/transform_traits.qbk b/doc/transform_traits.qbk index 9a7757c..321a06a 100644 --- a/doc/transform_traits.qbk +++ b/doc/transform_traits.qbk @@ -83,6 +83,9 @@ result of applying the transformation to the template argument `T`. template struct __remove_volatile; + template + struct __type_identity; + [h4 Broken Compiler Workarounds:] For all of these templates support for partial specialization of class templates is diff --git a/doc/type_identity.qbk b/doc/type_identity.qbk new file mode 100644 index 0000000..975653d --- /dev/null +++ b/doc/type_identity.qbk @@ -0,0 +1,31 @@ +[/ + 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). +] + +[section:type_identity type_identity] + + template + struct type_identity + { + typedef T type; + }; + +__header ` #include ` or ` #include ` + +[table Examples + +[ [Expression] [Result Type]] + +[[`type_identity::type`][`int`]] + +[[`type_identity::type`] [`int&`]] + +[[`type_identity::type`] [`int* const&`]] + +] + +[endsect] + diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 7924a72..4e43921 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -133,6 +133,7 @@ [def __is_complex [link boost_typetraits.reference.is_complex is_complex]] [def __copy_cv [link boost_typetraits.reference.copy_cv copy_cv]] +[def __type_identity [link boost_typetraits.reference.type_identity type_identity]] A printer-friendly [@http://sourceforge.net/projects/boost/files/boost-docs/ PDF version of this manual is also available]. @@ -309,6 +310,7 @@ See __has_trivial_constructor. [include remove_pointer.qbk] [include remove_reference.qbk] [include remove_volatile.qbk] +[include type_identity.qbk] [include type_with_alignment.qbk] [endsect] From 987b01b28ca1d07992e836d10d9c0d78c9d2e587 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 00:22:03 +0300 Subject: [PATCH 07/14] Add documentation for declval. --- doc/declval.qbk | 120 +++++--------------------------------------- doc/type_traits.qbk | 2 + 2 files changed, 15 insertions(+), 107 deletions(-) diff --git a/doc/declval.qbk b/doc/declval.qbk index 7bf5cb5..7b151ae 100644 --- a/doc/declval.qbk +++ b/doc/declval.qbk @@ -1,115 +1,21 @@ -[/ - / Copyright (c) 2008 Howard Hinnant - / Copyright (c) 2009-20012 Vicente J. Botet Escriba - / - / 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) - /] - -[article Declval - [quickbook 1.5] - [authors [Hinnant, Howard]] - [authors [Botet Escriba, Vicente J.]] - [copyright 2008 Howard Hinnant] - [copyright 2009-2012 Vicente J. Botet Escriba] - [license - 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]) - ] +[/ + 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). ] -[/===============] -[section Overview] -[/===============] +[section:declval declval] -The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958: -Moving Swap Forward]. Here follows a rewording of this chapter. + template + typename add_rvalue_reference::type declval() noexcept; // as unevaluated operand -With the provision of decltype, late-specified return types, and default template-arguments for function templates a -new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale. -Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration +__std_ref C++11 20.2.4 [declval]. - template - T&& declval(); // not used - -as part of the function template declaration +__header ` #include ` or ` #include ` - template - decltype(static_cast(declval())) convert(From&&); - -or as part of a class template definition - - template class result_of; - - template - struct result_of - { - typedef decltype(declval()(declval()...)) type; - }; - -The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function. -The name is supposed to direct the reader's attention to the fact that the expression `declval()` is an lvalue if and only if -T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to - - template - typename std::add_rvalue_reference::type declval(); // not used - -which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()` -already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C++0x standard. - -The provision of a new library component that allows the production of values in unevaluated expressions is considered -important to realize constrained templates in C++0x where concepts are not available. -This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer. +The function template `declval` is used when a value of a certain type is required in +a type computation context. For example, the type of the result of adding an `int` and +a `float` can be obtained with the expression `decltype( declval() + declval() )`. [endsect] - - -[/=================] -[section:reference Reference ] -[/=================] - -`#include ` - - namespace boost { - - template - typename add_rvalue_reference::type declval() noexcept; // as unevaluated operand - - } // namespace boost - - -The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands. - - template - typename add_rvalue_reference::type declval(); - -[*Remarks:] If this function is used, the program is ill-formed. - -[*Remarks:] The template parameter T of declval may be an incomplete type. - -[*Example:] - - template - decltype(static_cast(declval())) convert(From&&); - -Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To. - -[endsect] - -[/===============] -[section History] -[/===============] - -[heading boost 1.50] - -Fixes: - -* [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval. - - -[endsect] - - - - diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 4e43921..c0046a1 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -134,6 +134,7 @@ [def __copy_cv [link boost_typetraits.reference.copy_cv copy_cv]] [def __type_identity [link boost_typetraits.reference.type_identity type_identity]] +[def __declval [link boost_typetraits.reference.declval declval]] A printer-friendly [@http://sourceforge.net/projects/boost/files/boost-docs/ PDF version of this manual is also available]. @@ -188,6 +189,7 @@ that is the result of the transformation. [include common_type.qbk] [include copy_cv.qbk] [include decay.qbk] +[include declval.qbk] [include extent.qbk] [include floating_point_promotion.qbk] [include function_traits.qbk] From 2180399398816e2223a8b669c82685c3a66474a4 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 00:39:05 +0300 Subject: [PATCH 08/14] Update documentation of common_type a bit. --- doc/common_type.qbk | 88 ++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/doc/common_type.qbk b/doc/common_type.qbk index a34b9bb..801033f 100644 --- a/doc/common_type.qbk +++ b/doc/common_type.qbk @@ -11,83 +11,73 @@ [section:common_type common_type] [/===================================================================] -[def __declval [@../../../utility/doc/html/declval.html declval]] - - __header ` #include ` or ` #include ` namespace boost { - template struct __common_type; + template struct common_type; } -__common_type is a traits class used to deduce a type common to a several types, useful as the return type of functions +`common_type` is a traits class used to deduce a type common to a several types, useful as the return type of functions operating on multiple input types such as in mixed-mode arithmetic.. The nested typedef `::type` could be defined as follows: - template + template struct common_type; - template - struct common_type { - typedef typename __common_type::type, V...>::type type; + template + struct common_type { + typedef typename common_type::type, V...>::type type; + }; + + template <> + struct common_type<> { }; template struct common_type { - typedef T type; + typedef typename __decay::type type; }; template struct common_type { - typedef decltype(__declval() ? __declval() : __declval()) type; + typedef typename __decay< + decltype( __declval()? + __declval::type>(): + __declval::type>() ) + >::type type; }; All parameter types must be complete. This trait is permitted to be specialized by a user if at least one template parameter is a user-defined type. [*Note:] Such specializations are required when only explicit conversions -are desired among the __common_type arguments. +are desired among the `common_type` arguments. -Note that when the compiler does not support variadic templates (and the macro BOOST_NO_VARIADIC_TEMPLATES is defined) -then the maximum number of template arguments is 3. +Note that when the compiler does not support variadic templates (and the macro `BOOST_NO_CXX11_VARIADIC_TEMPLATES` is defined) +then the maximum number of template arguments is 9. -[h4 Configuration macros] - -When the compiler does not support static assertions then the user can select the way static assertions are reported. Define - -* BOOST_COMMON_TYPE_USES_STATIC_ASSERT: define it if you want to use Boost.StaticAssert -* BOOST_COMMON_TYPE_USES_MPL_ASSERT: define it if you want to use Boost.MPL static assertions - -The default behavior is to use mpl assertions in this case, but setting BOOST_COMMON_TYPE_USES_STATIC_ASSERT may reduce -compile times and header dependencies somewhat. - -Depending on the static assertion used you will have an hint of the failing assertion either through the symbol or through the text. - -When possible common_type is implemented using `decltype`. Otherwise when BOOST_COMMON_TYPE_DONT_USE_TYPEOF is not defined -it uses Boost.TypeOf. - [h4 Tutorial] -In a nutshell, __common_type is a trait that takes 1 or more types, and returns a type which +In a nutshell, `common_type` is a trait that takes 1 or more types, and returns a type which all of the types will convert to. The default definition demands this conversion be implicit. However the trait can be specialized for user-defined types which want to limit their inter-type conversions to explicit, -and yet still want to interoperate with the __common_type facility. +and yet still want to interoperate with the `common_type` facility. [*Example:] template - complex::type> + complex::type> operator+(complex, complex); -In the above example, "mixed-mode" complex arithmetic is allowed. The return type is described by __common_type. +In the above example, "mixed-mode" complex arithmetic is allowed. The return type is described by `common_type`. For example the resulting type of adding a `complex` and `complex` might be a `complex`. Here is how someone might produce a variadic comparison function: template - typename __common_type::type + typename common_type::type min(T... t); This is a very useful and broadly applicable utility. @@ -97,17 +87,17 @@ This is a very useful and broadly applicable utility. Another choice for the author of the preceding operator could be template - typename __common_type, complex >::type + typename common_type, complex >::type operator+(complex, complex); -As the default definition of __common_type demands the conversion be implicit, we need to specialize the trait for complex types as follows. +As the default definition of `common_type` demands the conversion be implicit, we need to specialize the trait for complex types as follows. template - struct __common_type, complex > { - typedef complex< __common_type > type; + struct common_type, complex > { + typedef complex< common_type > type; }; -[h4 How important is the order of the common_type<> template arguments?] +[h4 How important is the order of the `common_type<>` template arguments?] The order of the template parameters is important. @@ -164,7 +154,7 @@ Clients wanting to ask `common_type` in any order and get the same resu This is needed as the specialization of `common_type` is not be used implicitly for `common_type`. -[h4 Can the common_type of two types be a third type?] +[h4 Can the `common_type` of two types be a third type?] Given the preceding example, one might expect `common_type::type` to be `C` without any intervention from the user. But the default `common_type<>` implementation doesn't grant that. It is intended that clients who wish for `common_type` @@ -183,7 +173,7 @@ to be well defined to define it themselves: Now this client can ask for `common_type`. -[h4 How common_type behaves with pointers?] +[h4 How does `common_type` behave with pointers?] Consider @@ -209,17 +199,17 @@ But in the absence of a motivating use cases, we prefer not to add more than the Of course the user can always make this specialization. -[h4 Can you explain the pros/cons of common_type against Boost.Typeof?] +[h4 Can you explain the pros/cons of `common_type` against Boost.Typeof?] -Even if they appear to be close, `__common_type` and `typeof` have +Even if they appear to be close, `common_type` and `typeof` have different purposes. You use `typeof` to get the type of an expression, while -you use __common_type to set explicitly the type returned of a template -function. Both are complementary, and indeed __common_type is equivalent to -`decltype(__declval() ? __declval() : __declval())` +you use `common_type` to set explicitly the type returned of a template +function. Both are complementary, and indeed `common_type` is approximately equivalent to +`decltype(__declval() ? __declval() : __declval())`. -__common_type is also similar to promote_args in boost/math/tools/promotion.hpp, -though it is not exactly the same as promote_args either. __common_type::type simply represents the result of some -operation on T1 and T2, and defaults to the type obtained by putting T1 and T2 into a conditional statement. +`common_type` is also similar to `promote_args` in `boost/math/tools/promotion.hpp`, +though it is not exactly the same as `promote_args` either. `common_type::type` simply represents the result of some +operation on `T1` and `T2`, and defaults to the type obtained by putting `T1` and `T2` into a conditional statement. It is meant to be customizable (via specialization) if this default is not appropriate. From bc89aa61607a67720bb31f725133969155a928e8 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 00:54:19 +0300 Subject: [PATCH 09/14] Add a type_identity test. --- test/type_identity_test.cpp | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 test/type_identity_test.cpp diff --git a/test/type_identity_test.cpp b/test/type_identity_test.cpp new file mode 100644 index 0000000..acc3061 --- /dev/null +++ b/test/type_identity_test.cpp @@ -0,0 +1,60 @@ + +// (C) Copyright John Maddock 2000. +// (C) Copyright Peter Dimov 2015. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt) + +#include "test.hpp" +#include "check_type.hpp" +#ifdef TEST_STD +# include +#else +# include +#endif + +BOOST_DECL_TRANSFORM_TEST(type_identity_test_1, ::tt::type_identity, const, const) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_2, ::tt::type_identity, volatile, volatile) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_3, ::tt::type_identity, const volatile, const volatile) +BOOST_DECL_TRANSFORM_TEST0(type_identity_test_4, ::tt::type_identity) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_5, ::tt::type_identity, [], []) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_6, ::tt::type_identity, *const, *const) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_7, ::tt::type_identity, *volatile, *volatile) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_8, ::tt::type_identity, *const volatile, *const volatile) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_9, ::tt::type_identity, *, *) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_10, ::tt::type_identity, *, *) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_11, ::tt::type_identity, volatile*, volatile*) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_12, ::tt::type_identity, const[2], const[2]) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_13, ::tt::type_identity, volatile[2], volatile[2]) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_14, ::tt::type_identity, const volatile[2], const volatile[2]) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_15, ::tt::type_identity, [2], [2]) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_16, ::tt::type_identity, const*, const*) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_17, ::tt::type_identity, const*volatile, const*volatile) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_18, ::tt::type_identity, (), ()) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_19, ::tt::type_identity, (int), (int)) +BOOST_DECL_TRANSFORM_TEST(type_identity_test_20, ::tt::type_identity, (*const)(), (*const)()) + +TT_TEST_BEGIN(type_identity) + + type_identity_test_1(); + type_identity_test_2(); + type_identity_test_3(); + type_identity_test_4(); + type_identity_test_5(); + type_identity_test_6(); + type_identity_test_7(); + type_identity_test_8(); + type_identity_test_9(); + type_identity_test_10(); + type_identity_test_11(); + type_identity_test_12(); + type_identity_test_13(); + type_identity_test_14(); + type_identity_test_15(); + type_identity_test_16(); + type_identity_test_17(); + type_identity_test_18(); + type_identity_test_19(); + type_identity_test_20(); + +TT_TEST_END From b0f96746498975d3f6ffa2a7a3b87adf2bd10bfd Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 01:08:18 +0300 Subject: [PATCH 10/14] Add a test for copy_cv. --- test/copy_cv_test.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/copy_cv_test.cpp diff --git a/test/copy_cv_test.cpp b/test/copy_cv_test.cpp new file mode 100644 index 0000000..2f4f281 --- /dev/null +++ b/test/copy_cv_test.cpp @@ -0,0 +1,44 @@ + +// Copyright Peter Dimov 2015 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt) + +#include "test.hpp" +#include "check_type.hpp" +#ifdef TEST_STD +# include +#else +# include +#endif +#include + +TT_TEST_BEGIN(copy_cv) +{ + BOOST_CHECK_TYPE3(tt::copy_cv::type, int); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + + BOOST_CHECK_TYPE3(tt::copy_cv::type, int volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const volatile); + + BOOST_CHECK_TYPE3(tt::copy_cv::type, int&); + + BOOST_CHECK_TYPE3(tt::copy_cv::type, int const* volatile); + + BOOST_CHECK_TYPE3(tt::copy_cv::type, long); +} +TT_TEST_END From 01493e4acbe1417cdc9bb361f450916bc00c94cc Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 01:34:06 +0300 Subject: [PATCH 11/14] Add a few more common_type tests. --- test/common_type_3_test.cpp | 22 ++++++++++++++ test/common_type_4_test.cpp | 57 +++++++++++++++++++++++++++++++++++++ test/common_type_5_test.cpp | 56 ++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 test/common_type_3_test.cpp create mode 100644 test/common_type_4_test.cpp create mode 100644 test/common_type_5_test.cpp diff --git a/test/common_type_3_test.cpp b/test/common_type_3_test.cpp new file mode 100644 index 0000000..fd228b8 --- /dev/null +++ b/test/common_type_3_test.cpp @@ -0,0 +1,22 @@ + +// Copyright Peter Dimov 2015 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt) + +#include "test.hpp" +#include "check_type.hpp" +#ifdef TEST_STD +# include +#else +# include +#endif +#include + +TT_TEST_BEGIN(common_type_3) +{ + // just check whether the nullary specialization compiles + tt::common_type<> tmp; + (void)tmp; +} +TT_TEST_END diff --git a/test/common_type_4_test.cpp b/test/common_type_4_test.cpp new file mode 100644 index 0000000..3a6659f --- /dev/null +++ b/test/common_type_4_test.cpp @@ -0,0 +1,57 @@ + +// Copyright Peter Dimov 2015 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt) + +#include "test.hpp" +#include "check_type.hpp" +#ifdef TEST_STD +# include +#else +# include +#endif +#include + +TT_TEST_BEGIN(common_type_4) +{ + // the unary case should be the same as decay + + BOOST_CHECK_TYPE(tt::common_type::type, void); + BOOST_CHECK_TYPE(tt::common_type::type, void); + BOOST_CHECK_TYPE(tt::common_type::type, void); + BOOST_CHECK_TYPE(tt::common_type::type, void); + + BOOST_CHECK_TYPE(tt::common_type::type, char); + BOOST_CHECK_TYPE(tt::common_type::type, char); + BOOST_CHECK_TYPE(tt::common_type::type, char); + BOOST_CHECK_TYPE(tt::common_type::type, char); + + BOOST_CHECK_TYPE(tt::common_type::type, char); + BOOST_CHECK_TYPE(tt::common_type::type, char); + BOOST_CHECK_TYPE(tt::common_type::type, char); + BOOST_CHECK_TYPE(tt::common_type::type, char); + + BOOST_CHECK_TYPE(tt::common_type::type, char*); + BOOST_CHECK_TYPE(tt::common_type::type, char const*); + BOOST_CHECK_TYPE(tt::common_type::type, char volatile*); + BOOST_CHECK_TYPE(tt::common_type::type, char const volatile*); + + BOOST_CHECK_TYPE(tt::common_type::type, char*); + BOOST_CHECK_TYPE(tt::common_type::type, char const*); + BOOST_CHECK_TYPE(tt::common_type::type, char volatile*); + BOOST_CHECK_TYPE(tt::common_type::type, char const volatile*); + + BOOST_CHECK_TYPE(tt::common_type::type, char*); + BOOST_CHECK_TYPE(tt::common_type::type, char const*); + BOOST_CHECK_TYPE(tt::common_type::type, char volatile*); + BOOST_CHECK_TYPE(tt::common_type::type, char const volatile*); + + BOOST_CHECK_TYPE(tt::common_type::type, char(*)()); + + BOOST_CHECK_TYPE(tt::common_type::type, UDT(*)()); + BOOST_CHECK_TYPE(tt::common_type::type, UDT const(*)()); + BOOST_CHECK_TYPE(tt::common_type::type, UDT volatile(*)()); + BOOST_CHECK_TYPE(tt::common_type::type, UDT const volatile(*)()); +} +TT_TEST_END diff --git a/test/common_type_5_test.cpp b/test/common_type_5_test.cpp new file mode 100644 index 0000000..0a0e237 --- /dev/null +++ b/test/common_type_5_test.cpp @@ -0,0 +1,56 @@ + +// Copyright Peter Dimov 2015 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.tt.org/LICENSE_1_0.txt) + +#include "test.hpp" +#include "check_type.hpp" +#ifdef TEST_STD +# include +#else +# include +#endif +#include + +template struct X +{ + T t_; + + X(): t_() {} + template X( X const & x ): t_( x.t_ ) {} +}; + +namespace boost +{ + + template struct common_type< X, X > + { + typedef X::type> type; + }; + +} // namespace boost + +TT_TEST_BEGIN(common_type_5) +{ + // user specializations, binary + + BOOST_CHECK_TYPE3( tt::common_type< X, X >::type, X ); + + BOOST_CHECK_TYPE3( tt::common_type< X&, X& >::type, X ); + BOOST_CHECK_TYPE3( tt::common_type< X&, X const& >::type, X ); + BOOST_CHECK_TYPE3( tt::common_type< X const&, X& >::type, X ); + BOOST_CHECK_TYPE3( tt::common_type< X const&, X const& >::type, X ); + + BOOST_CHECK_TYPE3( tt::common_type< X, X >::type, X ); + + BOOST_CHECK_TYPE3( tt::common_type< X&, X& >::type, X ); + BOOST_CHECK_TYPE3( tt::common_type< X&, X const& >::type, X ); + BOOST_CHECK_TYPE3( tt::common_type< X const&, X& >::type, X ); + BOOST_CHECK_TYPE3( tt::common_type< X const&, X const& >::type, X ); + + // ternary + + BOOST_CHECK_TYPE4( tt::common_type< X&, X const&, X volatile& >::type, X ); +} +TT_TEST_END From 7cb0e840f1b408d62ce4328da3e5e55a23f0616d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 01:55:17 +0300 Subject: [PATCH 12/14] Moved utility/declval.hpp to type_traits/declval.hpp. --- include/boost/type_traits.hpp | 1 + include/boost/type_traits/common_type.hpp | 2 +- include/boost/type_traits/declval.hpp | 44 +++++++++++++++++++ include/boost/type_traits/is_convertible.hpp | 2 +- .../boost/type_traits/is_copy_assignable.hpp | 2 +- .../type_traits/is_copy_constructible.hpp | 2 +- .../is_nothrow_move_assignable.hpp | 2 +- .../is_nothrow_move_constructible.hpp | 2 +- include/boost/utility/declval.hpp | 33 +------------- 9 files changed, 52 insertions(+), 38 deletions(-) create mode 100644 include/boost/type_traits/declval.hpp diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp index 0ada915..8f5f5ca 100644 --- a/include/boost/type_traits.hpp +++ b/include/boost/type_traits.hpp @@ -23,6 +23,7 @@ #include "boost/type_traits/conditional.hpp" #include "boost/type_traits/copy_cv.hpp" #include "boost/type_traits/decay.hpp" +#include "boost/type_traits/declval.hpp" #include "boost/type_traits/extent.hpp" #include "boost/type_traits/floating_point_promotion.hpp" #include "boost/type_traits/function_traits.hpp" diff --git a/include/boost/type_traits/common_type.hpp b/include/boost/type_traits/common_type.hpp index cf733f3..33ac158 100644 --- a/include/boost/type_traits/common_type.hpp +++ b/include/boost/type_traits/common_type.hpp @@ -11,7 +11,7 @@ #include #include -#include +#include #if defined(BOOST_NO_CXX11_DECLTYPE) #include diff --git a/include/boost/type_traits/declval.hpp b/include/boost/type_traits/declval.hpp new file mode 100644 index 0000000..a050012 --- /dev/null +++ b/include/boost/type_traits/declval.hpp @@ -0,0 +1,44 @@ +// declval.hpp -------------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED + +#include + +//----------------------------------------------------------------------------// + +#include + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// 20.2.4 Function template declval [declval] // +// Written by Vicente J. Botet Escriba // +// // +// 1 The library provides the function template declval to simplify the +// definition of expressions which occur as unevaluated operands. +// 2 Remarks: If this function is used, the program is ill-formed. +// 3 Remarks: The template parameter T of declval may be an incomplete type. +// [ Example: +// +// template +// decltype(static_cast(declval())) convert(From&&); +// +// declares a function template convert which only participates in overloading +// if the type From can be explicitly converted to type To. For another example +// see class template common_type (20.9.7.6). -end example ] +//----------------------------------------------------------------------------// + +namespace boost { + + template + typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand + +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 6b4aa8d..9854f8b 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -31,7 +31,7 @@ #include #endif #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -# include +# include #endif #elif defined(BOOST_MSVC) || defined(BOOST_INTEL) #include diff --git a/include/boost/type_traits/is_copy_assignable.hpp b/include/boost/type_traits/is_copy_assignable.hpp index a6d19aa..76afdda 100644 --- a/include/boost/type_traits/is_copy_assignable.hpp +++ b/include/boost/type_traits/is_copy_assignable.hpp @@ -18,7 +18,7 @@ && !defined(BOOST_INTEL_CXX_VERSION) && \ !(defined(BOOST_MSVC) && _MSC_VER == 1800) #define BOOST_TT_CXX11_IS_COPY_ASSIGNABLE -#include +#include #else //For compilers without decltype #include diff --git a/include/boost/type_traits/is_copy_constructible.hpp b/include/boost/type_traits/is_copy_constructible.hpp index b26543f..2e80738 100644 --- a/include/boost/type_traits/is_copy_constructible.hpp +++ b/include/boost/type_traits/is_copy_constructible.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include namespace boost { diff --git a/include/boost/type_traits/is_nothrow_move_assignable.hpp b/include/boost/type_traits/is_nothrow_move_assignable.hpp index c0edf37..f45d20c 100644 --- a/include/boost/type_traits/is_nothrow_move_assignable.hpp +++ b/include/boost/type_traits/is_nothrow_move_assignable.hpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include namespace boost { diff --git a/include/boost/type_traits/is_nothrow_move_constructible.hpp b/include/boost/type_traits/is_nothrow_move_constructible.hpp index 09c0d88..323f443 100644 --- a/include/boost/type_traits/is_nothrow_move_constructible.hpp +++ b/include/boost/type_traits/is_nothrow_move_constructible.hpp @@ -31,7 +31,7 @@ template struct is_nothrow_move_constructible : public ::boost::f #elif !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) -#include +#include #include namespace boost{ namespace detail{ diff --git a/include/boost/utility/declval.hpp b/include/boost/utility/declval.hpp index a4ab2c8..229e9a3 100644 --- a/include/boost/utility/declval.hpp +++ b/include/boost/utility/declval.hpp @@ -8,37 +8,6 @@ #ifndef BOOST_UTILITY_DECLVAL_HPP #define BOOST_UTILITY_DECLVAL_HPP -#include - -//----------------------------------------------------------------------------// - -#include - -//----------------------------------------------------------------------------// -// // -// C++03 implementation of // -// 20.2.4 Function template declval [declval] // -// Written by Vicente J. Botet Escriba // -// // -// 1 The library provides the function template declval to simplify the -// definition of expressions which occur as unevaluated operands. -// 2 Remarks: If this function is used, the program is ill-formed. -// 3 Remarks: The template parameter T of declval may be an incomplete type. -// [ Example: -// -// template -// decltype(static_cast(declval())) convert(From&&); -// -// declares a function template convert which only participates in overloading -// if the type From can be explicitly converted to type To. For another example -// see class template common_type (20.9.7.6). -end example ] -//----------------------------------------------------------------------------// - -namespace boost { - - template - typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand - -} // namespace boost +#include #endif // BOOST_UTILITY_DECLVAL_HPP From 971fd13805155bc9bf85d900d05030885ca8c840 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 Jun 2015 02:03:14 +0300 Subject: [PATCH 13/14] Remove unnecessary includes. --- include/boost/type_traits/detail/common_type_impl.hpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/include/boost/type_traits/detail/common_type_impl.hpp b/include/boost/type_traits/detail/common_type_impl.hpp index c9587b9..53a634d 100644 --- a/include/boost/type_traits/detail/common_type_impl.hpp +++ b/include/boost/type_traits/detail/common_type_impl.hpp @@ -1,5 +1,5 @@ -#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP_INCLUDED -#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP_INCLUDED +#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED // // Copyright 2015 Peter Dimov @@ -13,17 +13,12 @@ #include #include #include -#include #include #include -#include #include -#include -#include #include #include #include -#include namespace boost { @@ -109,4 +104,4 @@ template struct common_type_impl5: public common_arithmetic_ty } // namespace boost -#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP_INCLUDED +#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED From ef2d00be2af8ed094d9113a0379fa0e64f082188 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 8 Jun 2015 09:18:00 +0100 Subject: [PATCH 14/14] Use boost::int128_type to avoid GCC warnings. Without this the type_traits tests fail as they use -Werror. --- .../type_traits/detail/common_arithmetic_type.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/type_traits/detail/common_arithmetic_type.hpp b/include/boost/type_traits/detail/common_arithmetic_type.hpp index 9e9a4cb..7211002 100644 --- a/include/boost/type_traits/detail/common_arithmetic_type.hpp +++ b/include/boost/type_traits/detail/common_arithmetic_type.hpp @@ -42,7 +42,7 @@ template<> struct arithmetic_type<3> }; // There are five standard signed integer types: -// “signed char”, “short int”, “int”, “long int”, and “long long int”. +// “signed char”, “short int”, “int”, “long int”, and “long long int”. template<> struct arithmetic_type<4> { @@ -75,8 +75,8 @@ template<> struct arithmetic_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” +// (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> { @@ -152,13 +152,13 @@ template<> struct arithmetic_type<18> template<> struct arithmetic_type<19> { - typedef __int128 type; + typedef boost::int128_type type; typedef char (&result_type) [19]; }; template<> struct arithmetic_type<20> { - typedef unsigned __int128 type; + typedef boost::uint128_type type; typedef char (&result_type) [20]; };