[range.iota.view]

# 25 Ranges library [[ranges]](./#ranges)

## 25.6 Range factories [[range.factories]](range.factories#range.iota.view)

### 25.6.4 Iota view [[range.iota]](range.iota#view)

#### 25.6.4.2 Class template iota_view [range.iota.view]

[ð](#lib:iota_view)

namespace std::ranges {template<class I>concept [*decrementable*](#concept:decrementable "25.6.4.2 Class template iota_­view [range.iota.view]") = *see below*; // *exposition only*template<class I>concept [*advanceable*](#concept:advanceable "25.6.4.2 Class template iota_­view [range.iota.view]") = *see below*; // *exposition only*template<[weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") W, [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]") Bound = unreachable_sentinel_t>requires [*weakly-equality-comparable-with*](concept.equalitycomparable#concept:weakly-equality-comparable-with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<W, Bound> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<W>class iota_view : public view_interface<iota_view<W, Bound>> {private:// [[range.iota.iterator]](range.iota.iterator "25.6.4.3 Class iota_­view​::​iterator"), class iota_view​::​*iterator*struct *iterator*; // *exposition only*// [[range.iota.sentinel]](range.iota.sentinel "25.6.4.4 Class iota_­view​::​sentinel"), class iota_view​::​*sentinel*struct *sentinel*; // *exposition only* W *value_* = W(); // *exposition only* Bound *bound_* = Bound(); // *exposition only*public: iota_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_­initializable [concept.default.init]")<W> = default; constexpr explicit iota_view(W value); constexpr explicit iota_view(type_identity_t<W> value, type_identity_t<Bound> bound); constexpr explicit iota_view(*iterator* first, *see below* last); constexpr *iterator* begin() const; constexpr auto end() const; constexpr *iterator* end() const requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<W, Bound>; constexpr bool empty() const; constexpr auto size() const requires *see below*; }; template<class W, class Bound>requires (!*is-integer-like*<W> || !*is-integer-like*<Bound> ||(*is-signed-integer-like*<W> == *is-signed-integer-like*<Bound>)) iota_view(W, Bound) -> iota_view<W, Bound>;}

[1](#1)

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

Let *IOTA-DIFF-T*(W) be defined as follows:

- [(1.1)](#1.1)

  If W is not an integral type, or
 if it is an integral type and sizeof(iter_difference_t<W>) is greater than sizeof(W),
 then *IOTA-DIFF-T*(W) denotes iter_difference_t<W>[.](#1.1.sentence-1)

- [(1.2)](#1.2)

  Otherwise, *IOTA-DIFF-T*(W) is a signed integer type of width greater than the width of W if such a type exists[.](#1.2.sentence-1)

- [(1.3)](#1.3)

  Otherwise, *IOTA-DIFF-T*(W) is an unspecified signed-integer-like type ([[iterator.concept.winc]](iterator.concept.winc "24.3.4.4 Concept weakly_­incrementable"))
 of width not less than the width of W[.](#1.3.sentence-1)
  [*Note [1](#note-1)*:
  It is unspecified
 whether this type satisfies [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]")[.](#1.3.sentence-2)
 â *end note*]

[2](#2)

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

The exposition-only [*decrementable*](#concept:decrementable "25.6.4.2 Class template iota_­view [range.iota.view]") concept is equivalent to:

[ð](#concept:decrementable)

`template<class I>
  concept [decrementable](#concept:decrementable "25.6.4.2 Class template iota_­view [range.iota.view]") =               // exposition only
    [incrementable](iterator.concept.inc#concept:incrementable "24.3.4.5 Concept incrementable [iterator.concept.inc]")<I> && requires(I i) {
      { --i } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I&>;
      { i-- } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I>;
    };
`

[3](#3)

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

When an object is in the domain of both pre- and post-decrement,
the object is said to be [*decrementable*](#def:decrementable)[.](#3.sentence-1)

[4](#4)

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

Let a and b be equal objects of type I[.](#4.sentence-1)

I models [*decrementable*](#concept:decrementable "25.6.4.2 Class template iota_­view [range.iota.view]") only if

- [(4.1)](#4.1)

  If a and b are decrementable,
 then the following are all true:
  * [(4.1.1)](#4.1.1)

addressof(--a) == addressof(a)

  * [(4.1.2)](#4.1.2)

bool(a-- == b)

  * [(4.1.3)](#4.1.3)

bool(((void)a--, a) == --b)

  * [(4.1.4)](#4.1.4)

bool(++(--a) == b)[.](#4.1.sentence-1)

- [(4.2)](#4.2)

  If a and b are incrementable,
 then bool(--(++a) == b)[.](#4.2.sentence-1)

[5](#5)

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

The exposition-only [*advanceable*](#concept:advanceable "25.6.4.2 Class template iota_­view [range.iota.view]") concept is equivalent to:

[ð](#concept:advanceable)

`template<class I>
  concept [advanceable](#concept:advanceable "25.6.4.2 Class template iota_­view [range.iota.view]") =                 // exposition only
    [decrementable](#concept:decrementable "25.6.4.2 Class template iota_­view [range.iota.view]")<I> && [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5 Concept totally_­ordered [concept.totallyordered]")<I> &&
    requires(I i, const I j, const IOTA-DIFF-T(I) n) {
      { i += n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I&>;
      { i -= n } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<I&>;
      I(j + n);
      I(n + j);
      I(j - n);
      { j - j } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<IOTA-DIFF-T(I)>;
    };
`

Let D be *IOTA-DIFF-T*(I)[.](#sentence-1)

Let a and b be objects of type I such thatb is reachable from a after n applications of ++a,
for some value n of type D[.](#sentence-2)

I models [*advanceable*](#concept:advanceable "25.6.4.2 Class template iota_­view [range.iota.view]") only if

- (a += n) is equal to b[.](#sentence-1)

- addressof(a += n) is equal to addressof(a)[.](#sentence-1)

- I(a + n) is equal to (a += n)[.](#sentence-1)

- For any two positive values x and y of type D,
 if I(a + D(x + y)) is well-defined, then I(a + D(x + y)) is equal to I(I(a + x) + y)[.](#sentence-1)

- I(a + D(0)) is equal to a[.](#sentence-1)

- If I(a + D(n - 1)) is well-defined, then I(a + n) is equal to [](I c) { return ++c; }(I(a + D(n - 1)))[.](#sentence-1)

- (b += -n) is equal to a[.](#sentence-1)

- (b -= n) is equal to a[.](#sentence-1)

- addressof(b -= n) is equal to addressof(b)[.](#sentence-1)

- I(b - n) is equal to (b -= n)[.](#sentence-1)

- D(b - a) is equal to n[.](#sentence-1)

- D(a - b) is equal to D(-n)[.](#sentence-1)

- bool(a <= b) is true[.](#sentence-1)

[ð](#lib:iota_view,constructor)

`constexpr explicit iota_view(W value);
`

[6](#6)

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

*Preconditions*: Bound denotes unreachable_sentinel_t orBound() is reachable from value[.](#6.sentence-1)

When W and Bound model [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5 Concept totally_­ordered [concept.totallyordered]"),
then bool(value <= Bound()) is true[.](#6.sentence-2)

[7](#7)

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

*Effects*: Initializes *value_* with value[.](#7.sentence-1)

[ð](#lib:iota_view,constructor_)

`constexpr explicit iota_view(type_identity_t<W> value, type_identity_t<Bound> bound);
`

[8](#8)

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

*Preconditions*: Bound denotes unreachable_sentinel_t orbound is reachable from value[.](#8.sentence-1)

When W and Bound model [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5 Concept totally_­ordered [concept.totallyordered]"),
then bool(value <= bound) is true[.](#8.sentence-2)

[9](#9)

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

*Effects*: Initializes *value_* with value and*bound_* with bound[.](#9.sentence-1)

[ð](#lib:iota_view,constructor__)

`constexpr explicit iota_view(iterator first, see below last);
`

[10](#10)

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

*Effects*: Equivalent to:

- [(10.1)](#10.1)

  If [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<W, Bound> is true,iota_view(first.*value_*, last.*value_*)[.](#10.1.sentence-1)

- [(10.2)](#10.2)

  Otherwise, if Bound denotes unreachable_sentinel_t,iota_view(first.*value_*, last)[.](#10.2.sentence-1)

- [(10.3)](#10.3)

  Otherwise, iota_view(first.*value_*, last.*bound_*)[.](#10.3.sentence-1)

[11](#11)

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

*Remarks*: The type of last is:

- [(11.1)](#11.1)

  If [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<W, Bound> is true, *iterator*[.](#11.1.sentence-1)

- [(11.2)](#11.2)

  Otherwise, if Bound denotes unreachable_sentinel_t,Bound[.](#11.2.sentence-1)

- [(11.3)](#11.3)

  Otherwise, *sentinel*[.](#11.3.sentence-1)

[ð](#lib:begin,iota_view)

`constexpr iterator begin() const;
`

[12](#12)

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

*Effects*: Equivalent to: return *iterator*{*value_*};

[ð](#lib:end,iota_view)

`constexpr auto end() const;
`

[13](#13)

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

*Effects*: Equivalent to:if constexpr ([same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<Bound, unreachable_sentinel_t>)return unreachable_sentinel;elsereturn *sentinel*{*bound_*};

[ð](#lib:end,iota_view_)

`constexpr iterator end() const requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<W, Bound>;
`

[14](#14)

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

*Effects*: Equivalent to: return *iterator*{*bound_*};

[ð](#lib:empty,iota_view)

`constexpr bool empty() const;
`

[15](#15)

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

*Effects*: Equivalent to: return *value_* == *bound_*;

[ð](#lib:size,iota_view)

`constexpr auto size() const requires see below;
`

[16](#16)

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

*Effects*: Equivalent to:if constexpr (*is-integer-like*<W> && *is-integer-like*<Bound>)return (*value_* < 0)? ((*bound_* < 0)? *to-unsigned-like*(-*value_*) - *to-unsigned-like*(-*bound_*): *to-unsigned-like*(*bound_*) + *to-unsigned-like*(-*value_*)): *to-unsigned-like*(*bound_*) - *to-unsigned-like*(*value_*);elsereturn *to-unsigned-like*(*bound_* - *value_*);

[17](#17)

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

*Remarks*: The expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is equivalent to:([same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<W, Bound> && [*advanceable*](#concept:advanceable "25.6.4.2 Class template iota_­view [range.iota.view]")<W>) || (*is-integer-like*<W> && *is-integer-like*<Bound>) ||[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<Bound, W>
