887 lines
51 KiB
Markdown
887 lines
51 KiB
Markdown
[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> 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)
|