From f91ab7005581d43c34760b2184b5de8f0e906073 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 23 Apr 2014 12:50:53 +0100 Subject: [PATCH] Apply fix for issue https://svn.boost.org/trac/boost/ticket/9910 which provides a C++11 conforming version of is_convertible. --- include/boost/type_traits/is_convertible.hpp | 42 +++++++++++++++++++- test/is_convertible_test.cpp | 21 ++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 4ae675d..1f083a7 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -30,7 +30,9 @@ #if defined(__MWERKS__) #include #endif - +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +# include +#endif #endif // BOOST_IS_CONVERTIBLE // should be always the last #include directive @@ -52,7 +54,43 @@ namespace boost { namespace detail { -#if defined(__BORLANDC__) && (__BORLANDC__ < 0x560) +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + // This is a C++11 conforming version: + + template + struct or_helper + { + static const bool value = (A::value || B::value || C::value); + }; + + template, boost::is_function, boost::is_array >::value> + struct is_convertible_basic_impl + { + // Nothing converts to function or array, but void converts to void: + static const bool value = is_void::value; + }; + + template + class is_convertible_basic_impl + { + typedef char one; + typedef int two; + + template + static void test_aux(To1); + + template + static decltype(test_aux(boost::declval()), one()) test(int); + + template + static two test(...); + + public: + static const bool value = sizeof(test(0)) == 1; + }; + +#elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560) // // special version for Borland compilers // this version breaks when used for some diff --git a/test/is_convertible_test.cpp b/test/is_convertible_test.cpp index 6378a18..9bcc3e0 100644 --- a/test/is_convertible_test.cpp +++ b/test/is_convertible_test.cpp @@ -56,6 +56,20 @@ struct bug_5271b #endif +#if ((!defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)) || defined(BOOST_IS_CONVERTIBLE)) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +struct bug9910 +{ + bug9910() = default; + bug9910(const bug9910&) = delete; // or private: A(const A&) = default; +}; +struct Ref_bug9910 +{ + // proxy reference to bug9910 + operator bug9910& () { return *_ptr; } + bug9910* _ptr; +}; +#endif + TT_TEST_BEGIN(is_convertible) BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); @@ -192,5 +206,12 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), fal BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), true); #endif +#if ((!defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)) || defined(BOOST_IS_CONVERTIBLE)) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +#ifndef _MSC_VER +// MSVC gives the wrong answer here, see https://connect.microsoft.com/VisualStudio/feedback/details/858956/std-is-convertible-returns-incorrect-value +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); +#endif +#endif + TT_TEST_END