[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 (_simple-view_<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 (_simple-view_<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:

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_;