mirror of
https://github.com/boostorg/core.git
synced 2025-05-09 23:03:54 +00:00
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.
129 lines
3.9 KiB
Plaintext
129 lines
3.9 KiB
Plaintext
[/
|
|
/ Copyright (c) 2008 Joseph Gauterin
|
|
/ Copyright (c) 2008, 2009 Niels Dekker
|
|
/ Copyright (c) 2014 Glen Fernandes
|
|
/
|
|
/ 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
|
|
/]
|
|
|
|
[section:swap swap]
|
|
|
|
[simplesect Authors]
|
|
|
|
* Niels Dekker
|
|
* Joseph Gauterin
|
|
* Steven Watanabe
|
|
* Eric Niebler
|
|
|
|
[endsimplesect]
|
|
|
|
[section Header <boost/core/invoke_swap.hpp>]
|
|
|
|
[^template<class T> void invoke_swap(T& left, T& right) noexcept(['see below]);]
|
|
|
|
[endsect]
|
|
|
|
[section Introduction]
|
|
|
|
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]
|
|
|
|
[section Rationale]
|
|
|
|
The generic `std::swap` function requires that the elements
|
|
to be swapped are assignable and copy constructible. It is
|
|
usually implemented using one copy construction and two
|
|
assignments (C++11 replaces copy operations with move) - this
|
|
is often both unnecessarily restrictive and unnecessarily slow.
|
|
In addition, where the generic swap implementation provides
|
|
only the basic guarantee, specialized swap functions are often
|
|
able to provide the no-throw exception guarantee (and it is
|
|
considered best practice to do so where possible[footnote Scott
|
|
Meyers, Effective C++ Third Edition, Item 25: "Consider support
|
|
for a non-throwing swap"].
|
|
|
|
The alternative to using argument dependent lookup in this
|
|
situation is to provide a template specialization of
|
|
`std::swap` for every type that requires a specialized swap.
|
|
Although this is legal C++, no Boost libraries use this method,
|
|
whereas many Boost libraries provide specialized swap functions
|
|
in their own namespaces.
|
|
|
|
`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
|
|
types]].
|
|
|
|
[endsect]
|
|
|
|
[section Exception Safety]
|
|
|
|
`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::core::invoke_swap` provides only the basic exception guarantee.
|
|
|
|
In C++11 and later, `boost::core::invoke_swap` propagates the same
|
|
`noexcept` specification as the one specified in the underlying swap
|
|
function.
|
|
|
|
[endsect]
|
|
|
|
[section Requirements]
|
|
|
|
Either:
|
|
|
|
* `T` must be copy assignable (/since C++11:/ move assignable)
|
|
* `T` must be copy constructible (/since C++11:/ move constructible)
|
|
|
|
Or:
|
|
|
|
* A function with the signature `swap(T&, T&)` is available via
|
|
argument dependent lookup
|
|
|
|
Or:
|
|
|
|
* A template specialization of `std::swap` exists for `T`
|
|
|
|
Or:
|
|
|
|
* `T` is a built-in array of swappable elements
|
|
|
|
[endsect]
|
|
|
|
[section Portability]
|
|
|
|
Several older compilers do not support argument dependent
|
|
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.
|
|
|
|
[endsect]
|
|
|
|
[section Credits]
|
|
|
|
* *Niels Dekker* - for implementing and documenting support for
|
|
built-in arrays
|
|
* *Joseph Gauterin* - for the initial idea, implementation,
|
|
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. However,
|
|
later the function was renamed to `boost::core::invoke_swap`
|
|
to avoid potential infinite recursion.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|