8 General utilities library [utilities]

8.2 Utility components [utility]

8.2.1 swap [utility.swap]

The name swap denotes a customization point object ([customization.point.object]). The effect of the expression ranges::swap(E1, E2) for some expressions E1 and E2 is equivalent to:

  • (void)swap(E1, E2), if that expression is valid, with overload resolution performed in a context that includes the declarations

      template <class T>
      void swap(T&, T&) = delete;
      template <class T, size_t N>
      void swap(T(&)[N], T(&)[N]) = delete;
    

    and does not include a declaration of ranges::swap. If the function selected by overload resolution does not exchange the values referenced by E1 and E2, the program is ill-formed with no diagnostic required.

  • Otherwise, (void)swap_ranges(E1, E2) if E1 and E2 are lvalues of array types ( ISO/IEC 14882:2014 §[basic.compound]) of equal extent and ranges::swap(*(E1), *(E2)) is a valid expression, except that noexcept(ranges::swap(E1, E2)) is equal to noexcept(ranges::swap(*(E1), *(E2))).

  • Otherwise, if E1 and E2 are lvalues of the same type T which meets the syntactic requirements of MoveConstructible<T> and Assignable<T&, T>, exchanges the referenced values. ranges::swap(E1, E2) is a constant expression if the constructor selected by overload resolution for T{std::move(E1)} is a constexpr constructor and the expression E1 = std::move(E2) can appear in a constexpr function. noexcept(ranges::swap(E1, E2)) is equal to is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value. If either MoveConstructible or Assignable is not satisfied, the program is ill-formed with no diagnostic required.

  • Otherwise, ranges::swap(E1, E2) is ill-formed.

Remark: Whenever ranges::swap(E1, E2) is a valid expression, it exchanges the values referenced by E1 and E2 and has type void.