[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 names a specialization generated from the primary template[.](#general-1.sentence-1) Otherwise, *ITER_TRAITS*(I) denotesiterator_traits[.](#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 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​::​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) templateconcept [*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; typename iter_reference_t; typename iter_rvalue_reference_t; { *in } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>; { ranges::iter_move(in) } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>; } &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")&&, iter_value_t&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")&&, iter_rvalue_reference_t&&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")&&, const iter_value_t&>; templateconcept [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]")>; [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) templateconcept [indirectly_writable](#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") =requires(Out&& o, T&& t) {*o = std::forward(t); // not required to be equality-preserving*std::forward(o) = std::forward(t); // not required to be equality-preservingconst_cast&&>(*o) = std::forward(t); // not required to be equality-preservingconst_cast&&>(*std::forward(o)) = std::forward(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]") 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]") && [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"), decay_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]")[.](#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) templateconstexpr bool *is-integer-like* = *see below*; // *exposition only*templateconstexpr bool *is-signed-integer-like* = *see below*; // *exposition only*templateconcept [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]") &&requires(I i) {typename iter_difference_t; requires *is-signed-integer-like*>; { ++i } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); // 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]") 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]") 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]") 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 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]") ([[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 is specialized such that each static data member m has the same value as numeric_limits​::​m, and each static member function f returns I(numeric_limits​::​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 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 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* is true if and only if I is an integer-like type[.](#iterator.concept.winc-13.sentence-1) *is-signed-integer-like* 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]") 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*] templateconcept [incrementable](#concept:incrementable "24.3.4.5 Concept incrementable [iterator.concept.inc]") =[regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") &&[weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") &&requires(I i) {{ i++ } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); }; [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) templateconcept [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  synopsis [iterator.synopsis]"); } &&[weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]"); [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 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]") && [input_or_output_iterator](#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") && [weakly-equality-comparable-with](concept.equalitycomparable#concept:weakly-equality-comparable-with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]"); // 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]") 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]") 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]") 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 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]") && !disable_sized_sentinel_for, remove_cv_t> && requires(const I& i, const S& s) { { s - i } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>; { i - s } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>; }; ` [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]") only if: - [(2.1)](#iterator.concept.sizedsentinel-2.1) If N is representable by iter_difference_t, 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, then i - s is well-defined and equals −N[.](#iterator.concept.sizedsentinel-2.2.sentence-1) [🔗](#lib:disable_sized_sentinel_for) `template 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*] templateconcept [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]") &&[indirectly_readable](#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]") &&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*] templateconcept [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]") &&[indirectly_writable](#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") &&requires(I i, T&& t) {*i++ = std::forward(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]") 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) templateconcept [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]") &&[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]") &&[sentinel_for](#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]"); [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) templateconcept [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]") &&[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-- } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); }; [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) templateconcept [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]") &&[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]") &&[sized_sentinel_for](#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") &&requires(I i, const I j, const iter_difference_t n) {{ i += n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); { j + n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); { n + j } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); { i -= n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); { j - n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"); { j[n] } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>; }; [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, 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) templateconcept [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]") &&[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> &&[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"), remove_cvref_t>> &&requires(const I& i) {{ to_address(i) } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>>; }; [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[.](#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)