Files
2025-10-25 03:02:53 +03:00

2821 lines
145 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[predef.iterators]
# 24 Iterators library [[iterators]](./#iterators)
## 24.5 Iterator adaptors [predef.iterators]
### [24.5.1](#reverse.iterators) Reverse iterators [[reverse.iterators]](reverse.iterators)
#### [24.5.1.1](#reverse.iterators.general) General [[reverse.iterators.general]](reverse.iterators.general)
[1](#reverse.iterators.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3185)
Class template reverse_iterator is an iterator adaptor that iterates from the end of the sequence defined by its underlying iterator to the beginning of that sequence[.](#reverse.iterators.general-1.sentence-1)
#### [24.5.1.2](#reverse.iterator) Class template reverse_iterator [[reverse.iterator]](reverse.iterator)
[🔗](#lib:reverse_iterator)
namespace std {template<class Iterator>class reverse_iterator {public:using iterator_type = Iterator; using iterator_concept = *see below*; using iterator_category = *see below*; using value_type = iter_value_t<Iterator>; using difference_type = iter_difference_t<Iterator>; using pointer = typename iterator_traits<Iterator>::pointer; using reference = iter_reference_t<Iterator>; constexpr reverse_iterator(); constexpr explicit reverse_iterator(Iterator x); template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u); template<class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u); constexpr Iterator base() const; constexpr reference operator*() const; constexpr pointer operator->() const requires *see below*; constexpr reverse_iterator& operator++(); constexpr reverse_iterator operator++(int); constexpr reverse_iterator& operator--(); constexpr reverse_iterator operator--(int); constexpr reverse_iterator operator+ (difference_type n) const; constexpr reverse_iterator& operator+=(difference_type n); constexpr reverse_iterator operator- (difference_type n) const; constexpr reverse_iterator& operator-=(difference_type n); constexpr *unspecified* operator[](difference_type n) const; friend constexpr iter_rvalue_reference_t<Iterator> iter_move(const reverse_iterator& i) noexcept(*see below*); template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<Iterator> Iterator2>friend constexpr void iter_swap(const reverse_iterator& x, const reverse_iterator<Iterator2>& y) noexcept(*see below*); protected: Iterator current; };}
[1](#reverse.iterator-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3237)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_concept denotes
- [(1.1)](#reverse.iterator-1.1)
random_access_iterator_tag if Iterator models[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]"), and
- [(1.2)](#reverse.iterator-1.2)
bidirectional_iterator_tag otherwise[.](#reverse.iterator-1.sentence-1)
[2](#reverse.iterator-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3247)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_category denotes
- [(2.1)](#reverse.iterator-2.1)
random_access_iterator_tag if
the typeiterator_traits<Iterator>::iterator_category models[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<random_access_iterator_tag>, and
- [(2.2)](#reverse.iterator-2.2)
iterator_traits<Iterator>::iterator_category otherwise[.](#reverse.iterator-2.sentence-1)
#### [24.5.1.3](#reverse.iter.requirements) Requirements [[reverse.iter.requirements]](reverse.iter.requirements)
[1](#reverse.iter.requirements-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3261)
The template parameterIterator shall either meet the requirements of a*Cpp17BidirectionalIterator* ([[bidirectional.iterators]](bidirectional.iterators "24.3.5.6Bidirectional iterators"))
or model[bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12Concept bidirectional_­iterator"))[.](#reverse.iter.requirements-1.sentence-1)
[2](#reverse.iter.requirements-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3269)
Additionally,Iterator shall either meet the requirements of a*Cpp17RandomAccessIterator* ([[random.access.iterators]](random.access.iterators "24.3.5.7Random access iterators"))
or model[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))
if the definitions of any of the members
- [(2.1)](#reverse.iter.requirements-2.1)
operator+,operator-,operator+=,operator-= ([[reverse.iter.nav]](#reverse.iter.nav "24.5.1.7Navigation")), or
- [(2.2)](#reverse.iter.requirements-2.2)
operator[] ([[reverse.iter.elem]](#reverse.iter.elem "24.5.1.6Element access")),
or the non-member operators ([[reverse.iter.cmp]](#reverse.iter.cmp "24.5.1.8Comparisons"))
- [(2.3)](#reverse.iter.requirements-2.3)
operator<,operator>,operator<=,operator>=,operator-,
oroperator+ ([[reverse.iter.nonmember]](#reverse.iter.nonmember "24.5.1.9Non-member functions"))
are instantiated ([[temp.inst]](temp.inst "13.9.2Implicit instantiation"))[.](#reverse.iter.requirements-2.sentence-1)
#### [24.5.1.4](#reverse.iter.cons) Construction and assignment [[reverse.iter.cons]](reverse.iter.cons)
[🔗](#lib:reverse_iterator,constructor)
`constexpr reverse_iterator();
`
[1](#reverse.iter.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3307)
*Effects*: Value-initializescurrent[.](#reverse.iter.cons-1.sentence-1)
[🔗](#lib:reverse_iterator,constructor_)
`constexpr explicit reverse_iterator(Iterator x);
`
[2](#reverse.iter.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3319)
*Effects*: Initializescurrent with x[.](#reverse.iter.cons-2.sentence-1)
[🔗](#lib:reverse_iterator,constructor__)
`template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
`
[3](#reverse.iter.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3332)
*Constraints*: is_same_v<U, Iterator> is false andconst U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator>[.](#reverse.iter.cons-3.sentence-1)
[4](#reverse.iter.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3337)
*Effects*: Initializescurrent withu.current[.](#reverse.iter.cons-4.sentence-1)
[🔗](#lib:operator=,reverse_iterator)
`template<class U>
constexpr reverse_iterator&
operator=(const reverse_iterator<U>& u);
`
[5](#reverse.iter.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3353)
*Constraints*: is_same_v<U, Iterator> is false,const U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator>, and[assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<Iterator&, const U&> is modeled[.](#reverse.iter.cons-5.sentence-1)
[6](#reverse.iter.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3359)
*Effects*: Assigns u.current to current[.](#reverse.iter.cons-6.sentence-1)
[7](#reverse.iter.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3363)
*Returns*: *this[.](#reverse.iter.cons-7.sentence-1)
#### [24.5.1.5](#reverse.iter.conv) Conversion [[reverse.iter.conv]](reverse.iter.conv)
[🔗](#lib:base,reverse_iterator)
`constexpr Iterator base() const;
`
[1](#reverse.iter.conv-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3376)
*Returns*: current[.](#reverse.iter.conv-1.sentence-1)
#### [24.5.1.6](#reverse.iter.elem) Element access [[reverse.iter.elem]](reverse.iter.elem)
[🔗](#lib:operator*,reverse_iterator)
`constexpr reference operator*() const;
`
[1](#reverse.iter.elem-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3389)
*Effects*: As if by:Iterator tmp = current;return *--tmp;
[🔗](#lib:operator-%3e,reverse_iterator)
`constexpr pointer operator->() const
requires (is_pointer_v<Iterator> ||
requires(const Iterator i) { i.operator->(); });
`
[2](#reverse.iter.elem-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3406)
*Effects*:
- [(2.1)](#reverse.iter.elem-2.1)
If Iterator is a pointer type, equivalent to:return prev(current);
- [(2.2)](#reverse.iter.elem-2.2)
Otherwise, equivalent to:return prev(current).operator->();
[🔗](#lib:operator%5b%5d,reverse_iterator)
`constexpr unspecified operator[](difference_type n) const;
`
[3](#reverse.iter.elem-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3423)
*Returns*: current[-n - 1][.](#reverse.iter.elem-3.sentence-1)
#### [24.5.1.7](#reverse.iter.nav) Navigation [[reverse.iter.nav]](reverse.iter.nav)
[🔗](#lib:operator+,reverse_iterator)
`constexpr reverse_iterator operator+(difference_type n) const;
`
[1](#reverse.iter.nav-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3436)
*Returns*: reverse_iterator(current - n)[.](#reverse.iter.nav-1.sentence-1)
[🔗](#lib:operator-,reverse_iterator)
`constexpr reverse_iterator operator-(difference_type n) const;
`
[2](#reverse.iter.nav-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3447)
*Returns*: reverse_iterator(current + n)[.](#reverse.iter.nav-2.sentence-1)
[🔗](#lib:operator++,reverse_iterator)
`constexpr reverse_iterator& operator++();
`
[3](#reverse.iter.nav-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3458)
*Effects*: As if by: --current;
[4](#reverse.iter.nav-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3462)
*Returns*: *this[.](#reverse.iter.nav-4.sentence-1)
[🔗](#lib:operator++,reverse_iterator_)
`constexpr reverse_iterator operator++(int);
`
[5](#reverse.iter.nav-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3473)
*Effects*: As if by:reverse_iterator tmp = *this;--current;return tmp;
[🔗](#lib:operator--,reverse_iterator)
`constexpr reverse_iterator& operator--();
`
[6](#reverse.iter.nav-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3489)
*Effects*: As if by ++current[.](#reverse.iter.nav-6.sentence-1)
[7](#reverse.iter.nav-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3493)
*Returns*: *this[.](#reverse.iter.nav-7.sentence-1)
[🔗](#lib:operator--,reverse_iterator_)
`constexpr reverse_iterator operator--(int);
`
[8](#reverse.iter.nav-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3504)
*Effects*: As if by:reverse_iterator tmp = *this;++current;return tmp;
[🔗](#lib:operator+=,reverse_iterator)
`constexpr reverse_iterator& operator+=(difference_type n);
`
[9](#reverse.iter.nav-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3520)
*Effects*: As if by: current -= n;
[10](#reverse.iter.nav-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3524)
*Returns*: *this[.](#reverse.iter.nav-10.sentence-1)
[🔗](#lib:operator-=,reverse_iterator)
`constexpr reverse_iterator& operator-=(difference_type n);
`
[11](#reverse.iter.nav-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3535)
*Effects*: As if by: current += n;
[12](#reverse.iter.nav-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3539)
*Returns*: *this[.](#reverse.iter.nav-12.sentence-1)
#### [24.5.1.8](#reverse.iter.cmp) Comparisons [[reverse.iter.cmp]](reverse.iter.cmp)
[🔗](#lib:operator==,reverse_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator==(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
`
[1](#reverse.iter.cmp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3555)
*Constraints*: x.base() == y.base() is well-formed and
convertible to bool[.](#reverse.iter.cmp-1.sentence-1)
[2](#reverse.iter.cmp-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3560)
*Returns*: x.base() == y.base()[.](#reverse.iter.cmp-2.sentence-1)
[🔗](#lib:operator!=,reverse_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator!=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
`
[3](#reverse.iter.cmp-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3574)
*Constraints*: x.base() != y.base() is well-formed and
convertible to bool[.](#reverse.iter.cmp-3.sentence-1)
[4](#reverse.iter.cmp-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3579)
*Returns*: x.base() != y.base()[.](#reverse.iter.cmp-4.sentence-1)
[🔗](#lib:operator%3c,reverse_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator<(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
`
[5](#reverse.iter.cmp-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3593)
*Constraints*: x.base() > y.base() is well-formed and
convertible to bool[.](#reverse.iter.cmp-5.sentence-1)
[6](#reverse.iter.cmp-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3598)
*Returns*: x.base() > y.base()[.](#reverse.iter.cmp-6.sentence-1)
[🔗](#lib:operator%3e,reverse_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator>(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
`
[7](#reverse.iter.cmp-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3612)
*Constraints*: x.base() < y.base() is well-formed and
convertible to bool[.](#reverse.iter.cmp-7.sentence-1)
[8](#reverse.iter.cmp-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3617)
*Returns*: x.base() < y.base()[.](#reverse.iter.cmp-8.sentence-1)
[🔗](#lib:operator%3c=,reverse_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator<=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
`
[9](#reverse.iter.cmp-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3631)
*Constraints*: x.base() >= y.base() is well-formed and
convertible to bool[.](#reverse.iter.cmp-9.sentence-1)
[10](#reverse.iter.cmp-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3636)
*Returns*: x.base() >= y.base()[.](#reverse.iter.cmp-10.sentence-1)
[🔗](#lib:operator%3e=,reverse_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator>=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
`
[11](#reverse.iter.cmp-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3650)
*Constraints*: x.base() <= y.base() is well-formed and
convertible to bool[.](#reverse.iter.cmp-11.sentence-1)
[12](#reverse.iter.cmp-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3655)
*Returns*: x.base() <= y.base()[.](#reverse.iter.cmp-12.sentence-1)
[🔗](#lib:operator%3c=%3e,reverse_iterator)
`template<class Iterator1, [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<Iterator1> Iterator2>
constexpr compare_three_way_result_t<Iterator1, Iterator2>
operator<=>(const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
`
[13](#reverse.iter.cmp-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3669)
*Returns*: y.base() <=> x.base()[.](#reverse.iter.cmp-13.sentence-1)
[14](#reverse.iter.cmp-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3673)
[*Note [1](#reverse.iter.cmp-note-1)*:
The argument order in the *Returns*: element is reversed
because this is a reverse iterator[.](#reverse.iter.cmp-14.sentence-1)
— *end note*]
#### [24.5.1.9](#reverse.iter.nonmember) Non-member functions [[reverse.iter.nonmember]](reverse.iter.nonmember)
[🔗](#lib:operator-,reverse_iterator_)
`template<class Iterator1, class Iterator2>
constexpr auto operator-(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
`
[1](#reverse.iter.nonmember-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3691)
*Returns*: y.base() - x.base()[.](#reverse.iter.nonmember-1.sentence-1)
[🔗](#lib:operator+,reverse_iterator_)
`template<class Iterator>
constexpr reverse_iterator<Iterator> operator+(
iter_difference_t<Iterator> n,
const reverse_iterator<Iterator>& x);
`
[2](#reverse.iter.nonmember-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3705)
*Returns*: reverse_iterator<Iterator>(x.base() - n)[.](#reverse.iter.nonmember-2.sentence-1)
[🔗](#lib:iter_move,reverse_iterator)
`friend constexpr iter_rvalue_reference_t<Iterator>
iter_move(const reverse_iterator& i) noexcept(see below);
`
[3](#reverse.iter.nonmember-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3717)
*Effects*: Equivalent to:auto tmp = i.base();return ranges::iter_move(--tmp);
[4](#reverse.iter.nonmember-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3725)
*Remarks*: The exception specification is equivalent to:is_nothrow_copy_constructible_v<Iterator> &&noexcept(ranges::iter_move(--declval<Iterator&>()))
[🔗](#lib:iter_swap,reverse_iterator)
`template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<Iterator> Iterator2>
friend constexpr void
iter_swap(const reverse_iterator& x,
const reverse_iterator<Iterator2>& y) noexcept(see below);
`
[5](#reverse.iter.nonmember-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3743)
*Effects*: Equivalent to:auto xtmp = x.base();auto ytmp = y.base();
ranges::iter_swap(--xtmp, --ytmp);
[6](#reverse.iter.nonmember-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3752)
*Remarks*: The exception specification is equivalent to:is_nothrow_copy_constructible_v<Iterator> && is_nothrow_copy_constructible_v<Iterator2> &&noexcept(ranges::iter_swap(--declval<Iterator&>(), --declval<Iterator2&>()))
[🔗](#lib:reverse_iterator,make_reverse_iterator_non-member_function)
`template<class Iterator>
constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
`
[7](#reverse.iter.nonmember-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3770)
*Returns*: reverse_iterator<Iterator>(i)[.](#reverse.iter.nonmember-7.sentence-1)
### [24.5.2](#insert.iterators) Insert iterators [[insert.iterators]](insert.iterators)
#### [24.5.2.1](#insert.iterators.general) General [[insert.iterators.general]](insert.iterators.general)
[1](#insert.iterators.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3779)
To make it possible to deal with insertion in the same way as writing into an array, a special kind of iterator
adaptors, called[*insert iterators*](#def:insert_iterators),
are provided in the library[.](#insert.iterators.general-1.sentence-1)
With regular iterator classes,while (first != last) *result++ = *first++; causes a range [first, last)
to be copied into a range starting with result[.](#insert.iterators.general-1.sentence-2)
The same code withresult being an insert iterator will insert corresponding elements into the container[.](#insert.iterators.general-1.sentence-3)
This device allows all of the
copying algorithms in the library to work in the[*insert mode*](#def:insert_mode) instead of the [*regular overwrite*](#def:regular_overwrite) mode[.](#insert.iterators.general-1.sentence-4)
[2](#insert.iterators.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3798)
An insert iterator is constructed from a container and possibly one of its iterators pointing to where
insertion takes place if it is neither at the beginning nor at the end of the container[.](#insert.iterators.general-2.sentence-1)
Insert iterators meet the requirements of output iterators[.](#insert.iterators.general-2.sentence-2)
operator* returns the insert iterator itself[.](#insert.iterators.general-2.sentence-3)
The assignmentoperator=(const T& x) is defined on insert iterators to allow writing into them, it insertsx right before where the insert iterator is pointing[.](#insert.iterators.general-2.sentence-4)
In other words, an insert iterator is like a cursor pointing into the
container where the insertion takes place[.](#insert.iterators.general-2.sentence-5)
back_insert_iterator inserts elements at the end of a container,front_insert_iterator inserts elements at the beginning of a container, andinsert_iterator inserts elements where the iterator points to in a container[.](#insert.iterators.general-2.sentence-6)
back_inserter,front_inserter,
andinserter are three
functions making the insert iterators out of a container[.](#insert.iterators.general-2.sentence-7)
#### [24.5.2.2](#back.insert.iterator) Class template back_insert_iterator [[back.insert.iterator]](back.insert.iterator)
#### [24.5.2.2.1](#back.insert.iter.general) General [[back.insert.iter.general]](back.insert.iter.general)
[🔗](#lib:back_insert_iterator)
namespace std {template<class Container>class back_insert_iterator {protected: Container* container; public:using iterator_category = output_iterator_tag; using value_type = void; using difference_type = ptrdiff_t; using pointer = void; using reference = void; using container_type = Container; constexpr explicit back_insert_iterator(Container& x); constexpr back_insert_iterator& operator=(const typename Container::value_type& value); constexpr back_insert_iterator& operator=(typename Container::value_type&& value); constexpr back_insert_iterator& operator*(); constexpr back_insert_iterator& operator++(); constexpr back_insert_iterator operator++(int); };}
#### [24.5.2.2.2](#back.insert.iter.ops) Operations [[back.insert.iter.ops]](back.insert.iter.ops)
[🔗](#lib:back_insert_iterator,constructor)
`constexpr explicit back_insert_iterator(Container& x);
`
[1](#back.insert.iter.ops-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3863)
*Effects*: Initializescontainer with addressof(x)[.](#back.insert.iter.ops-1.sentence-1)
[🔗](#lib:operator=,back_insert_iterator)
`constexpr back_insert_iterator& operator=(const typename Container::value_type& value);
`
[2](#back.insert.iter.ops-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3876)
*Effects*: As if by: container->push_back(value);
[3](#back.insert.iter.ops-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3880)
*Returns*: *this[.](#back.insert.iter.ops-3.sentence-1)
[🔗](#lib:operator=,back_insert_iterator_)
`constexpr back_insert_iterator& operator=(typename Container::value_type&& value);
`
[4](#back.insert.iter.ops-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3891)
*Effects*: As if by: container->push_back(std::move(value));
[5](#back.insert.iter.ops-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3895)
*Returns*: *this[.](#back.insert.iter.ops-5.sentence-1)
[🔗](#lib:operator*,back_insert_iterator)
`constexpr back_insert_iterator& operator*();
`
[6](#back.insert.iter.ops-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3906)
*Returns*: *this[.](#back.insert.iter.ops-6.sentence-1)
[🔗](#lib:operator++,back_insert_iterator)
`constexpr back_insert_iterator& operator++();
constexpr back_insert_iterator operator++(int);
`
[7](#back.insert.iter.ops-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3918)
*Returns*: *this[.](#back.insert.iter.ops-7.sentence-1)
#### [24.5.2.2.3](#back.inserter) back_inserter [[back.inserter]](back.inserter)
[🔗](#lib:back_inserter)
`template<class Container>
constexpr back_insert_iterator<Container> back_inserter(Container& x);
`
[1](#back.inserter-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3932)
*Returns*: back_insert_iterator<Container>(x)[.](#back.inserter-1.sentence-1)
#### [24.5.2.3](#front.insert.iterator) Class template front_insert_iterator [[front.insert.iterator]](front.insert.iterator)
#### [24.5.2.3.1](#front.insert.iter.general) General [[front.insert.iter.general]](front.insert.iter.general)
[🔗](#lib:front_insert_iterator)
namespace std {template<class Container>class front_insert_iterator {protected: Container* container; public:using iterator_category = output_iterator_tag; using value_type = void; using difference_type = ptrdiff_t; using pointer = void; using reference = void; using container_type = Container; constexpr explicit front_insert_iterator(Container& x); constexpr front_insert_iterator& operator=(const typename Container::value_type& value); constexpr front_insert_iterator& operator=(typename Container::value_type&& value); constexpr front_insert_iterator& operator*(); constexpr front_insert_iterator& operator++(); constexpr front_insert_iterator operator++(int); };}
#### [24.5.2.3.2](#front.insert.iter.ops) Operations [[front.insert.iter.ops]](front.insert.iter.ops)
[🔗](#lib:front_insert_iterator,constructor)
`constexpr explicit front_insert_iterator(Container& x);
`
[1](#front.insert.iter.ops-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3976)
*Effects*: Initializescontainer with addressof(x)[.](#front.insert.iter.ops-1.sentence-1)
[🔗](#lib:operator=,front_insert_iterator)
`constexpr front_insert_iterator& operator=(const typename Container::value_type& value);
`
[2](#front.insert.iter.ops-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3989)
*Effects*: As if by: container->push_front(value);
[3](#front.insert.iter.ops-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3993)
*Returns*: *this[.](#front.insert.iter.ops-3.sentence-1)
[🔗](#lib:operator=,front_insert_iterator_)
`constexpr front_insert_iterator& operator=(typename Container::value_type&& value);
`
[4](#front.insert.iter.ops-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4004)
*Effects*: As if by: container->push_front(std::move(value));
[5](#front.insert.iter.ops-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4008)
*Returns*: *this[.](#front.insert.iter.ops-5.sentence-1)
[🔗](#lib:operator*,front_insert_iterator)
`constexpr front_insert_iterator& operator*();
`
[6](#front.insert.iter.ops-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4019)
*Returns*: *this[.](#front.insert.iter.ops-6.sentence-1)
[🔗](#lib:operator++,front_insert_iterator)
`constexpr front_insert_iterator& operator++();
constexpr front_insert_iterator operator++(int);
`
[7](#front.insert.iter.ops-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4031)
*Returns*: *this[.](#front.insert.iter.ops-7.sentence-1)
#### [24.5.2.3.3](#front.inserter) front_inserter [[front.inserter]](front.inserter)
[🔗](#lib:front_inserter)
`template<class Container>
constexpr front_insert_iterator<Container> front_inserter(Container& x);
`
[1](#front.inserter-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4045)
*Returns*: front_insert_iterator<Container>(x)[.](#front.inserter-1.sentence-1)
#### [24.5.2.4](#insert.iterator) Class template insert_iterator [[insert.iterator]](insert.iterator)
#### [24.5.2.4.1](#insert.iter.general) General [[insert.iter.general]](insert.iter.general)
[🔗](#lib:insert_iterator)
namespace std {template<class Container>class insert_iterator {protected: Container* container;
ranges::iterator_t<Container> iter; public:using iterator_category = output_iterator_tag; using value_type = void; using difference_type = ptrdiff_t; using pointer = void; using reference = void; using container_type = Container; constexpr insert_iterator(Container& x, ranges::iterator_t<Container> i); constexpr insert_iterator& operator=(const typename Container::value_type& value); constexpr insert_iterator& operator=(typename Container::value_type&& value); constexpr insert_iterator& operator*(); constexpr insert_iterator& operator++(); constexpr insert_iterator& operator++(int); };}
#### [24.5.2.4.2](#insert.iter.ops) Operations [[insert.iter.ops]](insert.iter.ops)
[🔗](#lib:insert_iterator,constructor)
`constexpr insert_iterator(Container& x, ranges::iterator_t<Container> i);
`
[1](#insert.iter.ops-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4090)
*Effects*: Initializescontainer with addressof(x) anditer with i[.](#insert.iter.ops-1.sentence-1)
[🔗](#lib:operator=,insert_iterator)
`constexpr insert_iterator& operator=(const typename Container::value_type& value);
`
[2](#insert.iter.ops-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4105)
*Effects*: As if by:iter = container->insert(iter, value);++iter;
[3](#insert.iter.ops-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4113)
*Returns*: *this[.](#insert.iter.ops-3.sentence-1)
[🔗](#lib:operator=,insert_iterator_)
`constexpr insert_iterator& operator=(typename Container::value_type&& value);
`
[4](#insert.iter.ops-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4124)
*Effects*: As if by:iter = container->insert(iter, std::move(value));++iter;
[5](#insert.iter.ops-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4132)
*Returns*: *this[.](#insert.iter.ops-5.sentence-1)
[🔗](#lib:operator*,insert_iterator)
`constexpr insert_iterator& operator*();
`
[6](#insert.iter.ops-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4143)
*Returns*: *this[.](#insert.iter.ops-6.sentence-1)
[🔗](#lib:operator++,insert_iterator)
`constexpr insert_iterator& operator++();
constexpr insert_iterator& operator++(int);
`
[7](#insert.iter.ops-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4155)
*Returns*: *this[.](#insert.iter.ops-7.sentence-1)
#### [24.5.2.4.3](#inserter) inserter [[inserter]](inserter)
[🔗](#lib:inserter)
`template<class Container>
constexpr insert_iterator<Container>
inserter(Container& x, ranges::iterator_t<Container> i);
`
[1](#inserter-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4170)
*Returns*: insert_iterator<Container>(x, i)[.](#inserter-1.sentence-1)
### [24.5.3](#const.iterators) Constant iterators and sentinels [[const.iterators]](const.iterators)
#### [24.5.3.1](#const.iterators.general) General [[const.iterators.general]](const.iterators.general)
[1](#const.iterators.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4179)
Class template basic_const_iterator is an iterator adaptor
with the same behavior as the underlying iterator
except that its indirection operator implicitly converts
the value returned by the underlying iterator's indirection operator
to a type such that the adapted iterator is
a constant iterator ([[iterator.requirements]](iterator.requirements "24.3Iterator requirements"))[.](#const.iterators.general-1.sentence-1)
Some generic algorithms can be called with constant iterators to avoid mutation[.](#const.iterators.general-1.sentence-2)
[2](#const.iterators.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4188)
Specializations of basic_const_iterator are constant iterators[.](#const.iterators.general-2.sentence-1)
#### [24.5.3.2](#const.iterators.alias) Alias templates [[const.iterators.alias]](const.iterators.alias)
[🔗](#concept:constant-iterator)
`template<[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]") It>
using [iter_const_reference_t](#lib:iter_const_reference_t "24.5.3.2Alias templates[const.iterators.alias]") =
common_reference_t<const iter_value_t<It>&&, iter_reference_t<It>>;
template<class It>
concept [constant-iterator](#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]") = // exposition only
[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]")<It> && [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_const_reference_t<It>, iter_reference_t<It>>;
template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I>
using [const_iterator](#lib:const_iterator "24.5.3.2Alias templates[const.iterators.alias]") = see below;
`
[1](#const.iterators.alias-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4207)
*Result*: If I models [*constant-iterator*](#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]"), I[.](#const.iterators.alias-1.sentence-1)
Otherwise, basic_const_iterator<I>[.](#const.iterators.alias-1.sentence-2)
[🔗](#const.iterators.alias-itemdecl:2)
`template<[semiregular](concepts.object#concept:semiregular "18.6Object concepts[concepts.object]") S>
using [const_sentinel](#lib:const_sentinel "24.5.3.2Alias templates[const.iterators.alias]") = see below;
`
[2](#const.iterators.alias-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4219)
*Result*: If S models [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]"), const_iterator<S>[.](#const.iterators.alias-2.sentence-1)
Otherwise, S[.](#const.iterators.alias-2.sentence-2)
#### [24.5.3.3](#const.iterators.iterator) Class template basic_const_iterator [[const.iterators.iterator]](const.iterators.iterator)
namespace std {template<class I>concept [*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") = *see below*; // *exposition only*template<[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]") I>using *iter-const-rvalue-reference-t* = // *exposition only* common_reference_t<const iter_value_t<I>&&, iter_rvalue_reference_t<I>>; template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") Iterator>class [basic_const_iterator](#lib:basic_const_iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") { Iterator *current_* = Iterator(); // *exposition only*using *reference* = iter_const_reference_t<Iterator>; // *exposition only*using *rvalue-reference* = // *exposition only**iter-const-rvalue-reference-t*<Iterator>; public:using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = iter_value_t<Iterator>; using difference_type = iter_difference_t<Iterator>;
basic_const_iterator() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept default_­initializable[concept.default.init]")<Iterator> = default; constexpr basic_const_iterator(Iterator current); template<[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator> U>constexpr basic_const_iterator(basic_const_iterator<U> current); template<[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> T>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, Iterator>constexpr basic_const_iterator(T&& current); constexpr const Iterator& base() const & noexcept; constexpr Iterator base() &&; constexpr *reference* operator*() const; constexpr const auto* operator->() constrequires is_lvalue_reference_v<iter_reference_t<Iterator>> &&[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<remove_cvref_t<iter_reference_t<Iterator>>, value_type>; constexpr basic_const_iterator& operator++(); constexpr void operator++(int); constexpr basic_const_iterator operator++(int) requires [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]")<Iterator>; constexpr basic_const_iterator& operator--() requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<Iterator>; constexpr basic_const_iterator operator--(int) requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<Iterator>; constexpr basic_const_iterator& operator+=(difference_type n)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; constexpr basic_const_iterator& operator-=(difference_type n)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; constexpr *reference* operator[](difference_type n) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; template<[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<Iterator> S>constexpr bool operator==(const S& s) const; template<[*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") CI>requires [*constant-iterator*](#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]")<CI> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator const&, CI>constexpr operator CI() const &; template<[*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") CI>requires [*constant-iterator*](#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]")<CI> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator, CI>constexpr operator CI() &&; constexpr bool operator<(const basic_const_iterator& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; constexpr bool operator>(const basic_const_iterator& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; constexpr bool operator<=(const basic_const_iterator& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; constexpr bool operator>=(const basic_const_iterator& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; constexpr auto operator<=>(const basic_const_iterator& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<Iterator>; template<[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>constexpr bool operator<(const I& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; template<[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>constexpr bool operator>(const I& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; template<[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>constexpr bool operator<=(const I& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; template<[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>constexpr bool operator>=(const I& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; template<[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>constexpr auto operator<=>(const I& y) constrequires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I> &&[three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<Iterator, I>; template<[*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>friend constexpr bool operator<(const I& x, const basic_const_iterator& y)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; template<[*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>friend constexpr bool operator>(const I& x, const basic_const_iterator& y)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; template<[*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>friend constexpr bool operator<=(const I& x, const basic_const_iterator& y)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; template<[*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>friend constexpr bool operator>=(const I& x, const basic_const_iterator& y)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>; friend constexpr basic_const_iterator operator+(const basic_const_iterator& i,
difference_type n)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; friend constexpr basic_const_iterator operator+(difference_type n, const basic_const_iterator& i)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; friend constexpr basic_const_iterator operator-(const basic_const_iterator& i,
difference_type n)requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>; template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Iterator> S>constexpr difference_type operator-(const S& y) const; template<[*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") S>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, Iterator>friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y); friend constexpr *rvalue-reference* iter_move(const basic_const_iterator& i)noexcept(noexcept(static_cast<*rvalue-reference*>(ranges::iter_move(i.*current_*)))){return static_cast<*rvalue-reference*>(ranges::iter_move(i.*current_*)); }};}
[1](#const.iterators.iterator-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4353)
Given some type I,
the concept [*not-a-const-iterator*](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") is defined as false if I is a specialization of basic_const_iterator andtrue otherwise[.](#const.iterators.iterator-1.sentence-1)
#### [24.5.3.4](#const.iterators.types) Member types [[const.iterators.types]](const.iterators.types)
[1](#const.iterators.types-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4361)
basic_const_iterator<Iterator>::iterator_concept is defined as follows:
- [(1.1)](#const.iterators.types-1.1)
If Iterator models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]"),
then iterator_concept denotes contiguous_iterator_tag[.](#const.iterators.types-1.1.sentence-1)
- [(1.2)](#const.iterators.types-1.2)
Otherwise, if Iterator models [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]"),
then iterator_concept denotes random_access_iterator_tag[.](#const.iterators.types-1.2.sentence-1)
- [(1.3)](#const.iterators.types-1.3)
Otherwise, if Iterator models [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]"),
then iterator_concept denotes bidirectional_iterator_tag[.](#const.iterators.types-1.3.sentence-1)
- [(1.4)](#const.iterators.types-1.4)
Otherwise, if Iterator models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]"),
then iterator_concept denotes forward_iterator_tag[.](#const.iterators.types-1.4.sentence-1)
- [(1.5)](#const.iterators.types-1.5)
Otherwise, iterator_concept denotes input_iterator_tag[.](#const.iterators.types-1.5.sentence-1)
[2](#const.iterators.types-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4380)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_category is defined
if and only if Iterator models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]")[.](#const.iterators.types-2.sentence-1)
In that case,basic_const_iterator<Iterator>::iterator_category denotes
the type iterator_traits<Iterator>::iterator_category[.](#const.iterators.types-2.sentence-2)
#### [24.5.3.5](#const.iterators.ops) Operations [[const.iterators.ops]](const.iterators.ops)
[🔗](#lib:basic_const_iterator,constructor)
`constexpr basic_const_iterator(Iterator current);
`
[1](#const.iterators.ops-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4395)
*Effects*: Initializes *current_* with std::move(current)[.](#const.iterators.ops-1.sentence-1)
[🔗](#lib:basic_const_iterator,constructor_)
`template<[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator> U>
constexpr basic_const_iterator(basic_const_iterator<U> current);
`
[2](#const.iterators.ops-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4407)
*Effects*: Initializes *current_* with std::move(current.*current_*)[.](#const.iterators.ops-2.sentence-1)
[🔗](#lib:basic_const_iterator,constructor__)
`template<[different-from](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> T>
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, Iterator>
constexpr basic_const_iterator(T&& current);
`
[3](#const.iterators.ops-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4421)
*Effects*: Initializes *current_* with std::forward<T>(current)[.](#const.iterators.ops-3.sentence-1)
[🔗](#lib:base,basic_const_iterator)
`constexpr const Iterator& base() const & noexcept;
`
[4](#const.iterators.ops-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4432)
*Effects*: Equivalent to: return *current_*;
[🔗](#lib:base,basic_const_iterator_)
`constexpr Iterator base() &&;
`
[5](#const.iterators.ops-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4443)
*Effects*: Equivalent to: return std::move(*current_*);
[🔗](#lib:operator*,basic_const_iterator)
`constexpr reference operator*() const;
`
[6](#const.iterators.ops-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4454)
*Effects*: Equivalent to: return static_cast<*reference*>(**current_*);
[🔗](#lib:operator-%3e,basic_const_iterator)
`constexpr const auto* operator->() const
requires is_lvalue_reference_v<iter_reference_t<Iterator>> &&
[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<remove_cvref_t<iter_reference_t<Iterator>>, value_type>;
`
[7](#const.iterators.ops-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4467)
*Returns*: If Iterator models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]"),to_address(*current_*);
otherwise, addressof(**current_*)[.](#const.iterators.ops-7.sentence-1)
[🔗](#lib:operator++,basic_const_iterator)
`constexpr basic_const_iterator& operator++();
`
[8](#const.iterators.ops-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4480)
*Effects*: Equivalent to:++*current_*;return *this;
[🔗](#lib:operator++,basic_const_iterator_)
`constexpr void operator++(int);
`
[9](#const.iterators.ops-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4495)
*Effects*: Equivalent to: ++*current_*;
[🔗](#lib:operator++,basic_const_iterator__)
`constexpr basic_const_iterator operator++(int) requires [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]")<Iterator>;
`
[10](#const.iterators.ops-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4506)
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
[🔗](#lib:operator--,basic_const_iterator)
`constexpr basic_const_iterator& operator--() requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<Iterator>;
`
[11](#const.iterators.ops-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4522)
*Effects*: Equivalent to:--*current_*;return *this;
[🔗](#lib:operator--,basic_const_iterator_)
`constexpr basic_const_iterator operator--(int) requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<Iterator>;
`
[12](#const.iterators.ops-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4537)
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
[🔗](#lib:operator+=,basic_const_iterator)
`constexpr basic_const_iterator& operator+=(difference_type n)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
constexpr basic_const_iterator& operator-=(difference_type n)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
`
[13](#const.iterators.ops-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4557)
Let *op* be the operator[.](#const.iterators.ops-13.sentence-1)
[14](#const.iterators.ops-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4560)
*Effects*: Equivalent to:*current_* *op* n;return *this;
[🔗](#lib:operator%5b%5d,basic_const_iterator)
`constexpr reference operator[](difference_type n) const requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>
`
[15](#const.iterators.ops-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4575)
*Effects*: Equivalent to: return static_cast<*reference*>(*current_*[n]);
[🔗](#lib:operator==,basic_const_iterator)
`template<[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<Iterator> S>
constexpr bool operator==(const S& s) const;
`
[16](#const.iterators.ops-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4587)
*Effects*: Equivalent to: return *current_* == s;
[🔗](#const.iterators.ops-itemdecl:16)
`template<[not-a-const-iterator](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") CI>
requires [constant-iterator](#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]")<CI> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator const&, CI>
constexpr operator CI() const &;
`
[17](#const.iterators.ops-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4599)
*Returns*: *current_*[.](#const.iterators.ops-17.sentence-1)
[🔗](#const.iterators.ops-itemdecl:17)
`template<[not-a-const-iterator](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") CI>
requires [constant-iterator](#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]")<CI> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator, CI>
constexpr operator CI() &&;
`
[18](#const.iterators.ops-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4611)
*Returns*: std::move(*current_*)[.](#const.iterators.ops-18.sentence-1)
[🔗](#lib:operator%3c,basic_const_iterator)
`constexpr bool operator<(const basic_const_iterator& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
constexpr bool operator>(const basic_const_iterator& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
constexpr bool operator<=(const basic_const_iterator& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
constexpr bool operator>=(const basic_const_iterator& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
constexpr auto operator<=>(const basic_const_iterator& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<Iterator>;
`
[19](#const.iterators.ops-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4635)
Let *op* be the operator[.](#const.iterators.ops-19.sentence-1)
[20](#const.iterators.ops-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4638)
*Effects*: Equivalent to:return *current_* *op* *y.current_*;
[🔗](#lib:operator%3c,basic_const_iterator_)
`template<[different-from](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>
constexpr bool operator<(const I& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
template<[different-from](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>
constexpr bool operator>(const I& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
template<[different-from](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>
constexpr bool operator<=(const I& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
template<[different-from](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>
constexpr bool operator>=(const I& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
template<[different-from](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<basic_const_iterator> I>
constexpr auto operator<=>(const I& y) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I> &&
[three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<Iterator, I>;
`
[21](#const.iterators.ops-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4669)
Let *op* be the operator[.](#const.iterators.ops-21.sentence-1)
[22](#const.iterators.ops-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4672)
*Effects*: Equivalent to: return *current_* *op* y;
[🔗](#lib:operator%3c,basic_const_iterator__)
`template<[not-a-const-iterator](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>
friend constexpr bool operator<(const I& x, const basic_const_iterator& y)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
template<[not-a-const-iterator](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>
friend constexpr bool operator>(const I& x, const basic_const_iterator& y)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
template<[not-a-const-iterator](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>
friend constexpr bool operator<=(const I& x, const basic_const_iterator& y)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
template<[not-a-const-iterator](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") I>
friend constexpr bool operator>=(const I& x, const basic_const_iterator& y)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator> && [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<Iterator, I>;
`
[23](#const.iterators.ops-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4697)
Let *op* be the operator[.](#const.iterators.ops-23.sentence-1)
[24](#const.iterators.ops-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4700)
*Effects*: Equivalent to: return x *op* y.*current_*;
[🔗](#lib:operator+,basic_const_iterator)
`friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, difference_type n)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
friend constexpr basic_const_iterator operator+(difference_type n, const basic_const_iterator& i)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
`
[25](#const.iterators.ops-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4714)
*Effects*: Equivalent to: return basic_const_iterator(i.*current_* + n);
[🔗](#lib:operator-,basic_const_iterator)
`friend constexpr basic_const_iterator operator-(const basic_const_iterator& i, difference_type n)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<Iterator>;
`
[26](#const.iterators.ops-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4726)
*Effects*: Equivalent to: return basic_const_iterator(i.*current_* - n);
[🔗](#lib:operator-,basic_const_iterator_)
`template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Iterator> S>
constexpr difference_type operator-(const S& y) const;
`
[27](#const.iterators.ops-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4738)
*Effects*: Equivalent to: return *current_* - y;
[🔗](#lib:operator-,basic_const_iterator__)
`template<[not-a-const-iterator](#concept:not-a-const-iterator "24.5.3.3Class template basic_­const_­iterator[const.iterators.iterator]") S>
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, Iterator>
friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y);
`
[28](#const.iterators.ops-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4751)
*Effects*: Equivalent to: return x - y.*current_*;
### [24.5.4](#move.iterators) Move iterators and sentinels [[move.iterators]](move.iterators)
#### [24.5.4.1](#move.iterators.general) General [[move.iterators.general]](move.iterators.general)
[1](#move.iterators.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4760)
Class template move_iterator is an iterator adaptor
with the same behavior as the underlying iterator except that its
indirection operator implicitly converts the value returned by the
underlying iterator's indirection operator to an rvalue[.](#move.iterators.general-1.sentence-1)
Some generic algorithms can be called with move iterators to replace
copying with moving[.](#move.iterators.general-1.sentence-2)
[2](#move.iterators.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4768)
[*Example [1](#move.iterators.general-example-1)*: list<string> s;// populate the list s vector<string> v1(s.begin(), s.end()); // copies strings into v1 vector<string> v2(make_move_iterator(s.begin()),
make_move_iterator(s.end())); // moves strings into v2 — *end example*]
#### [24.5.4.2](#move.iterator) Class template move_iterator [[move.iterator]](move.iterator)
[🔗](#lib:move_iterator)
namespace std {template<class Iterator>class move_iterator {public:using iterator_type = Iterator; using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = iter_value_t<Iterator>; using difference_type = iter_difference_t<Iterator>; using pointer = Iterator; using reference = iter_rvalue_reference_t<Iterator>; constexpr move_iterator(); constexpr explicit move_iterator(Iterator i); template<class U> constexpr move_iterator(const move_iterator<U>& u); template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u); constexpr const Iterator& base() const & noexcept; constexpr Iterator base() &&; constexpr reference operator*() const; constexpr move_iterator& operator++(); constexpr auto operator++(int); constexpr move_iterator& operator--(); constexpr move_iterator operator--(int); constexpr move_iterator operator+(difference_type n) const; constexpr move_iterator& operator+=(difference_type n); constexpr move_iterator operator-(difference_type n) const; constexpr move_iterator& operator-=(difference_type n); constexpr reference operator[](difference_type n) const; template<[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<Iterator> S>friend constexpr booloperator==(const move_iterator& x, const move_sentinel<S>& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Iterator> S>friend constexpr iter_difference_t<Iterator>operator-(const move_sentinel<S>& x, const move_iterator& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Iterator> S>friend constexpr iter_difference_t<Iterator>operator-(const move_iterator& x, const move_sentinel<S>& y); friend constexpr iter_rvalue_reference_t<Iterator> iter_move(const move_iterator& i)noexcept(noexcept(ranges::iter_move(i.current))); template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<Iterator> Iterator2>friend constexpr void iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y)noexcept(noexcept(ranges::iter_swap(x.current, y.current))); private: Iterator current; // *exposition only*};}
[1](#move.iterator-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4838)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_concept is defined
as follows:
- [(1.1)](#move.iterator-1.1)
If Iterator models [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]"),
then iterator_concept denotes random_access_iterator_tag[.](#move.iterator-1.1.sentence-1)
- [(1.2)](#move.iterator-1.2)
Otherwise, if Iterator models [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]"),
then iterator_concept denotes bidirectional_iterator_tag[.](#move.iterator-1.2.sentence-1)
- [(1.3)](#move.iterator-1.3)
Otherwise, if Iterator models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]"),
then iterator_concept denotes forward_iterator_tag[.](#move.iterator-1.3.sentence-1)
- [(1.4)](#move.iterator-1.4)
Otherwise, iterator_concept denotes input_iterator_tag[.](#move.iterator-1.4.sentence-1)
[2](#move.iterator-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4855)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_category is defined
if and only if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]")iterator_traits<Iterator>::iterator_category is valid and denotes a type[.](#move.iterator-2.sentence-1)
In that case, iterator_category denotes
- [(2.1)](#move.iterator-2.1)
random_access_iterator_tag if
the typeiterator_traits<Iterator>::iterator_category models[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<random_access_iterator_tag>, and
- [(2.2)](#move.iterator-2.2)
iterator_traits<Iterator>::iterator_category otherwise[.](#move.iterator-2.sentence-2)
#### [24.5.4.3](#move.iter.requirements) Requirements [[move.iter.requirements]](move.iter.requirements)
[1](#move.iter.requirements-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4873)
The template parameter Iterator shall either
meet the *Cpp17InputIterator* requirements ([[input.iterators]](input.iterators "24.3.5.3Input iterators"))
or model [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") ([[iterator.concept.input]](iterator.concept.input "24.3.4.9Concept input_­iterator"))[.](#move.iter.requirements-1.sentence-1)
Additionally, if any of the bidirectional traversal
functions are instantiated, the template parameter shall either
meet the *Cpp17BidirectionalIterator* requirements ([[bidirectional.iterators]](bidirectional.iterators "24.3.5.6Bidirectional iterators"))
or model [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12Concept bidirectional_­iterator"))[.](#move.iter.requirements-1.sentence-2)
If any of the random access traversal functions are instantiated, the
template parameter shall either
meet the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7Random access iterators"))
or model[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))[.](#move.iter.requirements-1.sentence-3)
#### [24.5.4.4](#move.iter.cons) Construction and assignment [[move.iter.cons]](move.iter.cons)
[🔗](#lib:move_iterator,constructor)
`constexpr move_iterator();
`
[1](#move.iter.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4895)
*Effects*: Value-initializes current[.](#move.iter.cons-1.sentence-1)
[🔗](#lib:move_iterator,constructor_)
`constexpr explicit move_iterator(Iterator i);
`
[2](#move.iter.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4907)
*Effects*: Initializes current with std::move(i)[.](#move.iter.cons-2.sentence-1)
[🔗](#lib:move_iterator,constructor__)
`template<class U> constexpr move_iterator(const move_iterator<U>& u);
`
[3](#move.iter.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4919)
*Constraints*: is_same_v<U, Iterator> is false andconst U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator>[.](#move.iter.cons-3.sentence-1)
[4](#move.iter.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4924)
*Effects*: Initializes current with u.current[.](#move.iter.cons-4.sentence-1)
[🔗](#lib:operator=,move_iterator)
`template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
`
[5](#move.iter.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4935)
*Constraints*: is_same_v<U, Iterator> is false,const U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<Iterator>, and[assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<Iterator&, const U&> is modeled[.](#move.iter.cons-5.sentence-1)
[6](#move.iter.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4941)
*Effects*: Assigns u.current tocurrent[.](#move.iter.cons-6.sentence-1)
[7](#move.iter.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4946)
*Returns*: *this[.](#move.iter.cons-7.sentence-1)
#### [24.5.4.5](#move.iter.op.conv) Conversion [[move.iter.op.conv]](move.iter.op.conv)
[🔗](#lib:base,move_iterator)
`constexpr const Iterator& base() const & noexcept;
`
[1](#move.iter.op.conv-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4959)
*Returns*: current[.](#move.iter.op.conv-1.sentence-1)
[🔗](#lib:base,move_iterator_)
`constexpr Iterator base() &&;
`
[2](#move.iter.op.conv-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4970)
*Returns*: std::move(current)[.](#move.iter.op.conv-2.sentence-1)
#### [24.5.4.6](#move.iter.elem) Element access [[move.iter.elem]](move.iter.elem)
[🔗](#lib:operator*,move_iterator)
`constexpr reference operator*() const;
`
[1](#move.iter.elem-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4983)
*Effects*: Equivalent to: return ranges::iter_move(current);
[🔗](#lib:operator%5b%5d,move_iterator)
`constexpr reference operator[](difference_type n) const;
`
[2](#move.iter.elem-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4994)
*Effects*: Equivalent to: return ranges::iter_move(current + n);
#### [24.5.4.7](#move.iter.nav) Navigation [[move.iter.nav]](move.iter.nav)
[🔗](#lib:operator++,move_iterator)
`constexpr move_iterator& operator++();
`
[1](#move.iter.nav-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5007)
*Effects*: As if by ++current[.](#move.iter.nav-1.sentence-1)
[2](#move.iter.nav-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5011)
*Returns*: *this[.](#move.iter.nav-2.sentence-1)
[🔗](#lib:operator++,move_iterator_)
`constexpr auto operator++(int);
`
[3](#move.iter.nav-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5022)
*Effects*: If Iterator models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]"), equivalent to:move_iterator tmp = *this;++current;return tmp;
Otherwise, equivalent to ++current[.](#move.iter.nav-3.sentence-2)
[🔗](#lib:operator--,move_iterator)
`constexpr move_iterator& operator--();
`
[4](#move.iter.nav-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5039)
*Effects*: As if by --current[.](#move.iter.nav-4.sentence-1)
[5](#move.iter.nav-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5043)
*Returns*: *this[.](#move.iter.nav-5.sentence-1)
[🔗](#lib:operator--,move_iterator_)
`constexpr move_iterator operator--(int);
`
[6](#move.iter.nav-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5054)
*Effects*: As if by:move_iterator tmp = *this;--current;return tmp;
[🔗](#lib:operator+,move_iterator)
`constexpr move_iterator operator+(difference_type n) const;
`
[7](#move.iter.nav-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5070)
*Returns*: move_iterator(current + n)[.](#move.iter.nav-7.sentence-1)
[🔗](#lib:operator+=,move_iterator)
`constexpr move_iterator& operator+=(difference_type n);
`
[8](#move.iter.nav-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5081)
*Effects*: As if by: current += n;
[9](#move.iter.nav-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5085)
*Returns*: *this[.](#move.iter.nav-9.sentence-1)
[🔗](#lib:operator-,move_iterator)
`constexpr move_iterator operator-(difference_type n) const;
`
[10](#move.iter.nav-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5096)
*Returns*: move_iterator(current - n)[.](#move.iter.nav-10.sentence-1)
[🔗](#lib:operator-=,move_iterator)
`constexpr move_iterator& operator-=(difference_type n);
`
[11](#move.iter.nav-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5107)
*Effects*: As if by: current -= n;
[12](#move.iter.nav-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5111)
*Returns*: *this[.](#move.iter.nav-12.sentence-1)
#### [24.5.4.8](#move.iter.op.comp) Comparisons [[move.iter.op.comp]](move.iter.op.comp)
[🔗](#lib:operator==,move_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator==(const move_iterator<Iterator1>& x,
const move_iterator<Iterator2>& y);
template<[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<Iterator> S>
friend constexpr bool operator==(const move_iterator& x,
const move_sentinel<S>& y);
`
[1](#move.iter.op.comp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5129)
*Constraints*: x.base() == y.base() is well-formed and
convertible to bool[.](#move.iter.op.comp-1.sentence-1)
[2](#move.iter.op.comp-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5134)
*Returns*: x.base() == y.base()[.](#move.iter.op.comp-2.sentence-1)
[🔗](#lib:operator%3c,move_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
`
[3](#move.iter.op.comp-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5146)
*Constraints*: x.base() < y.base() is well-formed and
convertible to bool[.](#move.iter.op.comp-3.sentence-1)
[4](#move.iter.op.comp-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5151)
*Returns*: x.base() < y.base()[.](#move.iter.op.comp-4.sentence-1)
[🔗](#lib:operator%3e,move_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
`
[5](#move.iter.op.comp-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5163)
*Constraints*: y.base() < x.base() is well-formed and
convertible to bool[.](#move.iter.op.comp-5.sentence-1)
[6](#move.iter.op.comp-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5168)
*Returns*: y < x[.](#move.iter.op.comp-6.sentence-1)
[🔗](#lib:operator%3c=,move_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
`
[7](#move.iter.op.comp-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5180)
*Constraints*: y.base() < x.base() is well-formed and
convertible to bool[.](#move.iter.op.comp-7.sentence-1)
[8](#move.iter.op.comp-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5185)
*Returns*: !(y < x)[.](#move.iter.op.comp-8.sentence-1)
[🔗](#lib:operator%3e=,move_iterator)
`template<class Iterator1, class Iterator2>
constexpr bool operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
`
[9](#move.iter.op.comp-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5197)
*Constraints*: x.base() < y.base() is well-formed and
convertible to bool[.](#move.iter.op.comp-9.sentence-1)
[10](#move.iter.op.comp-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5202)
*Returns*: !(x < y)[.](#move.iter.op.comp-10.sentence-1)
[🔗](#lib:operator%3c=%3e,move_iterator)
`template<class Iterator1, [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<Iterator1> Iterator2>
constexpr compare_three_way_result_t<Iterator1, Iterator2>
operator<=>(const move_iterator<Iterator1>& x,
const move_iterator<Iterator2>& y);
`
[11](#move.iter.op.comp-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5216)
*Returns*: x.base() <=> y.base()[.](#move.iter.op.comp-11.sentence-1)
#### [24.5.4.9](#move.iter.nonmember) Non-member functions [[move.iter.nonmember]](move.iter.nonmember)
[🔗](#lib:operator-,move_iterator_)
`template<class Iterator1, class Iterator2>
constexpr auto operator-(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y)
-> decltype(x.base() - y.base());
template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Iterator> S>
friend constexpr iter_difference_t<Iterator>
operator-(const move_sentinel<S>& x, const move_iterator& y);
template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<Iterator> S>
friend constexpr iter_difference_t<Iterator>
operator-(const move_iterator& x, const move_sentinel<S>& y);
`
[1](#move.iter.nonmember-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5238)
*Returns*: x.base() - y.base()[.](#move.iter.nonmember-1.sentence-1)
[🔗](#lib:operator+,move_iterator_)
`template<class Iterator>
constexpr move_iterator<Iterator>
operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);
`
[2](#move.iter.nonmember-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5251)
*Constraints*: x.base() + n is well-formed and has type Iterator[.](#move.iter.nonmember-2.sentence-1)
[3](#move.iter.nonmember-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5255)
*Returns*: x + n[.](#move.iter.nonmember-3.sentence-1)
[🔗](#lib:iter_move,move_iterator)
`friend constexpr iter_rvalue_reference_t<Iterator>
iter_move(const move_iterator& i)
noexcept(noexcept(ranges::iter_move(i.current)));
`
[4](#move.iter.nonmember-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5268)
*Effects*: Equivalent to: return ranges::iter_move(i.current);
[🔗](#lib:iter_swap,move_iterator)
`template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<Iterator> Iterator2>
friend constexpr void
iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y)
noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
`
[5](#move.iter.nonmember-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5282)
*Effects*: Equivalent to: ranges::iter_swap(x.current, y.current)[.](#move.iter.nonmember-5.sentence-1)
[🔗](#lib:make_move_iterator)
`template<class Iterator>
constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
`
[6](#move.iter.nonmember-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5294)
*Returns*: move_iterator<Iterator>(std::move(i))[.](#move.iter.nonmember-6.sentence-1)
#### [24.5.4.10](#move.sentinel) Class template move_sentinel [[move.sentinel]](move.sentinel)
[1](#move.sentinel-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5301)
Class template move_sentinel is a sentinel adaptor useful for denoting
ranges together with move_iterator[.](#move.sentinel-1.sentence-1)
When an input iterator typeI and sentinel type S model [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I>,move_sentinel<S> and move_iterator<I> model[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<move_sentinel<S>, move_iterator<I>> as well[.](#move.sentinel-1.sentence-2)
[2](#move.sentinel-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5308)
[*Example [1](#move.sentinel-example-1)*:
A move_if algorithm is easily implemented withcopy_if using move_iterator and move_sentinel:template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") O, [indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3Indirect callables[indirectcallable.indirectinvocable]")<I> Pred>requires [indirectly_movable](alg.req.ind.move#concept:indirectly_movable "24.3.7.2Concept indirectly_­movable[alg.req.ind.move]")<I, O>void move_if(I first, S last, O out, Pred pred) { ranges::copy_if(move_iterator<I>{std::move(first)}, move_sentinel<S>{last},
std::move(out), pred);}
— *end example*]
[🔗](#lib:move_sentinel)
namespace std {template<[semiregular](concepts.object#concept:semiregular "18.6Object concepts[concepts.object]") S>class move_sentinel {public:constexpr move_sentinel(); constexpr explicit move_sentinel(S s); template<class S2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const S2&, S>constexpr move_sentinel(const move_sentinel<S2>& s); template<class S2>requires [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<S&, const S2&>constexpr move_sentinel& operator=(const move_sentinel<S2>& s); constexpr S base() const; private: S last; // *exposition only*};}
#### [24.5.4.11](#move.sent.ops) Operations [[move.sent.ops]](move.sent.ops)
[🔗](#lib:move_sentinel,constructor)
`constexpr move_sentinel();
`
[1](#move.sent.ops-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5354)
*Effects*: Value-initializes last[.](#move.sent.ops-1.sentence-1)
If is_trivially_default_constructible_v<S> is true,
then this constructor is a constexpr constructor[.](#move.sent.ops-1.sentence-2)
[🔗](#lib:move_sentinel,constructor_)
`constexpr explicit move_sentinel(S s);
`
[2](#move.sent.ops-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5367)
*Effects*: Initializes last with std::move(s)[.](#move.sent.ops-2.sentence-1)
[🔗](#lib:move_sentinel,constructor__)
`template<class S2>
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const S2&, S>
constexpr move_sentinel(const move_sentinel<S2>& s);
`
[3](#move.sent.ops-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5380)
*Effects*: Initializes last with s.last[.](#move.sent.ops-3.sentence-1)
[🔗](#lib:operator=,move_sentinel)
`template<class S2>
requires [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<S&, const S2&>
constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
`
[4](#move.sent.ops-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5394)
*Effects*: Equivalent to: last = s.last; return *this;
[🔗](#lib:base,move_sentinel)
`constexpr S base() const;
`
[5](#move.sent.ops-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5405)
*Returns*: last[.](#move.sent.ops-5.sentence-1)
### [24.5.5](#iterators.common) Common iterators [[iterators.common]](iterators.common)
#### [24.5.5.1](#common.iterator) Class template common_iterator [[common.iterator]](common.iterator)
[1](#common.iterator-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5414)
Class template common_iterator is an iterator/sentinel adaptor that is
capable of representing a non-common range of elements (where the types of the
iterator and sentinel differ) as a common range (where they are the same)[.](#common.iterator-1.sentence-1)
It
does this by holding either an iterator or a sentinel, and implementing the
equality comparison operators appropriately[.](#common.iterator-1.sentence-2)
[2](#common.iterator-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5421)
[*Note [1](#common.iterator-note-1)*:
The common_iterator type is useful for interfacing with legacy
code that expects the begin and end of a range to have the same type[.](#common.iterator-2.sentence-1)
— *end note*]
[3](#common.iterator-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5427)
[*Example [1](#common.iterator-example-1)*: template<class ForwardIterator>void fun(ForwardIterator begin, ForwardIterator end);
list<int> s;// populate the list susing CI = common_iterator<counted_iterator<list<int>::iterator>, default_sentinel_t>;// call fun on a range of 10 ints fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel)); — *end example*]
[🔗](#lib:common_iterator)
namespace std {template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S>requires (![same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I, S> && [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]")<I>)class common_iterator {public:constexpr common_iterator() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept default_­initializable[concept.default.init]")<I> = default; constexpr common_iterator(I i); constexpr common_iterator(S s); template<class I2, class S2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const S2&, S>constexpr common_iterator(const common_iterator<I2, S2>& x); template<class I2, class S2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const S2&, S> &&[assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<I&, const I2&> && [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<S&, const S2&>constexpr common_iterator& operator=(const common_iterator<I2, S2>& x); constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() constrequires [*dereferenceable*](iterator.synopsis#concept:dereferenceable "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]")<const I>; constexpr auto operator->() constrequires *see below*; constexpr common_iterator& operator++(); constexpr decltype(auto) operator++(int); template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S2>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S2>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I2> && [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<I, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S2>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I2>friend constexpr iter_difference_t<I2> operator-(const common_iterator& x, const common_iterator<I2, S2>& y); friend constexpr decltype(auto) iter_move(const common_iterator& i)noexcept(noexcept(ranges::iter_move(declval<const I&>())))requires [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]")<I>; template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<I> I2, class S2>friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>()))); private: variant<I, S> v_; // *exposition only*}; template<class I, class S>struct incrementable_traits<common_iterator<I, S>> {using difference_type = iter_difference_t<I>; }; template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I, class S>struct iterator_traits<common_iterator<I, S>> {using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = iter_value_t<I>; using difference_type = iter_difference_t<I>; using pointer = *see below*; using reference = iter_reference_t<I>; };}
#### [24.5.5.2](#common.iter.types) Associated types [[common.iter.types]](common.iter.types)
[1](#common.iter.types-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5513)
The nested [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_category of
the specialization of iterator_traits for common_iterator<I, S> is defined if and only if iter_difference_t<I> is an integral type[.](#common.iter.types-1.sentence-1)
In that case,iterator_category denotes forward_iterator_tag if
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") iterator_traits<I>::iterator_category is valid and denotes a type that
models [derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<forward_iterator_tag>;
otherwise it denotes input_iterator_tag[.](#common.iter.types-1.sentence-2)
[2](#common.iter.types-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5524)
The remaining nested [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s* of the specialization ofiterator_traits for common_iterator<I, S> are defined as follows:
- [(2.1)](#common.iter.types-2.1)
iterator_concept denotes forward_iterator_tag if I models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]");
otherwise it denotes input_iterator_tag[.](#common.iter.types-2.1.sentence-1)
- [(2.2)](#common.iter.types-2.2)
Let a denote an lvalue of type const common_iterator<I, S>[.](#common.iter.types-2.2.sentence-1)
If the expression a.operator->() is well-formed,
then pointer denotes decltype(a.operator->())[.](#common.iter.types-2.2.sentence-2)
Otherwise, pointer denotes void[.](#common.iter.types-2.2.sentence-3)
#### [24.5.5.3](#common.iter.const) Constructors and conversions [[common.iter.const]](common.iter.const)
[🔗](#lib:common_iterator,constructor)
`constexpr common_iterator(I i);
`
[1](#common.iter.const-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5548)
*Effects*: Initializes v_ as if by v_{in_place_type<I>, std::move(i)}[.](#common.iter.const-1.sentence-1)
[🔗](#lib:common_iterator,constructor_)
`constexpr common_iterator(S s);
`
[2](#common.iter.const-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5559)
*Effects*: Initializes v_ as if byv_{in_place_type<S>, std::move(s)}[.](#common.iter.const-2.sentence-1)
[🔗](#lib:common_iterator,constructor__)
`template<class I2, class S2>
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const S2&, S>
constexpr common_iterator(const common_iterator<I2, S2>& x);
`
[3](#common.iter.const-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5573)
*Hardened preconditions*: x.v_.valueless_by_exception() is false[.](#common.iter.const-3.sentence-1)
[4](#common.iter.const-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5577)
*Effects*: Initializes v_ as if byv_{in_place_index<i>, get<i>(x.v_)},
where i is x.v_.index()[.](#common.iter.const-4.sentence-1)
[🔗](#lib:operator=,common_iterator)
`template<class I2, class S2>
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const S2&, S> &&
[assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<I&, const I2&> && [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<S&, const S2&>
constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
`
[5](#common.iter.const-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5593)
*Hardened preconditions*: x.v_.valueless_by_exception() is false[.](#common.iter.const-5.sentence-1)
[6](#common.iter.const-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5597)
*Effects*: Equivalent to:
- [(6.1)](#common.iter.const-6.1)
If v_.index() == x.v_.index(), thenget<i>(v_) = get<i>(x.v_)[.](#common.iter.const-6.1.sentence-1)
- [(6.2)](#common.iter.const-6.2)
Otherwise, v_.emplace<i>(get<i>(x.v_))[.](#common.iter.const-6.2.sentence-1)
where i is x.v_.index()[.](#common.iter.const-6.sentence-2)
[7](#common.iter.const-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5608)
*Returns*: *this[.](#common.iter.const-7.sentence-1)
#### [24.5.5.4](#common.iter.access) Accessors [[common.iter.access]](common.iter.access)
[🔗](#lib:operator*,common_iterator)
`constexpr decltype(auto) operator*();
constexpr decltype(auto) operator*() const
requires [dereferenceable](iterator.synopsis#concept:dereferenceable "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]")<const I>;
`
[1](#common.iter.access-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5623)
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.access-1.sentence-1)
[2](#common.iter.access-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5627)
*Effects*: Equivalent to: return *get<I>(v_);
[🔗](#lib:operator-%3e,common_iterator)
`constexpr auto operator->() const
requires see below;
`
[3](#common.iter.access-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5639)
The expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]") is equivalent to:[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]")<const I> &&(requires(const I& i) { i.operator->(); } || is_reference_v<iter_reference_t<I>> ||[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<iter_value_t<I>, iter_reference_t<I>>)
[4](#common.iter.access-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5648)
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.access-4.sentence-1)
[5](#common.iter.access-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5652)
*Effects*:
- [(5.1)](#common.iter.access-5.1)
If I is a pointer type or if the expressionget<I>(v_).operator->() is
well-formed, equivalent to: return get<I>(v_);
- [(5.2)](#common.iter.access-5.2)
Otherwise, if iter_reference_t<I> is a reference type, equivalent to:auto&& tmp = *get<I>(v_);return addressof(tmp);
- [(5.3)](#common.iter.access-5.3)
Otherwise, equivalent to:return *proxy*(*get<I>(v_)); where*proxy* is the exposition-only class:class *proxy* { iter_value_t<I> keep_; constexpr *proxy*(iter_reference_t<I>&& x): keep_(std::move(x)) {}public:constexpr const iter_value_t<I>* operator->() const noexcept {return addressof(keep_); }};
#### [24.5.5.5](#common.iter.nav) Navigation [[common.iter.nav]](common.iter.nav)
[🔗](#lib:operator++,common_iterator)
`constexpr common_iterator& operator++();
`
[1](#common.iter.nav-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5693)
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.nav-1.sentence-1)
[2](#common.iter.nav-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5697)
*Effects*: Equivalent to ++get<I>(v_)[.](#common.iter.nav-2.sentence-1)
[3](#common.iter.nav-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5701)
*Returns*: *this[.](#common.iter.nav-3.sentence-1)
[🔗](#lib:operator++,common_iterator_)
`constexpr decltype(auto) operator++(int);
`
[4](#common.iter.nav-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5712)
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.nav-4.sentence-1)
[5](#common.iter.nav-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5716)
*Effects*: If I models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]"), equivalent to:common_iterator tmp = *this;++*this;return tmp;
Otherwise, ifrequires(I& i) { { *i++ } -> [*can-reference*](iterator.synopsis#concept:can-reference "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]"); } is true or[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2Concept indirectly_­readable[iterator.concept.readable]")<I> && [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<iter_value_t<I>, iter_reference_t<I>> &&[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13Concept move_­constructible[concept.moveconstructible]")<iter_value_t<I>> is false,
equivalent to:return get<I>(v_)++;
Otherwise, equivalent to:*postfix-proxy* p(**this);++*this;return p; where *postfix-proxy* is the exposition-only class:class *postfix-proxy* { iter_value_t<I> keep_; constexpr *postfix-proxy*(iter_reference_t<I>&& x): keep_(std::forward<iter_reference_t<I>>(x)) {}public:constexpr const iter_value_t<I>& operator*() const noexcept {return keep_; }};
#### [24.5.5.6](#common.iter.cmp) Comparisons [[common.iter.cmp]](common.iter.cmp)
[🔗](#lib:operator==,common_iterator)
`template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S2>
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I2>
friend constexpr bool operator==(
const common_iterator& x, const common_iterator<I2, S2>& y);
`
[1](#common.iter.cmp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5767)
*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-1.sentence-1)
[2](#common.iter.cmp-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5772)
*Returns*: true if i == j,
and otherwise get<i>(x.v_) == get<j>(y.v_),
where i is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-2.sentence-1)
[🔗](#lib:operator==,common_iterator_)
`template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S2>
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I2> && [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<I, I2>
friend constexpr bool operator==(
const common_iterator& x, const common_iterator<I2, S2>& y);
`
[3](#common.iter.cmp-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5788)
*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-3.sentence-1)
[4](#common.iter.cmp-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5793)
*Returns*: true if i and j are each 1, and otherwiseget<i>(x.v_) == get<j>(y.v_), wherei is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-4.sentence-1)
[🔗](#lib:operator-,common_iterator)
`template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S2>
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I2>
friend constexpr iter_difference_t<I2> operator-(
const common_iterator& x, const common_iterator<I2, S2>& y);
`
[5](#common.iter.cmp-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5809)
*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-5.sentence-1)
[6](#common.iter.cmp-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5814)
*Returns*: 0 if i and j are each 1, and otherwiseget<i>(x.v_) - get<j>(y.v_), wherei is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-6.sentence-1)
#### [24.5.5.7](#common.iter.cust) Customizations [[common.iter.cust]](common.iter.cust)
[🔗](#lib:iter_move,common_iterator)
`friend constexpr decltype(auto) iter_move(const common_iterator& i)
noexcept(noexcept(ranges::iter_move(declval<const I&>())))
requires [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]")<I>;
`
[1](#common.iter.cust-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5831)
*Hardened preconditions*: holds_alternative<I>(i.v_) is true[.](#common.iter.cust-1.sentence-1)
[2](#common.iter.cust-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5835)
*Effects*: Equivalent to: return ranges::iter_move(get<I>(i.v_));
[🔗](#lib:iter_swap,common_iterator)
`template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<I> I2, class S2>
friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
`
[3](#common.iter.cust-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5848)
*Hardened preconditions*: holds_alternative<I>(x.v_) and holds_alternative<I2>(y.v_) are each true[.](#common.iter.cust-3.sentence-1)
[4](#common.iter.cust-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5853)
*Effects*: Equivalent to ranges::iter_swap(get<I>(x.v_), get<I2>(y.v_))[.](#common.iter.cust-4.sentence-1)
### [24.5.6](#default.sentinel) Default sentinel [[default.sentinel]](default.sentinel)
[🔗](#lib:default_sentinel_t)
`namespace std {
struct default_sentinel_t { };
}
`
[1](#default.sentinel-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5867)
Class default_sentinel_t is an empty type used to denote the end of a
range[.](#default.sentinel-1.sentence-1)
It can be used together with iterator types that know the bound
of their range (e.g., counted_iterator ([[counted.iterator]](#counted.iterator "24.5.7.1Class template counted_­iterator")))[.](#default.sentinel-1.sentence-2)
### [24.5.7](#iterators.counted) Counted iterators [[iterators.counted]](iterators.counted)
#### [24.5.7.1](#counted.iterator) Class template counted_iterator [[counted.iterator]](counted.iterator)
[1](#counted.iterator-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[.](#counted.iterator-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[.](#counted.iterator-1.sentence-2)
[2](#counted.iterator-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5885)
[*Example [1](#counted.iterator-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](#counted.iterator-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[.](#counted.iterator-3.sentence-1)
[🔗](#lib:counted_iterator)
namespace std {template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept 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.2Concept 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.3Qualified 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.3Qualified 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.12Concept 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.4Concept 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.8Concept 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.2Header <iterator>&nbsp;synopsis[iterator.synopsis]")<const I>; constexpr auto operator->() const noexceptrequires [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept 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.11Concept forward_­iterator[iterator.concept.forward]")<I>; constexpr counted_iterator& operator--()requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<I>; constexpr counted_iterator operator--(int)requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept 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.13Concept 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.13Concept 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.13Concept 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.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>; template<[common_with](concept.common#concept:common_with "18.4.6Concept 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.13Concept 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.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>; template<[common_with](concept.common#concept:common_with "18.4.6Concept 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.6Concept 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.9Concept input_­iterator[iterator.concept.input]")<I>; template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept 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.9Concept input_­iterator[iterator.concept.input]") I>requires [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<*ITER_TRAITS*(I), iterator_traits<I>> // see [[iterator.concepts.general]](iterator.concepts.general "24.3.4.1General")struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {using pointer = conditional_t<[contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")<I>,
add_pointer_t<iter_reference_t<I>>, void>; };}
#### [24.5.7.2](#counted.iter.const) Constructors and conversions [[counted.iter.const]](counted.iter.const)
[🔗](#lib:counted_iterator,constructor)
`constexpr counted_iterator(I i, iter_difference_t<I> n);
`
[1](#counted.iter.const-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6013)
*Hardened preconditions*: n >= 0 is true[.](#counted.iter.const-1.sentence-1)
[2](#counted.iter.const-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6017)
*Effects*: Initializes current with std::move(i) andlength with n[.](#counted.iter.const-2.sentence-1)
[🔗](#lib:counted_iterator,constructor_)
`template<class I2>
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const I2&, I>
constexpr counted_iterator(const counted_iterator<I2>& x);
`
[3](#counted.iter.const-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6031)
*Effects*: Initializes current with x.current andlength with x.length[.](#counted.iter.const-3.sentence-1)
[🔗](#lib:operator=,counted_iterator)
`template<class I2>
requires [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<I&, const I2&>
constexpr counted_iterator& operator=(const counted_iterator<I2>& x);
`
[4](#counted.iter.const-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6045)
*Effects*: Assigns x.current to current andx.length to length[.](#counted.iter.const-4.sentence-1)
[5](#counted.iter.const-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6050)
*Returns*: *this[.](#counted.iter.const-5.sentence-1)
#### [24.5.7.3](#counted.iter.access) Accessors [[counted.iter.access]](counted.iter.access)
[🔗](#lib:base,counted_iterator)
`constexpr const I& base() const & noexcept;
`
[1](#counted.iter.access-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6063)
*Effects*: Equivalent to: return current;
[🔗](#lib:base,counted_iterator_)
`constexpr I base() &&;
`
[2](#counted.iter.access-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6074)
*Returns*: std::move(current)[.](#counted.iter.access-2.sentence-1)
[🔗](#lib:count,counted_iterator)
`constexpr iter_difference_t<I> count() const noexcept;
`
[3](#counted.iter.access-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6085)
*Effects*: Equivalent to: return length;
#### [24.5.7.4](#counted.iter.elem) Element access [[counted.iter.elem]](counted.iter.elem)
[🔗](#lib:operator*,counted_iterator)
`constexpr decltype(auto) operator*();
constexpr decltype(auto) operator*() const
requires [dereferenceable](iterator.synopsis#concept:dereferenceable "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]")<const I>;
`
[1](#counted.iter.elem-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6100)
*Hardened preconditions*: length > 0 is true[.](#counted.iter.elem-1.sentence-1)
[2](#counted.iter.elem-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6104)
*Effects*: Equivalent to: return *current;
[🔗](#lib:operator-%3e,counted_iterator)
`constexpr auto operator->() const noexcept
requires [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")<I>;
`
[3](#counted.iter.elem-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6116)
*Effects*: Equivalent to: return to_address(current);
[🔗](#lib:operator%5b%5d,counted_iterator)
`constexpr decltype(auto) operator[](iter_difference_t<I> n) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>;
`
[4](#counted.iter.elem-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6128)
*Hardened preconditions*: n < length is true[.](#counted.iter.elem-4.sentence-1)
[5](#counted.iter.elem-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6132)
*Effects*: Equivalent to: return current[n];
#### [24.5.7.5](#counted.iter.nav) Navigation [[counted.iter.nav]](counted.iter.nav)
[🔗](#lib:operator++,counted_iterator)
`constexpr counted_iterator& operator++();
`
[1](#counted.iter.nav-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6145)
*Hardened preconditions*: length > 0 is true[.](#counted.iter.nav-1.sentence-1)
[2](#counted.iter.nav-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6149)
*Effects*: Equivalent to:++current;--length;return *this;
[🔗](#lib:operator++,counted_iterator_)
`constexpr decltype(auto) operator++(int);
`
[3](#counted.iter.nav-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6165)
*Hardened preconditions*: length > 0 is true[.](#counted.iter.nav-3.sentence-1)
[4](#counted.iter.nav-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6169)
*Effects*: Equivalent to:--length;try { return current++; }catch(...) { ++length; throw; }
[🔗](#lib:operator++,counted_iterator__)
`constexpr counted_iterator operator++(int)
requires [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]")<I>;
`
[5](#counted.iter.nav-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6186)
*Effects*: Equivalent to:counted_iterator tmp = *this;++*this;return tmp;
[🔗](#lib:operator--,counted_iterator)
`constexpr counted_iterator& operator--()
requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<I>;
`
[6](#counted.iter.nav-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6203)
*Effects*: Equivalent to:--current;++length;return *this;
[🔗](#lib:operator--,counted_iterator_)
`constexpr counted_iterator operator--(int)
requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<I>;
`
[7](#counted.iter.nav-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6220)
*Effects*: Equivalent to:counted_iterator tmp = *this;--*this;return tmp;
[🔗](#lib:operator+,counted_iterator)
`constexpr counted_iterator operator+(iter_difference_t<I> n) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>;
`
[8](#counted.iter.nav-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6237)
*Effects*: Equivalent to: return counted_iterator(current + n, length - n);
[🔗](#lib:operator+,counted_iterator_)
`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.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>;
`
[9](#counted.iter.nav-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6250)
*Effects*: Equivalent to: return x + n;
[🔗](#lib:operator+=,counted_iterator)
`constexpr counted_iterator& operator+=(iter_difference_t<I> n)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>;
`
[10](#counted.iter.nav-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6262)
*Hardened preconditions*: n <= length is true[.](#counted.iter.nav-10.sentence-1)
[11](#counted.iter.nav-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6266)
*Effects*: Equivalent to:current += n;
length -= n;return *this;
[🔗](#lib:operator-,counted_iterator)
`constexpr counted_iterator operator-(iter_difference_t<I> n) const
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>;
`
[12](#counted.iter.nav-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6283)
*Effects*: Equivalent to: return counted_iterator(current - n, length + n);
[🔗](#lib:operator-,counted_iterator_)
`template<[common_with](concept.common#concept:common_with "18.4.6Concept common_­with[concept.common]")<I> I2>
friend constexpr iter_difference_t<I2> operator-(
const counted_iterator& x, const counted_iterator<I2>& y);
`
[13](#counted.iter.nav-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6296)
*Preconditions*: x and y refer to elements of the same
sequence ([[counted.iterator]](#counted.iterator "24.5.7.1Class template counted_­iterator"))[.](#counted.iter.nav-13.sentence-1)
[14](#counted.iter.nav-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6301)
*Effects*: Equivalent to: return y.length - x.length;
[🔗](#lib:operator-,counted_iterator__)
`friend constexpr iter_difference_t<I> operator-(
const counted_iterator& x, default_sentinel_t) noexcept;
`
[15](#counted.iter.nav-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6313)
*Effects*: Equivalent to:return -x.length;
[🔗](#lib:operator-,counted_iterator___)
`friend constexpr iter_difference_t<I> operator-(
default_sentinel_t, const counted_iterator& y) noexcept;
`
[16](#counted.iter.nav-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6326)
*Effects*: Equivalent to: return y.length;
[🔗](#lib:operator-=,counted_iterator)
`constexpr counted_iterator& operator-=(iter_difference_t<I> n)
requires [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]")<I>;
`
[17](#counted.iter.nav-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6338)
*Hardened preconditions*: -n <= length is true[.](#counted.iter.nav-17.sentence-1)
[18](#counted.iter.nav-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6342)
*Effects*: Equivalent to:current -= n;
length += n;return *this;
#### [24.5.7.6](#counted.iter.cmp) Comparisons [[counted.iter.cmp]](counted.iter.cmp)
[🔗](#lib:operator==,counted_iterator)
`template<[common_with](concept.common#concept:common_with "18.4.6Concept common_­with[concept.common]")<I> I2>
friend constexpr bool operator==(
const counted_iterator& x, const counted_iterator<I2>& y);
`
[1](#counted.iter.cmp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6362)
*Preconditions*: x and y refer to
elements of the same sequence ([[counted.iterator]](#counted.iterator "24.5.7.1Class template counted_­iterator"))[.](#counted.iter.cmp-1.sentence-1)
[2](#counted.iter.cmp-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6367)
*Effects*: Equivalent to: return x.length == y.length;
[🔗](#lib:operator==,counted_iterator_)
`friend constexpr bool operator==(
const counted_iterator& x, default_sentinel_t) noexcept;
`
[3](#counted.iter.cmp-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6379)
*Effects*: Equivalent to: return x.length == 0;
[🔗](#lib:operator%3c=%3e,counted_iterator)
`template<[common_with](concept.common#concept:common_with "18.4.6Concept common_­with[concept.common]")<I> I2>
friend constexpr strong_ordering operator<=>(
const counted_iterator& x, const counted_iterator<I2>& y);
`
[4](#counted.iter.cmp-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6392)
*Preconditions*: x and y refer to
elements of the same sequence ([[counted.iterator]](#counted.iterator "24.5.7.1Class template counted_­iterator"))[.](#counted.iter.cmp-4.sentence-1)
[5](#counted.iter.cmp-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6397)
*Effects*: Equivalent to: return y.length <=> x.length;
[6](#counted.iter.cmp-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6401)
[*Note [1](#counted.iter.cmp-note-1)*:
The argument order in the *Effects*: element is reversed
because length counts down, not up[.](#counted.iter.cmp-6.sentence-1)
— *end note*]
#### [24.5.7.7](#counted.iter.cust) Customizations [[counted.iter.cust]](counted.iter.cust)
[🔗](#lib:iter_move,counted_iterator)
`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.9Concept input_­iterator[iterator.concept.input]")<I>;
`
[1](#counted.iter.cust-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6419)
*Hardened preconditions*: i.length > 0 is true[.](#counted.iter.cust-1.sentence-1)
[2](#counted.iter.cust-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6423)
*Effects*: Equivalent to: return ranges::iter_move(i.current);
[🔗](#lib:iter_swap,counted_iterator)
`template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept 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)));
`
[3](#counted.iter.cust-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6437)
*Hardened preconditions*: Both x.length > 0 and y.length > 0 are true[.](#counted.iter.cust-3.sentence-1)
[4](#counted.iter.cust-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6441)
*Effects*: Equivalent to ranges::iter_swap(x.current, y.current)[.](#counted.iter.cust-4.sentence-1)
### [24.5.8](#unreachable.sentinel) Unreachable sentinel [[unreachable.sentinel]](unreachable.sentinel)
[1](#unreachable.sentinel-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6449)
Class unreachable_sentinel_t can be used with
any [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") type
to denote the “upper bound” of an unbounded interval[.](#unreachable.sentinel-1.sentence-1)
[2](#unreachable.sentinel-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6454)
[*Example [1](#unreachable.sentinel-example-1)*: char* p;// set p to point to a character buffer containing newlineschar* nl = find(p, unreachable_sentinel, '\n');
Provided a newline character really exists in the buffer, the use ofunreachable_sentinel above potentially makes the call to find more
efficient since the loop test against the sentinel does not require a
conditional branch[.](#unreachable.sentinel-2.sentence-1)
— *end example*]
[🔗](#lib:operator==,unreachable_sentinel_t)
namespace std {struct unreachable_sentinel_t {template<[weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") I>friend constexpr bool operator==(unreachable_sentinel_t, const I&) noexcept{ return false; }};}