Files
2025-10-25 03:02:53 +03:00

5.4 KiB
Raw Permalink Blame History

[iterator.cust]

24 Iterators library [iterators]

24.3 Iterator requirements [iterator.requirements]

24.3.3 Customization point objects [iterator.cust]

24.3.3.1 ranges::iter_move [iterator.cust.move]

1

#

The name ranges::iter_move denotes a customization point object ([customization.point.object]).

The expression ranges::iter_move(E) for a subexpression E is expression-equivalent to:

  • (1.1)

    iter_move(E), ifE has class or enumeration type anditer_move(E) is a well-formed expression when treated as an unevaluated operand, where the meaning of iter_move is established as-if by performing argument-dependent lookup only ([basic.lookup.argdep]).

  • (1.2)

    Otherwise, if the expression *E is well-formed:

if *E is an lvalue, std::move(*E);

otherwise, *E.

  • (1.3)

    Otherwise, ranges::iter_move(E) is ill-formed. [Note 1: This case can result in substitution failure when ranges::iter_move(E) appears in the immediate context of a template instantiation. — end note]

2

#

If ranges::iter_move(E) is not equal to *E, the program is ill-formed, no diagnostic required.

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

1

#

The name ranges::iter_swap denotes a customization point object ([customization.point.object]) that exchanges the values ([concept.swappable]) denoted by its arguments.

2

#

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

🔗

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

#

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

4

#

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

  • (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. 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. [Note 1: This precludes calling unconstrained std::iter_swap. When the deleted overload is viable, program-defined overloads need to be more specialized ([temp.func.order]) to be selected. — end note]

  • (4.2)

    Otherwise, if the types of E1 and E2 each modelindirectly_readable, and if the reference types of E1 and E2 model swappable_with ([concept.swappable]), then ranges::swap(*E1, *E2).

  • (4.3)

    Otherwise, if the types T1 and T2 of E1 andE2 model indirectly_movable_storable<T1, T2> andindirectly_movable_storable<T2, T1>, then(void)(*E1 = iter-exchange-move(E2, E1)), except that E1 is evaluated only once.

  • (4.4)

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