[iterators.counted] (original) (raw)
24 Iterators library [iterators]
24.5 Iterator adaptors [predef.iterators]
24.5.7 Counted iterators [iterators.counted]
24.5.7.1 Class template counted_iterator [counted.iterator]
24.5.7.2 Constructors and conversions [counted.iter.const]
24.5.7.3 Accessors [counted.iter.access]
24.5.7.4 Element access [counted.iter.elem]
24.5.7.5 Navigation [counted.iter.nav]
24.5.7.6 Comparisons [counted.iter.cmp]
24.5.7.7 Customizations [counted.iter.cust]
24.5.7.1 Class template counted_iterator [counted.iterator]
Class template counted_iterator is an iterator adaptor with the same behavior as the underlying iterator except that it keeps track of the distance to the end of its range.
It can be used together with default_sentinelin calls to generic algorithms to operate on a range of N elements starting at a given position without needing to know the end position a priori.
[Example 1: list<string> s; vector<string> v; ranges::copy(counted_iterator(s.begin(), 10), default_sentinel, back_inserter(v)); — _end example_]
Two values i1 and i2 of typescounted_iterator<I1>andcounted_iterator<I2>refer to elements of the same sequence if and only if there exists some integer n such thatnext(i1.base(), i1.count() + n)andnext(i2.base(), i2.count() + n)refer to the same (possibly past-the-end) element.
namespace std { template<input_or_output_iterator I> class counted_iterator { public: using iterator_type = I;using value_type = iter_value_t<I>; using difference_type = iter_difference_t<I>;using iterator_concept = I::iterator_concept; using iterator_category = I::iterator_category; constexpr counted_iterator() requires default_initializable<I> = default;constexpr counted_iterator(I x, iter_difference_t<I> n);template<class I2> requires convertible_to<const I2&, I> constexpr counted_iterator(const counted_iterator<I2>& x);template<class I2> requires assignable_from<I&, const I2&> constexpr counted_iterator& operator=(const counted_iterator<I2>& x);constexpr const I& base() const & noexcept;constexpr I base() &&;constexpr iter_difference_t<I> count() const noexcept;constexpr decltype(auto) operator*();constexpr decltype(auto) operator*() const requires dereferenceable<const I>;constexpr auto operator->() const noexcept requires contiguous_iterator<I>;constexpr counted_iterator& operator++();constexpr decltype(auto) operator++(int);constexpr counted_iterator operator++(int) requires forward_iterator<I>;constexpr counted_iterator& operator--() requires bidirectional_iterator<I>;constexpr counted_iterator operator--(int) requires bidirectional_iterator<I>;constexpr counted_iterator operator+(iter_difference_t<I> n) const requires random_access_iterator<I>;friend constexpr counted_iterator operator+( iter_difference_t<I> n, const counted_iterator& x) requires random_access_iterator<I>;constexpr counted_iterator& operator+=(iter_difference_t<I> n) requires random_access_iterator<I>;constexpr counted_iterator operator-(iter_difference_t<I> n) const requires random_access_iterator<I>;template<common_with<I> I2> friend constexpr iter_difference_t<I2> operator-( const counted_iterator& x, const counted_iterator<I2>& y);friend constexpr iter_difference_t<I> operator-( const counted_iterator& x, default_sentinel_t) noexcept;friend constexpr iter_difference_t<I> operator-( default_sentinel_t, const counted_iterator& y) noexcept;constexpr counted_iterator& operator-=(iter_difference_t<I> n) requires random_access_iterator<I>;constexpr decltype(auto) operator[](iter_difference_t<I> n) const requires random_access_iterator<I>;template<common_with<I> I2> friend constexpr bool operator==( const counted_iterator& x, const counted_iterator<I2>& y);friend constexpr bool operator==( const counted_iterator& x, default_sentinel_t) noexcept;template<common_with<I> I2> friend constexpr strong_ordering operator<=>( const counted_iterator& x, const counted_iterator<I2>& y);friend constexpr decltype(auto) iter_move(const counted_iterator& i) noexcept(noexcept(ranges::iter_move(i.current))) requires input_iterator<I>;template<indirectly_swappable<I> I2> friend constexpr void iter_swap(const counted_iterator& x, const counted_iterator<I2>& y) noexcept(noexcept(ranges::iter_swap(x.current, y.current)));private: I current = I(); iter_difference_t<I> length = 0; };template<input_iterator I> requires same_as<_ITER_TRAITS_(I), iterator_traits<I>> struct iterator_traits<counted_iterator<I>> : iterator_traits<I> { using pointer = conditional_t<contiguous_iterator<I>, add_pointer_t<iter_reference_t<I>>, void>;};}
24.5.7.2 Constructors and conversions [counted.iter.const]
constexpr counted_iterator(I i, iter_difference_t<I> n);
Hardened preconditions: n >= 0 is true.
Effects: Initializes current with std::move(i) andlength with n.
template<class I2> requires [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_to [concept.convertible]")<const I2&, I> constexpr counted_iterator(const counted_iterator<I2>& x);
Effects: Initializes current with x.current andlength with x.length.
template<class I2> requires [assignable_from](concept.assignable#concept:assignable%5Ffrom "18.4.8 Concept assignable_from [concept.assignable]")<I&, const I2&> constexpr counted_iterator& operator=(const counted_iterator<I2>& x);
Effects: Assigns x.current to current andx.length to length.
24.5.7.3 Accessors [counted.iter.access]
constexpr const I& base() const & noexcept;
Effects: Equivalent to: return current;
Returns: std::move(current).
constexpr iter_difference_t<I> count() const noexcept;
Effects: Equivalent to: return length;
24.5.7.4 Element access [counted.iter.elem]
constexpr decltype(auto) operator*();constexpr decltype(auto) operator*() const requires [_dereferenceable_](iterator.synopsis#concept:dereferenceable "24.2 Header <iterator> synopsis [iterator.synopsis]")<const I>;
Hardened preconditions: length > 0 is true.
Effects: Equivalent to: return *current;
Effects: Equivalent to: return to_address(current);
Hardened preconditions: n < length is true.
Effects: Equivalent to: return current[n];
24.5.7.5 Navigation [counted.iter.nav]
constexpr counted_iterator& operator++();
Hardened preconditions: length > 0 is true.
Effects: Equivalent to:++current;--length;return *this;
constexpr decltype(auto) operator++(int);
Hardened preconditions: length > 0 is true.
Effects: Equivalent to:--length;try { return current++; } catch(...) { ++length; throw; }
Effects: Equivalent to:counted_iterator tmp = *this;++*this;return tmp;
Effects: Equivalent to:--current;++length;return *this;
Effects: Equivalent to:counted_iterator tmp = *this;--*this;return tmp;
Effects: Equivalent to: return counted_iterator(current + n, length - n);
friend constexpr counted_iterator operator+( iter_difference_t<I> n, const counted_iterator& x) requires [random_access_iterator](iterator.concept.random.access#concept:random%5Faccess%5Fiterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]")<I>;
Effects: Equivalent to: return x + n;
Hardened preconditions: n <= length is true.
Effects: Equivalent to:current += n; length -= n;return *this;
Effects: Equivalent to: return counted_iterator(current - n, length + n);
template<[common_with](concept.common#concept:common%5Fwith "18.4.6 Concept common_with [concept.common]")<I> I2> friend constexpr iter_difference_t<I2> operator-( const counted_iterator& x, const counted_iterator<I2>& y);
Preconditions: x and y refer to elements of the same sequence ([counted.iterator]).
Effects: Equivalent to: return y.length - x.length;
friend constexpr iter_difference_t<I> operator-( const counted_iterator& x, default_sentinel_t) noexcept;
Effects: Equivalent to:return -x.length;
friend constexpr iter_difference_t<I> operator-( default_sentinel_t, const counted_iterator& y) noexcept;
Effects: Equivalent to: return y.length;
Hardened preconditions: -n <= length is true.
Effects: Equivalent to:current -= n; length += n;return *this;
24.5.7.6 Comparisons [counted.iter.cmp]
template<[common_with](concept.common#concept:common%5Fwith "18.4.6 Concept common_with [concept.common]")<I> I2> friend constexpr bool operator==( const counted_iterator& x, const counted_iterator<I2>& y);
Preconditions: x and y refer to elements of the same sequence ([counted.iterator]).
Effects: Equivalent to: return x.length == y.length;
friend constexpr bool operator==( const counted_iterator& x, default_sentinel_t) noexcept;
Effects: Equivalent to: return x.length == 0;
template<[common_with](concept.common#concept:common%5Fwith "18.4.6 Concept common_with [concept.common]")<I> I2> friend constexpr strong_ordering operator<=>( const counted_iterator& x, const counted_iterator<I2>& y);
Preconditions: x and y refer to elements of the same sequence ([counted.iterator]).
Effects: Equivalent to: return y.length <=> x.length;
[Note 1:
The argument order in the Effects: element is reversed because length counts down, not up.
— _end note_]
24.5.7.7 Customizations [counted.iter.cust]
friend constexpr decltype(auto) iter_move(const counted_iterator& i) noexcept(noexcept(ranges::iter_move(i.current))) requires [input_iterator](iterator.concept.input#concept:input%5Fiterator "24.3.4.9 Concept input_iterator [iterator.concept.input]")<I>;
Hardened preconditions: i.length > 0 is true.
Effects: Equivalent to: return ranges::iter_move(i.current);
template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly%5Fswappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<I> I2> friend constexpr void iter_swap(const counted_iterator& x, const counted_iterator<I2>& y) noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
Hardened preconditions: Both x.length > 0 and y.length > 0 are true.
Effects: Equivalent to ranges::iter_swap(x.current, y.current).