Issue 4170: contiguous_iterator should require to_address(I{}) (original) (raw)
This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.
4170. 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)) (respectivelyto_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 needsto_address(I{}) to be well-defined. Note that to_address is already implicitly equality-preserving for contiguous_iterator arguments. Given this additional requirementto_address(I{}) == to_address(I{}) and to_address(I{}) == to_address(I{)) + 0both 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
concept contiguous_iterator =
random_access_iterator &&
derived_from<_ITERCONCEPT_(I), contiguous_iterator_tag> &&
is_lvalue_reference_v<iter_reference_t> &&
same_as<iter_value_t, remove_cvref_t<iter_reference_t>> &&
requires(const I& i) {
{ to_address(i) } -> same_as<add_pointer_t<iter_reference_t>>;
};
-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).