[counted.iterator]

# 24 Iterators library [[iterators]](./#iterators)

## 24.5 Iterator adaptors [[predef.iterators]](predef.iterators#counted.iterator)

### 24.5.7 Counted iterators [[iterators.counted]](iterators.counted#counted.iterator)

#### 24.5.7.1 Class template counted_iterator [counted.iterator]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5876)

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[.](#1.sentence-1)

It can be used together with 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[.](#1.sentence-2)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5885)

[*Example [1](#example-1)*: list<string> s;// populate the list s with at least 10 strings vector<string> v;// copies 10 strings into v: ranges::copy(counted_iterator(s.begin(), 10), default_sentinel, back_inserter(v)); â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5896)

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[.](#3.sentence-1)

[ð](#lib:counted_iterator)

namespace std {template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") I>class counted_iterator {public:using iterator_type = I; using value_type = iter_value_t<I>; // present only// if I models [indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]")using difference_type = iter_difference_t<I>; using iterator_concept = typename I::iterator_concept; // present only// if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") I​::​iterator_concept is valid and denotes a typeusing iterator_category = typename I::iterator_category; // present only// if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") I​::​iterator_category is valid and denotes a typeconstexpr counted_iterator() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_­initializable [concept.default.init]")<I> = default; constexpr counted_iterator(I x, iter_difference_t<I> n); template<class I2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const I2&, I>constexpr counted_iterator(const counted_iterator<I2>& x); template<class I2>requires [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]")<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*() constrequires [*dereferenceable*](iterator.synopsis#concept:dereferenceable "24.2 Header <iterator>&nbsp;synopsis [iterator.synopsis]")<const I>; constexpr auto operator->() const noexceptrequires [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_­iterator [iterator.concept.contiguous]")<I>; constexpr counted_iterator& operator++(); constexpr decltype(auto) operator++(int); constexpr counted_iterator operator++(int)requires [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]")<I>; constexpr counted_iterator& operator--()requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_­iterator [iterator.concept.bidir]")<I>; constexpr counted_iterator operator--(int)requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_­iterator [iterator.concept.bidir]")<I>; constexpr counted_iterator operator+(iter_difference_t<I> n) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")<I>; friend constexpr counted_iterator operator+( iter_difference_t<I> n, const counted_iterator& x)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")<I>; constexpr counted_iterator& operator+=(iter_difference_t<I> n)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")<I>; constexpr counted_iterator operator-(iter_difference_t<I> n) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")<I>; template<[common_with](concept.common#concept:common_with "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); 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](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")<I>; constexpr decltype(auto) operator[](iter_difference_t<I> n) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]")<I>; template<[common_with](concept.common#concept:common_with "18.4.6 Concept common_­with [concept.common]")<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](concept.common#concept:common_with "18.4.6 Concept common_­with [concept.common]")<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](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]")<I>; template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "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))); private: I current = I(); // *exposition only* iter_difference_t<I> length = 0; // *exposition only*}; template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I>requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<*ITER_TRAITS*(I), iterator_traits<I>> // see [[iterator.concepts.general]](iterator.concepts.general "24.3.4.1 General")struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {using pointer = conditional_t<[contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_­iterator [iterator.concept.contiguous]")<I>,
 add_pointer_t<iter_reference_t<I>>, void>; };}
