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; } }; }
namespace std::ranges { template<copy_constructible T> requires is_object_v<T> class single_view : public view_interface<single_view<T>> { private: semiregular-box<T> value_; // exposition only (see [range.semi.wrap]) public: single_view() = default; constexpr explicit single_view(const T& t); constexpr explicit single_view(T&& t); template<class... Args> requires constructible_from<T, Args...> constexpr 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 size_t size() noexcept; constexpr T* data() noexcept; constexpr const T* data() const noexcept; }; }
constexpr explicit single_view(const T& t);
constexpr explicit single_view(T&& t);
template<class... Args>
constexpr 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 size_t size() noexcept;
constexpr T* data() noexcept;
constexpr const T* data() const noexcept;
namespace std::ranges { template<class I> concept decrementable = // exposition only see below; template<class I> concept advanceable = // exposition only see below; template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t> requires weakly-equality-comparable-with<W, Bound> && semiregular<W> class iota_view : public view_interface<iota_view<W, Bound>> { private: // [range.iota.iterator], class iota_view::iterator struct iterator; // exposition only // [range.iota.sentinel], class iota_view::sentinel struct sentinel; // exposition only W value_ = W(); // exposition only Bound bound_ = Bound(); // exposition only public: iota_view() = default; constexpr explicit iota_view(W value); constexpr iota_view(type_identity_t<W> value, type_identity_t<Bound> bound); constexpr iota_view(iterator first, sentinel last) : iota_view(*first, last.bound_) {} constexpr iterator begin() const; constexpr auto end() const; constexpr iterator end() const requires same_as<W, Bound>; 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>; }
template<class I>
concept decrementable =
incrementable<I> && requires(I i) {
{ --i } -> same_as<I&>;
{ i-- } -> same_as<I>;
};
template<class I>
concept advanceable =
decrementable<I> && totally_ordered<I> &&
requires(I i, const I j, const IOTA-DIFF-T(I) n) {
{ i += n } -> same_as<I&>;
{ i -= n } -> same_as<I&>;
I(j + n);
I(n + j);
I(j - n);
{ j - j } -> convertible_to<IOTA-DIFF-T(I)>;
};
constexpr explicit iota_view(W value);
constexpr iota_view(type_identity_t<W> value, type_identity_t<Bound> bound);
constexpr iterator begin() const;
constexpr auto end() const;
constexpr auto size() const requires see below;
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_);
(same_as<W, Bound> && advanceable<W>) || (integral<W> && integral<Bound>) || sized_sentinel_for<Bound, W>
namespace std::ranges { template<weakly_incrementable W, semiregular Bound> requires weakly-equality-comparable-with<W, Bound> struct iota_view<W, Bound>::iterator { private: W value_ = W(); // exposition only public: using iterator_concept = see below; using iterator_category = input_iterator_tag; using value_type = W; using difference_type = IOTA-DIFF-T(W); iterator() = 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>; }; }
constexpr explicit iterator(W value);
constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);
constexpr iterator& operator++();
constexpr void operator++(int);
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;
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;
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 auto operator<=>(const iterator& x, const iterator& y)
requires totally_ordered<W> && three_way_comparable<W>;
namespace std::ranges { template<weakly_incrementable W, semiregular Bound> requires weakly-equality-comparable-with<W, Bound> struct iota_view<W, Bound>::sentinel { private: Bound bound_ = Bound(); // exposition only 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);
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>;
namespace std::ranges { template<class Val, class CharT, class Traits> concept stream-extractable = // exposition only requires(basic_istream<CharT, Traits>& is, Val& t) { is >> t; }; template<movable Val, class CharT, class Traits> requires default_initializable<Val> && stream-extractable<Val, CharT, Traits> class basic_istream_view : public view_interface<basic_istream_view<Val, CharT, Traits>> { public: basic_istream_view() = default; constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream); constexpr auto begin() { if (stream_) { *stream_ >> object_; } return iterator{*this}; } constexpr default_sentinel_t end() const noexcept; private: struct iterator; // exposition only basic_istream<CharT, Traits>* stream_ = nullptr; // exposition only Val object_ = Val(); // exposition only }; }
constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);
constexpr default_sentinel_t end() const noexcept;
template<class Val, class CharT, class Traits>
basic_istream_view<Val, CharT, Traits> istream_view(basic_istream<CharT, Traits>& s);
namespace std::ranges { template<movable Val, class CharT, class Traits> requires default_initializable<Val> && stream-extractable<Val, CharT, Traits> class basic_istream_view<Val, CharT, Traits>::iterator { // exposition only public: using iterator_concept = input_iterator_tag; using difference_type = ptrdiff_t; using value_type = Val; iterator() = default; 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_ = nullptr; // exposition only }; }
constexpr explicit iterator(basic_istream_view& parent) noexcept;
iterator& operator++();
void operator++(int);
Val& operator*() const;
friend bool operator==(const iterator& x, default_sentinel_t);