[iterator.cpp17] (original) (raw)

24 Iterators library [iterators]

24.3 Iterator requirements [iterator.requirements]

24.3.5 C++17 iterator requirements [iterator.cpp17]

24.3.5.1 General [iterator.cpp17.general]

In the following sections,aandbdenote values of typeX or const X,difference_type and reference refer to the types iterator_traits<X>​::​difference_type anditerator_traits<X>​::​reference, respectively,ndenotes a value ofdifference_type,u,tmp, andmdenote identifiers,rdenotes a value ofX&,tdenotes a value of value typeT,odenotes a value of some type that is writable to the output iterator.

[Note 1:

For an iterator type X there must be an instantiation of iterator_traits<X> ([iterator.traits]).

— _end note_]

24.3.5.2 Cpp17Iterator [iterator.iterators]

The Cpp17Iterator requirements form the basis of the iterator taxonomy; every iterator meets the Cpp17Iterator requirements.

This set of requirements specifies operations for dereferencing and incrementing an iterator.

Most algorithms will require additional operations to read ([input.iterators]) or write ([output.iterators]) values, or to provide a richer set of iterator movements ([forward.iterators], [bidirectional.iterators], [random.access.iterators]).

A type X meets the Cpp17Iterator requirements if

Table 76Cpp17Iterator requirements [tab:iterator]

🔗Expression Return type Operational Assertion/note
🔗 semantics pre-/post-condition
🔗*r unspecified Preconditions: r is dereferenceable.
🔗++r X&

24.3.5.3 Input iterators [input.iterators]

A class or pointer typeXmeets the requirements of an input iterator for the value typeTifX meets the Cpp17Iterator ([iterator.iterators]) and_Cpp17EqualityComparable_ (Table 28) requirements and the expressions in Table 77 are valid and have the indicated semantics.

In Table 77, the termthe domain of ==is used in the ordinary mathematical sense to denote the set of values over which== is (required to be) defined.

This set can change over time.

Each algorithm places additional requirements on the domain of== for the iterator values it uses.

These requirements can be inferred from the uses that algorithm makes of == and !=.

[Example 1:

The call find(a,b,x)is defined only if the value of ahas the property _p_defined as follows:b has property _p_and a value ihas property p_if (*i==x) or if (*i!=xand++ihas property_p).

— _end example_]

Table 77Cpp17InputIterator requirements (in addition to Cpp17Iterator) [tab:inputiterator]

🔗Expression Return type Operational Assertion/note
🔗 semantics pre-/post-condition
🔗a != b decltype(a != b) models boolean-testable !(a == b) Preconditions: (a, b) is in the domain of ==.
🔗*a reference, convertible to T Preconditions: a is dereferenceable. The expression(void)*a, *a is equivalent to *a. If a == b and (a, b) is in the domain of == then *a is equivalent to *b.
🔗a->m (*a).m Preconditions: a is dereferenceable.
🔗++r X& Preconditions: r is dereferenceable. Postconditions: r is dereferenceable or r is past-the-end;any copies of the previous value of r are no longer required to be dereferenceable nor to be in the domain of ==.
🔗(void)r++ equivalent to (void)++r
🔗*r++ convertible to T { T tmp = *r;++r;return tmp; }

Recommended practice: The implementation of an algorithm on input iterators should never attempt to pass through the same iterator twice; such an algorithm should be a single pass algorithm.

[Note 1:

For input iterators, a == b does not imply ++a == ++b.

(Equality does not guarantee the substitution property or referential transparency.)

Value type T is not required to be a Cpp17CopyAssignable type (Table 34).

Such an algorithm can be used with istreams as the source of the input data through theistream_iteratorclass template.

— _end note_]

24.3.5.4 Output iterators [output.iterators]

A class or pointer typeXmeets the requirements of an output iterator if X meets the Cpp17Iterator requirements ([iterator.iterators]) and the expressions in Table 78are valid and have the indicated semantics.

Table 78Cpp17OutputIterator requirements (in addition to Cpp17Iterator) [tab:outputiterator]

🔗Expression Return type Operational Assertion/note
🔗 semantics pre-/post-condition
🔗*r = o result is not used Remarks: After this operation r is not required to be dereferenceable. Postconditions: r is incrementable.
🔗++r X& addressof(r) == addressof(++r). Remarks: After this operation r is not required to be dereferenceable. Postconditions: r is incrementable.
🔗r++ convertible to const X& { X tmp = r; ++r; return tmp; } Remarks: After this operation r is not required to be dereferenceable. Postconditions: r is incrementable.
🔗*r++ = o result is not used Remarks: After this operation r is not required to be dereferenceable. Postconditions: r is incrementable.

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.

[Note 1:

The only valid use of an operator*is on the left side of the assignment statement.

Assignment through the same value of the iterator happens only once.

Equality and inequality are not necessarily defined.

— _end note_]

24.3.5.5 Forward iterators [forward.iterators]

A class or pointer typeXmeets the Cpp17ForwardIterator requirements if

The domain of == for forward iterators is that of iterators over the same underlying sequence.

However, value-initialized iterators may be compared and shall compare equal to other value-initialized iterators of the same type.

[Note 1:

Value-initialized iterators behave as if they refer past the end of the same empty sequence.

— _end note_]

Two dereferenceable iterators a and b of type X offer themulti-pass guarantee if

[Note 2:

The requirement thata == bimplies++a == ++b(which is not true for input and output iterators) and the removal of the restrictions on the number of the assignments through a mutable iterator (which applies to output iterators) allows the use of multi-pass one-directional algorithms with forward iterators.

— _end note_]

Table 79Cpp17ForwardIterator requirements (in addition to Cpp17InputIterator) [tab:forwarditerator]

🔗Expression Return type Operational Assertion/note
🔗 semantics pre-/post-condition
🔗r++ convertible to const X& { X tmp = r; ++r; return tmp; }
🔗*r++ reference

If a and b are equal, then either a and bare both dereferenceable or else neither is dereferenceable.

If a and b are both dereferenceable, then a == bif and only if*a and *b are bound to the same object.

24.3.5.6 Bidirectional iterators [bidirectional.iterators]

A class or pointer typeXmeets the requirements of a bidirectional iterator if, in addition to meeting the Cpp17ForwardIterator requirements, the following expressions are valid as shown in Table 80.

Table 80Cpp17BidirectionalIterator requirements (in addition to Cpp17ForwardIterator) [tab:bidirectionaliterator]

🔗Expression Return type Operational Assertion/note
🔗 semantics pre-/post-condition
🔗--r X& Preconditions: there exists s such that r == ++s. Postconditions: r is dereferenceable. --(++r) == r. --r == --s implies r == s. addressof(r) == addressof(--r).
🔗r-- convertible to const X& { X tmp = r; --r; return tmp; }
🔗*r-- reference

[Note 1:

Bidirectional iterators allow algorithms to move iterators backward as well as forward.

— _end note_]

24.3.5.7 Random access iterators [random.access.iterators]

A class or pointer typeXmeets the requirements of a random access iterator if, in addition to meeting the Cpp17BidirectionalIterator requirements, the following expressions are valid as shown in Table 81.

Table 81Cpp17RandomAccessIterator requirements (in addition to Cpp17BidirectionalIterator) [tab:randomaccessiterator]

🔗Expression Return type Operational Assertion/note
🔗 semantics pre-/post-condition
🔗r += n X& { difference_type m = n; if (m >= 0) while (m--) ++r; else while (m++) --r; return r; }
🔗a + nn + a X { X tmp = a; return tmp += n; } a + n == n + a.
🔗r -= n X& return r += -n; Preconditions: the absolute value of n is in the range of representable values of difference_type.
🔗a - n X { X tmp = a; return tmp -= n; }
🔗b - a difference_type return n; Preconditions: there exists a value n of type difference_type such that a + n == b. b == a + (b - a).
🔗a[n] convertible to reference *(a + n)
🔗a < b decltype(a < b) models boolean-testable Effects: Equivalent to: return b - a > 0; < is a total ordering relation
🔗a > b decltype(a > b) models boolean-testable b < a > is a total ordering relation opposite to <.
🔗a >= b decltype(a >= b) models boolean-testable !(a < b)
🔗a <= b decltype(a <= b) models boolean-testable !(a > b)