[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.3 Qualified 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.3 Qualified 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.2 Concept 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.2 Concept 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.2 Concept same_­as [concept.same]")<iter_reference_t<In>>; { ranges::iter_move(in) } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<iter_rvalue_reference_t<In>>; } &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")<iter_reference_t<In>&&, iter_value_t<In>&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept 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.5 Concept 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.2 Concept indirectly_­readable [iterator.concept.readable]") =[*indirectly-readable-impl*](#concept:indirectly-readable-impl "24.3.4.2 Concept 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.2 Concept 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.3 Concept 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.3 Concept 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.3 Concept 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.2 Concept indirectly_­readable [iterator.concept.readable]")<Out> && [same_as](concept.same#concept:same_as "18.4.2 Concept 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.1 Value category")), the resulting
state of the object it denotes is valid but unspecified ([[lib.types.movedfrom]](lib.types.movedfrom "16.4.6.17 Moved-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.3 Concept 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.3 Concept 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.4 Concept 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.4 Concept 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.4 Concept weakly_­incrementable [iterator.concept.winc]") =[movable](concepts.object#concept:movable "18.6 Object 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.2 Concept 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.4 Concept 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â1 (inclusive) for some integer N,
in which case it is a [*signed-integer-class type*](#def:type,signed-integer-class "24.3.4.4 Concept 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.4 Concept 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.4 Concept 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.4 Concept weakly_­incrementable [iterator.concept.winc]") if it models [integral](concepts.arithmetic#concept:integral "18.4.7 Arithmetic 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.4 Concept weakly_­incrementable [iterator.concept.winc]") if it models [signed_integral](concepts.arithmetic#concept:signed_integral "18.4.7 Arithmetic 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.4 Concept weakly_­incrementable [iterator.concept.winc]") if it models [unsigned_integral](concepts.arithmetic#concept:unsigned_integral "18.4.7 Arithmetic 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.2 Fundamental 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.5 Class 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.1 General [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.6 Object concepts [concepts.object]") ([[concepts.object]](concepts.object "18.6 Object concepts")) and[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]")<strong_ordering> ([[cmp.concept]](cmp.concept "17.12.4 Concept 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.4 Concept weakly_­incrementable [iterator.concept.winc]")[.](#iterator.concept.winc-14.sentence-2)

I models [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept 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.4 Concept 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.5 Concept 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.4 Concept 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.4 Concept weakly_­incrementable [iterator.concept.winc]")[.](#iterator.concept.inc-1.sentence-3)

â *end note*]

template<class I>concept [incrementable](#concept:incrementable "24.3.4.5 Concept incrementable [iterator.concept.inc]") =[regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]")<I> &&[weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]")<I> &&requires(I i) {{ i++ } -> [same_as](concept.same#concept:same_as "18.4.2 Concept 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.5 Concept 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.5 Concept 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.6 Concept 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.6 Concept 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.7 Concept sentinel_­for")), to
read ([[iterator.concept.input]](#iterator.concept.input "24.3.4.9 Concept input_­iterator")) or write ([[iterator.concept.output]](#iterator.concept.output "24.3.4.10 Concept output_­iterator")) values, or
to provide a richer set of iterator movements ([[iterator.concept.forward]](#iterator.concept.forward "24.3.4.11 Concept forward_­iterator"), [[iterator.concept.bidir]](#iterator.concept.bidir "24.3.4.12 Concept bidirectional_­iterator"), [[iterator.concept.random.access]](#iterator.concept.random.access "24.3.4.13 Concept 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.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") =requires(I i) {{ *i } -> [*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator>&nbsp;synopsis [iterator.synopsis]"); } &&[weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept 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.6 Concept 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.7 Concept sentinel_­for [iterator.concept.sentinel]") concept specifies the relationship
between an [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") type and a [semiregular](concepts.object#concept:semiregular "18.6 Object 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.7 Concept sentinel_­for [iterator.concept.sentinel]") =
    [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")<S> &&
    [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]")<I> &&
    [weakly-equality-comparable-with](concept.equalitycomparable#concept:weakly-equality-comparable-with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<S, I>;      // see [[concept.equalitycomparable]](concept.equalitycomparable "18.5.4 Concept 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.7 Concept 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.8 Concept 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.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") concept specifies
requirements on an [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") type I and
a corresponding [sentinel_for](#concept:sentinel_for "24.3.4.7 Concept 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.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") =
    [sentinel_for](#concept:sentinel_for "24.3.4.7 Concept 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.2 Concept same_­as [concept.same]")<iter_difference_t<I>>;
      { i - s } -> [same_as](concept.same#concept:same_as "18.4.2 Concept 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.8 Concept 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.1 Namespace 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.7 Constant 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.8 Concept 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.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") concept is modeled by pairs of[random_access_iterator](#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")s ([[iterator.concept.random.access]](#iterator.concept.random.access "24.3.4.13 Concept random_­access_­iterator")) and by
counted iterators and their sentinels ([[counted.iterator]](counted.iterator "24.5.7.1 Class 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.9 Concept 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.2 Concept indirectly_­readable [iterator.concept.readable]") ([[iterator.concept.readable]](#iterator.concept.readable "24.3.4.2 Concept 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.3 Input iterators")),
the [input_iterator](#concept:input_iterator "24.3.4.9 Concept 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.9 Concept input_­iterator [iterator.concept.input]") =[input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]")<I> &&[indirectly_readable](#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]")<I> &&requires { typename *ITER_CONCEPT*(I); } &&[derived_from](concept.derived#concept:derived_from "18.4.3 Concept 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.10 Concept 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.3 Concept indirectly_­writable [iterator.concept.writable]") ([[iterator.concept.writable]](#iterator.concept.writable "24.3.4.3 Concept 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.4 Concept 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.10 Concept output_­iterator [iterator.concept.output]") =[input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]")<I> &&[indirectly_writable](#concept:indirectly_writable "24.3.4.3 Concept 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.10 Concept 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.11 Concept 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.11 Concept forward_­iterator [iterator.concept.forward]") =[input_iterator](#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]")<*ITER_CONCEPT*(I), forward_iterator_tag> &&[incrementable](#concept:incrementable "24.3.4.5 Concept incrementable [iterator.concept.inc]")<I> &&[sentinel_for](#concept:sentinel_for "24.3.4.7 Concept 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.5 Forward 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.12 Concept 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.12 Concept bidirectional_­iterator [iterator.concept.bidir]") =[forward_iterator](#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]")<*ITER_CONCEPT*(I), bidirectional_iterator_tag> &&requires(I i) {{ --i } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I&>; { i-- } -> [same_as](concept.same#concept:same_as "18.4.2 Concept 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.12 Concept 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.13 Concept 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.13 Concept random_­access_­iterator [iterator.concept.random.access]") =[bidirectional_iterator](#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_­iterator [iterator.concept.bidir]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]")<*ITER_CONCEPT*(I), random_access_iterator_tag> &&[totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5 Concept totally_­ordered [concept.totallyordered]")<I> &&[sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8 Concept 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.2 Concept same_­as [concept.same]")<I&>; { j + n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I>; { n + j } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I>; { i -= n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I&>; { j - n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I>; { j[n] } -> [same_as](concept.same#concept:same_as "18.4.2 Concept 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.13 Concept 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.14 Concept 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.14 Concept contiguous_­iterator [iterator.concept.contiguous]") =[random_access_iterator](#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")<I> &&[derived_from](concept.derived#concept:derived_from "18.4.3 Concept 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.2 Concept 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.2 Concept 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.14 Concept 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)
