Files
cppdraft_translate/cppdraft/range/iota.md
2025-10-25 03:02:53 +03:00

32 KiB
Raw Blame History

[range.iota]

25 Ranges library [ranges]

25.6 Range factories [range.factories]

25.6.4 Iota view [range.iota]

25.6.4.1 Overview [range.iota.overview]

1

#

iota_view generates a sequence of elements by repeatedly incrementing an initial value.

2

#

The name views::iota denotes a customization point object ([customization.point.object]).

Given subexpressions E and F, the expressionsviews::iota(E) and views::iota(E, F) are expression-equivalent toiota_view<decay_t<decltype((E))>>(E) and iota_view(E, F), respectively.

3

#

[Example 1: for (int i : views::iota(1, 10)) cout << i << ' '; // prints 1 2 3 4 5 6 7 8 9 — end example]

4

#

The name views::indices denotes a customization point object ([customization.point.object]).

Given subexpression E, let T be remove_cvref_t<decltype((E))>.

views::indices(E) is expression-equivalent toviews::iota(T(0), E) if is-integer-like is true, and ill-formed otherwise.

25.6.4.2 Class template iota_view [range.iota.view]

🔗

namespace std::ranges {templateconcept decrementable = see below; // exposition onlytemplateconcept advanceable = see below; // exposition onlytemplate<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>requires weakly-equality-comparable-with<W, Bound> && copyableclass iota_view : public view_interface<iota_view<W, Bound>> {private:// [range.iota.iterator], class iota_view::iteratorstruct iterator; // exposition only// [range.iota.sentinel], class iota_view::sentinelstruct sentinel; // exposition only W value_ = W(); // exposition only Bound bound_ = Bound(); // exposition onlypublic: iota_view() requires default_initializable = default; constexpr explicit iota_view(W value); constexpr explicit iota_view(type_identity_t value, type_identity_t 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<W, Bound>; constexpr bool empty() const; constexpr auto size() const requires see below; }; template<class W, class Bound>requires (!is-integer-like || !is-integer-like ||(is-signed-integer-like == is-signed-integer-like)) iota_view(W, Bound) -> iota_view<W, Bound>;}

1

#

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

  • (1.1)

    If W is not an integral type, or if it is an integral type and sizeof(iter_difference_t) is greater than sizeof(W), then IOTA-DIFF-T(W) denotes iter_difference_t.

  • (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.3)

    Otherwise, IOTA-DIFF-T(W) is an unspecified signed-integer-like type ([iterator.concept.winc]) of width not less than the width of W. [Note 1: It is unspecified whether this type satisfies weakly_incrementable. — end note]

2

#

The exposition-only decrementable concept is equivalent to:

🔗

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

3

#

When an object is in the domain of both pre- and post-decrement, the object is said to be decrementable.

4

#

Let a and b be equal objects of type I.

I models decrementable only if

  • (4.1)

    If a and b are decrementable, then the following are all true:

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

bool(a-- == b)

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

bool(++(--a) == b).

  • (4.2)

    If a and b are incrementable, then bool(--(++a) == b).

5

#

The exposition-only advanceable concept is equivalent to:

🔗

template<class I> concept [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]") = // exposition only [decrementable](#concept:decrementable "25.6.4.2Class template iota_­view[range.iota.view]")<I> && [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept 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.2Concept same_­as[concept.same]")<I&>; { i -= n } -> [same_as](concept.same#concept:same_as "18.4.2Concept 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.4Concept convertible_­to[concept.convertible]")<IOTA-DIFF-T(I)>; };

Let D be IOTA-DIFF-T(I).

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.

I models advanceable only if

  • (a += n) is equal to b.

  • addressof(a += n) is equal to addressof(a).

  • I(a + n) is equal to (a += n).

  • 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).

  • I(a + D(0)) is equal to a.

  • 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))).

  • (b += -n) is equal to a.

  • (b -= n) is equal to a.

  • addressof(b -= n) is equal to addressof(b).

  • I(b - n) is equal to (b -= n).

  • D(b - a) is equal to n.

  • D(a - b) is equal to D(-n).

  • bool(a <= b) is true.

🔗

constexpr explicit iota_view(W value);

6

#

Preconditions: Bound denotes unreachable_sentinel_t orBound() is reachable from value.

When W and Bound model totally_ordered_with, then bool(value <= Bound()) is true.

7

#

Effects: Initializes value_ with value.

🔗

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

8

#

Preconditions: Bound denotes unreachable_sentinel_t orbound is reachable from value.

When W and Bound model totally_ordered_with, then bool(value <= bound) is true.

9

#

Effects: Initializes value_ with value andbound_ with bound.

🔗

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

10

#

Effects: Equivalent to:

  • (10.1)

    If same_as<W, Bound> is true,iota_view(first.value_, last.value_).

  • (10.2)

    Otherwise, if Bound denotes unreachable_sentinel_t,iota_view(first.value_, last).

  • (10.3)

    Otherwise, iota_view(first.value_, last.bound_).

11

#

Remarks: The type of last is:

  • (11.1)

    If same_as<W, Bound> is true, iterator.

  • (11.2)

    Otherwise, if Bound denotes unreachable_sentinel_t,Bound.

  • (11.3)

    Otherwise, sentinel.

🔗

constexpr iterator begin() const;

12

#

Effects: Equivalent to: return iterator{value_};

🔗

constexpr auto end() const;

13

#

Effects: Equivalent to:if constexpr (same_as<Bound, unreachable_sentinel_t>)return unreachable_sentinel;elsereturn sentinel{bound_};

🔗

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

14

#

Effects: Equivalent to: return iterator{bound_};

🔗

constexpr bool empty() const;

15

#

Effects: Equivalent to: return value_ == bound_;

🔗

constexpr auto size() const requires see below;

16

#

Effects: Equivalent to:if constexpr (is-integer-like && is-integer-like)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

#

Remarks: The expression in the requires-clause is equivalent to:(same_as<W, Bound> && advanceable) || (is-integer-like && is-integer-like) ||sized_sentinel_for<Bound, W>

25.6.4.3 Class iota_view::iterator [range.iota.iterator]

🔗

namespace std::ranges {template<weakly_incrementable W, semiregular Bound>requires weakly-equality-comparable-with<W, Bound> && copyablestruct iota_view<W, Bound>::iterator {private: W value_ = W(); // exposition onlypublic:using iterator_concept = see below; using iterator_category = input_iterator_tag; // present only if W models incrementable and// IOTA-DIFF-T(W) is an integral typeusing value_type = W; using difference_type = IOTA-DIFF-T(W); iterator() requires default_initializable = default; constexpr explicit iterator(W value); constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v); constexpr iterator& operator++(); constexpr void operator++(int); constexpr iterator operator++(int) requires incrementable; constexpr iterator& operator--() requires decrementable; constexpr iterator operator--(int) requires decrementable; constexpr iterator& operator+=(difference_type n)requires advanceable; constexpr iterator& operator-=(difference_type n)requires advanceable; constexpr W operator[](difference_type n) constrequires advanceable; friend constexpr bool operator==(const iterator& x, const iterator& y)requires equality_comparable; friend constexpr bool operator<(const iterator& x, const iterator& y)requires totally_ordered; friend constexpr bool operator>(const iterator& x, const iterator& y)requires totally_ordered; friend constexpr bool operator<=(const iterator& x, const iterator& y)requires totally_ordered; friend constexpr bool operator>=(const iterator& x, const iterator& y)requires totally_ordered; friend constexpr auto operator<=>(const iterator& x, const iterator& y)requires totally_ordered && three_way_comparable; friend constexpr iterator operator+(iterator i, difference_type n)requires advanceable; friend constexpr iterator operator+(difference_type n, iterator i)requires advanceable; friend constexpr iterator operator-(iterator i, difference_type n)requires advanceable; friend constexpr difference_type operator-(const iterator& x, const iterator& y)requires advanceable; };}

1

#

iterator::iterator_concept is defined as follows:

  • (1.1)

    If W models advanceable, theniterator_concept is random_access_iterator_tag.

  • (1.2)

    Otherwise, if W models decrementable, theniterator_concept is bidirectional_iterator_tag.

  • (1.3)

    Otherwise, if W models incrementable, theniterator_concept is forward_iterator_tag.

  • (1.4)

    Otherwise, iterator_concept is input_iterator_tag.

2

#

[Note 1:

Overloads for iter_move and iter_swap are omitted intentionally.

— end note]

🔗

constexpr explicit iterator(W value);

3

#

Effects: Initializes value_ with value.

🔗

constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);

4

#

Effects: Equivalent to: return value_;

5

#

[Note 2:

The noexcept clause is needed by the default iter_move implementation.

— end note]

🔗

constexpr iterator& operator++();

6

#

Effects: Equivalent to:++value_;return *this;

🔗

constexpr void operator++(int);

7

#

Effects: Equivalent to ++*this.

🔗

constexpr iterator operator++(int) requires [incrementable](iterator.concept.inc#concept:incrementable "24.3.4.5Concept incrementable[iterator.concept.inc]")<W>;

8

#

Effects: Equivalent to:auto tmp = *this;++*this;return tmp;

🔗

constexpr iterator& operator--() requires [decrementable](#concept:decrementable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

9

#

Effects: Equivalent to:--value_;return *this;

🔗

constexpr iterator operator--(int) requires [decrementable](#concept:decrementable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

10

#

Effects: Equivalent to:auto tmp = *this;--*this;return tmp;

🔗

constexpr iterator& operator+=(difference_type n) requires [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

11

#

Effects: Equivalent to:if constexpr (is-integer-like && !is-signed-integer-like) {if (n >= difference_type(0))value_ += static_cast(n); elsevalue_ -= static_cast(-n);} else {value_ += n;}return *this;

🔗

constexpr iterator& operator-=(difference_type n) requires [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

12

#

Effects: Equivalent to:if constexpr (is-integer-like && !is-signed-integer-like) {if (n >= difference_type(0))value_ -= static_cast(n); elsevalue_ += static_cast(-n);} else {value_ -= n;}return *this;

🔗

constexpr W operator[](difference_type n) const requires [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

13

#

Effects: Equivalent to: return W(value_ + n);

🔗

friend constexpr bool operator==(const iterator& x, const iterator& y) requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<W>;

14

#

Effects: Equivalent to: return x.value_ == y.value_;

🔗

friend constexpr bool operator<(const iterator& x, const iterator& y) requires [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<W>;

15

#

Effects: Equivalent to: return x.value_ < y.value_;

🔗

friend constexpr bool operator>(const iterator& x, const iterator& y) requires [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<W>;

16

#

Effects: Equivalent to: return y < x;

🔗

friend constexpr bool operator<=(const iterator& x, const iterator& y) requires [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<W>;

17

#

Effects: Equivalent to: return !(y < x);

🔗

friend constexpr bool operator>=(const iterator& x, const iterator& y) requires [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<W>;

18

#

Effects: Equivalent to: return !(x < y);

🔗

friend constexpr auto operator<=>(const iterator& x, const iterator& y) requires [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<W> && [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<W>;

19

#

Effects: Equivalent to: return x.value_ <=> y.value_;

🔗

friend constexpr iterator operator+(iterator i, difference_type n) requires [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

20

#

Effects: Equivalent to:i += n;return i;

🔗

friend constexpr iterator operator+(difference_type n, iterator i) requires [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

21

#

Effects: Equivalent to: return i + n;

🔗

friend constexpr iterator operator-(iterator i, difference_type n) requires [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

22

#

Effects: Equivalent to:i -= n;return i;

🔗

friend constexpr difference_type operator-(const iterator& x, const iterator& y) requires [advanceable](#concept:advanceable "25.6.4.2Class template iota_­view[range.iota.view]")<W>;

23

#

Effects: Equivalent to:using D = difference_type;if constexpr (is-integer-like) {if constexpr (is-signed-integer-like)return D(D(x.value_) - D(y.value_)); elsereturn (y.value_ > x.value_)? D(-D(y.value_ - x.value_)): D(x.value_ - y.value_);} else {return x.value_ - y.value_;}

25.6.4.4 Class iota_view::sentinel [range.iota.sentinel]

🔗

namespace std::ranges {template<weakly_incrementable W, semiregular Bound>requires weakly-equality-comparable-with<W, Bound> && copyablestruct iota_view<W, Bound>::sentinel {private: Bound bound_ = Bound(); // exposition onlypublic:sentinel() = default; constexpr explicit sentinel(Bound bound); friend constexpr bool operator==(const iterator& x, const sentinel& y); friend constexpr iter_difference_t operator-(const iterator& x, const sentinel& y)requires sized_sentinel_for<Bound, W>; friend constexpr iter_difference_t operator-(const sentinel& x, const iterator& y)requires sized_sentinel_for<Bound, W>; };}

🔗

constexpr explicit sentinel(Bound bound);

1

#

Effects: Initializes bound_ with bound.

🔗

friend constexpr bool operator==(const iterator& x, const sentinel& y);

2

#

Effects: Equivalent to: return x.value_ == y.bound_;

🔗

friend constexpr iter_difference_t<W> operator-(const iterator& x, const sentinel& y) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Bound, W>;

3

#

Effects: Equivalent to: return x.value_ - y.bound_;

🔗

friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterator& y) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Bound, W>;

4

#

Effects: Equivalent to: return -(y - x);