[input.iterators]

# 24 Iterators library [[iterators]](./#iterators)

## 24.3 Iterator requirements [[iterator.requirements]](iterator.requirements#input.iterators)

### 24.3.5 C++17 iterator requirements [[iterator.cpp17]](iterator.cpp17#input.iterators)

#### 24.3.5.3 Input iterators [input.iterators]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2067)

A class or pointer typeX meets the requirements of an input iterator for the value typeT ifX meets the *Cpp17Iterator* ([[iterator.iterators]](iterator.iterators "24.3.5.2 Cpp17Iterator")) and*Cpp17EqualityComparable* (Table [28](utility.arg.requirements#tab:cpp17.equalitycomparable "Table 28: Cpp17EqualityComparable requirements")) requirements and
the expressions in Table [79](#tab:inputiterator "Table 79: Cpp17InputIterator requirements (in addition to Cpp17Iterator)") are valid and have
the indicated semantics[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2078)

In Table [79](#tab:inputiterator "Table 79: Cpp17InputIterator requirements (in addition to Cpp17Iterator)"), the term[*the domain of ==*](#def:the_domain_of_==) is used in the ordinary mathematical sense to denote
the set of values over which== is (required to be) defined[.](#2.sentence-1)

This set can change over time[.](#2.sentence-2)

Each algorithm places additional requirements on the domain of== for the iterator values it uses[.](#2.sentence-3)

These requirements can be inferred from the uses that algorithm
makes of == and !=[.](#2.sentence-4)

[*Example [1](#example-1)*:

The call find(a,b,x) is defined only if the value of a has the property *p* defined as follows:b has property *p* and a value i has property *p* if
(*i==x)
or if
(*i!=x and++i has property*p*)[.](#2.sentence-5)

â *end example*]

Table [79](#tab:inputiterator) — *Cpp17InputIterator* requirements (in addition to *Cpp17Iterator*) [[tab:inputiterator]](./tab:inputiterator)  

| [ð](#tab:inputiterator-row-1)<br>**Expression** | **Return type** | **Operational** | **Assertion/note** |
| --- | --- | --- | --- |
| [ð](#tab:inputiterator-row-2) |  | **semantics** | **pre-/post-condition** |
| [ð](#tab:inputiterator-row-3)<br>a != b | decltype(a != b) models *boolean-testable* | !(a == b) | *Preconditions*: (a, b) is in the domain of ==[.](#tab:inputiterator-row-3-column-4-sentence-1) |
| [ð](#tab:inputiterator-row-4)<br>*a | reference, convertible to T |  | *Preconditions*: a is dereferenceable[.](#tab:inputiterator-row-4-column-4-sentence-1)<br>   The expression   (void)*a, *a is equivalent to *a[.](#tab:inputiterator-row-4-column-4-sentence-2)<br>   If a == b and (a, b) is in the domain of ==  then *a is equivalent to *b[.](#tab:inputiterator-row-4-column-4-sentence-3) |
| [ð](#tab:inputiterator-row-5)<br>a->m |  | (*a).m | *Preconditions*: a is dereferenceable[.](#tab:inputiterator-row-5-column-4-sentence-1) |
| [ð](#tab:inputiterator-row-6)<br>++r | X& |  | *Preconditions*: r is dereferenceable[.](#tab:inputiterator-row-6-column-4-sentence-1)<br>   *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 ==[.](#tab:inputiterator-row-6-column-4-sentence-2) |
| [ð](#tab:inputiterator-row-7)<br>(void)r++ |  |  | equivalent to (void)++r |
| [ð](#tab:inputiterator-row-8)<br>*r++ | convertible to T | { T tmp = *r;   ++r;   return tmp; } |  |

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2155)

*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[.](#3.sentence-1)

[*Note [1](#note-1)*:

For input iterators, a == b does not imply ++a == ++b[.](#3.sentence-2)

(Equality does not guarantee the substitution property or referential transparency[.](#3.sentence-3))

Value type T is not required to be a *Cpp17CopyAssignable* type (Table [34](utility.arg.requirements#tab:cpp17.copyassignable "Table 34: Cpp17CopyAssignable requirements (in addition to Cpp17MoveAssignable)"))[.](#3.sentence-4)

Such an algorithm can be used with istreams as the source of the input data through theistream_iterator class template[.](#3.sentence-5)

â *end note*]
