From 3e9608230c678045bdb870ecaa2c2a71f7f2cf5c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 28 Nov 2017 22:12:01 +0000 Subject: [PATCH] Fallback for is_nothrow_swappable on pre-C++11 --- doc/is_nothrow_swappable.qbk | 7 ++- .../type_traits/is_nothrow_swappable.hpp | 14 +++++ test/is_nothrow_swappable_test.cpp | 59 +++++++++++++++---- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/doc/is_nothrow_swappable.qbk b/doc/is_nothrow_swappable.qbk index 8e5886e..68c32b2 100644 --- a/doc/is_nothrow_swappable.qbk +++ b/doc/is_nothrow_swappable.qbk @@ -1,4 +1,4 @@ -[/ +[/ Copyright 2017 Peter Dimov Distributed under the Boost Software License, Version 1.0. @@ -16,7 +16,10 @@ __inherit If the expression `swap(declval(), declval())` (in a context where `std::swap` is visible) is valid and non-throwing, inherits from __true_type, otherwise from __false_type. -__compat This trait requires C++11. +__compat This trait requires C++11 for full support. Without C++11 it will +inherit from __true_type for scalar types (including integral, floating point, +enumeration, pointer and pointer-to-member types), and from __false_type for +anything else. __header ` #include ` or ` #include ` diff --git a/include/boost/type_traits/is_nothrow_swappable.hpp b/include/boost/type_traits/is_nothrow_swappable.hpp index 397f296..f55d268 100644 --- a/include/boost/type_traits/is_nothrow_swappable.hpp +++ b/include/boost/type_traits/is_nothrow_swappable.hpp @@ -10,6 +10,20 @@ #include #if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + +#include +#include +#include + +namespace boost +{ +template struct is_nothrow_swappable : boost::integral_constant::value && !boost::is_const::value> {}; + +template struct is_nothrow_swappable_with : false_type {}; +template struct is_nothrow_swappable_with : is_nothrow_swappable {}; +} + #else #include diff --git a/test/is_nothrow_swappable_test.cpp b/test/is_nothrow_swappable_test.cpp index 1377c8a..009f9b2 100644 --- a/test/is_nothrow_swappable_test.cpp +++ b/test/is_nothrow_swappable_test.cpp @@ -13,15 +13,6 @@ #include -#if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) \ - || (defined(__GLIBCXX__) && __GLIBCXX__ <= 20120301) // built-in clang++ -std=c++11 on Travis, w/ libstdc++ 4.6 - -int main() -{ -} - -#else - #include "test.hpp" #include "check_integral_constant.hpp" #include @@ -46,7 +37,13 @@ struct V V& operator=( V const& ) { return *this; } }; -void swap( V&, V& ) noexcept {} +void swap( V&, V& ) BOOST_NOEXCEPT {} + +struct U +{ +}; + +void swap(U&, U&) {} TT_TEST_BEGIN(is_nothrow_swappable) @@ -55,16 +52,49 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, fals BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +#if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) \ + || (defined(__GLIBCXX__) && __GLIBCXX__ <= 20120301) // built-in clang++ -std=c++11 on Travis, w/ libstdc++ 4.6 +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +#else BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +#endif BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +#if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) \ + || (defined(__GLIBCXX__) && __GLIBCXX__ <= 20120301) // built-in clang++ -std=c++11 on Travis, w/ libstdc++ 4.6 + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); + +#else + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); @@ -105,6 +135,11 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, fal BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable >::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable const>::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable volatile>::value), false); @@ -120,6 +155,6 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable cons BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable volatile>::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable const volatile>::value), false); -TT_TEST_END - #endif + +TT_TEST_END