contiguous_iterator
should require to_address(I{})
Section: 24.3.4.14 [iterator.concept.contiguous] Status: New Submitter: Casey Carter Opened: 2024-11-01 Last modified: 2024-11-01
Priority: Not Prioritized
View all other issues in [iterator.concept.contiguous].
View all issues with New 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.
Proposed resolution:
This wording is relative to N4993.
Modify 24.3.4.14 [iterator.concept.contiguous] as indicated:
-1- The
contiguous_iterator
concept 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
a
andb
be dereferenceable iterators andc
be a non-dereferenceable iterator of typeI
such thatb
is reachable froma
andc
is reachable fromb
, and letD
beiter_difference_t<I>
. The typeI
modelscontiguous_iterator
only 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)
.