[range.factories] (original) (raw)
25.6.1 General [range.factories.general]
Subclause [range.factories] defines range factories, which are utilities to create a view.
Range factories are declared in namespace std::ranges::views.
25.6.2 Empty view [range.empty]
25.6.2.1 Overview [range.empty.overview]
empty_view produces a view of no elements of a particular type.
[Example 1: auto e = views::empty<int>;static_assert(ranges::empty(e));static_assert(0 == e.size()); — _end example_]
25.6.2.2 Class template empty_view [range.empty.view]
namespace std::ranges { template<class T> requires is_object_v<T> class empty_view : public view_interface<empty_view<T>> { public: static constexpr T* begin() noexcept { return nullptr; } static constexpr T* end() noexcept { return nullptr; } static constexpr T* data() noexcept { return nullptr; } static constexpr size_t size() noexcept { return 0; } static constexpr bool empty() noexcept { return true; } };}
25.6.3 Single view [range.single]
25.6.3.1 Overview [range.single.overview]
single_view produces a view that contains exactly one element of a specified value.
Given a subexpression E, the expressionviews::single(E) is expression-equivalent tosingle_view<decay_t<decltype((E))>>(E).
[Example 1: for (int i : views::single(4)) cout << i; — _end example_]
25.6.3.2 Class template single_view [range.single.view]
namespace std::ranges { template<move_constructible T> requires is_object_v<T> class single_view : public view_interface<single_view<T>> { private: movable-box<T> value_; public: single_view() requires default_initializable<T> = default;constexpr explicit single_view(const T& t) requires copy_constructible<T>;constexpr explicit single_view(T&& t);template<class... Args> requires constructible_from<T, Args...> constexpr explicit single_view(in_place_t, Args&&... args);constexpr T* begin() noexcept;constexpr const T* begin() const noexcept;constexpr T* end() noexcept;constexpr const T* end() const noexcept;static constexpr bool empty() noexcept;static constexpr size_t size() noexcept;constexpr T* data() noexcept;constexpr const T* data() const noexcept;};template<class T> single_view(T) -> single_view<T>;}
Effects: Initializes value_ with t.
constexpr explicit single_view(T&& t);
Effects: Initializes value_ with std::move(t).
template<class... Args> requires [constructible_from](concept.constructible#concept:constructible%5Ffrom "18.4.11 Concept constructible_from [concept.constructible]")<T, Args...> constexpr explicit single_view(in_place_t, Args&&... args);
Effects: Initializes value_ as if by_value__{in_place, std::forward<Args>(args)...}.
constexpr T* begin() noexcept;constexpr const T* begin() const noexcept;
Effects: Equivalent to: return data();
constexpr T* end() noexcept;constexpr const T* end() const noexcept;
Effects: Equivalent to: return data() + 1;
static constexpr bool empty() noexcept;
Effects: Equivalent to: return false;
static constexpr size_t size() noexcept;
Effects: Equivalent to: return 1;
constexpr T* data() noexcept;constexpr const T* data() const noexcept;
Effects: Equivalent to: return value_.operator->();
25.6.4 Iota view [range.iota]
25.6.4.1 Overview [range.iota.overview]
iota_view generates a sequence of elements by repeatedly incrementing an initial value.
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.
[Example 1: for (int i : views::iota(1, 10)) cout << i << ' '; — _end example_]
25.6.4.2 Class template iota_view [range.iota.view]
namespace std::ranges { template<class I> concept decrementable = see below; template<class I> concept advanceable = see below; template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t> requires weakly-equality-comparable-with<W, Bound> && copyable<W> class iota_view : public view_interface<iota_view<W, Bound>> { private: struct iterator; struct sentinel; W value_ = W(); Bound bound_ = Bound(); public: iota_view() requires default_initializable<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<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>;}
Let IOTA-DIFF-T(W) be defined as follows:
- 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>.
- Otherwise, IOTA-DIFF-T(W) is a signed integer type of width greater than the width of W if such a type exists.
- Otherwise, IOTA-DIFF-T(W) is an unspecified signed-integer-like type ([iterator.concept.winc]) of width not less than the width of W.
The exposition-only decrementable concept is equivalent to:
When an object is in the domain of both pre- and post-decrement, the object is said to be decrementable.
Let a and b be equal objects of type I.
I models decrementable only if
- 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).
- If a and b are incrementable, then bool(--(++a) == b).
The exposition-only advanceable concept is equivalent to:
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%5Fordered "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%5Fas "18.4.2 Concept same_as [concept.same]")<I&>;{ i -= n } -> [same_as](concept.same#concept:same%5Fas "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%5Fto "18.4.4 Concept 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 aafter n applications of ++a, for some value n of type D.
I models advanceable only if
- addressof(a += n) is equal to addressof(a).
- I(a + n) is equal to (a += n).
- For any two positive valuesx and y of type D, if I(a + D(x + y)) is well-defined, thenI(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, thenI(a + n) is equal to [](I c) { return ++c; }(I(a + D(n - 1))).
- addressof(b -= n) is equal to addressof(b).
- I(b - n) is equal to (b -= n).
- D(a - b) is equal to D(-n).
constexpr explicit iota_view(W value);
Preconditions: Bound denotes unreachable_sentinel_t orBound() is reachable from value.
Effects: Initializes value_ with value.
constexpr explicit iota_view(type_identity_t<W> value, type_identity_t<Bound> bound);
Preconditions: Bound denotes unreachable_sentinel_t orbound is reachable from value.
Effects: Initializes value_ with value and_bound__ with bound.
constexpr explicit iota_view(_iterator_ first, _see below_ last);
Effects: Equivalent to:
- If same_as<W, Bound> is true,iota_view(first.value_, last.value_).
- Otherwise, if Bound denotes unreachable_sentinel_t,iota_view(first.value_, last).
- Otherwise, iota_view(first.value_, last.bound_).
Remarks: The type of last is:
constexpr _iterator_ begin() const;
Effects: Equivalent to: return iterator{value_};
constexpr auto end() const;
Effects: Equivalent to:if constexpr (same_as<Bound, unreachable_sentinel_t>) return unreachable_sentinel;else return sentinel{bound_};
constexpr _iterator_ end() const requires [same_as](concept.same#concept:same%5Fas "18.4.2 Concept same_as [concept.same]")<W, Bound>;
Effects: Equivalent to: return iterator{bound_};
constexpr bool empty() const;
Effects: Equivalent to: return value_ == bound_;
constexpr auto size() const requires _see below_;
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_);else return to-unsigned-like(bound_ - value_);
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> && copyable<W> struct iota_view<W, Bound>::iterator { private: W value_ = W(); public: using iterator_concept = see below;using iterator_category = input_iterator_tag; using value_type = W;using difference_type = IOTA-DIFF-T(W);iterator() requires default_initializable<W> = default;constexpr explicit iterator(W value);constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);constexpr iterator& operator++();constexpr void operator++(int);constexpr iterator operator++(int) requires incrementable<W>;constexpr iterator& operator--() requires decrementable<W>;constexpr iterator operator--(int) requires decrementable<W>;constexpr iterator& operator+=(difference_type n) requires advanceable<W>;constexpr iterator& operator-=(difference_type n) requires advanceable<W>;constexpr W operator[](difference_type n) const requires advanceable<W>;friend constexpr bool operator==(const iterator& x, const iterator& y) requires equality_comparable<W>;friend constexpr bool operator<(const _iterator_& x, const _iterator_& y) requires totally_ordered<W>;friend constexpr bool operator>(const iterator& x, const iterator& y) requires totally_ordered<W>;friend constexpr bool operator<=(const _iterator_& x, const _iterator_& y) requires totally_ordered<W>;friend constexpr bool operator>=(const iterator& x, const iterator& y) requires totally_ordered<W>;friend constexpr auto operator<=>(const iterator& x, const iterator& y) requires totally_ordered<W> && three_way_comparable<W>;friend constexpr iterator operator+(iterator i, difference_type n) requires advanceable<W>;friend constexpr iterator operator+(difference_type n, iterator i) requires advanceable<W>;friend constexpr iterator operator-(iterator i, difference_type n) requires advanceable<W>;friend constexpr difference_type operator-(const iterator& x, const iterator& y) requires advanceable<W>;};}
_iterator_::iterator_concept is defined as follows:
- If W models advanceable, theniterator_concept is random_access_iterator_tag.
- Otherwise, if W models decrementable, theniterator_concept is bidirectional_iterator_tag.
- Otherwise, if W models incrementable, theniterator_concept is forward_iterator_tag.
- Otherwise, iterator_concept is input_iterator_tag.
[Note 1:
Overloads for iter_move and iter_swap are omitted intentionally.
— _end note_]
constexpr explicit _iterator_(W value);
Effects: Initializes value_ with value.
constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);
Effects: Equivalent to: return value_;
[Note 2:
The noexcept clause is needed by the default iter_moveimplementation.
— _end note_]
constexpr _iterator_& operator++();
Effects: Equivalent to:++value_;return *this;
constexpr void operator++(int);
Effects: Equivalent to ++*this.
Effects: Equivalent to:auto tmp = *this;++*this;return tmp;
constexpr _iterator_& operator--() requires [_decrementable_](#concept:decrementable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to:--value_;return *this;
constexpr _iterator_ operator--(int) requires [_decrementable_](#concept:decrementable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to:auto tmp = *this;--*this;return tmp;
constexpr _iterator_& operator+=(difference_type n) requires [_advanceable_](#concept:advanceable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to:if constexpr (is-integer-like<W> && !is-signed-integer-like<W>) { if (n >= difference_type(0)) value_ += static_cast<W>(n);else value_ -= static_cast<W>(-n);} else { value_ += n;} return *this;
constexpr _iterator_& operator-=(difference_type n) requires [_advanceable_](#concept:advanceable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to:if constexpr (is-integer-like<W> && !is-signed-integer-like<W>) { if (n >= difference_type(0)) value_ -= static_cast<W>(n);else value_ += static_cast<W>(-n);} else { value_ -= n;} return *this;
constexpr W operator[](difference_type n) const requires [_advanceable_](#concept:advanceable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to: return W(value_ + n);
friend constexpr bool operator==(const _iterator_& x, const _iterator_& y) requires [equality_comparable](concept.equalitycomparable#concept:equality%5Fcomparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<W>;
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%5Fordered "18.5.5 Concept totally_ordered [concept.totallyordered]")<W>;
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%5Fordered "18.5.5 Concept totally_ordered [concept.totallyordered]")<W>;
Effects: Equivalent to: return y < x;
friend constexpr bool operator<=(const _iterator_& x, const _iterator_& y) requires [totally_ordered](concept.totallyordered#concept:totally%5Fordered "18.5.5 Concept totally_ordered [concept.totallyordered]")<W>;
Effects: Equivalent to: return !(y < x);
friend constexpr bool operator>=(const _iterator_& x, const _iterator_& y) requires [totally_ordered](concept.totallyordered#concept:totally%5Fordered "18.5.5 Concept totally_ordered [concept.totallyordered]")<W>;
Effects: Equivalent to: return !(x < y);
Effects: Equivalent to: return x.value_ <=> y.value_;
friend constexpr _iterator_ operator+(_iterator_ i, difference_type n) requires [_advanceable_](#concept:advanceable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to:i += n;return i;
friend constexpr _iterator_ operator+(difference_type n, _iterator_ i) requires [_advanceable_](#concept:advanceable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to: return i + n;
friend constexpr _iterator_ operator-(_iterator_ i, difference_type n) requires [_advanceable_](#concept:advanceable "25.6.4.2 Class template iota_view [range.iota.view]")<W>;
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.2 Class template iota_view [range.iota.view]")<W>;
Effects: Equivalent to:using D = difference_type;if constexpr (is-integer-like<W>) { if constexpr (is-signed-integer-like<W>) return D(D(x.value_) - D(y.value_));else return (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> && copyable<W> struct iota_view<W, Bound>::sentinel { private: Bound bound_ = Bound(); public: sentinel() = default;constexpr explicit sentinel(Bound bound);friend constexpr bool operator==(const iterator& x, const sentinel& y);friend constexpr iter_difference_t<W> operator-(const iterator& x, const sentinel& y) requires sized_sentinel_for<Bound, W>;friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterator& y) requires sized_sentinel_for<Bound, W>;};}
constexpr explicit _sentinel_(Bound bound);
Effects: Initializes bound_ with bound.
friend constexpr bool operator==(const _iterator_& x, const _sentinel_& y);
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%5Fsentinel%5Ffor "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<Bound, W>;
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%5Fsentinel%5Ffor "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<Bound, W>;
Effects: Equivalent to: return -(y - x);
25.6.5 Repeat view [range.repeat]
25.6.5.1 Overview [range.repeat.overview]
repeat_view generates a sequence of elements by repeatedly producing the same value.
Given subexpressions E and F, the expressions views::repeat(E) and views::repeat(E, F)are expression-equivalent torepeat_view<decay_t<decltype((E))>>(E) and repeat_view(E, F), respectively.
[Example 1: for (int i : views::repeat(17, 4)) cout << i << ' '; — _end example_]
25.6.5.2 Class template repeat_view [range.repeat.view]
namespace std::ranges { template<class T> concept integer-like-with-usable-difference-type = is-signed-integer-like<T> || (is-integer-like<T> && weakly_incrementable<T>);template<move_constructible T, semiregular Bound = unreachable_sentinel_t> requires (is_object_v<T> && same_as<T, remove_cv_t<T>> && (integer-like-with-usable-difference-type<Bound> || same_as<Bound, unreachable_sentinel_t>)) class repeat_view : public view_interface<repeat_view<T, Bound>> { private: struct iterator; movable-box<T> value_; Bound bound_ = Bound(); public: repeat_view() requires default_initializable<T> = default;constexpr explicit repeat_view(const T& value, Bound bound = Bound()) requires copy_constructible<T>;constexpr explicit repeat_view(T&& value, Bound bound = Bound());template<class... TArgs, class... BoundArgs> requires constructible_from<T, TArgs...> && constructible_from<Bound, BoundArgs...> constexpr explicit repeat_view(piecewise_construct_t, tuple<TArgs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});constexpr iterator begin() const;constexpr iterator end() const requires (<Bound, unreachable_sentinel_t>);constexpr unreachable_sentinel_t end() const noexcept;constexpr auto size() const requires (
<Bound, unreachable_sentinel_t>);};template<class T, class Bound = unreachable_sentinel_t> repeat_view(T, Bound = Bound()) -> repeat_view<T, Bound>;}
constexpr explicit repeat_view(const T& value, Bound bound = Bound()) requires [copy_constructible](concept.copyconstructible#concept:copy%5Fconstructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<T>;
Preconditions: If Bound is not unreachable_sentinel_t,bound ≥ 0.
Effects: Initializes value_ with value and_bound__ with bound.
constexpr explicit repeat_view(T&& value, Bound bound = Bound());
Preconditions: If Bound is not unreachable_sentinel_t, bound ≥ 0.
Effects: Initializes value_ with std::move(value) and_bound__ with bound.
template<class... TArgs, class... BoundArgs> requires [constructible_from](concept.constructible#concept:constructible%5Ffrom "18.4.11 Concept constructible_from [concept.constructible]")<T, TArgs...> && [constructible_from](concept.constructible#concept:constructible%5Ffrom "18.4.11 Concept constructible_from [concept.constructible]")<Bound, BoundArgs...> constexpr explicit repeat_view(piecewise_construct_t, tuple<TArgs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
Effects: Initializes value_ withmake_from_tuple<T>(std::move(value_args))and initializes bound_ withmake_from_tuple<Bound>(std::move(bound_args)).
The behavior is undefined ifBound is not unreachable_sentinel_t and_bound__ is negative.
constexpr _iterator_ begin() const;
Effects: Equivalent to: return iterator(addressof(*value_));
constexpr _iterator_ end() const requires (<Bound, unreachable_sentinel_t>);
Effects: Equivalent to: return iterator(addressof(*value_), bound_);
constexpr unreachable_sentinel_t end() const noexcept;
Effects: Equivalent to: return unreachable_sentinel;
constexpr auto size() const requires (<Bound, unreachable_sentinel_t>);
Effects: Equivalent to: return to-unsigned-like(bound_);
25.6.5.3 Class repeat_view::iterator [range.repeat.iterator]
namespace std::ranges { template<move_constructible T, semiregular Bound> requires (is_object_v<T> && same_as<T, remove_cv_t<T>> && (integer-like-with-usable-difference-type<Bound> || same_as<Bound, unreachable_sentinel_t>)) class repeat_view<T, Bound>::iterator { private: using index-type = conditional_t<same_as<Bound, unreachable_sentinel_t>, ptrdiff_t, Bound>;const T* value_ = nullptr; index-type current_ = index-type(); constexpr explicit iterator(const T* value, index-type b = index-type()); public: using iterator_concept = random_access_iterator_tag;using iterator_category = random_access_iterator_tag;using value_type = T;using difference_type = see below;iterator() = default;constexpr const T& operator*() const noexcept;constexpr iterator& operator++();constexpr iterator operator++(int);constexpr iterator& operator--();constexpr iterator operator--(int);constexpr iterator& operator+=(difference_type n);constexpr iterator& operator-=(difference_type n);constexpr const T& operator[](difference_type n) const noexcept;friend constexpr bool operator==(const iterator& x, const iterator& y);friend constexpr auto operator<=>(const iterator& x, const iterator& y);friend constexpr iterator operator+(iterator i, difference_type n);friend constexpr iterator operator+(difference_type n, iterator i);friend constexpr iterator operator-(iterator i, difference_type n);friend constexpr difference_type operator-(const iterator& x, const iterator& y);};}
If is-signed-integer-like<_index-type_> is true, the member typedef-name difference_typedenotes index-type.
Otherwise, it denotes IOTA-DIFF-T(index-type) ([range.iota.view]).
constexpr explicit _iterator_(const T* value, _index-type_ b = _index-type_());
Preconditions: If Bound is not unreachable_sentinel_t, b ≥ 0.
Effects: Initializes value_ with value and_current__ with b.
constexpr const T& operator*() const noexcept;
Effects: Equivalent to: return *value_;
constexpr _iterator_& operator++();
Effects: Equivalent to:++current_;return *this;
constexpr _iterator_ operator++(int);
Effects: Equivalent to:auto tmp = *this;++*this;return tmp;
constexpr _iterator_& operator--();
Preconditions: If Bound is not unreachable_sentinel_t,.
Effects: Equivalent to:--current_;return *this;
constexpr _iterator_ operator--(int);
Effects: Equivalent to:auto tmp = *this;--*this;return tmp;
constexpr _iterator_& operator+=(difference_type n);
Preconditions: If Bound is not unreachable_sentinel_t,.
Effects: Equivalent to:current_ += n;return *this;
constexpr _iterator_& operator-=(difference_type n);
Preconditions: If Bound is not unreachable_sentinel_t,.
Effects: Equivalent to:current_ -= n;return *this;
constexpr const T& operator[](difference_type n) const noexcept;
Effects: Equivalent to: return *(*this + n);
friend constexpr bool operator==(const _iterator_& x, const _iterator_& y);
Effects: Equivalent to: return x.current_ == y.current_;
friend constexpr auto operator<=>(const _iterator_& x, const _iterator_& y);
Effects: Equivalent to: return x.current_ <=> y.current_;
friend constexpr _iterator_ operator+(_iterator_ i, difference_type n);friend constexpr _iterator_ operator+(difference_type n, _iterator_ i);
Effects: Equivalent to:i += n;return i;
friend constexpr _iterator_ operator-(_iterator_ i, difference_type n);
Effects: Equivalent to:i -= n;return i;
friend constexpr difference_type operator-(const _iterator_& x, const _iterator_& y);
Effects: Equivalent to:return static_cast<difference_type>(x.current_) - static_cast<difference_type>(y.current_);
25.6.6 Istream view [range.istream]
25.6.6.1 Overview [range.istream.overview]
basic_istream_view models input_range and reads (using operator>>) successive elements from its corresponding input stream.
Given a type T and a subexpression E of type U, if U modelsderived_from<basic_istream<typename U::char_type,typename U::traits_type>>, then the expression views::istream<T>(E) is expression-equivalent tobasic_istream_view<T, typename U::char_type,typename U::traits_type>(E); otherwise, views::istream<T>(E) is ill-formed.
[Example 1: auto ints = istringstream{"0 1 2 3 4"}; ranges::copy(views::istream<int>(ints), ostream_iterator<int>{cout, "-"}); — _end example_]
25.6.6.2 Class template basic_istream_view [range.istream.view]
namespace std::ranges { template<class Val, class CharT, class Traits> concept stream-extractable = requires(basic_istream<CharT, Traits>& is, Val& t) { is >> t;};template<movable Val, class CharT, class Traits = char_traits<CharT>> requires default_initializable<Val> && <Val, CharT, Traits> class basic_istream_view : public view_interface<basic_istream_view<Val, CharT, Traits>> { public: constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);constexpr auto begin() { *stream_ >> value_;return iterator{*this};} constexpr default_sentinel_t end() const noexcept;private: struct iterator; basic_istream<CharT, Traits>* stream_; Val value_ = Val(); };}
constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);
Effects: Initializes stream_ with addressof(stream).
constexpr default_sentinel_t end() const noexcept;
Effects: Equivalent to: return default_sentinel;
25.6.6.3 Class basic_istream_view::iterator [range.istream.iterator]
namespace std::ranges { template<movable Val, class CharT, class Traits> requires default_initializable<Val> && <Val, CharT, Traits> class basic_istream_view<Val, CharT, Traits>::iterator { public: using iterator_concept = input_iterator_tag;using difference_type = ptrdiff_t;using value_type = Val;constexpr explicit iterator(basic_istream_view& parent) noexcept;iterator(const iterator&) = delete;iterator(iterator&&) = default;iterator& operator=(const iterator&) = delete;iterator& operator=(iterator&&) = default;iterator& operator++();void operator++(int); Val& operator*() const;friend bool operator==(const iterator& x, default_sentinel_t);private: basic_istream_view* parent_; };}
constexpr explicit _iterator_(basic_istream_view& parent) noexcept;
Effects: Initializes parent_ with addressof(parent).
Effects: Equivalent to:*_parent__->stream_ >> _parent__->value_;return *this;
Effects: Equivalent to ++*this.
Effects: Equivalent to: return _parent__->value_;
friend bool operator==(const _iterator_& x, default_sentinel_t);
Effects: Equivalent to: return !*x._parent__->stream_;