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

View File

@ -1,12 +1,29 @@
[/ [/
Copyright 2021 Peter Dimov Copyright 2021 Peter Dimov
Copyright 2022 Andrey Semashev Copyright 2022-2023 Andrey Semashev
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt) https://boost.org/LICENSE_1_0.txt)
] ]
[section Revision History] [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] [section Changes in 1.83.0]
* Added support for incomplete types to [link core.type_name `boost::core::type_name`]. * Added support for incomplete types to [link core.type_name `boost::core::type_name`].

View File

@ -20,17 +20,17 @@
[endsimplesect] [endsimplesect]
[section Header <boost/core/swap.hpp>] [section Header <boost/core/invoke_swap.hpp>]
[^template<class T> void swap(T& left, T& right) noexcept(['see below]);] [^template<class T> void invoke_swap(T& left, T& right) noexcept(['see below]);]
[endsect] [endsect]
[section Introduction] [section Introduction]
The template function `boost::swap` allows the values of two The template function `boost::core::invoke_swap` allows the
variables to be swapped, using argument dependent lookup to values of two variables to be swapped, using argument dependent
select a specialized swap function if available. If no lookup to select a specialized swap function if available. If no
specialized swap function is available, `std::swap` is used. specialized swap function is available, `std::swap` is used.
[endsect] [endsect]
@ -56,9 +56,9 @@ Although this is legal C++, no Boost libraries use this method,
whereas many Boost libraries provide specialized swap functions whereas many Boost libraries provide specialized swap functions
in their own namespaces. in their own namespaces.
`boost::swap` also supports swapping built-in arrays. Note that `boost::core::invoke_swap` also supports swapping built-in arrays.
`std::swap` originally did not do so, but a request to add an Note that `std::swap` originally did not do so, but a request to
overload of `std::swap` for built-in arrays has been accepted add an overload of `std::swap` for built-in arrays has been accepted
by the C++ Standards Committee[footnote by the C++ Standards Committee[footnote
[@http://open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809 [@http://open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809
LWG Defect Report 809: std::swap should be overloaded for array LWG Defect Report 809: std::swap should be overloaded for array
@ -68,14 +68,15 @@ by the C++ Standards Committee[footnote
[section Exception Safety] [section Exception Safety]
`boost::swap` provides the same exception guarantee as the `boost::core::invoke_swap` provides the same exception guarantee as
underlying swap function used, with one exception; for an array the underlying swap function used, with one exception; for an array
of type `T[n]`, where `n > 1` and the underlying swap function of type `T[n]`, where `n > 1` and the underlying swap function
for `T` provides the strong exception guarantee, `boost::swap` for `T` provides the strong exception guarantee,
provides only the basic exception guarantee. `boost::core::invoke_swap` provides only the basic exception guarantee.
In C++11 and later, `boost::swap` propagates the same `noexcept` In C++11 and later, `boost::core::invoke_swap` propagates the same
specification as the one specified in the underlying swap function. `noexcept` specification as the one specified in the underlying swap
function.
[endsect] [endsect]
@ -104,7 +105,7 @@ Or:
[section Portability] [section Portability]
Several older compilers do not support argument dependent 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 `std::swap`, ignoring any specialized swap functions that
could be found as a result of argument dependent lookup. 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 tests, and documentation
* *Steven Watanabe* - for the idea to make `boost::swap` less * *Steven Watanabe* - for the idea to make `boost::swap` less
specialized than `std::swap`, thereby allowing the function 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] [endsect]

View File

@ -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 <boost/core/enable_if.hpp>
#include <boost/config.hpp>
#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB)
#include <utility> // for std::swap (C++11)
#else
#include <algorithm> // for std::swap (C++98)
#endif
#include <cstddef> // 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<class T> struct is_const { enum _vt { value = 0 }; };
template<class T> struct is_const<T 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<class T>
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<class T, std::size_t N>
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<class T>
BOOST_GPU_ENABLED
inline typename enable_if_c< !::boost_swap_impl::is_const<T>::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

View File

@ -10,80 +10,31 @@
#define BOOST_CORE_SWAP_HPP #define BOOST_CORE_SWAP_HPP
// Note: the implementation of this utility contains various workarounds: // 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 // - boost::swap has two template arguments, instead of one, to
// avoid ambiguity when swapping objects of a Boost type that does // avoid ambiguity when swapping objects of a Boost type that does
// not have its own boost::swap overload. // not have its own boost::swap overload.
#include <boost/core/enable_if.hpp> #include <boost/core/enable_if.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB) #include <boost/config/header_deprecated.hpp>
#include <utility> // for std::swap (C++11) #include <boost/core/invoke_swap.hpp>
#else
#include <algorithm> // for std::swap (C++98)
#endif
#include <cstddef> // for std::size_t
#ifdef BOOST_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
#if defined(BOOST_GCC) && (BOOST_GCC < 40700) BOOST_HEADER_DEPRECATED("boost/core/invoke_swap.hpp")
// 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<class T> struct is_const { enum _vt { value = 0 }; };
template<class T> struct is_const<T 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<class T>
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<class T, std::size_t N>
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]);
}
}
}
namespace boost namespace boost
{ {
template<class T1, class T2> template<class T1, class T2>
BOOST_GPU_ENABLED BOOST_GPU_ENABLED
typename enable_if_c< !boost_swap_impl::is_const<T1>::value && !boost_swap_impl::is_const<T2>::value >::type BOOST_DEPRECATED("This function is deprecated, use boost::core::invoke_swap instead.")
inline typename enable_if_c< !boost_swap_impl::is_const<T1>::value && !boost_swap_impl::is_const<T2>::value >::type
swap(T1& left, T2& right) 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 #endif // BOOST_CORE_SWAP_HPP

View File

@ -10,8 +10,11 @@
#define BOOST_SWAP_HPP #define BOOST_SWAP_HPP
// The header file at this path is deprecated; // The header file at this path is deprecated;
// use boost/core/swap.hpp instead. // use boost/core/invoke_swap.hpp instead.
#include <boost/config/header_deprecated.hpp>
#include <boost/core/swap.hpp> #include <boost/core/swap.hpp>
BOOST_HEADER_DEPRECATED("boost/core/invoke_swap.hpp")
#endif #endif

View File

@ -10,8 +10,11 @@
#define BOOST_UTILITY_SWAP_HPP #define BOOST_UTILITY_SWAP_HPP
// The header file at this path is deprecated; // The header file at this path is deprecated;
// use boost/core/swap.hpp instead. // use boost/core/invoke_swap.hpp instead.
#include <boost/config/header_deprecated.hpp>
#include <boost/core/swap.hpp> #include <boost/core/swap.hpp>
BOOST_HEADER_DEPRECATED("boost/core/invoke_swap.hpp")
#endif #endif

View File

@ -7,12 +7,8 @@
# bring in rules for testing # bring in rules for testing
import 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_1.cpp ;
compile swap_lib_header_2.cpp ; compile swap_lib_header_2.cpp ;
compile swap_mixed_headers_1.cpp ;
compile swap_mixed_headers_2.cpp ;
compile swap_noexcept.cpp ; compile swap_noexcept.cpp ;
compile-fail swap_const_wrapper_fail.cpp ; compile-fail swap_const_wrapper_fail.cpp ;

View File

@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -59,7 +59,7 @@ int main()
ptr2[i].set_data( static_cast<int>(i + number_of_elements) ); 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) for (std::size_t i = 0; i < number_of_elements; ++i)
{ {

View File

@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -32,7 +32,7 @@ int main()
ptr2[i] = static_cast<int>(i + number_of_elements); 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) for (std::size_t i = 0; i < number_of_elements; ++i)
{ {

View File

@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -54,7 +54,7 @@ int main()
std::copy(initial_array2, initial_array2 + array_size, array2); std::copy(initial_array2, initial_array2 + array_size, array2);
swap_test_class::reset(); 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(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));

View File

@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #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_array1, initial_array1 + array_size, array1);
std::copy(initial_array2, initial_array2 + array_size, array2); 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(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));

View File

@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -60,7 +60,7 @@ int main()
std::copy(initial_array2, initial_array2 + array_size, array2); std::copy(initial_array2, initial_array2 + array_size, array2);
swap_test_class::reset(); 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(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));

View File

@ -1,8 +1,8 @@
// Copyright 2018 Andrzej Krzemieński // Copyright 2018 Andrzej Krzemieński
// Copyright 2018 Peter Dimov // Copyright 2018 Peter Dimov
// Distributed under the Boost Software License, Version 1.0. // Distributed under the Boost Software License, Version 1.0.
#include <boost/core/swap.hpp> #include <boost/core/invoke_swap.hpp>
namespace boost namespace boost
{ {
@ -14,7 +14,7 @@ template<class T> struct Wrapper
template<class T> inline void swap( Wrapper<T> & w, Wrapper<T> & v ) template<class T> inline void swap( Wrapper<T> & w, Wrapper<T> & v )
{ {
boost::swap( w, v ); boost::core::invoke_swap( w, v );
} }
} // namespace boost } // namespace boost

View File

@ -6,5 +6,5 @@
// Tests that the swap header compiles as a standalone translation unit // Tests that the swap header compiles as a standalone translation unit
#include <boost/utility/swap.hpp> #include <boost/core/invoke_swap.hpp>

View File

@ -6,6 +6,6 @@
// Tests that the swap header include guards work correctly // Tests that the swap header include guards work correctly
#include <boost/utility/swap.hpp> #include <boost/core/invoke_swap.hpp>
#include <boost/utility/swap.hpp> #include <boost/core/invoke_swap.hpp>

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>

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>

View File

@ -4,15 +4,15 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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 // This could have led to ambiguity or infinite recursion, when the
// objects to be swapped would themselves be from the boost namespace. // objects to be swapped would themselves be from the boost namespace.
// If so, boost::swap itself might be found by argument dependent lookup. // If so, boost::core::invoke_swap itself might be found by argument dependent lookup.
// The implementation of boost::swap resolves this issue by giving // The implementation of boost::core::invoke_swap resolves this issue by giving
// boost::swap two template argumetns, thereby making it less specialized // boost::core::invoke_swap two template argumetns, thereby making it less specialized
// than std::swap. // than std::swap.
#include <boost/utility/swap.hpp> #include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -33,7 +33,7 @@ int main()
boost::swap_test_class object2 = initial_value2; boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset(); boost::swap_test_class::reset();
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2); BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1); BOOST_CHECK(object2 == initial_value1);

View File

@ -4,9 +4,9 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_STATIC_ASSERT) && \ #if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_STATIC_ASSERT) && \
@ -34,9 +34,9 @@ struct class_with_except_swap
} // namespace test_ns } // namespace test_ns
static_assert(noexcept(boost::swap(test_ns::class_with_noexcept_swap::instance(), test_ns::class_with_noexcept_swap::instance())), static_assert(noexcept(boost::core::invoke_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"); "boost::core::invoke_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())), static_assert(!noexcept(boost::core::invoke_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"); "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) ... #endif // !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_STATIC_ASSERT) ...

View File

@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -14,7 +14,7 @@ int main()
int object1 = 1; int object1 = 1;
int object2 = 2; int object2 = 2;
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1,2); BOOST_CHECK_EQUAL(object1,2);
BOOST_CHECK_EQUAL(object2,1); BOOST_CHECK_EQUAL(object2,1);

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>

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>

View File

@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -33,7 +33,7 @@ int main()
boost::swap_test_class object2 = initial_value2; boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset(); boost::swap_test_class::reset();
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2); BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1); BOOST_CHECK(object2 == initial_value1);

View File

@ -8,13 +8,13 @@
// properly swapped, when both boost and the other namespace have a custom // 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 // 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 // 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 // boost::core::invoke_swap utility should find the swap function in the other
// argument dependent lookup (ADL). Unfortunately ADL isn't fully implemented // namespace, by argument dependent lookup (ADL). Unfortunately ADL isn't fully
// by some specific compiler versions, including Intel C++ 8.1, MSVC 7.1, and // implemented by some specific compiler versions, including Intel C++ 8.1, MSVC 7.1,
// Borland 5.9.3. Users of those compilers might consider adding a swap overload // and Borland 5.9.3. Users of those compilers might consider adding a swap overload
// to the boost namespace. // to the boost namespace.
#include <boost/utility/swap.hpp> #include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -52,7 +52,7 @@ int main()
other::swap_test_class object2 = initial_value2; other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset(); other::swap_test_class::reset();
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2); BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1); BOOST_CHECK(object2 == initial_value1);

View File

@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -27,7 +27,7 @@ int main()
swap_test_class object2 = initial_value2; swap_test_class object2 = initial_value2;
swap_test_class::reset(); swap_test_class::reset();
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2); BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1); BOOST_CHECK(object2 == initial_value1);

View File

@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -33,7 +33,7 @@ int main()
other::swap_test_class object2 = initial_value2; other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset(); other::swap_test_class::reset();
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2); BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1); BOOST_CHECK(object2 == initial_value1);

View File

@ -4,7 +4,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -32,7 +32,7 @@ int main()
swap_test_class object2 = initial_value2; swap_test_class object2 = initial_value2;
swap_test_class::reset(); swap_test_class::reset();
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK(object1 == initial_value2); BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1); BOOST_CHECK(object2 == initial_value1);

View File

@ -4,11 +4,11 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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, // Unlike most other Standard C++ Library template classes,
// std::bitset<T> does not have its own std::swap overload. // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -24,7 +24,7 @@ int main()
bitset_type object1 = initial_value1; bitset_type object1 = initial_value1;
bitset_type object2 = initial_value2; bitset_type object2 = initial_value2;
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2); BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1); BOOST_CHECK_EQUAL(object2,initial_value1);

View File

@ -4,11 +4,11 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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::time_base::dateorder is an enumerated type. It does not have an
// std::swap overload or template specialization. // std::swap overload or template specialization.
#include <boost/utility/swap.hpp> #include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -23,7 +23,7 @@ int main()
std::time_base::dateorder object1 = initial_value1; std::time_base::dateorder object1 = initial_value1;
std::time_base::dateorder object2 = initial_value2; 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(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1); BOOST_CHECK_EQUAL(object2,initial_value1);

View File

@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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. // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -22,7 +22,7 @@ int main()
std::string object1 = initial_value1; std::string object1 = initial_value1;
std::string object2 = initial_value2; std::string object2 = initial_value2;
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2); BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1); BOOST_CHECK_EQUAL(object2,initial_value1);

View File

@ -4,11 +4,11 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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 // There is no std::swap overload or template specialization
// for std::type_info pointers. // for std::type_info pointers.
#include <boost/utility/swap.hpp> #include <boost/core/invoke_swap.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -23,7 +23,7 @@ int main()
const std::type_info * ptr1 = initial_value1; const std::type_info * ptr1 = initial_value1;
const std::type_info * ptr2 = initial_value2; 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(ptr1,initial_value2);
BOOST_CHECK_EQUAL(ptr2,initial_value1); BOOST_CHECK_EQUAL(ptr2,initial_value1);

View File

@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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. // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -45,7 +45,7 @@ int main()
swap_test_class_type::reset(); 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(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1); BOOST_CHECK_EQUAL(object2.size(),initial_size1);

View File

@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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. // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -38,7 +38,7 @@ int main()
swap_test_class::reset(); swap_test_class::reset();
boost::swap(object1,object2); boost::core::invoke_swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2); BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1); BOOST_CHECK_EQUAL(object2.size(),initial_size1);

View File

@ -4,10 +4,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // 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. // 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> #include <boost/core/lightweight_test.hpp>
#define BOOST_CHECK BOOST_TEST #define BOOST_CHECK BOOST_TEST
#define BOOST_CHECK_EQUAL BOOST_TEST_EQ #define BOOST_CHECK_EQUAL BOOST_TEST_EQ
@ -45,7 +45,7 @@ int main()
swap_test_class_type::reset(); 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(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1); BOOST_CHECK_EQUAL(object2.size(),initial_size1);