std:: contiguous_iterator
|
Defined in header
<iterator>
|
||
|
template
<
class
I
>
concept contiguous_iterator
=
|
(since C++20) | |
The
contiguous_iterator
concept refines
random_access_iterator
by providing a guarantee the denoted elements are stored contiguously in the memory.
|
Given an iterator
i
of a type that models
This means a program cannot rely on any side effects of dereferencing, incrementing or decrementing a contiguous iterator i , because standard library functions might operate on pointers obtained by std:: to_address ( i ) instead of operating on i directly. |
(since C++26) |
Contents |
Iterator concept determination
Definition of this concept is specified via an exposition-only alias template /*ITER_CONCEPT*/ .
In order to determine /*ITER_CONCEPT*/ < I > , let ITER_TRAITS < I > denote I if the specialization std:: iterator_traits < I > is generated from the primary template, or std:: iterator_traits < I > otherwise:
- If ITER_TRAITS < I > :: iterator_concept is valid and names a type, /*ITER_CONCEPT*/ < I > denotes the type.
- Otherwise, if ITER_TRAITS < I > :: iterator_category is valid and names a type, /*ITER_CONCEPT*/ < I > denotes the type.
-
Otherwise, if
std::
iterator_traits
<
I
>
is generated from the primary template,
/*ITER_CONCEPT*/
<
I
>
denotes
std::random_access_iterator_tag
.
(That is, std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: contiguous_iterator_tag > is assumed to be false .) - Otherwise, /*ITER_CONCEPT*/ < I > does not denote a type and results in a substitution failure.
Semantic requirements
Let
a
and
b
be
dereferenceable
iterators and
c
be a non-dereferenceable iterator of type
I
such that
b
is
reachable
from
a
and
c
is reachable from
b
, the type
I
models
contiguous_iterator
only if all the concepts it subsumes are modeled and all following conditions are satisfied:
- std:: to_address ( a ) == std:: addressof ( * a ) .
- std:: to_address ( b ) == std:: to_address ( a ) + std:: iter_difference_t < I > ( b - a ) .
- std:: to_address ( c ) == std:: to_address ( a ) + std:: iter_difference_t < I > ( c - a ) .
- std:: to_address ( I { } ) is well-defined.
- ranges:: iter_move ( a ) has the same type, value category, and effects as std :: move ( * a ) .
- If ranges:: iter_swap ( a, b ) is well-formed, it has effects equivalent to ranges:: swap ( * a, * b ) .
Equality preservation
Expressions declared in requires expressions of the standard library concepts are required to be equality-preserving (except where stated otherwise).
Implicit expression variations
A requires expression that uses an expression that is non-modifying for some constant lvalue operand also requires implicit expression variations .
Notes
contiguous_iterator
is modeled by every pointer type to complete object type.
Iterator types in the standard library that are required to satisfy the
LegacyContiguousIterator
requirements in C++17 are also required to model
contiguous_iterator
in C++20.
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3607 | C++20 |
contiguous_iterator
could have custom
ranges::iter_move and ranges::iter_swap behaviors |
prohibited |
| LWG 4170 | C++20 |
a pair of value-initialized
contiguous_iterator
s
might not be able to represent an empty range |
guaranteed |
See also
|
(C++20)
|
specifies that a
bidirectional_iterator
is a random-access iterator, supporting advancement in constant time and subscripting
(concept) |