[reverse.iterators] # 24 Iterators library [[iterators]](./#iterators) ## 24.5 Iterator adaptors [[predef.iterators]](predef.iterators#reverse.iterators) ### 24.5.1 Reverse iterators [reverse.iterators] #### [24.5.1.1](#general) General [[reverse.iterators.general]](reverse.iterators.general) [1](#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[.](#general-1.sentence-1) #### [24.5.1.2](#reverse.iterator) Class template reverse_iterator [[reverse.iterator]](reverse.iterator) [🔗](#lib:reverse_iterator) namespace std {templateclass reverse_iterator {public:using iterator_type = Iterator; using iterator_concept = *see below*; using iterator_category = *see below*; using value_type = iter_value_t; using difference_type = iter_difference_t; using pointer = typename iterator_traits::pointer; using reference = iter_reference_t; constexpr reverse_iterator(); constexpr explicit reverse_iterator(Iterator x); template constexpr reverse_iterator(const reverse_iterator& u); template constexpr reverse_iterator& operator=(const reverse_iterator& 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 iter_move(const reverse_iterator& i) noexcept(*see below*); template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]") Iterator2>friend constexpr void iter_swap(const reverse_iterator& x, const reverse_iterator& 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.4 The 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.13 Concept 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.4 The 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.3 Concept derived_­from [concept.derived]"), 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.6 Bidirectional iterators")) or model[bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_­iterator [iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12 Concept 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.7 Random access iterators")) or model[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13 Concept 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.7 Navigation")), or - [(2.2)](#reverse.iter.requirements-2.2) operator[] ([[reverse.iter.elem]](#reverse.iter.elem "24.5.1.6 Element access")), or the non-member operators ([[reverse.iter.cmp]](#reverse.iter.cmp "24.5.1.8 Comparisons")) - [(2.3)](#reverse.iter.requirements-2.3) operator<,operator>,operator<=,operator>=,operator-, oroperator+ ([[reverse.iter.nonmember]](#reverse.iter.nonmember "24.5.1.9 Non-member functions")) are instantiated ([[temp.inst]](temp.inst "13.9.2 Implicit 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 constexpr reverse_iterator(const reverse_iterator& u); ` [3](#reverse.iter.cons-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3332) *Constraints*: is_same_v is false andconst U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")[.](#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 constexpr reverse_iterator& operator=(const reverse_iterator& u); ` [5](#reverse.iter.cons-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3353) *Constraints*: is_same_v is false,const U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"), and[assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]") 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 || 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 constexpr bool operator==( const reverse_iterator& x, const reverse_iterator& 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 constexpr bool operator!=( const reverse_iterator& x, const reverse_iterator& 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 constexpr bool operator<( const reverse_iterator& x, const reverse_iterator& 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 constexpr bool operator>( const reverse_iterator& x, const reverse_iterator& 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 constexpr bool operator<=( const reverse_iterator& x, const reverse_iterator& 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 constexpr bool operator>=( const reverse_iterator& x, const reverse_iterator& 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 Iterator2> constexpr compare_three_way_result_t operator<=>(const reverse_iterator& x, const reverse_iterator& 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 constexpr auto operator-( const reverse_iterator& x, const reverse_iterator& 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 constexpr reverse_iterator operator+( iter_difference_t n, const reverse_iterator& x); ` [2](#reverse.iter.nonmember-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3705) *Returns*: reverse_iterator(x.base() - n)[.](#reverse.iter.nonmember-2.sentence-1) [🔗](#lib:iter_move,reverse_iterator) `friend constexpr iter_rvalue_reference_t 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 &&noexcept(ranges::iter_move(--declval())) [🔗](#lib:iter_swap,reverse_iterator) `template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]") Iterator2> friend constexpr void iter_swap(const reverse_iterator& x, const reverse_iterator& 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 && is_nothrow_copy_constructible_v &&noexcept(ranges::iter_swap(--declval(), --declval())) [🔗](#lib:reverse_iterator,make_reverse_iterator_non-member_function) `template constexpr reverse_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(i)[.](#reverse.iter.nonmember-7.sentence-1)