[range.enumerate] (original) (raw)
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.
Given a subexpression E, the expression views::enumerate(E) is expression-equivalent toenumerate_view<views::all_t<decltype((E))>>(E).
[Example 1: vector<int> vec{ 1, 2, 3 };for (auto [index, value] : views::enumerate(vec)) cout << index << ":" << value << ' '; — _end example_]
25.7.24.2 Class template enumerate_view [range.enumerate.view]
namespace std::ranges { template<view V> requires range-with-movable-references<V> class enumerate_view : public view_interface<enumerate_view<V>> { V base_ = V(); template<bool Const> class iterator; template<bool Const> class sentinel; public: constexpr enumerate_view() requires default_initializable<V> = default;constexpr explicit enumerate_view(V base);constexpr auto begin() requires (<V>) { return iterator<false>(ranges::begin(base_), 0); } constexpr auto begin() const requires range-with-movable-references<const V> { return iterator<true>(ranges::begin(base_), 0); } constexpr auto end() requires (
<V>) { if constexpr (forward_range<V> && common_range<V> && sized_range<V>) return iterator<false>(ranges::end(base_), ranges::distance(base_));else return sentinel<false>(ranges::end(base_));} constexpr auto end() const requires range-with-movable-references<const V> { if constexpr (forward_range<const V> && common_range<const V> && sized_range<const V>) return iterator<true>(ranges::end(base_), ranges::distance(base_));else return sentinel<true>(ranges::end(base_));} constexpr auto size() requires sized_range<V> { return ranges::size(base_); } constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); } constexpr auto reserve_hint() requires approximately_sized_range<V> { return ranges::reserve_hint(base_); } constexpr auto reserve_hint() const requires approximately_sized_range<const V> { return ranges::reserve_hint(base_); } constexpr V base() const & requires copy_constructible<V> { return base_; } constexpr V base() && { return std::move(base_); } };template<class R> enumerate_view(R&&) -> enumerate_view<views::all_t<R>>;}
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-references<V> template<bool Const> class enumerate_view<V>::iterator { using Base = maybe-const<Const, V>; public: 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 = tuple<difference_type, range_reference_t<_Base_>>; iterator_t<_Base_> current_ = iterator_t<_Base_>(); difference_type pos_ = 0; constexpr explicit iterator(iterator_t<_Base_> current, difference_type pos); public: iterator() requires default_initializable<iterator_t<_Base_>> = default;constexpr iterator(iterator<!Const> i) requires Const && convertible_to<iterator_t<V>, 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) const requires 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-name _iterator_::iterator_conceptis defined as follows:
- 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) and_pos__ with pos.
constexpr _iterator_(_iterator_<!Const> i) requires Const && [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<_Base_>>;
Effects: Initializes current_ with std::move(i.current_) and_pos__ 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.
Effects: Equivalent to:auto temp = *this;++*this;return temp;
Effects: Equivalent to:--current_;--pos_;return *this;
Effects: Equivalent to:auto temp = *this;--*this;return temp;
Effects: Equivalent to:current_ += n;pos_ += n;return *this;
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%5Faccess%5Frange "25.4.5 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%5Faccess%5Frange "25.4.5 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%5Faccess%5Frange "25.4.5 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-references<V> template<bool Const> class enumerate_view<V>::sentinel { using Base = maybe-const<Const, V>; sentinel_t<_Base_> end_ = sentinel_t<_Base_>(); constexpr explicit sentinel(sentinel_t<_Base_> end); public: sentinel() = default;constexpr sentinel(sentinel<!Const> other) requires Const && convertible_to<sentinel_t<V>, sentinel_t<_Base_>>;constexpr sentinel_t<_Base_> base() const;template<bool OtherConst> requires sentinel_for<sentinel_t<_Base_>, iterator_t<_maybe-const_<OtherConst, V>>> friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);template<bool OtherConst> requires sized_sentinel_for<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);template<bool OtherConst> requires 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<OtherConst>& 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%5Fto "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%5Ffor "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%5Fsentinel%5Ffor "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%5Fsentinel%5Ffor "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_;