Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

swap

Header <boost/core/invoke_swap.hpp>
Introduction
Rationale
Exception Safety
Requirements
Portability
Credits

Authors

  • Niels Dekker
  • Joseph Gauterin
  • Steven Watanabe
  • Eric Niebler

template<class T> void invoke_swap(T& left, T& right) noexcept(see below);

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.

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[1].

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[2].

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.

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

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.

  • 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.


[1] Scott Meyers, Effective C++ Third Edition, Item 25: "Consider support for a non-throwing swap"


PrevUpHomeNext