23 Iterators library [iterators]

23.3 Iterator requirements [iterator.requirements]

23.3.4 Iterator concepts [iterator.concepts] Concept weakly_­incrementable [iterator.concept.winc]

The weakly_­incrementable concept specifies the requirements on types that can be incremented with the pre- and post-increment operators.
The increment operations are not required to be equality-preserving, nor is the type required to be equality_­comparable.
template<class T>
  inline constexpr bool is-integer-like = see below;            // exposition only

template<class T>
  inline constexpr bool is-signed-integer-like = see below;     // exposition only

template<class I>
  concept weakly_incrementable =
    default_constructible<I> && movable<I> &&
    requires(I i) {
      typename iter_difference_t<I>;
      requires is-signed-integer-like<iter_difference_t<I>>;
      { ++i } -> same_as<I&>;   // not required to be equality-preserving
      i++;                      // not required to be equality-preserving
A type I is an integer-class type if it is in a set of implementation-defined class types that behave as integer types do, as defined in below.
The range of representable values of an integer-class type is the continuous set of values over which it is defined.
The values 0 and 1 are part of the range of every integer-class type.
If any negative numbers are part of the range, the type is a signed-integer-class type; otherwise, it is an unsigned-integer-class type.
For every integer-class type I, let B(I) be a hypothetical extended integral type of the same signedness with the smallest width ([basic.fundamental]) capable of representing the same range of values.
The width of I is equal to the width of B(I).
Let a and b be objects of integer-class type I, let x and y be objects of type B(I) as described above that represent the same values as a and b respectively, and let c be an lvalue of any integral type.
All integer-class types are explicitly convertible to all integral types and implicitly and explicitly convertible from all integral types.
All integer-class types are contextually convertible to bool as if by bool(a != I(0)), where a is an instance of the integral-class type I.
All integer-class types model regular ([concepts.object]) and totally_­ordered ([concept.totallyordered]).
A value-initialized object of integer-class type has value 0.
For every (possibly cv-qualified) integer-class type I, numeric_­limits<I> is specialized such that:
  • numeric_­limits<I>​::​is_­specialized is true,
  • numeric_­limits<I>​::​is_­signed is true if and only if I is a signed-integer-class type,
  • numeric_­limits<I>​::​is_­integer is true,
  • numeric_­limits<I>​::​is_­exact is true,
  • numeric_­limits<I>​::​digits is equal to the width of the integer-class type,
  • numeric_­limits<I>​::​digits10 is equal to static_­cast<int>(digits * log10(2)), and
  • numeric_­limits<I>​::​min() and numeric_­limits<I>​::​max() return the lowest and highest representable values of I, respectively, and numeric_­limits<I>​::​lowest() returns numeric_­limits<I>​::​​min().
A type I is integer-like if it models integral<I> or if it is an integer-class type.
A type I is signed-integer-like if it models signed_­integral<I> or if it is a signed-integer-class type.
A type I is unsigned-integer-like if it models unsigned_­integral<I> or if it is an unsigned-integer-class type.
is-integer-like<I> is true if and only if I is an integer-like type.
is-signed-integer-like<I> is true if and only if I is a signed-integer-like type.
Let i be an object of type I.
When i is in the domain of both pre- and post-increment, i is said to be incrementable.
I models weakly_­incrementable<I> only if
  • The expressions ++i and i++ have the same domain.
  • If i is incrementable, then both ++i and i++ advance i to the next element.
  • If i is incrementable, then addressof(++i) is equal to addressof(i).
For weakly_­incrementable types, a equals b does not imply that ++a equals ++b.
(Equality does not guarantee the substitution property or referential transparency.)
Algorithms on weakly incrementable types should never attempt to pass through the same incrementable value twice.
They should be single-pass algorithms.
These algorithms can be used with istreams as the source of the input data through the istream_­iterator class template.
— end note