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_initializable<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 integer type
of the same signedness with the smallest width ([basic.fundamental])
capable of representing the same range of values.

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.

- For every unary operator @ for which the expression @x is well-formed, @a shall also be well-formed and have the same value, effects, and value category as @x provided that value is representable by I.
- For every assignment operator @= for which c @= x is well-formed, c @= a shall also be well-formed and shall have the same value and effects as c @= x.
- For every binary operator @ for which x @ y is well-formed, a @ b shall also be well-formed and shall have the same value, effects, and value category as x @ y provided that value is representable by I.

Expressions of integer-class type are
explicitly convertible to any integral type.

Expressions of integral type are
both implicitly and explicitly convertible to any integer-class type.

Conversions between integral and integer-class types
do not exit via an exception.

An expression E of integer-class type I is
contextually convertible to bool
as if by bool(E != I(0)).

All integer-class types model
regular ([concepts.object]) and
totally_ordered ([concept.totallyordered]).

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 *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.

[Note: *end note*]

(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.

—