[iterator.concept.winc]

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

## 24.3 Iterator requirements [[iterator.requirements]](iterator.requirements#iterator.concept.winc)

### 24.3.4 Iterator concepts [[iterator.concepts]](iterator.concepts#iterator.concept.winc)

#### 24.3.4.4 Concept weakly_incrementable [iterator.concept.winc]

[1](#1)

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

The [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") concept specifies the requirements on
types that can be incremented with the pre- and post-increment operators[.](#1.sentence-1)

The increment operations are not required to be equality-preserving,
nor is the type required to be [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")[.](#1.sentence-2)

template<class T>constexpr bool *is-integer-like* = *see below*; // *exposition only*template<class T>constexpr bool *is-signed-integer-like* = *see below*; // *exposition only*template<class I>concept [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") =[movable](concepts.object#concept:movable "18.6 Object concepts [concepts.object]")<I> &&requires(I i) {typename iter_difference_t<I>; requires *is-signed-integer-like*<iter_difference_t<I>>; { ++i } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I&>; // not required to be equality-preserving i++; // not required to be equality-preserving};

[2](#2)

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

A type I is an [*integer-class type*](#def:type,integer-class "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") if it is in a set of implementation-defined types
that behave as integer types do, as defined below[.](#2.sentence-1)

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

An integer-class type is not necessarily a class type[.](#2.sentence-2)

â *end note*]

[3](#3)

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

The range of representable values of an integer-class type
is the continuous set of values over which it is defined[.](#3.sentence-1)

For any integer-class type,
its range of representable values is
either â2Nâ1 to 2Nâ1â1 (inclusive) for some integer N,
in which case it is a [*signed-integer-class type*](#def:type,signed-integer-class "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]"), or0 to 2Nâ1 (inclusive) for some integer N,
in which case it is an [*unsigned-integer-class type*](#def:type,unsigned-integer-class "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]")[.](#3.sentence-2)

In both cases, N is called
the [*width*](#def:width,of_integer-class_type "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") of the integer-class type[.](#3.sentence-3)

The width of an integer-class type is greater than
that of every integral type of the same signedness[.](#3.sentence-4)

[4](#4)

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

A type I other than cv bool is [*integer-like*](#def:integer-like "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") if it models [integral](concepts.arithmetic#concept:integral "18.4.7 Arithmetic concepts [concepts.arithmetic]")<I> or
if it is an integer-class type[.](#4.sentence-1)

An integer-like type I is [*signed-integer-like*](#def:signed-integer-like "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") if it models [signed_integral](concepts.arithmetic#concept:signed_integral "18.4.7 Arithmetic concepts [concepts.arithmetic]")<I> or
if it is a signed-integer-class type[.](#4.sentence-2)

An integer-like type I is [*unsigned-integer-like*](#def:unsigned-integer-like "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") if it models [unsigned_integral](concepts.arithmetic#concept:unsigned_integral "18.4.7 Arithmetic concepts [concepts.arithmetic]")<I> or
if it is an unsigned-integer-class type[.](#4.sentence-3)

[5](#5)

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

For every integer-class type I,
let B(I) be a unique hypothetical extended integer type
of the same signedness with the same width ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) as I[.](#5.sentence-1)

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

The corresponding hypothetical specialization numeric_limits<B(I)> meets the requirements on numeric_limits specializations
for integral types ([[numeric.limits]](numeric.limits "17.3.5 Class template numeric_­limits"))[.](#5.sentence-2)

â *end note*]

For every integral type J, let B(J) be the same type as J[.](#5.sentence-3)

[6](#6)

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

Expressions of integer-class type are
explicitly convertible to any integer-like type, and
implicitly convertible to any integer-class type
of equal or greater width and the same signedness[.](#6.sentence-1)

Expressions of integral type are
both implicitly and explicitly convertible to any integer-class type[.](#6.sentence-2)

Conversions between integral and integer-class types
and between two integer-class types do not exit via an exception[.](#6.sentence-3)

The result of such a conversion is the unique value of the destination type
that is congruent to the source modulo 2N,
where N is the width of the destination type[.](#6.sentence-4)

[7](#7)

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

Let a be an object of integer-class type I,
let b be an object of integer-like type I2 such that the expression b is implicitly convertible to I,
let x and y be, respectively,
objects of type B(I) and B(I2) as described above
that represent the same values as a and b, and
let c be an lvalue of any integral type[.](#7.sentence-1)

- [(7.1)](#7.1)

  The expressions a++ and a-- shall be prvalues of type I whose values are equal to
that of a prior to the evaluation of the expressions[.](#7.1.sentence-1)
  The expression a++ shall modify the value of a by adding 1 to it[.](#7.1.sentence-2)
  The expression a-- shall modify the value of a by subtracting 1 from it[.](#7.1.sentence-3)

- [(7.2)](#7.2)

  The expressions ++a, --a, and &a shall be
expression-equivalent toa += 1, a -= 1, and addressof(a), respectively[.](#7.2.sentence-1)

- [(7.3)](#7.3)

  For every [*unary-operator*](expr.unary.general#nt:unary-operator "7.6.2.1 General [expr.unary.general]") @ other than & 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[.](#7.3.sentence-1)
  If @x has type bool, so too does @a;
 if @x has type B(I), then @a has type I[.](#7.3.sentence-2)

- [(7.4)](#7.4)

  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[.](#7.4.sentence-1)
  The expression c @= a shall be an lvalue referring to c[.](#7.4.sentence-2)

- [(7.5)](#7.5)

  For every assignment operator @= for which x @= y is well-formed,a @= b shall also be well-formed and
shall have the same effects as x @= y,
except that the value that would be stored into x is stored into a[.](#7.5.sentence-1)
  The expression a @= b shall be an lvalue referring to a[.](#7.5.sentence-2)

- [(7.6)](#7.6)

  For every non-assignment binary operator @ for which x @ y and y @ x are well-formed, a @ b and b @ a shall also be well-formed and
 shall have the same value, effects, and value category as x @ y and y @ x, respectively[.](#7.6.sentence-1)
  If x @ y or y @ x has type B(I),
 then a @ b or b @ a, respectively, has type I;
 if x @ y or y @ x has type B(I2),
 then a @ b or b @ a, respectively, has type I2;
 if x @ y or y @ x has any other type,
 then a @ b or b @ a, respectively, has that type[.](#7.6.sentence-2)

[8](#8)

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

An expression E of integer-class type I is
contextually convertible to bool as if by bool(E != I(0))[.](#8.sentence-1)

[9](#9)

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

All integer-class types model[regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") ([[concepts.object]](concepts.object "18.6 Object concepts")) and[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]")<strong_ordering> ([[cmp.concept]](cmp.concept "17.12.4 Concept three_­way_­comparable"))[.](#9.sentence-1)

[10](#10)

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

A value-initialized object of integer-class type has value 0[.](#10.sentence-1)

[11](#11)

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

For every (possibly cv-qualified) integer-class type I,numeric_limits<I> is specialized such that
each static data member m has the same value as numeric_limits<B(I)>​::​m, and
each static member function f returns I(numeric_limits<B(I)>​::​f())[.](#11.sentence-1)

[12](#12)

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

For any two integer-like types I1 and I2,
at least one of which is an integer-class type,common_type_t<I1, I2> denotes an integer-class type
whose width is not less than that of I1 or I2[.](#12.sentence-1)

If both I1 and I2 are signed-integer-like types,
then common_type_t<I1, I2> is also a signed-integer-like type[.](#12.sentence-2)

[13](#13)

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

*is-integer-like*<I> is true if and only if I is an integer-like type[.](#13.sentence-1)

*is-signed-integer-like*<I> is true if and only if I is a signed-integer-like type[.](#13.sentence-2)

[14](#14)

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

Let i be an object of type I[.](#14.sentence-1)

When i is in the domain of
both pre- and post-increment, i is said to be [*incrementable*](#def:incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]")[.](#14.sentence-2)

I models [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]")<I> only if:

- [(14.1)](#14.1)

  The expressions ++i and i++ have the same domain[.](#14.1.sentence-1)

- [(14.2)](#14.2)

  If i is incrementable, then both ++i and i++ advance i to the next element[.](#14.2.sentence-1)

- [(14.3)](#14.3)

  If i is incrementable, then addressof(++i) is equal to addressof(i)[.](#14.3.sentence-1)

[15](#15)

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

*Recommended practice*: The implementation of an algorithm on a weakly incrementable type
should never attempt to pass through the same incrementable value twice;
such an algorithm should be a single-pass algorithm[.](#15.sentence-1)

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

For [weakly_incrementable](#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") types, a equals b does not imply that ++a equals ++b[.](#15.sentence-2)

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

Such algorithms
can be used with istreams as the source of the input data through the istream_iterator class
template[.](#15.sentence-4)

â *end note*]
