Skip to main content

C++ named requirements: LegacyInputIterator

A LegacyInputIterator is a LegacyIterator that can read from the pointed-to element. LegacyInputIterators only guarantee validity for single pass algorithms: once a LegacyInputIterator i has been incremented, all copies of its previous value may be invalidated.

Requirements

The type It satisfies LegacyInputIterator if

And, given

  • i and j, values of type It or const It
  • r, an lvalue of type It
  • reference, the type denoted by std::iterator_traits<It>::reference
  • value_type, the type denoted by std::iterator_traits<It>::value_type

The following expressions must be valid and have their specified effects:

ExpressionReturn typeEquivalent expressionNotes
i != jcontextually convertible to bool!(i == j)Precondition: (i, j) is in the domain of ==.
*ireference, convertible to value_typeIf i == j and (i, j) is in the domain of == then this is equivalent to *j.Precondition: i is dereferenceable. The expression (void)*i, *i is equivalent to *i.
i->m(*i).mPrecondition: i is dereferenceable.
++rIt&Precondition: r is dereferenceable.
Postcondition: r is dereferenceable or r is past-the-end.
Postcondition: Any copies of the previous value of r are no longer required to be either dereferenceable or to be in the domain of ==.
(void)r++(void)++r
*r++convertible to value_typevalue_type x = *r;
++r;
return x;

Notes

"in the domain of ==" means equality comparison is defined between the two iterator values. For input iterators, equality comparison does not need to be defined for all values, and the set of the values in the domain of == may change over time.

The reference type for an input iterator that is not also a LegacyForwardIterator does not have to be a reference type: dereferencing an input iterator may return a proxy object or value_type itself by value (as in the case of std::istreambuf_iterator).

Concept (since C++20)

Click to expand

For the definition of std::iterator_traits, the following exposition-only concept is defined.

template<class I>
concept __LegacyInputIterator =
__LegacyIterator<I> && std::equality_comparable<I> && requires(I i) {
typename std::incrementable_traits<I>::difference_type;
typename std::indirectly_readable_traits<I>::value_type;
typename std::common_reference_t<std::iter_reference_t<I>&&,
typename std::indirectly_readable_traits<I>::value_type&>;
*i++;
typename std::common_reference_t<decltype(*i++)&&,
typename std::indirectly_readable_traits<I>::value_type&>;
requires std::signed_integral<typename std::incrementable_traits<I>::difference_type>;
};

where the exposition-only concept __LegacyIterator is described in LegacyIterator#Concept.

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DRApplied toBehavior as publishedCorrect behavior
LWG 98C++98the return type of *i++ was value_typeit can be any type convertible to value_type

C++ named requirements: LegacyInputIterator

A LegacyInputIterator is a LegacyIterator that can read from the pointed-to element. LegacyInputIterators only guarantee validity for single pass algorithms: once a LegacyInputIterator i has been incremented, all copies of its previous value may be invalidated.

Requirements

The type It satisfies LegacyInputIterator if

And, given

  • i and j, values of type It or const It
  • r, an lvalue of type It
  • reference, the type denoted by std::iterator_traits<It>::reference
  • value_type, the type denoted by std::iterator_traits<It>::value_type

The following expressions must be valid and have their specified effects:

ExpressionReturn typeEquivalent expressionNotes
i != jcontextually convertible to bool!(i == j)Precondition: (i, j) is in the domain of ==.
*ireference, convertible to value_typeIf i == j and (i, j) is in the domain of == then this is equivalent to *j.Precondition: i is dereferenceable. The expression (void)*i, *i is equivalent to *i.
i->m(*i).mPrecondition: i is dereferenceable.
++rIt&Precondition: r is dereferenceable.
Postcondition: r is dereferenceable or r is past-the-end.
Postcondition: Any copies of the previous value of r are no longer required to be either dereferenceable or to be in the domain of ==.
(void)r++(void)++r
*r++convertible to value_typevalue_type x = *r;
++r;
return x;

Notes

"in the domain of ==" means equality comparison is defined between the two iterator values. For input iterators, equality comparison does not need to be defined for all values, and the set of the values in the domain of == may change over time.

The reference type for an input iterator that is not also a LegacyForwardIterator does not have to be a reference type: dereferencing an input iterator may return a proxy object or value_type itself by value (as in the case of std::istreambuf_iterator).

Concept (since C++20)

Click to expand

For the definition of std::iterator_traits, the following exposition-only concept is defined.

template<class I>
concept __LegacyInputIterator =
__LegacyIterator<I> && std::equality_comparable<I> && requires(I i) {
typename std::incrementable_traits<I>::difference_type;
typename std::indirectly_readable_traits<I>::value_type;
typename std::common_reference_t<std::iter_reference_t<I>&&,
typename std::indirectly_readable_traits<I>::value_type&>;
*i++;
typename std::common_reference_t<decltype(*i++)&&,
typename std::indirectly_readable_traits<I>::value_type&>;
requires std::signed_integral<typename std::incrementable_traits<I>::difference_type>;
};

where the exposition-only concept __LegacyIterator is described in LegacyIterator#Concept.

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DRApplied toBehavior as publishedCorrect behavior
LWG 98C++98the return type of *i++ was value_typeit can be any type convertible to value_type