[iterator.cust.swap]

# 24 Iterators library [[iterators]](./#iterators)

## 24.3 Iterator requirements [[iterator.requirements]](iterator.requirements#iterator.cust.swap)

### 24.3.3 Customization point objects [[iterator.cust]](iterator.cust#swap)

#### 24.3.3.2 ranges​::​iter_swap [iterator.cust.swap]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1182)

The name ranges​::​iter_swap denotes
a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))
that exchanges the values ([[concept.swappable]](concept.swappable "18.4.9 Concept swappable")) denoted by its
arguments[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1188)

Let *iter-exchange-move* be the exposition-only function template:

[ð](#itemdecl:1)

`template<class X, class Y>
  constexpr iter_value_t<X> iter-exchange-move(X&& x, Y&& y)
    noexcept(noexcept(iter_value_t<X>(iter_move(x))) &&
             noexcept(*x = iter_move(y)));
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1198)

*Effects*: Equivalent to:iter_value_t<X> old_value(iter_move(x));*x = iter_move(y);return old_value;

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1208)

The expression ranges​::​iter_swap(E1, E2) for subexpressionsE1 and E2 is expression-equivalent to:

- [(4.1)](#4.1)

  (void)iter_swap(E1, E2), if eitherE1 or E2 has class or enumeration type anditer_swap(E1, E2) is a well-formed expression
with overload resolution performed in a context that includes the declarationtemplate<class I1, class I2>void iter_swap(I1, I2) = delete; and does not include a declaration of ranges​::​iter_swap[.](#4.1.sentence-1)
  If the function selected by overload resolution does not exchange the values
denoted by E1 and E2,
the program is ill-formed, no diagnostic required[.](#4.1.sentence-2)
  [*Note [1](#note-1)*:
  This precludes calling unconstrained std​::​iter_swap[.](#4.1.sentence-3)
  When the deleted
overload is viable, program-defined overloads need to be more
specialized ([[temp.func.order]](temp.func.order "13.7.7.3 Partial ordering of function templates")) to be selected[.](#4.1.sentence-4)
 â *end note*]

- [(4.2)](#4.2)

  Otherwise, if the types of E1 and E2 each model[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]"), and if the reference types of E1 and E2 model [swappable_with](concept.swappable#concept:swappable_with "18.4.9 Concept swappable [concept.swappable]") ([[concept.swappable]](concept.swappable "18.4.9 Concept swappable")),
then ranges​::​swap(*E1, *E2)[.](#4.2.sentence-1)

- [(4.3)](#4.3)

  Otherwise, if the types T1 and T2 of E1 andE2 model [indirectly_movable_storable](alg.req.ind.move#concept:indirectly_movable_storable "24.3.7.2 Concept indirectly_­movable [alg.req.ind.move]")<T1, T2> and[indirectly_movable_storable](alg.req.ind.move#concept:indirectly_movable_storable "24.3.7.2 Concept indirectly_­movable [alg.req.ind.move]")<T2, T1>, then(void)(*E1 = *iter-exchange-move*(E2, E1)),
except that E1 is evaluated only once[.](#4.3.sentence-1)

- [(4.4)](#4.4)

  Otherwise, ranges​::​iter_swap(E1, E2) is ill-formed[.](#4.4.sentence-1)
  [*Note [2](#note-2)*:
  This case can result in substitution failure when ranges​::​iter_swap(E1, E2) appears in the immediate context of a template instantiation[.](#4.4.sentence-2)
 â *end note*]
