< cpp‎ | iterator
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
Iterator adaptors
Stream iterators
Iterator customization points
Iterator operations
Range access
Defined in header <iterator>
inline namespace /*unspecified*/ {

    inline constexpr /*unspecified*/ iter_swap = /*unspecified*/;

(since C++20)
(customization point object)
Call signature
template< class I1, class I2 >

    requires /* see below */

constexpr void iter_swap( I1&& i1, I2&& i2 ) noexcept(/* see below */);
(since C++20)

Swaps values denoted by two iterators.

A call to ranges::iter_swap is expression-equivalent to:

  1. (void)iter_swap(std::forward<I1>(i1), std::forward<I2>(i2)), if either std::remove_cvref_t<I1> or std::remove_cvref_t<I2> is a class or enumeration type and the expression is well-formed in unevaluated context, where the overload resolution is performed with the following candidates:
    If the selected overload does not exchange the value denoted by i1 and i2, the program is ill-formed, no diagnostic required.
  2. otherwise, ranges::swap(*std::forward<I1>(i1), *std::forward<I2>(i2)) if both I1 and I2 model indirectly_readable and if std::iter_reference_t<I1> and std::iter_reference_t<I2> model swappable_with.
  3. otherwise, (void)(*std::forward<I1>(i1) = /*iter_exchange_move*/(std::forward<I2>(i2), std::forward<I1>(i1))), if I1 and I2 model std::indirectly_movable_storable<I1, I2> and std::indirectly_movable_storable<I2, I1>, where iter_exchange_move is an expositon-only function template described below.

In all other cases, a call to ranges::iter_swap is ill-formed, which can result in substitution failure when ranges::iter_swap(e1, e2) appears in the immediate context of a template instantiation.

The exposition-only function template iter_exchange_move is equivalently defined as:

template<class X, class Y>
constexpr std::iter_value_t<X> /*iter_exchange_move*/(X&& x, Y&& y)
    noexcept(noexcept(std::iter_value_t<X>(std::ranges::iter_move(x)) &&
             noexcept(*x = std::ranges::iter_move(y))))
    std::iter_value_t<X> old(std::ranges::iter_move(x));
    *x = std::ranges::iter_move(y);
    return old;

[edit] Expression-equivalent

Expression e is expression-equivalent to expression f, if e and f have the same effects, either are both potentially-throwing or are both not potentially-throwing (i.e. noexcept(e) == noexcept(f)), and either are both constant subexpressions or are both not constant subexpressions.

[edit] Customization point objects

The name ranges::iter_swap denotes a customization point object, which is a const function object of a literal semiregular class type. For exposition purposes, the cv-unqualified version of its type is denoted as __iter_swap_fn.

All instances of __iter_swap_fn are equal. The effects of invoking different instances of type __iter_swap_fn on the same arguments are equivalent, regardless of whether the expression denoting the instance is an lvalue or rvalue, and is const-qualified or not (however, a volatile-qualified instance is not required to be invocable). Thus, ranges::iter_swap can be copied freely and its copies can be used interchangeably.

Given a set of types Args..., if std::declval<Args>()... meet the requirements for arguments to ranges::iter_swap above, __iter_swap_fn models std::invocable<__iter_swap_fn, Args...>, std::invocable<const __iter_swap_fn, Args...>, std::invocable<__iter_swap_fn&, Args...>, and std::invocable<const __iter_swap_fn&, Args...>. Otherwise, no function call operator of __iter_swap_fn participates in overload resolution.

[edit] See also

swaps the objects pointed to by two adjusted underlying iterators
(function template) [edit]
swaps the objects pointed to by two underlying iterators
(function template) [edit]
swaps the elements pointed to by two iterators
(function template) [edit]