From 9fc2a2f1ac9f1eacd45f810a3a5a5ce81aebc55d Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 11 Jul 2023 01:45:19 +0300 Subject: [PATCH] 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. --- doc/changes.qbk | 19 +++- doc/swap.qbk | 35 +++---- include/boost/core/invoke_swap.hpp | 93 +++++++++++++++++++ include/boost/core/swap.hpp | 61 ++---------- include/boost/swap.hpp | 5 +- include/boost/utility/swap.hpp | 5 +- test/swap/Jamfile.v2 | 4 - test/swap/swap_array_of_array_of_class.cpp | 6 +- test/swap/swap_array_of_array_of_int.cpp | 6 +- test/swap/swap_array_of_class.cpp | 6 +- test/swap/swap_array_of_int.cpp | 6 +- test/swap/swap_array_of_template.cpp | 6 +- test/swap/swap_const_wrapper_fail.cpp | 6 +- test/swap/swap_lib_header_1.cpp | 2 +- test/swap/swap_lib_header_2.cpp | 4 +- test/swap/swap_mixed_headers_1.cpp | 11 --- test/swap/swap_mixed_headers_2.cpp | 12 --- test/swap/swap_no_ambiguity_in_boost.cpp | 12 +-- test/swap/swap_noexcept.cpp | 12 +-- test/swap/swap_primitive.cpp | 4 +- test/swap/swap_root_header_1.cpp | 10 -- test/swap/swap_root_header_2.cpp | 11 --- test/swap/swap_specialized_in_boost.cpp | 4 +- .../swap_specialized_in_boost_and_other.cpp | 12 +-- test/swap/swap_specialized_in_global.cpp | 4 +- test/swap/swap_specialized_in_other.cpp | 4 +- test/swap/swap_specialized_in_std.cpp | 4 +- test/swap/swap_std_bitset.cpp | 6 +- test/swap/swap_std_dateorder.cpp | 6 +- test/swap/swap_std_string.cpp | 6 +- test/swap/swap_std_typeinfo_ptr.cpp | 6 +- test/swap/swap_std_vector_of_boost.cpp | 6 +- test/swap/swap_std_vector_of_global.cpp | 6 +- test/swap/swap_std_vector_of_other.cpp | 6 +- 34 files changed, 214 insertions(+), 192 deletions(-) create mode 100644 include/boost/core/invoke_swap.hpp delete mode 100644 test/swap/swap_mixed_headers_1.cpp delete mode 100644 test/swap/swap_mixed_headers_2.cpp delete mode 100644 test/swap/swap_root_header_1.cpp delete mode 100644 test/swap/swap_root_header_2.cpp diff --git a/doc/changes.qbk b/doc/changes.qbk index 796e585..aa14d51 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -1,12 +1,29 @@ [/ Copyright 2021 Peter Dimov - Copyright 2022 Andrey Semashev + Copyright 2022-2023 Andrey Semashev Distributed under the Boost Software License, Version 1.0. https://boost.org/LICENSE_1_0.txt) ] [section Revision History] +[section Changes in 1.84.0] + +* `boost::swap` utility function has been renamed to `boost::core::invoke_swap` to + avoid forming a potential infinite recursion when the arguments are not swappable. + The new function is defined in `boost/core/invoke_swap.hpp` and is functionally equivalent + to `boost::swap`. The old `boost::swap` name is preserved for backward compatibility + but deprecated and will be removed in a future release. Its `noexcept` specification + has been removed to avoid compile errors caused by compile-time recursion. + `BOOST_ALLOW_DEPRECATED_SYMBOLS` or `BOOST_ALLOW_DEPRECATED` can be defined to suppress + deprecation warnings for the transition period. ([@https://github.com/boostorg/core/issues/148 #148]) +* Headers `boost/swap.hpp`, `boost/utility/swap.hpp` and `boost/core/swap.hpp` are + deprecated and will be removed. Please, switch to `boost/core/invoke_swap.hpp`. + `BOOST_ALLOW_DEPRECATED_HEADERS` or `BOOST_ALLOW_DEPRECATED` can be defined to suppress + deprecation warnings. + +[endsect] + [section Changes in 1.83.0] * Added support for incomplete types to [link core.type_name `boost::core::type_name`]. diff --git a/doc/swap.qbk b/doc/swap.qbk index 5770b9d..98aeb09 100644 --- a/doc/swap.qbk +++ b/doc/swap.qbk @@ -20,17 +20,17 @@ [endsimplesect] -[section Header ] +[section Header ] -[^template void swap(T& left, T& right) noexcept(['see below]);] +[^template void invoke_swap(T& left, T& right) noexcept(['see below]);] [endsect] [section Introduction] -The template function `boost::swap` allows the values of two -variables to be swapped, using argument dependent lookup to -select a specialized swap function if available. If no +The template function `boost::core::invoke_swap` allows the +values of two variables to be swapped, using argument dependent +lookup to select a specialized swap function if available. If no specialized swap function is available, `std::swap` is used. [endsect] @@ -56,9 +56,9 @@ Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces. -`boost::swap` also supports swapping built-in arrays. Note that -`std::swap` originally did not do so, but a request to add an -overload of `std::swap` for built-in arrays has been accepted +`boost::core::invoke_swap` also supports swapping built-in arrays. +Note that `std::swap` originally did not do so, but a request to +add an overload of `std::swap` for built-in arrays has been accepted by the C++ Standards Committee[footnote [@http://open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809 LWG Defect Report 809: std::swap should be overloaded for array @@ -68,14 +68,15 @@ by the C++ Standards Committee[footnote [section Exception Safety] -`boost::swap` provides the same exception guarantee as the -underlying swap function used, with one exception; for an array +`boost::core::invoke_swap` provides the same exception guarantee as +the underlying swap function used, with one exception; for an array of type `T[n]`, where `n > 1` and the underlying swap function -for `T` provides the strong exception guarantee, `boost::swap` -provides only the basic exception guarantee. +for `T` provides the strong exception guarantee, +`boost::core::invoke_swap` provides only the basic exception guarantee. -In C++11 and later, `boost::swap` propagates the same `noexcept` -specification as the one specified in the underlying swap function. +In C++11 and later, `boost::core::invoke_swap` propagates the same +`noexcept` specification as the one specified in the underlying swap +function. [endsect] @@ -104,7 +105,7 @@ Or: [section Portability] Several older compilers do not support argument dependent -lookup. On these compilers `boost::swap` will call +lookup. On these compilers `boost::core::invoke_swap` will call `std::swap`, ignoring any specialized swap functions that could be found as a result of argument dependent lookup. @@ -118,7 +119,9 @@ could be found as a result of argument dependent lookup. tests, and documentation * *Steven Watanabe* - for the idea to make `boost::swap` less specialized than `std::swap`, thereby allowing the function - to have the name 'swap' without introducing ambiguity + to have the name 'swap' without introducing ambiguity. However, + later the function was renamed to `boost::core::invoke_swap` + to avoid potential infinite recursion. [endsect] diff --git a/include/boost/core/invoke_swap.hpp b/include/boost/core/invoke_swap.hpp new file mode 100644 index 0000000..8056289 --- /dev/null +++ b/include/boost/core/invoke_swap.hpp @@ -0,0 +1,93 @@ +// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker +// Copyright (C) 2023 Andrey Semashev +// +// 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) +// For more information, see http://www.boost.org + +#ifndef BOOST_CORE_INVOKE_SWAP_HPP +#define BOOST_CORE_INVOKE_SWAP_HPP + +// Note: the implementation of this utility contains various workarounds: +// - invoke_swap_impl is put outside the boost namespace, to avoid infinite +// recursion (causing stack overflow) when swapping objects of a primitive +// type. +// - std::swap is imported with a using-directive, rather than +// a using-declaration, because some compilers (including MSVC 7.1, +// Borland 5.9.3, and Intel 8.1) don't do argument-dependent lookup +// when it has a using-declaration instead. +// - The main entry function is called invoke_swap rather than swap +// to avoid forming an infinite recursion when the arguments are not +// swappable. + +#include +#include +#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB) +#include // for std::swap (C++11) +#else +#include // for std::swap (C++98) +#endif +#include // for std::size_t + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_GCC) && (BOOST_GCC < 40700) +// gcc 4.6 ICEs on noexcept specifications below +#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) +#else +#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x) +#endif + +namespace boost_swap_impl { + +// we can't use type_traits here + +template struct is_const { enum _vt { value = 0 }; }; +template struct is_const { enum _vt { value = 1 }; }; + +// Use std::swap if argument dependent lookup fails. +// We need to have this at namespace scope to be able to use unqualified swap() call +// in noexcept specification. +using namespace std; + +template +BOOST_GPU_ENABLED +inline void invoke_swap_impl(T& left, T& right) BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(swap(left, right))) +{ + swap(left, right); +} + +template +BOOST_GPU_ENABLED +inline void invoke_swap_impl(T (& left)[N], T (& right)[N]) + BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::invoke_swap_impl(left[0], right[0]))) +{ + for (std::size_t i = 0; i < N; ++i) + { + ::boost_swap_impl::invoke_swap_impl(left[i], right[i]); + } +} + +} // namespace boost_swap_impl + +namespace boost { +namespace core { + +template +BOOST_GPU_ENABLED +inline typename enable_if_c< !::boost_swap_impl::is_const::value >::type +invoke_swap(T& left, T& right) + BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::invoke_swap_impl(left, right))) +{ + ::boost_swap_impl::invoke_swap_impl(left, right); +} + +} // namespace core +} // namespace boost + +#undef BOOST_CORE_SWAP_NOEXCEPT_IF + +#endif // BOOST_CORE_INVOKE_SWAP_HPP diff --git a/include/boost/core/swap.hpp b/include/boost/core/swap.hpp index 7add2fb..4696c44 100644 --- a/include/boost/core/swap.hpp +++ b/include/boost/core/swap.hpp @@ -10,80 +10,31 @@ #define BOOST_CORE_SWAP_HPP // Note: the implementation of this utility contains various workarounds: -// - swap_impl is put outside the boost namespace, to avoid infinite -// recursion (causing stack overflow) when swapping objects of a primitive -// type. -// - std::swap is imported with a using-directive, rather than -// a using-declaration, because some compilers (including MSVC 7.1, -// Borland 5.9.3, and Intel 8.1) don't do argument-dependent lookup -// when it has a using-declaration instead. // - boost::swap has two template arguments, instead of one, to // avoid ambiguity when swapping objects of a Boost type that does // not have its own boost::swap overload. #include #include -#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB) -#include // for std::swap (C++11) -#else -#include // for std::swap (C++98) -#endif -#include // for std::size_t +#include +#include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif -#if defined(BOOST_GCC) && (BOOST_GCC < 40700) -// gcc 4.6 ICEs on noexcept specifications below -#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) -#else -#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x) -#endif - -namespace boost_swap_impl -{ - // we can't use type_traits here - - template struct is_const { enum _vt { value = 0 }; }; - template struct is_const { enum _vt { value = 1 }; }; - - // Use std::swap if argument dependent lookup fails. - // We need to have this at namespace scope to be able to use unqualified swap() call - // in noexcept specification. - using namespace std; - - template - BOOST_GPU_ENABLED - void swap_impl(T& left, T& right) BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(swap(left, right))) - { - swap(left, right); - } - - template - BOOST_GPU_ENABLED - void swap_impl(T (& left)[N], T (& right)[N]) - BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::swap_impl(left[0], right[0]))) - { - for (std::size_t i = 0; i < N; ++i) - { - ::boost_swap_impl::swap_impl(left[i], right[i]); - } - } -} +BOOST_HEADER_DEPRECATED("boost/core/invoke_swap.hpp") namespace boost { template BOOST_GPU_ENABLED - typename enable_if_c< !boost_swap_impl::is_const::value && !boost_swap_impl::is_const::value >::type + BOOST_DEPRECATED("This function is deprecated, use boost::core::invoke_swap instead.") + inline typename enable_if_c< !boost_swap_impl::is_const::value && !boost_swap_impl::is_const::value >::type swap(T1& left, T2& right) - BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::swap_impl(left, right))) { - ::boost_swap_impl::swap_impl(left, right); + boost::core::invoke_swap(left, right); } } -#undef BOOST_CORE_SWAP_NOEXCEPT_IF - #endif // BOOST_CORE_SWAP_HPP diff --git a/include/boost/swap.hpp b/include/boost/swap.hpp index 55cafa4..7d2232e 100644 --- a/include/boost/swap.hpp +++ b/include/boost/swap.hpp @@ -10,8 +10,11 @@ #define BOOST_SWAP_HPP // The header file at this path is deprecated; -// use boost/core/swap.hpp instead. +// use boost/core/invoke_swap.hpp instead. +#include #include +BOOST_HEADER_DEPRECATED("boost/core/invoke_swap.hpp") + #endif diff --git a/include/boost/utility/swap.hpp b/include/boost/utility/swap.hpp index dd9ecd9..662899e 100644 --- a/include/boost/utility/swap.hpp +++ b/include/boost/utility/swap.hpp @@ -10,8 +10,11 @@ #define BOOST_UTILITY_SWAP_HPP // The header file at this path is deprecated; -// use boost/core/swap.hpp instead. +// use boost/core/invoke_swap.hpp instead. +#include #include +BOOST_HEADER_DEPRECATED("boost/core/invoke_swap.hpp") + #endif diff --git a/test/swap/Jamfile.v2 b/test/swap/Jamfile.v2 index d7f705e..dcd18f9 100644 --- a/test/swap/Jamfile.v2 +++ b/test/swap/Jamfile.v2 @@ -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 ; diff --git a/test/swap/swap_array_of_array_of_class.cpp b/test/swap/swap_array_of_array_of_class.cpp index 1ea78da..5f0a7e6 100644 --- a/test/swap/swap_array_of_array_of_class.cpp +++ b/test/swap/swap_array_of_array_of_class.cpp @@ -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 +#include #include #define BOOST_CHECK BOOST_TEST #define BOOST_CHECK_EQUAL BOOST_TEST_EQ @@ -59,7 +59,7 @@ int main() ptr2[i].set_data( static_cast(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) { diff --git a/test/swap/swap_array_of_array_of_int.cpp b/test/swap/swap_array_of_array_of_int.cpp index 3f9b239..8fe45f9 100644 --- a/test/swap/swap_array_of_array_of_int.cpp +++ b/test/swap/swap_array_of_array_of_int.cpp @@ -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 +#include #include #define BOOST_CHECK BOOST_TEST #define BOOST_CHECK_EQUAL BOOST_TEST_EQ @@ -32,7 +32,7 @@ int main() ptr2[i] = static_cast(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) { diff --git a/test/swap/swap_array_of_class.cpp b/test/swap/swap_array_of_class.cpp index b8b496a..52c529d 100644 --- a/test/swap/swap_array_of_class.cpp +++ b/test/swap/swap_array_of_class.cpp @@ -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 +#include #include #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)); diff --git a/test/swap/swap_array_of_int.cpp b/test/swap/swap_array_of_int.cpp index 1978d90..9f4775e 100644 --- a/test/swap/swap_array_of_int.cpp +++ b/test/swap/swap_array_of_int.cpp @@ -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 +#include #include #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)); diff --git a/test/swap/swap_array_of_template.cpp b/test/swap/swap_array_of_template.cpp index 652d418..3921eab 100644 --- a/test/swap/swap_array_of_template.cpp +++ b/test/swap/swap_array_of_template.cpp @@ -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 objects by means of boost::swap. +// Tests swapping an array of swap_test_template objects by means of boost::core::invoke_swap. -#include +#include #include #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)); diff --git a/test/swap/swap_const_wrapper_fail.cpp b/test/swap/swap_const_wrapper_fail.cpp index ea44a4d..d773e57 100644 --- a/test/swap/swap_const_wrapper_fail.cpp +++ b/test/swap/swap_const_wrapper_fail.cpp @@ -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 +#include namespace boost { @@ -14,7 +14,7 @@ template struct Wrapper template inline void swap( Wrapper & w, Wrapper & v ) { - boost::swap( w, v ); + boost::core::invoke_swap( w, v ); } } // namespace boost diff --git a/test/swap/swap_lib_header_1.cpp b/test/swap/swap_lib_header_1.cpp index 923dea6..1547eef 100644 --- a/test/swap/swap_lib_header_1.cpp +++ b/test/swap/swap_lib_header_1.cpp @@ -6,5 +6,5 @@ // Tests that the swap header compiles as a standalone translation unit -#include +#include diff --git a/test/swap/swap_lib_header_2.cpp b/test/swap/swap_lib_header_2.cpp index e88909d..f226892 100644 --- a/test/swap/swap_lib_header_2.cpp +++ b/test/swap/swap_lib_header_2.cpp @@ -6,6 +6,6 @@ // Tests that the swap header include guards work correctly -#include -#include +#include +#include diff --git a/test/swap/swap_mixed_headers_1.cpp b/test/swap/swap_mixed_headers_1.cpp deleted file mode 100644 index cdb9fe5..0000000 --- a/test/swap/swap_mixed_headers_1.cpp +++ /dev/null @@ -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 -#include - diff --git a/test/swap/swap_mixed_headers_2.cpp b/test/swap/swap_mixed_headers_2.cpp deleted file mode 100644 index 94e9d87..0000000 --- a/test/swap/swap_mixed_headers_2.cpp +++ /dev/null @@ -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 -#include - - diff --git a/test/swap/swap_no_ambiguity_in_boost.cpp b/test/swap/swap_no_ambiguity_in_boost.cpp index 795ffe3..3c91f0c 100644 --- a/test/swap/swap_no_ambiguity_in_boost.cpp +++ b/test/swap/swap_no_ambiguity_in_boost.cpp @@ -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 +#include #include #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); diff --git a/test/swap/swap_noexcept.cpp b/test/swap/swap_noexcept.cpp index cafbde1..2036142 100644 --- a/test/swap/swap_noexcept.cpp +++ b/test/swap/swap_noexcept.cpp @@ -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 +#include #include #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) ... diff --git a/test/swap/swap_primitive.cpp b/test/swap/swap_primitive.cpp index a996f01..4522641 100644 --- a/test/swap/swap_primitive.cpp +++ b/test/swap/swap_primitive.cpp @@ -4,7 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #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); diff --git a/test/swap/swap_root_header_1.cpp b/test/swap/swap_root_header_1.cpp deleted file mode 100644 index 575d2cb..0000000 --- a/test/swap/swap_root_header_1.cpp +++ /dev/null @@ -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 - diff --git a/test/swap/swap_root_header_2.cpp b/test/swap/swap_root_header_2.cpp deleted file mode 100644 index d26b3a6..0000000 --- a/test/swap/swap_root_header_2.cpp +++ /dev/null @@ -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 -#include - diff --git a/test/swap/swap_specialized_in_boost.cpp b/test/swap/swap_specialized_in_boost.cpp index ab74b5e..4617269 100644 --- a/test/swap/swap_specialized_in_boost.cpp +++ b/test/swap/swap_specialized_in_boost.cpp @@ -4,7 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #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); diff --git a/test/swap/swap_specialized_in_boost_and_other.cpp b/test/swap/swap_specialized_in_boost_and_other.cpp index 3f874bc..31e3b42 100644 --- a/test/swap/swap_specialized_in_boost_and_other.cpp +++ b/test/swap/swap_specialized_in_boost_and_other.cpp @@ -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 +#include #include #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); diff --git a/test/swap/swap_specialized_in_global.cpp b/test/swap/swap_specialized_in_global.cpp index 72eb15c..170f4ec 100644 --- a/test/swap/swap_specialized_in_global.cpp +++ b/test/swap/swap_specialized_in_global.cpp @@ -4,7 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #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); diff --git a/test/swap/swap_specialized_in_other.cpp b/test/swap/swap_specialized_in_other.cpp index 74240fc..f93bd72 100644 --- a/test/swap/swap_specialized_in_other.cpp +++ b/test/swap/swap_specialized_in_other.cpp @@ -4,7 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #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); diff --git a/test/swap/swap_specialized_in_std.cpp b/test/swap/swap_specialized_in_std.cpp index 6be5e77..45f78a2 100644 --- a/test/swap/swap_specialized_in_std.cpp +++ b/test/swap/swap_specialized_in_std.cpp @@ -4,7 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #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); diff --git a/test/swap/swap_std_bitset.cpp b/test/swap/swap_std_bitset.cpp index 6fc3ecb..7b8e5d1 100644 --- a/test/swap/swap_std_bitset.cpp +++ b/test/swap/swap_std_bitset.cpp @@ -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 objects by means of boost::swap. +// Tests swapping std::bitset objects by means of boost::core::invoke_swap. // Unlike most other Standard C++ Library template classes, // std::bitset does not have its own std::swap overload. -#include +#include #include #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); diff --git a/test/swap/swap_std_dateorder.cpp b/test/swap/swap_std_dateorder.cpp index 7f6df73..d26729d 100644 --- a/test/swap/swap_std_dateorder.cpp +++ b/test/swap/swap_std_dateorder.cpp @@ -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 +#include #include #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); diff --git a/test/swap/swap_std_string.cpp b/test/swap/swap_std_string.cpp index 128f3b5..14c8e7c 100644 --- a/test/swap/swap_std_string.cpp +++ b/test/swap/swap_std_string.cpp @@ -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 +#include #include #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); diff --git a/test/swap/swap_std_typeinfo_ptr.cpp b/test/swap/swap_std_typeinfo_ptr.cpp index dfd35a5..b255aa7 100644 --- a/test/swap/swap_std_typeinfo_ptr.cpp +++ b/test/swap/swap_std_typeinfo_ptr.cpp @@ -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 +#include #include #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); diff --git a/test/swap/swap_std_vector_of_boost.cpp b/test/swap/swap_std_vector_of_boost.cpp index e2badc5..f32a168 100644 --- a/test/swap/swap_std_vector_of_boost.cpp +++ b/test/swap/swap_std_vector_of_boost.cpp @@ -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 +#include #include #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); diff --git a/test/swap/swap_std_vector_of_global.cpp b/test/swap/swap_std_vector_of_global.cpp index 11fe9b3..f394b1a 100644 --- a/test/swap/swap_std_vector_of_global.cpp +++ b/test/swap/swap_std_vector_of_global.cpp @@ -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 +#include #include #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); diff --git a/test/swap/swap_std_vector_of_other.cpp b/test/swap/swap_std_vector_of_other.cpp index a713767..d7d4396 100644 --- a/test/swap/swap_std_vector_of_other.cpp +++ b/test/swap/swap_std_vector_of_other.cpp @@ -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 +#include #include #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);