forked from boostorg/type_traits
New implementation of common_type.
This commit is contained in:
@@ -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 <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/utility/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
|
||||
|
34
include/boost/type_traits/copy_cv.hpp
Normal file
34
include/boost/type_traits/copy_cv.hpp
Normal 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
|
212
include/boost/type_traits/detail/common_arithmetic_type.hpp
Normal file
212
include/boost/type_traits/detail/common_arithmetic_type.hpp
Normal 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:
|
||||
// <20>signed char<61>, <20>short int<6E>, <20>int<6E>, <20>long int<6E>, and <20>long long int<6E>.
|
||||
|
||||
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: <20>unsigned char<61>, <20>unsigned short int<6E>,
|
||||
// <20>unsigned int<6E>, <20>unsigned long int<6E>, and <20>unsigned long long int<6E>
|
||||
|
||||
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 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
|
@@ -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
|
||||
|
112
include/boost/type_traits/detail/common_type_impl.hpp
Normal file
112
include/boost/type_traits/detail/common_type_impl.hpp
Normal file
@@ -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 <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/tp_identity.hpp>
|
||||
#include <boost/type_traits/is_lvalue_reference.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_union.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/decay.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::tp_identity<U>,
|
||||
|
||||
typename boost::conditional<
|
||||
|
||||
boost::is_convertible<U, T>::value && !boost::is_convertible<T, U>::value,
|
||||
boost::tp_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_HPP_INCLUDED
|
@@ -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
|
145
include/boost/type_traits/detail/composite_pointer_type.hpp
Normal file
145
include/boost/type_traits/detail/composite_pointer_type.hpp
Normal file
@@ -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 <boost/type_traits/copy_cv.hpp>
|
||||
#include <boost/type_traits/tp_identity.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
|
22
include/boost/type_traits/tp_identity.hpp
Normal file
22
include/boost/type_traits/tp_identity.hpp
Normal file
@@ -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<class T> struct tp_identity
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TYPE_TRAITS_TP_IDENTITY_HPP_INCLUDED
|
Reference in New Issue
Block a user