Files
2025-10-25 03:02:53 +03:00

887 lines
51 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[iterator.concepts]
# 24 Iterators library [[iterators]](./#iterators)
## 24.3 Iterator requirements [[iterator.requirements]](iterator.requirements#iterator.concepts)
### 24.3.4 Iterator concepts [iterator.concepts]
#### [24.3.4.1](#general) General [[iterator.concepts.general]](iterator.concepts.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1252)
For a type I, let *ITER_TRAITS*(I) denote
the type I if iterator_traits<I> names
a specialization generated from the primary template[.](#general-1.sentence-1)
Otherwise, *ITER_TRAITS*(I) denotesiterator_traits<I>[.](#general-1.sentence-2)
- [(1.1)](#general-1.1)
If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]")*ITER_TRAITS*(I)::iterator_concept is valid
and names a type, then *ITER_CONCEPT*(I) denotes that
type[.](#general-1.1.sentence-1)
- [(1.2)](#general-1.2)
Otherwise, if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]")*ITER_TRAITS*(I)::iterator_category is valid and names a type, then *ITER_CONCEPT*(I) denotes that type[.](#general-1.2.sentence-1)
- [(1.3)](#general-1.3)
Otherwise, if iterator_traits<I> names a specialization generated
from the primary template, then *ITER_CONCEPT*(I) denotes random_access_iterator_tag[.](#general-1.3.sentence-1)
- [(1.4)](#general-1.4)
Otherwise, *ITER_CONCEPT*(I) does not denote a type[.](#general-1.4.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1273)
[*Note [1](#general-note-1)*:
*ITER_TRAITS* enables independent syntactic determination
of an iterator's category and concept[.](#general-2.sentence-1)
— *end note*]
[*Example [1](#general-example-1)*:
struct I {using value_type = int; using difference_type = int; int operator*() const;
I& operator++();
I operator++(int);
I& operator--();
I operator--(int); bool operator==(I) const;};iterator_traits<I>::iterator_category denotes input_iterator_tag,
and *ITER_CONCEPT*(I) denotes random_access_iterator_tag[.](#general-2.sentence-2)
— *end example*]
#### [24.3.4.2](#iterator.concept.readable) Concept indirectly_readable [[iterator.concept.readable]](iterator.concept.readable)
[1](#iterator.concept.readable-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1299)
Types that are indirectly readable by applying operator* model the [indirectly_readable](#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]") concept, including
pointers, smart pointers, and iterators[.](#iterator.concept.readable-1.sentence-1)
template<class In>concept [*indirectly-readable-impl*](#concept:indirectly-readable-impl "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]") = // *exposition only*requires(const In in) {typename iter_value_t<In>; typename iter_reference_t<In>; typename iter_rvalue_reference_t<In>; { *in } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_reference_t<In>>; { ranges::iter_move(in) } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_rvalue_reference_t<In>>; } &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<iter_reference_t<In>&&, iter_value_t<In>&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<iter_reference_t<In>&&, iter_rvalue_reference_t<In>&&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<iter_rvalue_reference_t<In>&&, const iter_value_t<In>&>;
template<class In>concept [indirectly_readable](#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]") =[*indirectly-readable-impl*](#concept:indirectly-readable-impl "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]")<remove_cvref_t<In>>;
[2](#iterator.concept.readable-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1325)
Given a value i of type I, I models [indirectly_readable](#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]") only if the expression *i is equality-preserving[.](#iterator.concept.readable-2.sentence-1)
#### [24.3.4.3](#iterator.concept.writable) Concept indirectly_writable [[iterator.concept.writable]](iterator.concept.writable)
[1](#iterator.concept.writable-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1331)
The [indirectly_writable](#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.writable]") concept specifies the requirements
for writing a value into an iterator's referenced object[.](#iterator.concept.writable-1.sentence-1)
template<class Out, class T>concept [indirectly_writable](#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.writable]") =requires(Out&& o, T&& t) {*o = std::forward<T>(t); // not required to be equality-preserving*std::forward<Out>(o) = std::forward<T>(t); // not required to be equality-preservingconst_cast<const iter_reference_t<Out>&&>(*o) = std::forward<T>(t); // not required to be equality-preservingconst_cast<const iter_reference_t<Out>&&>(*std::forward<Out>(o)) = std::forward<T>(t); // not required to be equality-preserving};
[2](#iterator.concept.writable-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1348)
Let E be an expression such that decltype((E)) is T,
and let o be a dereferenceable object of type Out[.](#iterator.concept.writable-2.sentence-1)
Out and T model [indirectly_writable](#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.writable]")<Out, T> only if:
- [(2.1)](#iterator.concept.writable-2.1)
If Out and T model [indirectly_readable](#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]")<Out> && [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_value_t<Out>, decay_t<T>>,
then *o after any above assignment is equal to
the value of E before the assignment[.](#iterator.concept.writable-2.sentence-2)
[3](#iterator.concept.writable-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1359)
After evaluating any above assignment expression, o is not required to be dereferenceable[.](#iterator.concept.writable-3.sentence-1)
[4](#iterator.concept.writable-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1362)
If E is an xvalue ([[basic.lval]](basic.lval "7.2.1Value category")), the resulting
state of the object it denotes is valid but unspecified ([[lib.types.movedfrom]](lib.types.movedfrom "16.4.6.17Moved-from state of library types"))[.](#iterator.concept.writable-4.sentence-1)
[5](#iterator.concept.writable-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1366)
[*Note [1](#iterator.concept.writable-note-1)*:
The only valid use of an operator* is on the left side of the assignment statement[.](#iterator.concept.writable-5.sentence-1)
Assignment through the same value of the indirectly writable type happens only once[.](#iterator.concept.writable-5.sentence-2)
— *end note*]
[6](#iterator.concept.writable-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1372)
[*Note [2](#iterator.concept.writable-note-2)*:
[indirectly_writable](#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.writable]") has the awkward const_cast expressions to reject
iterators with prvalue non-proxy reference types that permit rvalue
assignment but do not also permit const rvalue assignment[.](#iterator.concept.writable-6.sentence-1)
Consequently, an iterator type I that returns std::string by value does not model [indirectly_writable](#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.writable]")<I, std::string>[.](#iterator.concept.writable-6.sentence-2)
— *end note*]
#### [24.3.4.4](#iterator.concept.winc) Concept weakly_incrementable [[iterator.concept.winc]](iterator.concept.winc)
[1](#iterator.concept.winc-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1383)
The [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") concept specifies the requirements on
types that can be incremented with the pre- and post-increment operators[.](#iterator.concept.winc-1.sentence-1)
The increment operations are not required to be equality-preserving,
nor is the type required to be [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")[.](#iterator.concept.winc-1.sentence-2)
template<class T>constexpr bool *is-integer-like* = *see below*; // *exposition only*template<class T>constexpr bool *is-signed-integer-like* = *see below*; // *exposition only*template<class I>concept [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") =[movable](concepts.object#concept:movable "18.6Object concepts[concepts.object]")<I> &&requires(I i) {typename iter_difference_t<I>; requires *is-signed-integer-like*<iter_difference_t<I>>; { ++i } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; // not required to be equality-preserving i++; // not required to be equality-preserving};
[2](#iterator.concept.winc-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1407)
A type I is an [*integer-class type*](#def:type,integer-class "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") if it is in a set of implementation-defined types
that behave as integer types do, as defined below[.](#iterator.concept.winc-2.sentence-1)
[*Note [1](#iterator.concept.winc-note-1)*:
An integer-class type is not necessarily a class type[.](#iterator.concept.winc-2.sentence-2)
— *end note*]
[3](#iterator.concept.winc-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1415)
The range of representable values of an integer-class type
is the continuous set of values over which it is defined[.](#iterator.concept.winc-3.sentence-1)
For any integer-class type,
its range of representable values is
either −2N−1 to 2N−ˆ’1 (inclusive) for some integer N,
in which case it is a [*signed-integer-class type*](#def:type,signed-integer-class "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]"), or0 to 2N−1 (inclusive) for some integer N,
in which case it is an [*unsigned-integer-class type*](#def:type,unsigned-integer-class "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]")[.](#iterator.concept.winc-3.sentence-2)
In both cases, N is called
the [*width*](#def:width,of_integer-class_type "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") of the integer-class type[.](#iterator.concept.winc-3.sentence-3)
The width of an integer-class type is greater than
that of every integral type of the same signedness[.](#iterator.concept.winc-3.sentence-4)
[4](#iterator.concept.winc-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1429)
A type I other than cv bool is [*integer-like*](#def:integer-like "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") if it models [integral](concepts.arithmetic#concept:integral "18.4.7Arithmetic concepts[concepts.arithmetic]")<I> or
if it is an integer-class type[.](#iterator.concept.winc-4.sentence-1)
An integer-like type I is [*signed-integer-like*](#def:signed-integer-like "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") if it models [signed_integral](concepts.arithmetic#concept:signed_integral "18.4.7Arithmetic concepts[concepts.arithmetic]")<I> or
if it is a signed-integer-class type[.](#iterator.concept.winc-4.sentence-2)
An integer-like type I is [*unsigned-integer-like*](#def:unsigned-integer-like "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") if it models [unsigned_integral](concepts.arithmetic#concept:unsigned_integral "18.4.7Arithmetic concepts[concepts.arithmetic]")<I> or
if it is an unsigned-integer-class type[.](#iterator.concept.winc-4.sentence-3)
[5](#iterator.concept.winc-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1440)
For every integer-class type I,
let B(I) be a unique hypothetical extended integer type
of the same signedness with the same width ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")) as I[.](#iterator.concept.winc-5.sentence-1)
[*Note [2](#iterator.concept.winc-note-2)*:
The corresponding hypothetical specialization numeric_limits<B(I)> meets the requirements on numeric_limits specializations
for integral types ([[numeric.limits]](numeric.limits "17.3.5Class template numeric_­limits"))[.](#iterator.concept.winc-5.sentence-2)
— *end note*]
For every integral type J, let B(J) be the same type as J[.](#iterator.concept.winc-5.sentence-3)
[6](#iterator.concept.winc-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1451)
Expressions of integer-class type are
explicitly convertible to any integer-like type, and
implicitly convertible to any integer-class type
of equal or greater width and the same signedness[.](#iterator.concept.winc-6.sentence-1)
Expressions of integral type are
both implicitly and explicitly convertible to any integer-class type[.](#iterator.concept.winc-6.sentence-2)
Conversions between integral and integer-class types
and between two integer-class types do not exit via an exception[.](#iterator.concept.winc-6.sentence-3)
The result of such a conversion is the unique value of the destination type
that is congruent to the source modulo 2N,
where N is the width of the destination type[.](#iterator.concept.winc-6.sentence-4)
[7](#iterator.concept.winc-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1464)
Let a be an object of integer-class type I,
let b be an object of integer-like type I2 such that the expression b is implicitly convertible to I,
let x and y be, respectively,
objects of type B(I) and B(I2) as described above
that represent the same values as a and b, and
let c be an lvalue of any integral type[.](#iterator.concept.winc-7.sentence-1)
- [(7.1)](#iterator.concept.winc-7.1)
The expressions a++ and a-- shall be prvalues of type I whose values are equal to
that of a prior to the evaluation of the expressions[.](#iterator.concept.winc-7.1.sentence-1)
The expression a++ shall modify the value of a by adding 1 to it[.](#iterator.concept.winc-7.1.sentence-2)
The expression a-- shall modify the value of a by subtracting 1 from it[.](#iterator.concept.winc-7.1.sentence-3)
- [(7.2)](#iterator.concept.winc-7.2)
The expressions ++a, --a, and &a shall be
expression-equivalent toa += 1, a -= 1, and addressof(a), respectively[.](#iterator.concept.winc-7.2.sentence-1)
- [(7.3)](#iterator.concept.winc-7.3)
For every [*unary-operator*](expr.unary.general#nt:unary-operator "7.6.2.1General[expr.unary.general]") @ other than & for which the expression @x is well-formed, @a shall also be well-formed
and have the same value, effects, and value category as @x[.](#iterator.concept.winc-7.3.sentence-1)
If @x has type bool, so too does @a;
if @x has type B(I), then @a has type I[.](#iterator.concept.winc-7.3.sentence-2)
- [(7.4)](#iterator.concept.winc-7.4)
For every assignment operator @= for which c @= x is well-formed, c @= a shall also be well-formed and
shall have the same value and effects as c @= x[.](#iterator.concept.winc-7.4.sentence-1)
The expression c @= a shall be an lvalue referring to c[.](#iterator.concept.winc-7.4.sentence-2)
- [(7.5)](#iterator.concept.winc-7.5)
For every assignment operator @= for which x @= y is well-formed,a @= b shall also be well-formed and
shall have the same effects as x @= y,
except that the value that would be stored into x is stored into a[.](#iterator.concept.winc-7.5.sentence-1)
The expression a @= b shall be an lvalue referring to a[.](#iterator.concept.winc-7.5.sentence-2)
- [(7.6)](#iterator.concept.winc-7.6)
For every non-assignment binary operator @ for which x @ y and y @ x are well-formed, a @ b and b @ a shall also be well-formed and
shall have the same value, effects, and value category as x @ y and y @ x, respectively[.](#iterator.concept.winc-7.6.sentence-1)
If x @ y or y @ x has type B(I),
then a @ b or b @ a, respectively, has type I;
if x @ y or y @ x has type B(I2),
then a @ b or b @ a, respectively, has type I2;
if x @ y or y @ x has any other type,
then a @ b or b @ a, respectively, has that type[.](#iterator.concept.winc-7.6.sentence-2)
[8](#iterator.concept.winc-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1519)
An expression E of integer-class type I is
contextually convertible to bool as if by bool(E != I(0))[.](#iterator.concept.winc-8.sentence-1)
[9](#iterator.concept.winc-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1524)
All integer-class types model[regular](concepts.object#concept:regular "18.6Object concepts[concepts.object]") ([[concepts.object]](concepts.object "18.6Object concepts")) and[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<strong_ordering> ([[cmp.concept]](cmp.concept "17.12.4Concept three_­way_­comparable"))[.](#iterator.concept.winc-9.sentence-1)
[10](#iterator.concept.winc-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1529)
A value-initialized object of integer-class type has value 0[.](#iterator.concept.winc-10.sentence-1)
[11](#iterator.concept.winc-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1532)
For every (possibly cv-qualified) integer-class type I,numeric_limits<I> is specialized such that
each static data member m has the same value as numeric_limits<B(I)>::m, and
each static member function f returns I(numeric_limits<B(I)>::f())[.](#iterator.concept.winc-11.sentence-1)
[12](#iterator.concept.winc-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1540)
For any two integer-like types I1 and I2,
at least one of which is an integer-class type,common_type_t<I1, I2> denotes an integer-class type
whose width is not less than that of I1 or I2[.](#iterator.concept.winc-12.sentence-1)
If both I1 and I2 are signed-integer-like types,
then common_type_t<I1, I2> is also a signed-integer-like type[.](#iterator.concept.winc-12.sentence-2)
[13](#iterator.concept.winc-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1548)
*is-integer-like*<I> is true if and only if I is an integer-like type[.](#iterator.concept.winc-13.sentence-1)
*is-signed-integer-like*<I> is true if and only if I is a signed-integer-like type[.](#iterator.concept.winc-13.sentence-2)
[14](#iterator.concept.winc-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1554)
Let i be an object of type I[.](#iterator.concept.winc-14.sentence-1)
When i is in the domain of
both pre- and post-increment, i is said to be [*incrementable*](#def:incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]")[.](#iterator.concept.winc-14.sentence-2)
I models [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]")<I> only if:
- [(14.1)](#iterator.concept.winc-14.1)
The expressions ++i and i++ have the same domain[.](#iterator.concept.winc-14.1.sentence-1)
- [(14.2)](#iterator.concept.winc-14.2)
If i is incrementable, then both ++i and i++ advance i to the next element[.](#iterator.concept.winc-14.2.sentence-1)
- [(14.3)](#iterator.concept.winc-14.3)
If i is incrementable, then addressof(++i) is equal to addressof(i)[.](#iterator.concept.winc-14.3.sentence-1)
[15](#iterator.concept.winc-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1567)
*Recommended practice*: The implementation of an algorithm on a weakly incrementable type
should never attempt to pass through the same incrementable value twice;
such an algorithm should be a single-pass algorithm[.](#iterator.concept.winc-15.sentence-1)
[*Note [3](#iterator.concept.winc-note-3)*:
For [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") types, a equals b does not imply that ++a equals ++b[.](#iterator.concept.winc-15.sentence-2)
(Equality does not guarantee the substitution property or referential
transparency[.](#iterator.concept.winc-15.sentence-3))
Such algorithms
can be used with istreams as the source of the input data through the istream_iterator class
template[.](#iterator.concept.winc-15.sentence-4)
— *end note*]
#### [24.3.4.5](#iterator.concept.inc) Concept incrementable [[iterator.concept.inc]](iterator.concept.inc)
[1](#iterator.concept.inc-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1583)
The [incrementable](#concept:incrementable "24.3.4.5Concept incrementable[iterator.concept.inc]") concept specifies requirements on types that can be incremented with the pre-
and post-increment operators[.](#iterator.concept.inc-1.sentence-1)
The increment operations are required to be equality-preserving,
and the type is required to be [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")[.](#iterator.concept.inc-1.sentence-2)
[*Note [1](#iterator.concept.inc-note-1)*:
This supersedes the annotations on the increment expressions
in the definition of [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]")[.](#iterator.concept.inc-1.sentence-3)
— *end note*]
template<class I>concept [incrementable](#concept:incrementable "24.3.4.5Concept incrementable[iterator.concept.inc]") =[regular](concepts.object#concept:regular "18.6Object concepts[concepts.object]")<I> &&[weakly_incrementable](#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]")<I> &&requires(I i) {{ i++ } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; };
[2](#iterator.concept.inc-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1602)
Let a and b be incrementable objects of type I[.](#iterator.concept.inc-2.sentence-1)
I models [incrementable](#concept:incrementable "24.3.4.5Concept incrementable[iterator.concept.inc]") only if:
- [(2.1)](#iterator.concept.inc-2.1)
If bool(a == b) then bool(a++ == b)[.](#iterator.concept.inc-2.1.sentence-1)
- [(2.2)](#iterator.concept.inc-2.2)
If bool(a == b) then bool(((void)a++, a) == ++b)[.](#iterator.concept.inc-2.2.sentence-1)
[3](#iterator.concept.inc-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1610)
[*Note [2](#iterator.concept.inc-note-2)*:
The requirement thata equals b implies++a equals ++b (which is not true for weakly incrementable types)
allows the use of multi-pass one-directional
algorithms with types that model [incrementable](#concept:incrementable "24.3.4.5Concept incrementable[iterator.concept.inc]")[.](#iterator.concept.inc-3.sentence-1)
— *end note*]
#### [24.3.4.6](#iterator.concept.iterator) Concept input_or_output_iterator [[iterator.concept.iterator]](iterator.concept.iterator)
[1](#iterator.concept.iterator-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1623)
The [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") concept forms the basis
of the iterator concept taxonomy; every iterator models [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]")[.](#iterator.concept.iterator-1.sentence-1)
This concept specifies operations for dereferencing and incrementing
an iterator[.](#iterator.concept.iterator-1.sentence-2)
Most algorithms will require additional operations
to compare iterators with sentinels ([[iterator.concept.sentinel]](#iterator.concept.sentinel "24.3.4.7Concept sentinel_­for")), to
read ([[iterator.concept.input]](#iterator.concept.input "24.3.4.9Concept input_­iterator")) or write ([[iterator.concept.output]](#iterator.concept.output "24.3.4.10Concept output_­iterator")) values, or
to provide a richer set of iterator movements ([[iterator.concept.forward]](#iterator.concept.forward "24.3.4.11Concept forward_­iterator"), [[iterator.concept.bidir]](#iterator.concept.bidir "24.3.4.12Concept bidirectional_­iterator"), [[iterator.concept.random.access]](#iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))[.](#iterator.concept.iterator-1.sentence-3)
template<class I>concept [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") =requires(I i) {{ *i } -> [*can-reference*](iterator.synopsis#concept:can-reference "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]"); } &&[weakly_incrementable](#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]")<I>;
[2](#iterator.concept.iterator-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1642)
[*Note [1](#iterator.concept.iterator-note-1)*:
Unlike the *Cpp17Iterator* requirements,
the [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") concept does not require copyability[.](#iterator.concept.iterator-2.sentence-1)
— *end note*]
#### [24.3.4.7](#iterator.concept.sentinel) Concept sentinel_for [[iterator.concept.sentinel]](iterator.concept.sentinel)
[1](#iterator.concept.sentinel-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1650)
The [sentinel_for](#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]") concept specifies the relationship
between an [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") type and a [semiregular](concepts.object#concept:semiregular "18.6Object concepts[concepts.object]") type
whose values denote a range[.](#iterator.concept.sentinel-1.sentence-1)
[🔗](#concept:sentinel_for)
`template<class S, class I>
concept [sentinel_for](#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]") =
[semiregular](concepts.object#concept:semiregular "18.6Object concepts[concepts.object]")<S> &&
[input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]")<I> &&
[weakly-equality-comparable-with](concept.equalitycomparable#concept:weakly-equality-comparable-with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<S, I>; // see [[concept.equalitycomparable]](concept.equalitycomparable "18.5.4Concept equality_­comparable")
`
[2](#iterator.concept.sentinel-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1664)
Let s and i be values of type S andI such that [i, s) denotes a range[.](#iterator.concept.sentinel-2.sentence-1)
TypesS and I model [sentinel_for](#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I> only if:
- [(2.1)](#iterator.concept.sentinel-2.1)
i == s is well-defined[.](#iterator.concept.sentinel-2.1.sentence-1)
- [(2.2)](#iterator.concept.sentinel-2.2)
If bool(i != s) then i is dereferenceable and
[++i, s) denotes a range[.](#iterator.concept.sentinel-2.2.sentence-1)
- [(2.3)](#iterator.concept.sentinel-2.3)
[assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<I&, S> is either modeled or not satisfied[.](#iterator.concept.sentinel-2.3.sentence-1)
[3](#iterator.concept.sentinel-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1678)
The domain of == is not static[.](#iterator.concept.sentinel-3.sentence-1)
Given an iterator i and sentinel s such that [i, s)
denotes a range and i != s, i and s are not required to
continue to denote a range after incrementing any other iterator equal
to i[.](#iterator.concept.sentinel-3.sentence-2)
Consequently, i == s is no longer required to be
well-defined[.](#iterator.concept.sentinel-3.sentence-3)
#### [24.3.4.8](#iterator.concept.sizedsentinel) Concept sized_sentinel_for [[iterator.concept.sizedsentinel]](iterator.concept.sizedsentinel)
[1](#iterator.concept.sizedsentinel-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1688)
The [sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]") concept specifies
requirements on an [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") type I and
a corresponding [sentinel_for](#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> that allow the use of the - operator to compute the distance
between them in constant time[.](#iterator.concept.sizedsentinel-1.sentence-1)
[🔗](#concept:sized_sentinel_for)
`template<class S, class I>
concept [sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]") =
[sentinel_for](#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I> &&
!disable_sized_sentinel_for<remove_cv_t<S>, remove_cv_t<I>> &&
requires(const I& i, const S& s) {
{ s - i } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_difference_t<I>>;
{ i - s } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_difference_t<I>>;
};
`
[2](#iterator.concept.sizedsentinel-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1707)
Let i be an iterator of type I, and s a sentinel of type S such that [i, s) denotes a range[.](#iterator.concept.sizedsentinel-2.sentence-1)
Let N be the smallest number of applications of ++i necessary to make bool(i == s) be true[.](#iterator.concept.sizedsentinel-2.sentence-2)
S and I model [sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I> only if:
- [(2.1)](#iterator.concept.sizedsentinel-2.1)
If N is representable by iter_difference_t<I>,
then s - i is well-defined and equals N[.](#iterator.concept.sizedsentinel-2.1.sentence-1)
- [(2.2)](#iterator.concept.sizedsentinel-2.2)
If −N is representable by iter_difference_t<I>,
then i - s is well-defined and equals −N[.](#iterator.concept.sizedsentinel-2.2.sentence-1)
[🔗](#lib:disable_sized_sentinel_for)
`template<class S, class I>
constexpr bool disable_sized_sentinel_for = false;
`
[3](#iterator.concept.sizedsentinel-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1729)
*Remarks*: Pursuant to [[namespace.std]](namespace.std "16.4.5.2.1Namespace std"),
users may specialize disable_sized_sentinel_for for cv-unqualified non-array object types S and I if S and/or I is a program-defined type[.](#iterator.concept.sizedsentinel-3.sentence-1)
Such specializations shall
be usable in constant expressions ([[expr.const]](expr.const "7.7Constant expressions")) and
have type const bool[.](#iterator.concept.sizedsentinel-3.sentence-2)
[4](#iterator.concept.sizedsentinel-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1739)
[*Note [1](#iterator.concept.sizedsentinel-note-1)*:
disable_sized_sentinel_for allows use of sentinels and iterators with
the library that satisfy but do not in fact model [sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")[.](#iterator.concept.sizedsentinel-4.sentence-1)
— *end note*]
[5](#iterator.concept.sizedsentinel-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1745)
[*Example [1](#iterator.concept.sizedsentinel-example-1)*:
The [sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]") concept is modeled by pairs of[random_access_iterator](#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")s ([[iterator.concept.random.access]](#iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator")) and by
counted iterators and their sentinels ([[counted.iterator]](counted.iterator "24.5.7.1Class template counted_­iterator"))[.](#iterator.concept.sizedsentinel-5.sentence-1)
— *end example*]
#### [24.3.4.9](#iterator.concept.input) Concept input_iterator [[iterator.concept.input]](iterator.concept.input)
[1](#iterator.concept.input-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1755)
The [input_iterator](#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") concept defines requirements for a type
whose referenced values can be read (from the requirement for[indirectly_readable](#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]") ([[iterator.concept.readable]](#iterator.concept.readable "24.3.4.2Concept indirectly_­readable")))
and which can be both pre- and post-incremented[.](#iterator.concept.input-1.sentence-1)
[*Note [1](#iterator.concept.input-note-1)*:
Unlike the *Cpp17InputIterator* requirements ([[input.iterators]](input.iterators "24.3.5.3Input iterators")),
the [input_iterator](#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") concept does not need
equality comparison since iterators are typically compared to sentinels[.](#iterator.concept.input-1.sentence-2)
— *end note*]
template<class I>concept [input_iterator](#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") =[input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]")<I> &&[indirectly_readable](#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]")<I> &&requires { typename *ITER_CONCEPT*(I); } &&[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<*ITER_CONCEPT*(I), input_iterator_tag>;
#### [24.3.4.10](#iterator.concept.output) Concept output_iterator [[iterator.concept.output]](iterator.concept.output)
[1](#iterator.concept.output-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1777)
The [output_iterator](#concept:output_iterator "24.3.4.10Concept output_­iterator[iterator.concept.output]") concept defines requirements for a type that
can be used to write values (from the requirement for[indirectly_writable](#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.writable]") ([[iterator.concept.writable]](#iterator.concept.writable "24.3.4.3Concept indirectly_­writable")))
and which can be both pre- and post-incremented[.](#iterator.concept.output-1.sentence-1)
[*Note [1](#iterator.concept.output-note-1)*:
Output iterators are not required to model [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")[.](#iterator.concept.output-1.sentence-2)
— *end note*]
template<class I, class T>concept [output_iterator](#concept:output_iterator "24.3.4.10Concept output_­iterator[iterator.concept.output]") =[input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]")<I> &&[indirectly_writable](#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.writable]")<I, T> &&requires(I i, T&& t) {*i++ = std::forward<T>(t); // not required to be equality-preserving};
[2](#iterator.concept.output-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1796)
Let E be an expression such that decltype((E)) is T, and let i be a
dereferenceable object of type I[.](#iterator.concept.output-2.sentence-1)
I and T model [output_iterator](#concept:output_iterator "24.3.4.10Concept output_­iterator[iterator.concept.output]")<I, T> only if*i++ = E; has effects equivalent to:*i = E;++i;
[3](#iterator.concept.output-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1805)
*Recommended practice*: The implementation of an algorithm on output iterators
should never attempt to pass through the same iterator twice;
such an algorithm should be a single-pass algorithm[.](#iterator.concept.output-3.sentence-1)
#### [24.3.4.11](#iterator.concept.forward) Concept forward_iterator [[iterator.concept.forward]](iterator.concept.forward)
[1](#iterator.concept.forward-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1813)
The [forward_iterator](#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]") concept adds
copyability, equality comparison, and
the multi-pass guarantee, specified below[.](#iterator.concept.forward-1.sentence-1)
template<class I>concept [forward_iterator](#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]") =[input_iterator](#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<*ITER_CONCEPT*(I), forward_iterator_tag> &&[incrementable](#concept:incrementable "24.3.4.5Concept incrementable[iterator.concept.inc]")<I> &&[sentinel_for](#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I, I>;
[2](#iterator.concept.forward-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1827)
The domain of == for forward iterators is that of iterators over the same
underlying sequence[.](#iterator.concept.forward-2.sentence-1)
However, value-initialized iterators of the same type
may be compared and shall compare equal to other value-initialized iterators of the same type[.](#iterator.concept.forward-2.sentence-2)
[*Note [1](#iterator.concept.forward-note-1)*:
Value-initialized iterators behave as if they refer past the end of the same
empty sequence[.](#iterator.concept.forward-2.sentence-3)
— *end note*]
[3](#iterator.concept.forward-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1836)
Pointers and references obtained from a forward iterator into a range [i, s)
shall remain valid while [i, s) continues to denote a range[.](#iterator.concept.forward-3.sentence-1)
[4](#iterator.concept.forward-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1840)
Two dereferenceable iterators a and b of type X offer the [*multi-pass guarantee*](forward.iterators#def:multi-pass_guarantee "24.3.5.5Forward iterators[forward.iterators]") if
- [(4.1)](#iterator.concept.forward-4.1)
a == b implies ++a == ++b and
- [(4.2)](#iterator.concept.forward-4.2)
the expression((void)[](X x){++x;}(a), *a) is equivalent to the expression *a[.](#iterator.concept.forward-4.sentence-1)
[5](#iterator.concept.forward-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1849)
[*Note [2](#iterator.concept.forward-note-2)*:
The requirement thata == b implies++a == ++b and the removal of the restrictions on the number of assignments through
a mutable iterator
(which applies to output iterators)
allow the use of multi-pass one-directional algorithms with forward iterators[.](#iterator.concept.forward-5.sentence-1)
— *end note*]
#### [24.3.4.12](#iterator.concept.bidir) Concept bidirectional_iterator [[iterator.concept.bidir]](iterator.concept.bidir)
[1](#iterator.concept.bidir-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1863)
The [bidirectional_iterator](#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") concept adds the ability
to move an iterator backward as well as forward[.](#iterator.concept.bidir-1.sentence-1)
template<class I>concept [bidirectional_iterator](#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") =[forward_iterator](#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<*ITER_CONCEPT*(I), bidirectional_iterator_tag> &&requires(I i) {{ --i } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; { i-- } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; };
[2](#iterator.concept.bidir-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1878)
A bidirectional iterator r is decrementable if and only if there exists some q such that++q == r[.](#iterator.concept.bidir-2.sentence-1)
Decrementable iterators r shall be in the domain of the expressions--r and r--[.](#iterator.concept.bidir-2.sentence-2)
[3](#iterator.concept.bidir-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1883)
Let a and b be equal objects of type I[.](#iterator.concept.bidir-3.sentence-1)
I models [bidirectional_iterator](#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") only if:
- [(3.1)](#iterator.concept.bidir-3.1)
If a and b are decrementable,
then all of the following are true:
* [(3.1.1)](#iterator.concept.bidir-3.1.1)
addressof(--a) == addressof(a)
* [(3.1.2)](#iterator.concept.bidir-3.1.2)
bool(a-- == b)
* [(3.1.3)](#iterator.concept.bidir-3.1.3)
after evaluating both a-- and --b, bool(a == b) is still true
* [(3.1.4)](#iterator.concept.bidir-3.1.4)
bool(++(--a) == b)
- [(3.2)](#iterator.concept.bidir-3.2)
If a and b are incrementable, then bool(--(++a) == b)[.](#iterator.concept.bidir-3.sentence-2)
#### [24.3.4.13](#iterator.concept.random.access) Concept random_access_iterator [[iterator.concept.random.access]](iterator.concept.random.access)
[1](#iterator.concept.random.access-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1902)
The [random_access_iterator](#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") concept adds support for
constant-time advancement with +=, +, -=, and -,
as well as the computation of distance in constant time with -[.](#iterator.concept.random.access-1.sentence-1)
Random access iterators also support array notation via subscripting[.](#iterator.concept.random.access-1.sentence-2)
template<class I>concept [random_access_iterator](#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") =[bidirectional_iterator](#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<*ITER_CONCEPT*(I), random_access_iterator_tag> &&[totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<I> &&[sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I, I> &&requires(I i, const I j, const iter_difference_t<I> n) {{ i += n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; { j + n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; { n + j } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; { i -= n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; { j - n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; { j[n] } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_reference_t<I>>; };
[2](#iterator.concept.random.access-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1925)
Let a and b be valid iterators of type I such that b is reachable from a after n applications of ++a,
let D be iter_difference_t<I>,
and let n denote a value of type D[.](#iterator.concept.random.access-2.sentence-1)
I models [random_access_iterator](#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") only if:
- [(2.1)](#iterator.concept.random.access-2.1)
(a += n) is equal to b[.](#iterator.concept.random.access-2.1.sentence-1)
- [(2.2)](#iterator.concept.random.access-2.2)
addressof(a += n) is equal to addressof(a)[.](#iterator.concept.random.access-2.2.sentence-1)
- [(2.3)](#iterator.concept.random.access-2.3)
(a + n) is equal to (a += n)[.](#iterator.concept.random.access-2.3.sentence-1)
- [(2.4)](#iterator.concept.random.access-2.4)
For any two positive values x and y of type D,
if (a + D(x + y)) is valid, then (a + D(x + y)) is equal to ((a + x) + y)[.](#iterator.concept.random.access-2.4.sentence-1)
- [(2.5)](#iterator.concept.random.access-2.5)
(a + D(0)) is equal to a[.](#iterator.concept.random.access-2.5.sentence-1)
- [(2.6)](#iterator.concept.random.access-2.6)
If (a + D(n - 1)) is valid, then (a + n) is equal to [](I c){ return ++c; }(a + D(n - 1))[.](#iterator.concept.random.access-2.6.sentence-1)
- [(2.7)](#iterator.concept.random.access-2.7)
(b += D(-n)) is equal to a[.](#iterator.concept.random.access-2.7.sentence-1)
- [(2.8)](#iterator.concept.random.access-2.8)
(b -= n) is equal to a[.](#iterator.concept.random.access-2.8.sentence-1)
- [(2.9)](#iterator.concept.random.access-2.9)
addressof(b -= n) is equal to addressof(b)[.](#iterator.concept.random.access-2.9.sentence-1)
- [(2.10)](#iterator.concept.random.access-2.10)
(b - n) is equal to (b -= n)[.](#iterator.concept.random.access-2.10.sentence-1)
- [(2.11)](#iterator.concept.random.access-2.11)
If b is dereferenceable, then a[n] is valid and is equal to *b[.](#iterator.concept.random.access-2.11.sentence-1)
- [(2.12)](#iterator.concept.random.access-2.12)
bool(a <= b) is true[.](#iterator.concept.random.access-2.12.sentence-1)
#### [24.3.4.14](#iterator.concept.contiguous) Concept contiguous_iterator [[iterator.concept.contiguous]](iterator.concept.contiguous)
[1](#iterator.concept.contiguous-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1954)
The [contiguous_iterator](#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") concept provides a guarantee that
the denoted elements are stored contiguously in memory[.](#iterator.concept.contiguous-1.sentence-1)
template<class I>concept [contiguous_iterator](#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") =[random_access_iterator](#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<*ITER_CONCEPT*(I), contiguous_iterator_tag> && is_lvalue_reference_v<iter_reference_t<I>> &&[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> &&requires(const I& i) {{ to_address(i) } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<add_pointer_t<iter_reference_t<I>>>; };
[2](#iterator.concept.contiguous-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1970)
Let a and b be dereferenceable iterators andc be a non-dereferenceable iterator of type I such that b is reachable from a andc is reachable from b,
and let D be iter_difference_t<I>[.](#iterator.concept.contiguous-2.sentence-1)
The type I models [contiguous_iterator](#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") only if
- [(2.1)](#iterator.concept.contiguous-2.1)
to_address(a) == addressof(*a),
- [(2.2)](#iterator.concept.contiguous-2.2)
to_address(b) == to_address(a) + D(b - a),
- [(2.3)](#iterator.concept.contiguous-2.3)
to_address(c) == to_address(a) + D(c - a),
- [(2.4)](#iterator.concept.contiguous-2.4)
to_address(I{}) is well-defined,
- [(2.5)](#iterator.concept.contiguous-2.5)
ranges::iter_move(a) has
the same type, value category, and effects as std::move(*a), and
- [(2.6)](#iterator.concept.contiguous-2.6)
if ranges::iter_swap(a, b) is well-formed,
it has effects equivalent to ranges::swap(*a, *b)[.](#iterator.concept.contiguous-2.sentence-2)