Renamed boost::swap to boost::core::invoke_swap, deprecated boost::swap.

The rename allows to avoid forming an infinite recursion in compile time
(because of noexcept specification that needs to resolve the unqualified call
to swap) or run time (in case if the boost::swap function is the only one
suitable for the passed arguments).

To avoid the compile-time recursion, removed noexcept specification from
boost::swap. The specification is still present in boost::core::invoke_swap.

Deprecated boost::swap and associated headers. boost::core::invoke_swap
is defined in a new boost/core/invoke_swap.hpp header.

Updated docs and tests. Removed tests that check inclusion of deprecated
headers.

Fixes https://github.com/boostorg/core/issues/148.
This commit is contained in:
Andrey Semashev
2023-07-11 01:45:19 +03:00
parent 216999e552
commit 9fc2a2f1ac
34 changed files with 214 additions and 192 deletions
-4
View File
@@ -7,12 +7,8 @@
# bring in rules for testing
import testing ;
compile swap_root_header_1.cpp ;
compile swap_root_header_2.cpp ;
compile swap_lib_header_1.cpp ;
compile swap_lib_header_2.cpp ;
compile swap_mixed_headers_1.cpp ;
compile swap_mixed_headers_2.cpp ;
compile swap_noexcept.cpp ;
compile-fail swap_const_wrapper_fail.cpp ;
+3 -3
View File
@@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
// Tests swapping an array of arrays of swap_test_class objects by means of boost::core::invoke_swap.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -59,7 +59,7 @@ int main()
ptr2[i].set_data( static_cast<int>(i + number_of_elements) );
}
boost::swap(array1, array2);
boost::core::invoke_swap(array1, array2);
for (std::size_t i = 0; i < number_of_elements; ++i)
{
+3 -3
View File
@@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping an array of arrays of integers by means of boost::swap.
// Tests swapping an array of arrays of integers by means of boost::core::invoke_swap.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -32,7 +32,7 @@ int main()
ptr2[i] = static_cast<int>(i + number_of_elements);
}
boost::swap(array1, array2);
boost::core::invoke_swap(array1, array2);
for (std::size_t i = 0; i < number_of_elements; ++i)
{
+3 -3
View File
@@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
// Tests swapping an array of arrays of swap_test_class objects by means of boost::core::invoke_swap.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -54,7 +54,7 @@ int main()
std::copy(initial_array2, initial_array2 + array_size, array2);
swap_test_class::reset();
boost::swap(array1, array2);
boost::core::invoke_swap(array1, array2);
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
+3 -3
View File
@@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping an array of integers by means of boost::swap.
// Tests swapping an array of integers by means of boost::core::invoke_swap.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -27,7 +27,7 @@ int main()
std::copy(initial_array1, initial_array1 + array_size, array1);
std::copy(initial_array2, initial_array2 + array_size, array2);
boost::swap(array1, array2);
boost::core::invoke_swap(array1, array2);
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
+3 -3
View File
@@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping an array of swap_test_template<int> objects by means of boost::swap.
// Tests swapping an array of swap_test_template<int> objects by means of boost::core::invoke_swap.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -60,7 +60,7 @@ int main()
std::copy(initial_array2, initial_array2 + array_size, array2);
swap_test_class::reset();
boost::swap(array1, array2);
boost::core::invoke_swap(array1, array2);
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
+3 -3
View File
@@ -1,8 +1,8 @@
// Copyright 2018 Andrzej Krzemieński
// Copyright 2018 Andrzej Krzemieński
// Copyright 2018 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
#include <boost/core/swap.hpp>
#include <boost/core/invoke_swap.hpp>
namespace boost
{
@@ -14,7 +14,7 @@ template<class T> struct Wrapper
template<class T> inline void swap( Wrapper<T> & w, Wrapper<T> & v )
{
boost::swap( w, v );
boost::core::invoke_swap( w, v );
}
} // namespace boost
+1 -1
View File
@@ -6,5 +6,5 @@
// Tests that the swap header compiles as a standalone translation unit
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
+2 -2
View File
@@ -6,6 +6,6 @@
// Tests that the swap header include guards work correctly
#include <boost/utility/swap.hpp>
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/invoke_swap.hpp>
-11
View File
@@ -1,11 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests that the swap headers work when both are included
#include <boost/swap.hpp>
#include <boost/utility/swap.hpp>
-12
View File
@@ -1,12 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests that the swap headers work when both are included
#include <boost/utility/swap.hpp>
#include <boost/swap.hpp>
+6 -6
View File
@@ -4,15 +4,15 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// boost::swap internally does an unqualified function call to swap.
// boost::core::invoke_swap internally does an unqualified function call to swap.
// This could have led to ambiguity or infinite recursion, when the
// objects to be swapped would themselves be from the boost namespace.
// If so, boost::swap itself might be found by argument dependent lookup.
// The implementation of boost::swap resolves this issue by giving
// boost::swap two template argumetns, thereby making it less specialized
// If so, boost::core::invoke_swap itself might be found by argument dependent lookup.
// The implementation of boost::core::invoke_swap resolves this issue by giving
// boost::core::invoke_swap two template argumetns, thereby making it less specialized
// than std::swap.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -33,7 +33,7 @@ int main()
boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
+6 -6
View File
@@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests that boost::swap propagates noexcept specification correctly
// Tests that boost::core::invoke_swap propagates noexcept specification correctly
#include <boost/core/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_STATIC_ASSERT) && \
@@ -34,9 +34,9 @@ struct class_with_except_swap
} // namespace test_ns
static_assert(noexcept(boost::swap(test_ns::class_with_noexcept_swap::instance(), test_ns::class_with_noexcept_swap::instance())),
"boost::swap for class_with_noexcept_swap should have noexcept specification");
static_assert(!noexcept(boost::swap(test_ns::class_with_except_swap::instance(), test_ns::class_with_except_swap::instance())),
"boost::swap for class_with_except_swap should not have noexcept specification");
static_assert(noexcept(boost::core::invoke_swap(test_ns::class_with_noexcept_swap::instance(), test_ns::class_with_noexcept_swap::instance())),
"boost::core::invoke_swap for class_with_noexcept_swap should have noexcept specification");
static_assert(!noexcept(boost::core::invoke_swap(test_ns::class_with_except_swap::instance(), test_ns::class_with_except_swap::instance())),
"boost::core::invoke_swap for class_with_except_swap should not have noexcept specification");
#endif // !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_STATIC_ASSERT) ...
+2 -2
View File
@@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -14,7 +14,7 @@ int main()
int object1 = 1;
int object2 = 2;
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1,2);
BOOST_CHECK_EQUAL(object2,1);
-10
View File
@@ -1,10 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests that the swap header compiles as a standalone translation unit
#include <boost/swap.hpp>
-11
View File
@@ -1,11 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests that the swap header include guards work correctly
#include <boost/swap.hpp>
#include <boost/swap.hpp>
+2 -2
View File
@@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -33,7 +33,7 @@ int main()
boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
@@ -8,13 +8,13 @@
// properly swapped, when both boost and the other namespace have a custom
// swap function for that class. Note that it shouldn't be necessary for a class
// in an other namespace to have a custom swap function in boost, because the
// boost::swap utility should find the swap function in the other namespace, by
// argument dependent lookup (ADL). Unfortunately ADL isn't fully implemented
// by some specific compiler versions, including Intel C++ 8.1, MSVC 7.1, and
// Borland 5.9.3. Users of those compilers might consider adding a swap overload
// boost::core::invoke_swap utility should find the swap function in the other
// namespace, by argument dependent lookup (ADL). Unfortunately ADL isn't fully
// implemented by some specific compiler versions, including Intel C++ 8.1, MSVC 7.1,
// and Borland 5.9.3. Users of those compilers might consider adding a swap overload
// to the boost namespace.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -52,7 +52,7 @@ int main()
other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
+2 -2
View File
@@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -27,7 +27,7 @@ int main()
swap_test_class object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
+2 -2
View File
@@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -33,7 +33,7 @@ int main()
other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
+2 -2
View File
@@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -32,7 +32,7 @@ int main()
swap_test_class object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
+3 -3
View File
@@ -4,11 +4,11 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::bitset<T> objects by means of boost::swap.
// Tests swapping std::bitset<T> objects by means of boost::core::invoke_swap.
// Unlike most other Standard C++ Library template classes,
// std::bitset<T> does not have its own std::swap overload.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -24,7 +24,7 @@ int main()
bitset_type object1 = initial_value1;
bitset_type object2 = initial_value2;
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
+3 -3
View File
@@ -4,11 +4,11 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::time_base::dateorder objects by means of boost::swap.
// Tests swapping std::time_base::dateorder objects by means of boost::core::invoke_swap.
// std::time_base::dateorder is an enumerated type. It does not have an
// std::swap overload or template specialization.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -23,7 +23,7 @@ int main()
std::time_base::dateorder object1 = initial_value1;
std::time_base::dateorder object2 = initial_value2;
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
+3 -3
View File
@@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::string objects by means of boost::swap.
// Tests swapping std::string objects by means of boost::core::invoke_swap.
// std::string has its own std::swap overload.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -22,7 +22,7 @@ int main()
std::string object1 = initial_value1;
std::string object2 = initial_value2;
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
+3 -3
View File
@@ -4,11 +4,11 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::type_info pointers by means of boost::swap.
// Tests swapping std::type_info pointers by means of boost::core::invoke_swap.
// There is no std::swap overload or template specialization
// for std::type_info pointers.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -23,7 +23,7 @@ int main()
const std::type_info * ptr1 = initial_value1;
const std::type_info * ptr2 = initial_value2;
boost::swap(ptr1,ptr2);
boost::core::invoke_swap(ptr1,ptr2);
BOOST_CHECK_EQUAL(ptr1,initial_value2);
BOOST_CHECK_EQUAL(ptr2,initial_value1);
+3 -3
View File
@@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::vector objects by means of boost::swap,
// Tests swapping std::vector objects by means of boost::core::invoke_swap,
// having boost::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -45,7 +45,7 @@ int main()
swap_test_class_type::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
+3 -3
View File
@@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::vector objects by means of boost::swap,
// Tests swapping std::vector objects by means of boost::core::invoke_swap,
// having ::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -38,7 +38,7 @@ int main()
swap_test_class::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
+3 -3
View File
@@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::vector objects by means of boost::swap,
// Tests swapping std::vector objects by means of boost::core::invoke_swap,
// having other::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@@ -45,7 +45,7 @@ int main()
swap_test_class_type::reset();
boost::swap(object1,object2);
boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);