C++ named requirements: LegacyInputIterator

From cppreference.com
< cpp‎ | named req
C++ named requirements

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

Requirements

Type Definition
X An input iterator type
T The value type of X (i.e. std::iterator_traits <X> :: value_type
R std::iterator_traits <X> :: reference
Value Definition
i, j Values of type X or const X
r A value of type X&
Other Definition
m An identifier which possibly denotes a data member or member function


X satisfies LegacyInputIterator if all following conditions are satisfied:

Expression  Type Semantics
i != j
a type satisfying BooleanTestable (until C++20)
a type modeling boolean-testable (since C++20)
Precondition i and j are in the domain of ==
Effect Equivalent to !(i == j).
*i R, convertible to T Precondition i is dereferenceable.
Effect
  • The expression (void)*i, *i is equivalent to *i
  • If i and j are in the domain of ==, and i == j, then *i is equivalent to *j
i->m Precondition i is dereferenceable.
Effect Equivalent to (*i).m.
++r X& Precondition r is dereferenceable.
Postcondition 
  • r is dereferenceable or r is past-the-end.
  • 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++ Effect Equivalent to (void)++r.
*r++ convertible to T Effect Equivalent to T x = *r; ++r; return x;

Equality domain

The term the domain of == is used in the ordinary mathematical sense to denote the set of values which can be compared using ==

Each algorithm places additional requirements on the equality domain for the iterator values it uses. These requirements can be inferred from the uses that algorithm makes of == and !=

Notes

For an input iterator X that is not a LegacyForwardIterator, std::iterator_traits <X> :: reference does not have to be a reference type: dereferencing an input iterator may return a proxy object or std::iterator_traits <X> :: value_type itself by value (as in the case of std::istreambuf_iterator

Concept

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.

(since C++20)

Defect reports

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

DR Applied to Behavior as published Correct behavior
LWG 98 C++98 the return type of *i++ was required to be T it can be any type convertible to T
LWG 2114
(P2167R3)
C++98 convertibility to bool was too weak to
reflect the expectation of implementations
requirements strengthened

See also

(C++20)
specifies that a type is an input iterator, that is, its referenced values can be read and it can be both pre- and post-incremented
(concept)
Iterator library provides definitions for iterators, iterator traits, adaptors, and utility functions