9 Iterators library [iterators]

9.7 Iterator adaptors [iterators.predef]

9.7.6 Counted iterators [iterators.counted]

9.7.6.2 counted_iterator operations [counted.iter.ops]

9.7.6.2.1 counted_iterator constructors [counted.iter.op.const]

constexpr counted_iterator();

Effects: Constructs a counted_iterator, value-initializing current and cnt. Iterator operations applied to the resulting iterator have defined behavior if and only if the corresponding operations are defined on a value-initialized iterator of type I.

constexpr counted_iterator(I i, difference_type_t<I> n);

Requires: n >= 0

Effects: Constructs a counted_iterator, initializing current with i and cnt with n.

constexpr counted_iterator(const counted_iterator<ConvertibleTo<I>>& i);

Effects: Constructs a counted_iterator, initializing current with i.current and cnt with i.cnt.

9.7.6.2.2 counted_iterator::operator= [counted.iter.op=]

constexpr counted_iterator& operator=(const counted_iterator<ConvertibleTo<I>>& i);

Effects: Assigns i.current to current and i.cnt to cnt.

9.7.6.2.3 counted_iterator conversion [counted.iter.op.conv]

constexpr I base() const;

Returns: current.

9.7.6.2.4 counted_iterator count [counted.iter.op.cnt]

constexpr difference_type_t<I> count() const;

Returns: cnt.

9.7.6.2.5 counted_iterator::operator* [counted.iter.op.star]

constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() const requires dereferenceable<const I>;

Effects: Equivalent to: return *current;

9.7.6.2.6 counted_iterator::operator++ [counted.iter.op.incr]

constexpr counted_iterator& operator++();

Requires: cnt > 0

Effects: Equivalent to:

++current;
--cnt;

Returns: *this.

decltype(auto) operator++(int);

Requires: cnt > 0.

Effects: Equivalent to:

--cnt;
try { return current++; }
catch(...) { ++cnt; throw; }

constexpr counted_iterator operator++(int) requires ForwardIterator<I>;

Requires: cnt > 0

Effects: Equivalent to:

counted_iterator tmp = *this;
++*this;
return tmp;

9.7.6.2.7 counted_iterator::operator-- [counted.iter.op.decr]

constexpr counted_iterator& operator--(); requires BidirectionalIterator<I>

Effects: Equivalent to:

--current;
++cnt;

Returns: *this.

constexpr counted_iterator operator--(int) requires BidirectionalIterator<I>;

Effects: Equivalent to:

counted_iterator tmp = *this;
--*this;
return tmp;

9.7.6.2.8 counted_iterator::operator+ [counted.iter.op.+]

constexpr counted_iterator operator+(difference_type n) const requires RandomAccessIterator<I>;

Requires: n <= cnt

Effects: Equivalent to: return counted_iterator(current + n, cnt - n);

9.7.6.2.9 counted_iterator::operator+= [counted.iter.op.+=]

constexpr counted_iterator& operator+=(difference_type n) requires RandomAccessIterator<I>;

Requires: n <= cnt

Effects:

current += n;
cnt -= n;

Returns: *this.

9.7.6.2.10 counted_iterator::operator- [counted.iter.op.-]

constexpr counted_iterator operator-(difference_type n) const requires RandomAccessIterator<I>;

Requires: -n <= cnt

Effects: Equivalent to: return counted_iterator(current - n, cnt + n);

9.7.6.2.11 counted_iterator::operator-= [counted.iter.op.-=]

constexpr counted_iterator& operator-=(difference_type n) requires RandomAccessIterator<I>;

Requires: -n <= cnt

Effects:

current -= n;
cnt += n;

Returns: *this.

9.7.6.2.12 counted_iterator::operator[] [counted.iter.op.index]

constexpr decltype(auto) operator[](difference_type n) const requires RandomAccessIterator<I>;

Requires: n <= cnt

Effects: Equivalent to: return current[n];

9.7.6.2.13 counted_iterator comparisons [counted.iter.op.comp]

template <class I1, class I2> requires Common<I1, I2> constexpr bool operator==( const counted_iterator<I1>& x, const counted_iterator<I2>& y);

Requires: x and y shall refer to elements of the same sequence ([iterators.counted]).

Effects: Equivalent to: return x.cnt == y.cnt;

constexpr bool operator==( const counted_iterator<auto>& x, default_sentinel); constexpr bool operator==( default_sentinel, const counted_iterator<auto>& x);

Effects: Equivalent to: return x.cnt == 0;

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

Requires: For the first overload, x and y shall refer to elements of the same sequence ([iterators.counted]).

Effects: Equivalent to: return !(x == y);

template <class I1, class I2> requires Common<I1, I2> constexpr bool operator<( const counted_iterator<I1>& x, const counted_iterator<I2>& y);

Requires: x and y shall refer to elements of the same sequence ([iterators.counted]).

Effects: Equivalent to: return y.cnt < x.cnt;

Note: The argument order in the Effects element is reversed because cnt counts down, not up.  — end note ]

template <class I1, class I2> requires Common<I1, I2> constexpr bool operator<=( const counted_iterator<I1>& x, const counted_iterator<I2>& y);

Requires: x and y shall refer to elements of the same sequence ([iterators.counted]).

Effects: Equivalent to: return !(y < x);

template <class I1, class I2> requires Common<I1, I2> constexpr bool operator>( const counted_iterator<I1>& x, const counted_iterator<I2>& y);

Requires: x and y shall refer to elements of the same sequence ([iterators.counted]).

Effects: Equivalent to: return y < x;

template <class I1, class I2> requires Common<I1, I2> constexpr bool operator>=( const counted_iterator<I1>& x, const counted_iterator<I2>& y);

Requires: x and y shall refer to elements of the same sequence ([iterators.counted]).

Effects: Equivalent to: return !(x < y);

9.7.6.2.14 counted_iterator non-member functions [counted.iter.nonmember]

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

Requires: x and y shall refer to elements of the same sequence ([iterators.counted]).

Effects: Equivalent to: return y.cnt - x.cnt;

template <class I> constexpr difference_type_t<I> operator-( const counted_iterator<I>& x, default_sentinel y);

Effects: Equivalent to: return -x.cnt;

template <class I> constexpr difference_type_t<I> operator-( default_sentinel x, const counted_iterator<I>& y);

Effects: Equivalent to: return y.cnt;

template <RandomAccessIterator I> constexpr counted_iterator<I> operator+( difference_type_t<I> n, const counted_iterator<I>& x);

Requires: n <= x.cnt.

Effects: Equivalent to: return x + n;

friend constexpr rvalue_reference_t<I> iter_move(const counted_iterator& i) noexcept(see below) requires InputIterator<I>;

Effects: Equivalent to: return ranges::iter_move(i.current);

Remarks: The expression in noexcept is equivalent to:

noexcept(ranges::iter_move(i.current))

template <IndirectlySwappable<I> I2> friend constexpr void iter_swap(const counted_iterator& x, const counted_iterator<I2>& y) noexcept(see below);

Effects: Equivalent to ranges::iter_swap(x.current, y.current).

Remarks: The expression in noexcept is equivalent to:

noexcept(ranges::iter_swap(x.current, y.current))

template <Iterator I> constexpr counted_iterator<I> make_counted_iterator(I i, difference_type_t<I> n);

Requires: n >= 0.

Returns: counted_iterator<I>(i, n).