Class template counted_iterator is an iterator adaptor with the same behavior as the underlying iterator except that it keeps track of its distance from its starting position. It can be used together with class default_sentinel in 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:
list<string> s; // populate the list s with at least 10 strings vector<string> v(make_counted_iterator(s.begin(), 10), default_sentinel()); // copies 10 strings into v
— end example ]
Two values i1 and i2 of (possibly differing) types counted_iterator<I1> and counted_iterator<I2> refer to elements of the same sequence if and only if next(i1.base(), i1.count()) and next(i2.base(), i2.count()) refer to the same (possibly past-the-end) element.
namespace std { namespace experimental { namespace ranges { inline namespace v1 { template <Iterator I> class counted_iterator { public: using iterator_type = I; using difference_type = difference_type_t<I>; constexpr counted_iterator(); constexpr counted_iterator(I x, difference_type_t<I> n); constexpr counted_iterator(const counted_iterator<ConvertibleTo<I>>& i); constexpr counted_iterator& operator=(const counted_iterator<ConvertibleTo<I>>& i); constexpr I base() const; constexpr difference_type_t<I> count() const; constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() const requires dereferenceable<const I>; constexpr counted_iterator& operator++(); decltype(auto) operator++(int); constexpr counted_iterator operator++(int) requires ForwardIterator<I>; constexpr counted_iterator& operator--() requires BidirectionalIterator<I>; constexpr counted_iterator operator--(int) requires BidirectionalIterator<I>; constexpr counted_iterator operator+ (difference_type n) const requires RandomAccessIterator<I>; constexpr counted_iterator& operator+=(difference_type n) requires RandomAccessIterator<I>; constexpr counted_iterator operator- (difference_type n) const requires RandomAccessIterator<I>; constexpr counted_iterator& operator-=(difference_type n) requires RandomAccessIterator<I>; constexpr decltype(auto) operator[](difference_type n) const requires RandomAccessIterator<I>; friend constexpr rvalue_reference_t<I> iter_move(const counted_iterator& i) noexcept(see below) requires InputIterator<I>; template <IndirectlySwappable<I> I2> friend constexpr void iter_swap(const counted_iterator& x, const counted_iterator<I2>& y) noexcept(see below); private: I current; // exposition only difference_type_t<I> cnt; // exposition only }; template <Readable I> struct value_type<counted_iterator<I>> { using type = value_type_t<I>; }; template <InputIterator I> struct iterator_category<counted_iterator<I>> { using type = iterator_category_t<I>; }; template <class I1, class I2> requires Common<I1, I2> constexpr bool operator==( const counted_iterator<I1>& x, const counted_iterator<I2>& y); constexpr bool operator==( const counted_iterator<auto>& x, default_sentinel); constexpr bool operator==( default_sentinel, const counted_iterator<auto>& x); template <class I1, class I2> requires Common<I1, I2> constexpr bool operator!=( const counted_iterator<I1>& x, const counted_iterator<I2>& y); constexpr bool operator!=( const counted_iterator<auto>& x, default_sentinel y); constexpr bool operator!=( default_sentinel x, const counted_iterator<auto>& y); template <class I1, class I2> requires Common<I1, I2> constexpr bool operator<( const counted_iterator<I1>& x, const counted_iterator<I2>& y); template <class I1, class I2> requires Common<I1, I2> constexpr bool operator<=( const counted_iterator<I1>& x, const counted_iterator<I2>& y); template <class I1, class I2> requires Common<I1, I2> constexpr bool operator>( const counted_iterator<I1>& x, const counted_iterator<I2>& y); template <class I1, class I2> requires Common<I1, I2> constexpr bool operator>=( const counted_iterator<I1>& x, const counted_iterator<I2>& y); template <class I1, class I2> requires Common<I1, I2> constexpr difference_type_t<I2> operator-( const counted_iterator<I1>& x, const counted_iterator<I2>& y); template <class I> constexpr difference_type_t<I> operator-( const counted_iterator<I>& x, default_sentinel y); template <class I> constexpr difference_type_t<I> operator-( default_sentinel x, const counted_iterator<I>& y); template <RandomAccessIterator I> constexpr counted_iterator<I> operator+( difference_type_t<I> n, const counted_iterator<I>& x); template <Iterator I> constexpr counted_iterator<I> make_counted_iterator(I i, difference_type_t<I> n); }}}}