diff options
Diffstat (limited to 'boost/type_traits/is_convertible.hpp')
-rw-r--r-- | boost/type_traits/is_convertible.hpp | 124 |
1 files changed, 59 insertions, 65 deletions
diff --git a/boost/type_traits/is_convertible.hpp b/boost/type_traits/is_convertible.hpp index a844cecb36..417ece20b4 100644 --- a/boost/type_traits/is_convertible.hpp +++ b/boost/type_traits/is_convertible.hpp @@ -13,14 +13,14 @@ #define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED #include <boost/type_traits/intrinsics.hpp> +#include <boost/type_traits/integral_constant.hpp> #ifndef BOOST_IS_CONVERTIBLE #include <boost/type_traits/detail/yes_no_type.hpp> -#include <boost/type_traits/config.hpp> +#include <boost/type_traits/detail/config.hpp> #include <boost/type_traits/is_array.hpp> -#include <boost/type_traits/ice.hpp> #include <boost/type_traits/is_arithmetic.hpp> #include <boost/type_traits/is_void.hpp> -#ifndef BOOST_NO_IS_ABSTRACT +#if !defined(BOOST_NO_IS_ABSTRACT) #include <boost/type_traits/is_abstract.hpp> #endif #include <boost/type_traits/add_lvalue_reference.hpp> @@ -31,13 +31,13 @@ #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> +#include <boost/type_traits/is_same.hpp> #endif // BOOST_IS_CONVERTIBLE -// should be always the last #include directive -#include <boost/type_traits/detail/bool_trait_def.hpp> - namespace boost { #ifndef BOOST_IS_CONVERTIBLE @@ -54,7 +54,7 @@ namespace boost { namespace detail { -#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(BOOST_GCC) && (BOOST_GCC < 40700)) // This is a C++11 conforming version, place this first and use it wherever possible: @@ -300,13 +300,26 @@ struct is_convertible_basic_impl: // 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 (...). // + +//Workaround for old compilers like MSVC 7.1 to avoid +//forming a reference to an array of unknown bound +template <typename From> +struct is_convertible_basic_impl_add_lvalue_reference + : add_lvalue_reference<From> +{}; + +template <typename From> +struct is_convertible_basic_impl_add_lvalue_reference<From[]> +{ + typedef From type []; +}; + template <typename From, typename To> 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); - typedef typename add_lvalue_reference<From>::type lvalue_type; - typedef typename add_rvalue_reference<From>::type rvalue_type; + typedef typename is_convertible_basic_impl_add_lvalue_reference<From>::type lvalue_type; static lvalue_type _m_from; #ifdef BOOST_MSVC #pragma warning(push) @@ -316,6 +329,7 @@ struct is_convertible_basic_impl #endif #endif #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + typedef typename add_rvalue_reference<From>::type rvalue_type; BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type) ); @@ -336,38 +350,15 @@ struct is_convertible_basic_impl template <typename From, typename To> struct is_convertible_impl { - enum { value = - (::boost::type_traits::ice_and< - ::boost::type_traits::ice_or< - ::boost::detail::is_convertible_basic_impl<From,To>::value, - ::boost::is_void<To>::value - >::value, - ::boost::type_traits::ice_not< - ::boost::is_array<To>::value - >::value, - ::boost::type_traits::ice_not< - ::boost::is_function<To>::value - >::value - >::value) }; + enum { + value = ( ::boost::detail::is_convertible_basic_impl<From,To>::value && ! ::boost::is_array<To>::value && ! ::boost::is_function<To>::value) + }; }; #elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551 template <typename From, typename To> struct is_convertible_impl { - BOOST_STATIC_CONSTANT(bool, value = - (::boost::type_traits::ice_and< - ::boost::type_traits::ice_or< - ::boost::detail::is_convertible_basic_impl<From,To>::value, - ::boost::is_void<To>::value - >::value, - ::boost::type_traits::ice_not< - ::boost::is_array<To>::value - >::value, - ::boost::type_traits::ice_not< - ::boost::is_function<To>::value - >::value - >::value) - ); + BOOST_STATIC_CONSTANT(bool, value = ( ::boost::detail::is_convertible_basic_impl<From, To>::value && !::boost::is_array<To>::value && !::boost::is_function<To>::value)); }; #endif @@ -443,52 +434,55 @@ struct is_convertible_impl_dispatch // implementation above: // #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS -# define TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1,spec2,value) \ - BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2,value) \ - BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 const,value) \ - BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 volatile,value) \ - BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 const volatile,value) \ - /**/ -# define TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2(trait,spec1,spec2,value) \ - TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1,spec2,value) \ - TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 const,spec2,value) \ - TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 volatile,spec2,value) \ - TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 const volatile,spec2,value) \ - /**/ +template <> struct is_convertible_impl_dispatch<void, void> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void, void const> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void, void const volatile> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void, void volatile> : public true_type{}; + +template <> struct is_convertible_impl_dispatch<void const, void> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void const, void const> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void const, void const volatile> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void const, void volatile> : public true_type{}; - TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2(is_convertible,void,void,true) +template <> struct is_convertible_impl_dispatch<void const volatile, void> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void const volatile, void const> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void const volatile, void const volatile> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void const volatile, void volatile> : public true_type{}; -# undef TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2 -# undef TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1 +template <> struct is_convertible_impl_dispatch<void volatile, void> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void volatile, void const> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void volatile, void const volatile> : public true_type{}; +template <> struct is_convertible_impl_dispatch<void volatile, void volatile> : public true_type{}; #else - BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(is_convertible,void,void,true) +template <> struct is_convertible_impl_dispatch<void, void> : public true_type{}; #endif // BOOST_NO_CV_VOID_SPECIALIZATIONS -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void,To,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void,false) +template <class To> struct is_convertible_impl_dispatch<void, To> : public false_type{}; +template <class From> struct is_convertible_impl_dispatch<From, void> : public false_type{}; + #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const,To,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void volatile,To,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const volatile,To,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void volatile,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const volatile,false) +template <class To> struct is_convertible_impl_dispatch<void const, To> : public false_type{}; +template <class From> struct is_convertible_impl_dispatch<From, void const> : public false_type{}; +template <class To> struct is_convertible_impl_dispatch<void const volatile, To> : public false_type{}; +template <class From> struct is_convertible_impl_dispatch<From, void const volatile> : public false_type{}; +template <class To> struct is_convertible_impl_dispatch<void volatile, To> : public false_type{}; +template <class From> struct is_convertible_impl_dispatch<From, void volatile> : public false_type{}; #endif } // namespace detail -BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,(::boost::detail::is_convertible_impl_dispatch<From,To>::value)) +template <class From, class To> +struct is_convertible : public integral_constant<bool, ::boost::detail::is_convertible_impl_dispatch<From, To>::value> {}; #else -BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,BOOST_IS_CONVERTIBLE(From,To)) +template <class From, class To> +struct is_convertible : public integral_constant<bool, BOOST_IS_CONVERTIBLE(From, To)> {}; #endif } // namespace boost -#include <boost/type_traits/detail/bool_trait_undef.hpp> - #endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED |