1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* An iterator that acts like another iterator, but iterating in
8 * the negative direction. (Note that not all iterators can iterate
9 * in the negative direction.) */
11 #ifndef mozilla_ReverseIterator_h
12 #define mozilla_ReverseIterator_h
16 #include "mozilla/Attributes.h"
20 template <typename IteratorT
>
21 class ReverseIterator
{
23 template <typename Iterator
>
24 explicit ReverseIterator(Iterator aIter
) : mCurrent(aIter
) {}
26 template <typename Iterator
>
27 MOZ_IMPLICIT
ReverseIterator(const ReverseIterator
<Iterator
>& aOther
)
28 : mCurrent(aOther
.mCurrent
) {}
30 decltype(*std::declval
<IteratorT
>()) operator*() const {
31 IteratorT tmp
= mCurrent
;
35 /* Increments and decrements operators */
37 ReverseIterator
& operator++() {
41 ReverseIterator
& operator--() {
45 ReverseIterator
operator++(int) {
50 ReverseIterator
operator--(int) {
56 /* Comparison operators */
58 template <typename Iterator1
, typename Iterator2
>
59 friend bool operator==(const ReverseIterator
<Iterator1
>& aIter1
,
60 const ReverseIterator
<Iterator2
>& aIter2
);
61 template <typename Iterator1
, typename Iterator2
>
62 friend bool operator!=(const ReverseIterator
<Iterator1
>& aIter1
,
63 const ReverseIterator
<Iterator2
>& aIter2
);
64 template <typename Iterator1
, typename Iterator2
>
65 friend bool operator<(const ReverseIterator
<Iterator1
>& aIter1
,
66 const ReverseIterator
<Iterator2
>& aIter2
);
67 template <typename Iterator1
, typename Iterator2
>
68 friend bool operator<=(const ReverseIterator
<Iterator1
>& aIter1
,
69 const ReverseIterator
<Iterator2
>& aIter2
);
70 template <typename Iterator1
, typename Iterator2
>
71 friend bool operator>(const ReverseIterator
<Iterator1
>& aIter1
,
72 const ReverseIterator
<Iterator2
>& aIter2
);
73 template <typename Iterator1
, typename Iterator2
>
74 friend bool operator>=(const ReverseIterator
<Iterator1
>& aIter1
,
75 const ReverseIterator
<Iterator2
>& aIter2
);
81 template <typename Iterator1
, typename Iterator2
>
82 bool operator==(const ReverseIterator
<Iterator1
>& aIter1
,
83 const ReverseIterator
<Iterator2
>& aIter2
) {
84 return aIter1
.mCurrent
== aIter2
.mCurrent
;
87 template <typename Iterator1
, typename Iterator2
>
88 bool operator!=(const ReverseIterator
<Iterator1
>& aIter1
,
89 const ReverseIterator
<Iterator2
>& aIter2
) {
90 return aIter1
.mCurrent
!= aIter2
.mCurrent
;
93 template <typename Iterator1
, typename Iterator2
>
94 bool operator<(const ReverseIterator
<Iterator1
>& aIter1
,
95 const ReverseIterator
<Iterator2
>& aIter2
) {
96 return aIter1
.mCurrent
> aIter2
.mCurrent
;
99 template <typename Iterator1
, typename Iterator2
>
100 bool operator<=(const ReverseIterator
<Iterator1
>& aIter1
,
101 const ReverseIterator
<Iterator2
>& aIter2
) {
102 return aIter1
.mCurrent
>= aIter2
.mCurrent
;
105 template <typename Iterator1
, typename Iterator2
>
106 bool operator>(const ReverseIterator
<Iterator1
>& aIter1
,
107 const ReverseIterator
<Iterator2
>& aIter2
) {
108 return aIter1
.mCurrent
< aIter2
.mCurrent
;
111 template <typename Iterator1
, typename Iterator2
>
112 bool operator>=(const ReverseIterator
<Iterator1
>& aIter1
,
113 const ReverseIterator
<Iterator2
>& aIter2
) {
114 return aIter1
.mCurrent
<= aIter2
.mCurrent
;
119 template <typename IteratorT
>
120 class IteratorRange
{
122 typedef IteratorT iterator
;
123 typedef IteratorT const_iterator
;
124 typedef ReverseIterator
<IteratorT
> reverse_iterator
;
125 typedef ReverseIterator
<IteratorT
> const_reverse_iterator
;
127 template <typename Iterator1
, typename Iterator2
>
128 MOZ_IMPLICIT
IteratorRange(Iterator1 aIterBegin
, Iterator2 aIterEnd
)
129 : mIterBegin(aIterBegin
), mIterEnd(aIterEnd
) {}
131 template <typename Iterator
>
132 MOZ_IMPLICIT
IteratorRange(const IteratorRange
<Iterator
>& aOther
)
133 : mIterBegin(aOther
.mIterBegin
), mIterEnd(aOther
.mIterEnd
) {}
135 iterator
begin() const { return mIterBegin
; }
136 const_iterator
cbegin() const { return begin(); }
137 iterator
end() const { return mIterEnd
; }
138 const_iterator
cend() const { return end(); }
139 reverse_iterator
rbegin() const { return reverse_iterator(mIterEnd
); }
140 const_reverse_iterator
crbegin() const { return rbegin(); }
141 reverse_iterator
rend() const { return reverse_iterator(mIterBegin
); }
142 const_reverse_iterator
crend() const { return rend(); }
145 IteratorT mIterBegin
;
149 } // namespace detail
151 template <typename Range
>
152 detail::IteratorRange
<typename
Range::reverse_iterator
> Reversed(
154 return {aRange
.rbegin(), aRange
.rend()};
157 template <typename Range
>
158 detail::IteratorRange
<typename
Range::const_reverse_iterator
> Reversed(
159 const Range
& aRange
) {
160 return {aRange
.rbegin(), aRange
.rend()};
163 } // namespace mozilla
165 #endif // mozilla_ReverseIterator_h