[iterator.concept.winc] (original) (raw)
23 Iterators library [iterators]
23.3 Iterator requirements [iterator.requirements]
23.3.4 Iterator concepts [iterator.concepts]
23.3.4.4 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; template<class T> inline constexpr bool is-signed-integer-like = see below; 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&>; i++; };
A type I is an integer-class typeif 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.
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.
- 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.
If @x has type bool, so too does @a; if @x has type B(I), then @a has type 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.
The expression c @= a shall be an lvalue referring to c. - 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.
If x @ y has type bool, so too does a @ b; if x @ y has type B(I), then a @ b has type 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 boolas if by bool(E != I(0)).
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, andnumeric_limits<I>::lowest() returns numeric_limits<I>::min().
A type I is integer-likeif it models integral<I> or if it is an integer-class type.
A type I is signed-integer-likeif it models signed_integral<I> or if it is a signed-integer-class type.
A type I is unsigned-integer-likeif it models unsigned_integral<I> or if it is an unsigned-integer-class type.
is-integer-like<I> is trueif and only if I is an integer-like type.
is-signed-integer-like<I> is trueif 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, thenaddressof(++i) is equal toaddressof(i).
Recommended practice: The implementaton 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.
[Note 1:
For weakly_incrementable types, a equals b does not imply that ++aequals ++b.
(Equality does not guarantee the substitution property or referential transparency.)
Such algorithms can be used with istreams as the source of the input data through the istream_iterator class template.
— _end note_]