diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index 8408ec3..b1f553c 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -79,7 +79,8 @@ # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif -#if defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215) +#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\ + || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)) # include # define BOOST_IS_UNION(T) __is_union(T) @@ -221,6 +222,11 @@ # define BOOST_ALIGNMENT_OF(T) __alignof__(T) # endif +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# include +# define BOOST_IS_CONVERTIBLE(T,U) (std::is_convertible::value) +#endif + # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 0d42c46..799341b 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -120,6 +120,8 @@ struct is_convertible_impl struct any_conversion { template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); template any_conversion(T&); }; @@ -132,8 +134,9 @@ template struct checker template struct is_convertible_basic_impl { - static typename add_rvalue_reference::type _m_from; - static bool const value = sizeof( boost::detail::checker::_m_check(_m_from, 0) ) + typedef typename add_rvalue_reference::type rvalue_type; + static From _m_from; + static bool const value = sizeof( boost::detail::checker::_m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type); }; @@ -152,6 +155,8 @@ struct is_convertible_basic_impl struct any_conversion { template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); // we need this constructor to catch references to functions // (which can not be cv-qualified): template any_conversion(T&); @@ -162,10 +167,11 @@ struct is_convertible_basic_impl { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int); - static typename add_rvalue_reference::type _m_from; + typedef typename add_rvalue_reference::type rvalue_type; + static From _m_from; BOOST_STATIC_CONSTANT(bool, value = - sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type) + sizeof( _m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type) ); }; @@ -174,6 +180,8 @@ struct is_convertible_basic_impl struct any_conversion { template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); // we need this constructor to catch references to functions // (which can not be cv-qualified): template any_conversion(T&); @@ -186,12 +194,13 @@ struct is_convertible_basic_impl template static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion, float, T); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int); - static typename add_rvalue_reference::type _m_from; + typedef typename add_rvalue_reference::type rvalue_type; + static From _m_from; // Static constants sometime cause the conversion of _m_from to To to be // called. This doesn't happen with an enum. enum { value = - sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type) + sizeof( _m_check(static_cast(_m_from), 0, 0) ) == sizeof(::boost::type_traits::yes_type) }; }; @@ -209,6 +218,9 @@ struct is_convertible_basic_impl_aux; struct any_conversion { template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); + template any_conversion(T&); }; template @@ -216,10 +228,11 @@ struct is_convertible_basic_impl_aux { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int); - static typename add_rvalue_reference::type _m_from; + typedef typename add_rvalue_reference::type rvalue_type; + static From _m_from; BOOST_STATIC_CONSTANT(bool, value = - sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type) + sizeof( _m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type) ); }; @@ -228,9 +241,10 @@ struct is_convertible_basic_impl_aux { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To); - static typename add_rvalue_reference::type _m_from; + typedef typename add_rvalue_reference::type rvalue_type; + static From _m_from; BOOST_STATIC_CONSTANT(bool, value = - sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type) + sizeof( _m_check(static_cast(_m_from)) ) == sizeof(::boost::type_traits::yes_type) ); }; @@ -243,7 +257,6 @@ struct is_convertible_basic_impl: {}; #else - // // This version seems to work pretty well for a wide spectrum of compilers, // however it does rely on undefined behaviour by passing UDT's through (...). @@ -253,7 +266,8 @@ struct is_convertible_basic_impl { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To); - static typename add_rvalue_reference::type _m_from; + typedef typename add_rvalue_reference::type rvalue_type; + static From _m_from; #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable:4244) @@ -262,7 +276,7 @@ struct is_convertible_basic_impl #endif #endif BOOST_STATIC_CONSTANT(bool, value = - sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type) + sizeof( _m_check(static_cast(_m_from)) ) == sizeof(::boost::type_traits::yes_type) ); #ifdef BOOST_MSVC #pragma warning(pop) diff --git a/test/is_convertible_test.cpp b/test/is_convertible_test.cpp index 7c04e91..61a7c33 100644 --- a/test/is_convertible_test.cpp +++ b/test/is_convertible_test.cpp @@ -102,6 +102,8 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); #ifndef BOOST_NO_RVALUE_REFERENCES BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); #endif BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); diff --git a/test/test.hpp b/test/test.hpp index 00a1e60..0eb7960 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -260,7 +260,7 @@ struct nothrow_copy_UDT { nothrow_copy_UDT(); nothrow_copy_UDT(const nothrow_copy_UDT&)throw(); - ~nothrow_copy_UDT(){}; + ~nothrow_copy_UDT(){} nothrow_copy_UDT& operator=(const nothrow_copy_UDT&); bool operator==(const nothrow_copy_UDT&)const { return true; } diff --git a/test/tricky_rvalue_test.cpp b/test/tricky_rvalue_test.cpp index 5c01402..a768f10 100644 --- a/test/tricky_rvalue_test.cpp +++ b/test/tricky_rvalue_test.cpp @@ -9,6 +9,7 @@ #ifdef TEST_STD # include #else +# include # include # include # include @@ -20,6 +21,7 @@ TT_TEST_BEGIN(rvalue_reference_test) BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_reference::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_rvalue_reference::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_rvalue_reference::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); #endif TT_TEST_END