< 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 */);

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_move_storable<I1, I2> and std::indirectly_move_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::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 (denoted, for exposition purposes, as iter_swap_ftor). All instances of iter_swap_ftor are equal. 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_ftor will satisfy std::invocable<const iter_swap_ftor&, Args...>. Otherwise, no function call operator of iter_swap_ftor 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]