Merge pull request #13 from boostorg/feature/common_type

New implementation of common_type.
This commit is contained in:
jzmaddock
2015-06-08 09:18:28 +01:00
21 changed files with 982 additions and 511 deletions

View File

@ -21,7 +21,9 @@
#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/declval.hpp"
#include "boost/type_traits/extent.hpp"
#include "boost/type_traits/floating_point_promotion.hpp"
#include "boost/type_traits/function_traits.hpp"
@ -91,6 +93,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"

View File

@ -1,163 +1,88 @@
// 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
#ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP
#define BOOST_TYPE_TRAITS_COMMON_TYPE_HPP
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#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 <boost/utility/declval.hpp>
#elif defined(BOOST_COMMON_TYPE_USE_TYPEOF)
#include <boost/type_traits/add_rvalue_reference.hpp>
#elif defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF)
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/detail/common_type_imp.hpp>
#else
#include <boost/typeof/typeof.hpp> // boost wonders never cease!
#include <boost/type_traits/detail/common_type_imp.hpp>
#include <boost/type_traits/add_rvalue_reference.hpp>
#endif
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/declval.hpp>
//----------------------------------------------------------------------------//
// //
// 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 <class T>
struct std_decay: boost::remove_cv<
typename boost::decay<T>::type> {};
}
// prototype
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename... T>
struct common_type;
#else // or no specialization
template <class T, class U = void, class V = void>
struct common_type
{
public:
typedef typename common_type<typename common_type<T, U>::type, V>::type type;
};
#if defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/type_traits/detail/common_type_impl.hpp>
#endif
namespace boost
{
// variadic common_type
// 1 arg
template<typename T>
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
struct common_type<T>
template<class... T> struct common_type
{
};
template<class T1, class T2, class... T>
struct common_type<T1, T2, T...>: common_type<typename common_type<T1, T2>::type, T...>
{
};
#else
struct common_type<T, void, void>
#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<T>::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<typename common_type<T1, T2>::type, T3, T4, T5, T6, T7, T8, T9>
{
};
// 2 args
namespace type_traits_detail {
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class T, class U>
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<class T> struct common_type<T>: boost::decay<T>
{
};
// two arguments
namespace type_traits_detail
{
// binary common_type
#if !defined(BOOST_NO_CXX11_DECLTYPE)
public:
typedef typename std_decay<decltype(declval<bool>() ? declval<T>() : declval<U>())>::type type;
#elif defined(BOOST_COMMON_TYPE_USE_TYPEOF)
static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std
static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std
static typename add_rvalue_reference<bool>::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<T>::type,
typename remove_cv<U>::type
>::type type;
#else
static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std
static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std
static typename add_rvalue_reference<bool>::type declval_b();
public:
typedef typename std_decay<BOOST_TYPEOF_TPL(declval_b() ? declval_T() : declval_U())>::type type;
#endif
#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 3
public:
void public_dummy_function_just_to_silence_warning();
#endif
};
template<class T1, class T2> struct common_type_impl: boost::decay<decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() )>
{
};
template <class T>
struct common_type_2<T, T>
{
typedef typename type_traits_detail::std_decay<T>::type type;
};
}
#endif // #if !defined(BOOST_NO_CXX11_DECLTYPE)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class T, class U>
struct common_type<T, U>
#else
template <class T, class U>
struct common_type<T, U, void>
#endif
: public type_traits_detail::common_type_2<T,U>
{ };
// decay helper
template<class T1, class T2, class T1d = typename boost::decay<T1>::type, class T2d = typename boost::decay<T2>::type> struct common_type_decay_helper: boost::common_type<T1d, T2d>
{
};
// 3 or more args
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename T, typename U, typename... V>
struct common_type<T, U, V...> {
public:
typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
};
#endif
} // namespace boost
template<class T1, class T2> struct common_type_decay_helper<T1, T2, T1, T2>: common_type_impl<T1, T2>
{
};
#endif // BOOST_TYPE_TRAITS_COMMON_TYPE_HPP
} // type_traits_detail
template<class T1, class T2> struct common_type<T1, T2>: type_traits_detail::common_type_decay_helper<T1, T2>
{
};
} // namespace boost
#endif // #ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED

View File

@ -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 <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_volatile.hpp>
#include <boost/type_traits/conditional.hpp>
namespace boost
{
template<class T, class U> struct copy_cv
{
private:
typedef typename boost::conditional<boost::is_const<U>::value, typename boost::add_const<T>::type, T>::type CT;
public:
typedef typename boost::conditional<boost::is_volatile<U>::value, typename boost::add_volatile<CT>::type, CT>::type type;
};
} // namespace boost
#endif // #ifndef BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED

View File

@ -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 <boost/config.hpp>
//----------------------------------------------------------------------------//
#include <boost/type_traits/add_rvalue_reference.hpp>
//----------------------------------------------------------------------------//
// //
// 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 <class To, class From>
// decltype(static_cast<To>(declval<From>())) 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 T>
typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
} // namespace boost
#endif // BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED

View File

@ -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 <boost/config.hpp>
namespace boost
{
namespace type_traits_detail
{
template<int I> 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 boost::int128_type type;
typedef char (&result_type) [19];
};
template<> struct arithmetic_type<20>
{
typedef boost::uint128_type type;
typedef char (&result_type) [20];
};
#endif
template<class T, class U> 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

View File

@ -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<T,U>
*
* common_type<T,U>::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 <cstddef>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/inserter.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/vector/vector0.hpp>
#include <boost/mpl/vector/vector10.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/make_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
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<T>
*
* 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<T>, is_enum<T> >
{ };
template<>
struct is_integral_or_enum< bool >
: public false_type
{ };
/*******************************************************************************
* struct make_unsigned_soft<T>
* struct make_signed_soft<T>
*
* 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<T>
{ };
template<>
struct make_unsigned_soft< bool >
{ typedef bool type; };
template< class T >
struct make_signed_soft
: public make_signed<T>
{ };
template<>
struct make_signed_soft< bool >
{ typedef bool type; };
/*******************************************************************************
* struct sizeof_t<N>
* 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<T,U>
* struct common_type_dispatch_on_rvalueness<T,U>
* struct common_type_impl<T,U>
*
* 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<T>() : declval<U>()
* 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<X>::type and
* signed_soft(X) is make_signed_soft<X>::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<T>() : declval<U>()
) ) - 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<T>::type >::type,
class W = typename remove_cv< typename remove_reference<U>::type >::type,
bool = is_integral_or_enum<V>::value && is_integral_or_enum<W>::value
>
struct nominal_candidates
{ typedef mpl::vector2<V,W> 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<V>::type,
typename make_unsigned_soft<W>::type,
typename make_signed_soft<V>::type,
typename make_signed_soft<W>::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<W,V>::type *,
typename propagate_cv<V,W>::type *
> type;
};
template<class T, class U, bool b>
struct common_type_dispatch_on_rvalueness
: public deduce_common_type< T, U, typename nominal_candidates<T,U>::type >
{ };
template< class T, class U >
struct common_type_dispatch_on_rvalueness< T, U, false >
{
private:
typedef typename remove_reference<T>::type unrefed_T_type;
typedef typename remove_reference<U>::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<T,U, sizeof( ::boost::detail_type_traits_common_type::rvalue_test(
declval< bool >() ? declval<T>() : declval<U>() ) ) == 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

View File

@ -0,0 +1,107 @@
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_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 <boost/type_traits/detail/common_arithmetic_type.hpp>
#include <boost/type_traits/detail/composite_pointer_type.hpp>
#include <boost/type_traits/detail/composite_member_pointer_type.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_union.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/conditional.hpp>
namespace boost
{
namespace type_traits_detail
{
// the arguments to common_type_impl have already been passed through decay<>
template<class T, class U> struct common_type_impl;
// same type
template<class T> struct common_type_impl<T, T>
{
typedef T type;
};
// one of the operands is a class type, try conversions in both directions
template<class T, class U> struct ct_class
{
BOOST_STATIC_CONSTANT( bool, ct = boost::is_class<T>::value || boost::is_union<T>::value );
BOOST_STATIC_CONSTANT( bool, cu = boost::is_class<U>::value || boost::is_union<U>::value );
BOOST_STATIC_CONSTANT( bool, value = ct || cu );
};
template<class T, class U> struct common_type_impl3;
template<class T, class U> struct common_type_class: public boost::conditional<
boost::is_convertible<T, U>::value && !boost::is_convertible<U, T>::value,
boost::type_identity<U>,
typename boost::conditional<
boost::is_convertible<U, T>::value && !boost::is_convertible<T, U>::value,
boost::type_identity<T>,
common_type_impl3<T, U>
>::type
>::type
{
};
template<class T, class U> struct common_type_impl: public boost::conditional<
ct_class<T, U>::value,
common_type_class<T, U>,
common_type_impl3<T, U> >::type
{
};
// pointers
template<class T, class U> struct common_type_impl4;
template<class T, class U> struct common_type_impl3: public boost::conditional<
boost::is_pointer<T>::value || boost::is_pointer<U>::value,
composite_pointer_type<T, U>,
common_type_impl4<T, U> >::type
{
};
// pointers to members
template<class T, class U> struct common_type_impl5;
template<class T, class U> struct common_type_impl4: public boost::conditional<
boost::is_member_pointer<T>::value || boost::is_member_pointer<U>::value,
composite_member_pointer_type<T, U>,
common_type_impl5<T, U> >::type
{
};
// arithmetic types (including class types w/ conversions to arithmetic and enums)
template<class T, class U> struct common_type_impl5: public common_arithmetic_type<T, U>
{
};
} // namespace type_traits_detail
} // namespace boost
#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED

View File

@ -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 <boost/type_traits/detail/composite_pointer_type.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/config.hpp>
#include <cstddef>
namespace boost
{
namespace type_traits_detail
{
template<class T, class U> 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<class C, class T> struct composite_member_pointer_type<T C::*, decltype(nullptr)>
{
typedef T C::* type;
};
template<class C, class T> struct composite_member_pointer_type<decltype(nullptr), T C::*>
{
typedef T C::* type;
};
template<> struct composite_member_pointer_type<decltype(nullptr), decltype(nullptr)>
{
typedef decltype(nullptr) type;
};
#else
template<class C, class T> struct composite_member_pointer_type<T C::*, std::nullptr_t>
{
typedef T C::* type;
};
template<class C, class T> struct composite_member_pointer_type<std::nullptr_t, T C::*>
{
typedef T C::* type;
};
template<> struct composite_member_pointer_type<std::nullptr_t, std::nullptr_t>
{
typedef std::nullptr_t type;
};
#endif
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
template<class C1, class C2> struct common_member_class;
template<class C> struct common_member_class<C, C>
{
typedef C type;
};
template<class C1, class C2> struct common_member_class
{
typedef typename boost::conditional<
boost::is_base_of<C1, C2>::value,
C2,
typename boost::conditional<boost::is_base_of<C2, C1>::value, C1, void>::type
>::type type;
};
template<class C1, class T1, class C2, class T2> struct composite_member_pointer_type<T1 C1::*, T2 C2::*>
{
private:
typedef typename composite_pointer_type<T1*, T2*>::type CPT;
typedef typename boost::remove_pointer<CPT>::type CT;
typedef typename common_member_class<C1, C2>::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

View File

@ -0,0 +1,144 @@
#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 <boost/type_traits/copy_cv.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/config.hpp>
#include <cstddef>
namespace boost
{
namespace type_traits_detail
{
template<class T, class U> struct composite_pointer_type;
// same type
template<class T> struct composite_pointer_type<T*, T*>
{
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<class T> struct composite_pointer_type<T*, decltype(nullptr)>
{
typedef T* type;
};
template<class T> struct composite_pointer_type<decltype(nullptr), T*>
{
typedef T* type;
};
template<> struct composite_pointer_type<decltype(nullptr), decltype(nullptr)>
{
typedef decltype(nullptr) type;
};
#else
template<class T> struct composite_pointer_type<T*, std::nullptr_t>
{
typedef T* type;
};
template<class T> struct composite_pointer_type<std::nullptr_t, T*>
{
typedef T* type;
};
template<> struct composite_pointer_type<std::nullptr_t, std::nullptr_t>
{
typedef std::nullptr_t type;
};
#endif
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
namespace detail
{
template<class T, class U> struct has_common_pointee
{
private:
typedef typename boost::remove_cv<T>::type T2;
typedef typename boost::remove_cv<U>::type U2;
public:
BOOST_STATIC_CONSTANT( bool, value =
(boost::is_same<T2, U2>::value)
|| boost::is_void<T2>::value
|| boost::is_void<U2>::value
|| (boost::is_base_of<T2, U2>::value)
|| (boost::is_base_of<U2, T2>::value) );
};
template<class T, class U> struct common_pointee
{
private:
typedef typename boost::remove_cv<T>::type T2;
typedef typename boost::remove_cv<U>::type U2;
public:
typedef typename boost::conditional<
boost::is_same<T2, U2>::value || boost::is_void<T2>::value || boost::is_base_of<T2, U2>::value,
typename boost::copy_cv<T, U>::type,
typename boost::copy_cv<U, T>::type
>::type type;
};
template<class T, class U> struct composite_pointer_impl
{
private:
typedef typename boost::remove_cv<T>::type T2;
typedef typename boost::remove_cv<U>::type U2;
public:
typedef typename boost::copy_cv<typename boost::copy_cv<typename composite_pointer_type<T2, U2>::type const, T>::type, U>::type type;
};
} // detail
template<class T, class U> struct composite_pointer_type<T*, U*>
{
typedef typename boost::conditional<
detail::has_common_pointee<T, U>::value,
detail::common_pointee<T, U>,
detail::composite_pointer_impl<T, U>
>::type::type * type;
};
} // namespace type_traits_detail
} // namespace boost
#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED

View File

@ -31,7 +31,7 @@
#include <boost/type_traits/remove_reference.hpp>
#endif
#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
# include <boost/utility/declval.hpp>
# include <boost/type_traits/declval.hpp>
#endif
#elif defined(BOOST_MSVC) || defined(BOOST_INTEL)
#include <boost/type_traits/is_function.hpp>

View File

@ -18,7 +18,7 @@
&& !defined(BOOST_INTEL_CXX_VERSION) && \
!(defined(BOOST_MSVC) && _MSC_VER == 1800)
#define BOOST_TT_CXX11_IS_COPY_ASSIGNABLE
#include <boost/utility/declval.hpp>
#include <boost/type_traits/declval.hpp>
#else
//For compilers without decltype
#include <boost/type_traits/is_const.hpp>

View File

@ -13,7 +13,7 @@
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include <boost/utility/declval.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/noncopyable.hpp>
namespace boost {

View File

@ -17,7 +17,7 @@
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/declval.hpp>
#include <boost/type_traits/declval.hpp>
namespace boost {

View File

@ -31,7 +31,7 @@ template <class T> struct is_nothrow_move_constructible<T&&> : public ::boost::f
#elif !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR)
#include <boost/utility/declval.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost{ namespace detail{

View File

@ -0,0 +1,22 @@
#ifndef BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_TYPE_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<class T> struct type_identity
{
typedef T type;
};
} // namespace boost
#endif // #ifndef BOOST_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED

View File

@ -8,37 +8,6 @@
#ifndef BOOST_UTILITY_DECLVAL_HPP
#define BOOST_UTILITY_DECLVAL_HPP
#include <boost/config.hpp>
//----------------------------------------------------------------------------//
#include <boost/type_traits/add_rvalue_reference.hpp>
//----------------------------------------------------------------------------//
// //
// 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 <class To, class From>
// decltype(static_cast<To>(declval<From>())) 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 T>
typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
} // namespace boost
#include <boost/type_traits/declval.hpp>
#endif // BOOST_UTILITY_DECLVAL_HPP

View File

@ -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 <type_traits>
#else
# include <boost/type_traits/common_type.hpp>
#endif
#include <iostream>
TT_TEST_BEGIN(common_type_3)
{
// just check whether the nullary specialization compiles
tt::common_type<> tmp;
(void)tmp;
}
TT_TEST_END

View File

@ -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 <type_traits>
#else
# include <boost/type_traits/common_type.hpp>
#endif
#include <iostream>
TT_TEST_BEGIN(common_type_4)
{
// the unary case should be the same as decay
BOOST_CHECK_TYPE(tt::common_type<void>::type, void);
BOOST_CHECK_TYPE(tt::common_type<void const>::type, void);
BOOST_CHECK_TYPE(tt::common_type<void volatile>::type, void);
BOOST_CHECK_TYPE(tt::common_type<void const volatile>::type, void);
BOOST_CHECK_TYPE(tt::common_type<char>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char const>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char volatile>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char const volatile>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char&>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char const&>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char volatile&>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char const volatile&>::type, char);
BOOST_CHECK_TYPE(tt::common_type<char[]>::type, char*);
BOOST_CHECK_TYPE(tt::common_type<char const[]>::type, char const*);
BOOST_CHECK_TYPE(tt::common_type<char volatile[]>::type, char volatile*);
BOOST_CHECK_TYPE(tt::common_type<char const volatile[]>::type, char const volatile*);
BOOST_CHECK_TYPE(tt::common_type<char[2]>::type, char*);
BOOST_CHECK_TYPE(tt::common_type<char const[2]>::type, char const*);
BOOST_CHECK_TYPE(tt::common_type<char volatile[2]>::type, char volatile*);
BOOST_CHECK_TYPE(tt::common_type<char const volatile[2]>::type, char const volatile*);
BOOST_CHECK_TYPE(tt::common_type<char (&) [2]>::type, char*);
BOOST_CHECK_TYPE(tt::common_type<char const (&) [2]>::type, char const*);
BOOST_CHECK_TYPE(tt::common_type<char volatile (&) [2]>::type, char volatile*);
BOOST_CHECK_TYPE(tt::common_type<char const volatile (&) [2]>::type, char const volatile*);
BOOST_CHECK_TYPE(tt::common_type<char()>::type, char(*)());
BOOST_CHECK_TYPE(tt::common_type<UDT()>::type, UDT(*)());
BOOST_CHECK_TYPE(tt::common_type<UDT const()>::type, UDT const(*)());
BOOST_CHECK_TYPE(tt::common_type<UDT volatile()>::type, UDT volatile(*)());
BOOST_CHECK_TYPE(tt::common_type<UDT const volatile()>::type, UDT const volatile(*)());
}
TT_TEST_END

View File

@ -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 <type_traits>
#else
# include <boost/type_traits/common_type.hpp>
#endif
#include <iostream>
template<class T> struct X
{
T t_;
X(): t_() {}
template<class U> X( X<U> const & x ): t_( x.t_ ) {}
};
namespace boost
{
template<class T, class U> struct common_type< X<T>, X<U> >
{
typedef X<typename common_type<T, U>::type> type;
};
} // namespace boost
TT_TEST_BEGIN(common_type_5)
{
// user specializations, binary
BOOST_CHECK_TYPE3( tt::common_type< X<char>, X<char> >::type, X<char> );
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<char>& >::type, X<char> );
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<char> const& >::type, X<char> );
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<char>& >::type, X<char> );
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<char> const& >::type, X<char> );
BOOST_CHECK_TYPE3( tt::common_type< X<char>, X<unsigned char> >::type, X<int> );
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<unsigned char>& >::type, X<int> );
BOOST_CHECK_TYPE3( tt::common_type< X<char>&, X<unsigned char> const& >::type, X<int> );
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<unsigned char>& >::type, X<int> );
BOOST_CHECK_TYPE3( tt::common_type< X<char> const&, X<unsigned char> const& >::type, X<int> );
// ternary
BOOST_CHECK_TYPE4( tt::common_type< X<char>&, X<long> const&, X<short> volatile& >::type, X<long> );
}
TT_TEST_END

44
test/copy_cv_test.cpp Normal file
View File

@ -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 <type_traits>
#else
# include <boost/type_traits/copy_cv.hpp>
#endif
#include <iostream>
TT_TEST_BEGIN(copy_cv)
{
BOOST_CHECK_TYPE3(tt::copy_cv<int, void>::type, int);
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void>::type, int const);
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void>::type, int volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int, void const>::type, int const);
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void const>::type, int const);
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void const>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void const>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int, void volatile>::type, int volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void volatile>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void volatile>::type, int volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void volatile>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int, void const volatile>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int const, void const volatile>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int volatile, void const volatile>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int const volatile, void const volatile>::type, int const volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<int&, void const volatile>::type, int&);
BOOST_CHECK_TYPE3(tt::copy_cv<int const*, void volatile>::type, int const* volatile);
BOOST_CHECK_TYPE3(tt::copy_cv<long, int const volatile&>::type, long);
}
TT_TEST_END

View File

@ -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 <type_traits>
#else
# include <boost/type_traits/type_identity.hpp>
#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