*This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.*

`ranges::advance(i, s)`

**Section:** 25.4.4.2 [range.iter.op.advance], 25.3.4.7 [iterator.concept.sentinel] **Status:** C++23
**Submitter:** Casey Carter **Opened:** 2020-06-18 **Last modified:** 2023-11-22

**Priority: **2

**View all other** issues in [range.iter.op.advance].

**View all issues with** C++23 status.

**Discussion:**

The specification of the iterator & sentinel overload of `ranges::advance`

in 25.4.4.2 [range.iter.op.advance] reads:

template<input_or_output_iterator I, sentinel_for<I> S> constexpr void ranges::advance(I& i, S bound);-3-

Preconditions:`[i, bound)`

denotes a range.-4-

Effects:

(4.1) — If

`I`

and`S`

model`assignable_from<I&, S>`

, equivalent to`i = std::move(bound)`

.(4.2) — […]

The assignment optimization in bullet 4.1 is just fine for callers with concrete types who can decide whether
or not to call `advance`

depending on the semantics of the assignment performed. However, since this assignment
operation isn't part of the `input_or_output_iterator`

or `sentinel_for`

requirements its semantics
are unknown for arbitrary types. Effectively, generic code is forbidden to call this overload of `advance`

when
`assignable_from<I&, S>`

is satisfied and non-generic code must tread lightly. This seems to
make the library dangerously unusable.
We can correct this problem by either:

Making the assignment operation in question an optional part of the

`sentinel_for`

concept with well-defined semantics. This concept change should be relatively safe given that`assignable_from<I&, S>`

requires`common_reference_with<const I&, const S&>`

, which is very rarely satisfied inadvertently.Requiring instead

`same_as<I, S>`

to trigger the assignment optimization in bullet 4.1 above.`S`

is`semiregular`

, so`i = std::move(s)`

is certainly well-formed (and has well-defined semantics thanks to`semiregular`

) when`I`

and`S`

are the same type. The optimization will not apply in as many cases, but we don't need to make a scary concept change, either.

*[2020-06-26; Reflector prioritization]*

Set priority to 2 after reflector discussions.

*[2020-08-21; Issue processing telecon: Option A is Tentatively Ready]*

**Previous resolution [SUPERSEDED]:**

This wording is relative to N4861.

Wording for both

Option AandOption Bare provided.

Option A:

Modify 25.3.4.7 [iterator.concept.sentinel] as indicated:

template<class S, class I> concept sentinel_for = semiregular<S> && input_or_output_iterator<I> &&weakly-equality-comparable-with<S, I>;// See 18.5.4 [concept.equalitycomparable]-2- Let

`s`

and`i`

be values of type`S`

and`I`

such that`[i, s)`

denotes a range. Types`S`

and`I`

model`sentinel_for<S, I>`

only if

(2.1) —

`i == s`

is well-defined.(2.2) — If

`bool(i != s)`

then`i`

is dereferenceable and`[++i, s)`

denotes a range.(2.?) —

`assignable_from<I&, S>`

is either modeled or not satisfied.

Option B:

Modify 25.4.4.2 [range.iter.op.advance] as indicated:

template<input_or_output_iterator I, sentinel_for<I> S> constexpr void ranges::advance(I& i, S bound);-3-

Preconditions:`[i, bound)`

denotes a range.-4-

Effects:

(4.1) — If

`I`

and`S`

model`, equivalent to`

~~assignable_from<I&, S>~~same_as<I, S>`i = std::move(bound)`

.(4.2) — […]

*[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]*

**Proposed resolution:**

This wording is relative to N4861.

Modify 25.3.4.7 [iterator.concept.sentinel] as indicated:

template<class S, class I> concept sentinel_for = semiregular<S> && input_or_output_iterator<I> &&

*weakly-equality-comparable-with*<S, I>;*// See 18.5.4 [concept.equalitycomparable]*-2- Let

`s`

and`i`

be values of type`S`

and`I`

such that`[i, s)`

denotes a range. Types`S`

and`I`

model`sentinel_for<S, I>`

only if(2.1) —

`i == s`

is well-defined.(2.2) — If

`bool(i != s)`

then`i`

is dereferenceable and`[++i, s)`

denotes a range.(2.?) —

`assignable_from<I&, S>`

is either modeled or not satisfied.