22 KiB
[range.enumerate]
25 Ranges library [ranges]
25.7 Range adaptors [range.adaptors]
25.7.24 Enumerate view [range.enumerate]
25.7.24.1 Overview [range.enumerate.overview]
enumerate_view is a view whose elements represent both the position and value from a sequence of elements.
The name views::enumerate denotes a range adaptor object ([range.adaptor.object]).
Given a subexpression E, the expression views::enumerate(E) is expression-equivalent toenumerate_view<views::all_t<decltype((E))>>(E).
[Example 1: vector vec{ 1, 2, 3 };for (auto [index, value] : views::enumerate(vec)) cout << index << ":" << value << ' '; // prints 0:1 1:2 2:3 â end example]
25.7.24.2 Class template enumerate_view [range.enumerate.view]
namespace std::ranges {template<view V>requires range-with-movable-referencesclass enumerate_view : public view_interface<enumerate_view> { V base_ = V(); // exposition only// [range.enumerate.iterator], class template enumerate_view::iteratortemplateclass iterator; // exposition only// [range.enumerate.sentinel], class template enumerate_view::sentineltemplateclass sentinel; // exposition onlypublic:constexpr enumerate_view() requires default_initializable = default; constexpr explicit enumerate_view(V base); constexpr auto begin() requires (){ return iterator(ranges::begin(base_), 0); }constexpr auto begin() const requires range-with-movable-references{ return iterator(ranges::begin(base_), 0); }constexpr auto end() requires (
) {if constexpr (forward_range && common_range && sized_range)return iterator(ranges::end(base_), ranges::distance(base_)); elsereturn sentinel(ranges::end(base_)); }constexpr auto end() const requires range-with-movable-references {if constexpr (forward_range && common_range && sized_range)return iterator(ranges::end(base_), ranges::distance(base_)); elsereturn sentinel(ranges::end(base_)); }constexpr auto size() requires sized_range{ return ranges::size(base_); }constexpr auto size() const requires sized_range{ return ranges::size(base_); }constexpr auto reserve_hint() requires approximately_sized_range{ return ranges::reserve_hint(base_); }constexpr auto reserve_hint() const requires approximately_sized_range{ return ranges::reserve_hint(base_); }constexpr V base() const & requires copy_constructible { return base_; }constexpr V base() && { return std::move(base_); }}; template enumerate_view(R&&) -> enumerate_view<views::all_t>;}
constexpr explicit enumerate_view(V base);
Effects: Initializes base_ with std::move(base).
25.7.24.3 Class template enumerate_view::iterator [range.enumerate.iterator]
namespace std::ranges {template<view V>requires range-with-movable-referencestemplateclass enumerate_view::iterator {using Base = maybe-const<Const, V>; // exposition onlypublic:using iterator_category = input_iterator_tag; using iterator_concept = see below; using difference_type = range_difference_t<Base>; using value_type = tuple<difference_type, range_value_t<Base>>; private:using reference-type = // exposition only tuple<difference_type, range_reference_t<Base>>; iterator_t<Base> current_ = iterator_t<Base>(); // exposition only difference_type pos_ = 0; // exposition onlyconstexpr explicititerator(iterator_t<Base> current, difference_type pos); // exposition onlypublic:iterator() requires default_initializable<iterator_t<Base>> = default; constexpr iterator(iterator i)requires Const && convertible_to<iterator_t, iterator_t<Base>>; constexpr const iterator_t<Base>& base() const & noexcept; constexpr iterator_t<Base> base() &&; constexpr difference_type index() const noexcept; constexpr auto operator*() const {return reference-type(pos_, **current_*); }constexpr iterator& operator++(); constexpr void operator++(int); constexpr iterator operator++(int) requires forward_range<Base>; constexpr iterator& operator--() requires bidirectional_range<Base>; constexpr iterator operator--(int) requires bidirectional_range<Base>; constexpr iterator& operator+=(difference_type x)requires random_access_range<Base>; constexpr iterator& operator-=(difference_type x)requires random_access_range<Base>; constexpr auto operator[](difference_type n) constrequires random_access_range<Base>{ return reference-type(pos_ + n, current_[n]); }friend constexpr bool operator==(const iterator& x, const iterator& y) noexcept; friend constexpr strong_ordering operator<=>(const iterator& x, const iterator& y) noexcept; friend constexpr iterator operator+(const iterator& x, difference_type y)requires random_access_range<Base>; friend constexpr iterator operator+(difference_type x, const iterator& y)requires random_access_range<Base>; friend constexpr iterator operator-(const iterator& x, difference_type y)requires random_access_range<Base>; friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept; friend constexpr auto iter_move(const iterator& i)noexcept(noexcept(ranges::iter_move(i.current_)) && is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {return tuple<difference_type, range_rvalue_reference_t<Base>>(i.pos_, ranges::iter_move(i.current_)); }};}
The member typedef-nameiterator::iterator_concept is defined as follows:
-
If Base models random_access_range, then iterator_concept denotes random_access_iterator_tag.
-
Otherwise, if Base models bidirectional_range, then iterator_concept denotes bidirectional_iterator_tag.
-
Otherwise, if Base models forward_range, then iterator_concept denotes forward_iterator_tag.
-
Otherwise, iterator_concept denotes input_iterator_tag.
constexpr explicit iterator(iterator_t<Base> current, difference_type pos);
Effects: Initializes current_ with std::move(current) andpos_ with pos.
constexpr iterator(iterator<!Const> i) requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
Effects: Initializes current_ with std::move(i.current_) andpos_ with i.pos_.
constexpr const iterator_t<Base>& base() const & noexcept;
Effects: Equivalent to: return current_;
constexpr iterator_t<Base> base() &&;
Effects: Equivalent to: return std::move(current_);
constexpr difference_type index() const noexcept;
Effects: Equivalent to: return pos_;
constexpr iterator& operator++();
Effects: Equivalent to:++current_;++pos_;return *this;
constexpr void operator++(int);
Effects: Equivalent to ++*this.
constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to:auto temp = *this;++*this;return temp;
constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to:--current_;--pos_;return *this;
constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to:auto temp = *this;--*this;return temp;
constexpr iterator& operator+=(difference_type n) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to:current_ += n;pos_ += n;return *this;
constexpr iterator& operator-=(difference_type n) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to:current_ -= n;pos_ -= n;return *this;
friend constexpr bool operator==(const iterator& x, const iterator& y) noexcept;
Effects: Equivalent to: return x.pos_ == y.pos_;
friend constexpr strong_ordering operator<=>(const iterator& x, const iterator& y) noexcept;
Effects: Equivalent to: return x.pos_ <=> y.pos_;
friend constexpr iterator operator+(const iterator& x, difference_type y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to:auto temp = x; temp += y;return temp;
friend constexpr iterator operator+(difference_type x, const iterator& y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to: return y + x;
friend constexpr iterator operator-(const iterator& x, difference_type y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
Effects: Equivalent to:auto temp = x; temp -= y;return temp;
friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
Effects: Equivalent to: return x.pos_ - y.pos_;
25.7.24.4 Class template enumerate_view::sentinel [range.enumerate.sentinel]
namespace std::ranges {template<view V>requires range-with-movable-referencestemplateclass enumerate_view::sentinel {using Base = maybe-const<Const, V>; // exposition only sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition onlyconstexpr explicit sentinel(sentinel_t<Base> end); // exposition onlypublic:sentinel() = default; constexpr sentinel(sentinel other)requires Const && convertible_to<sentinel_t, sentinel_t<Base>>; constexpr sentinel_t<Base> base() const; templaterequires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>friend constexpr bool operator==(const iterator& x, const sentinel& y); templaterequires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>friend constexpr range_difference_t<maybe-const<OtherConst, V>>operator-(const iterator& x, const sentinel& y); templaterequires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>friend constexpr range_difference_t<maybe-const<OtherConst, V>>operator-(const sentinel& x, const iterator& y); };}
constexpr explicit sentinel(sentinel_t<Base> end);
Effects: Initializes end_ with std::move(end).
constexpr sentinel(sentinel<!Const> other) requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
Effects: Initializes end_ with std::move(other.end_).
constexpr sentinel_t<Base> base() const;
Effects: Equivalent to: return end_;
template<bool OtherConst> requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>> friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
Effects: Equivalent to: return x.current_ == y.end_;
template<bool OtherConst> requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>> friend constexpr range_difference_t<maybe-const<OtherConst, V>> operator-(const iterator<OtherConst>& x, const sentinel& y);
Effects: Equivalent to: return x.current_ - y.end_;
template<bool OtherConst> requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>> friend constexpr range_difference_t<maybe-const<OtherConst, V>> operator-(const sentinel& x, const iterator<OtherConst>& y);
Effects: Equivalent to: return x.end_ - y.current_;