contiguous_iterator should require to_address(I{})Section: 24.3.4.14 [iterator.concept.contiguous] Status: WP Submitter: Casey Carter Opened: 2024-11-01 Last modified: 2024-11-28
Priority: Not Prioritized
View all other issues in [iterator.concept.contiguous].
View all issues with WP status.
Discussion:
The design intent of the contiguous_iterator concept is that iterators can be converted
to pointers denoting the same sequence of elements. This enables a common range [i, j)
or counted range i + [0, n) to be processed with extremely efficient low-level C
or assembly code that operates on [to_address(i), to_address(j)) (respectively
to_address(i) + [0, n)).
A value-initialized iterator I{} can be used to denote the empty ranges [I{}, I{})
and I{} + [0, 0). While the existing semantic requirements of contiguous_iterator enable us
to convert both dereferenceable and past-the-end iterators with to_address, converting
ranges involving value-initialized iterators to pointer ranges additionally needs
to_address(I{}) to be well-defined. Note that to_address is already implicitly
equality-preserving for contiguous_iterator arguments. Given this additional requirement
to_address(I{}) == to_address(I{}) and to_address(I{}) == to_address(I{)) + 0
both hold, so the two types of empty ranges involving value-initialized iterators convert
to empty pointer ranges as desired.
[2024-11-13; Reflector poll]
Set status to Tentatively Ready after eight votes in favour during reflector poll.
[Wrocław 2024-11-23; Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4993.
Modify 24.3.4.14 [iterator.concept.contiguous] as indicated:
-1- The
contiguous_iteratorconcept provides a guarantee that the denoted elements are stored contiguously in memory.template<class I> concept contiguous_iterator = random_access_iterator<I> && derived_from<ITER_CONCEPT(I), contiguous_iterator_tag> && is_lvalue_reference_v<iter_reference_t<I>> && same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> && requires(const I& i) { { to_address(i) } -> same_as<add_pointer_t<iter_reference_t<I>>>; };-2- Let
aandbbe dereferenceable iterators andcbe a non-dereferenceable iterator of typeIsuch thatbis reachable fromaandcis reachable fromb, and letDbeiter_difference_t<I>. The typeImodelscontiguous_iteratoronly if
(2.1) —
to_address(a) == addressof(*a),(2.2) —
to_address(b) == to_address(a) + D(b - a),(2.3) —
to_address(c) == to_address(a) + D(c - a),(2.?) —
to_address(I{})is well-defined,(2.4) —
ranges::iter_move(a)has the same type, value category, and effects asstd::move(*a), and(2.5) — if
ranges::iter_swap(a, b)is well-formed, it has effects equivalent toranges::swap(*a, *b).