forked from boostorg/type_traits
Extracted C++11 implementation of is_nothrow_swappable to a separate header.
Also modified the implementation to avoid referencing any potential swap overloads in namespace boost, unless these overloads are found by ADL. Added tests to verify is_nothrow_swappable works with ADL.
This commit is contained in:
1 parent
2370288a79
commit
1c31fee575
3 files changed
+111
-29
No files matched your search
@@ -1,4 +1,3 @@
|
||||
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -17,6 +16,13 @@
|
||||
#include "check_integral_constant.hpp"
|
||||
#include <utility>
|
||||
|
||||
// These conditions should be similar to those in is_nothrow_swappable.hpp
|
||||
#if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) \
|
||||
|| BOOST_WORKAROUND(BOOST_GCC, < 40700) \
|
||||
|| (defined(__GLIBCXX__) && __GLIBCXX__ <= 20120301) // built-in clang++ -std=c++11 on Travis, w/ libstdc++ 4.6
|
||||
#define BOOST_TYPE_TRAITS_IS_NOTHROW_SWAPPABLE_EMULATED
|
||||
#endif
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
@@ -45,6 +51,44 @@ struct U
|
||||
|
||||
void swap(U&, U&) {}
|
||||
|
||||
#if !defined(BOOST_TYPE_TRAITS_IS_NOTHROW_SWAPPABLE_EMULATED) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||
|
||||
namespace test_ns {
|
||||
|
||||
// Not swappable using std::swap, but swappable using test_ns::swap
|
||||
struct only_adl_swappable
|
||||
{
|
||||
only_adl_swappable(only_adl_swappable const&) = delete;
|
||||
only_adl_swappable& operator= (only_adl_swappable const&) = delete;
|
||||
};
|
||||
|
||||
inline void swap(only_adl_swappable&, only_adl_swappable&) BOOST_NOEXCEPT {}
|
||||
|
||||
} // namespace test_ns
|
||||
|
||||
namespace boost {
|
||||
namespace type_traits_is_nothrow_swappable_test {
|
||||
|
||||
// Some type that is defined within boost namespace and that has a specialized swap overload
|
||||
struct swappable
|
||||
{
|
||||
swappable(swappable const&) = delete;
|
||||
swappable& operator= (swappable const&) = delete;
|
||||
};
|
||||
|
||||
// This overload should be selected by is_nothrow_swappable
|
||||
inline void swap(swappable&, swappable&) BOOST_NOEXCEPT {}
|
||||
|
||||
} // namespace type_traits_is_nothrow_swappable_test
|
||||
|
||||
// Some generic swap implementation, such as the one from Boost.Swap. This overload should *not* be selected by is_nothrow_swappable.
|
||||
template< typename T1, typename T2 >
|
||||
inline void swap(T1&, T2&) {}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
TT_TEST_BEGIN(is_nothrow_swappable)
|
||||
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<int>::value, true);
|
||||
@@ -52,9 +96,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<int const>::value, fals
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<int volatile>::value, true);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<int const volatile>::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) \
|
||||
|| BOOST_WORKAROUND(BOOST_GCC, < 40700)\
|
||||
|| (defined(__GLIBCXX__) && __GLIBCXX__ <= 20120301) // built-in clang++ -std=c++11 on Travis, w/ libstdc++ 4.6
|
||||
#if defined(BOOST_TYPE_TRAITS_IS_NOTHROW_SWAPPABLE_EMULATED)
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<int[2]>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<int const[2]>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<int volatile[2]>::value, false);
|
||||
@@ -71,9 +113,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<void const>::value, fal
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<void volatile>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<void const volatile>::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) \
|
||||
|| BOOST_WORKAROUND(BOOST_GCC, < 40700)\
|
||||
|| (defined(__GLIBCXX__) && __GLIBCXX__ <= 20120301) // built-in clang++ -std=c++11 on Travis, w/ libstdc++ 4.6
|
||||
#if defined(BOOST_TYPE_TRAITS_IS_NOTHROW_SWAPPABLE_EMULATED)
|
||||
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<X>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<X const>::value, false);
|
||||
@@ -157,6 +197,30 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable<std::pair<V, int> cons
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable<std::pair<V, int> volatile>::value), false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_nothrow_swappable<std::pair<V, int> const volatile>::value), false);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable>::value, true);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable const>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable volatile>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable const volatile>::value, false);
|
||||
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable[2]>::value, true);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable const[2]>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable volatile[2]>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<test_ns::only_adl_swappable const volatile[2]>::value, false);
|
||||
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable>::value, true);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable const>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable volatile>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable const volatile>::value, false);
|
||||
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable[2]>::value, true);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable const[2]>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable volatile[2]>::value, false);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_nothrow_swappable<boost::type_traits_is_nothrow_swappable_test::swappable const volatile[2]>::value, false);
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||
|
||||
#endif
|
||||
|
||||
TT_TEST_END
|
||||
Reference in new issue
Block a user