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
14 #include "mozilla/Attributes.h"
15 #include "mozilla/TypeTraits.h"
19 template <typename IteratorT
>
20 class ReverseIterator
{
22 template <typename Iterator
>
23 explicit ReverseIterator(Iterator aIter
) : mCurrent(aIter
) {}
25 template <typename Iterator
>
26 MOZ_IMPLICIT
ReverseIterator(const ReverseIterator
<Iterator
>& aOther
)
27 : mCurrent(aOther
.mCurrent
) {}
29 decltype(*DeclVal
<IteratorT
>()) operator*() const {
30 IteratorT tmp
= mCurrent
;
34 /* Increments and decrements operators */
36 ReverseIterator
& operator++() {
40 ReverseIterator
& operator--() {
44 ReverseIterator
operator++(int) {
49 ReverseIterator
operator--(int) {
55 /* Comparison operators */
57 template <typename Iterator1
, typename Iterator2
>
58 friend bool operator==(const ReverseIterator
<Iterator1
>& aIter1
,
59 const ReverseIterator
<Iterator2
>& aIter2
);
60 template <typename Iterator1
, typename Iterator2
>
61 friend bool operator!=(const ReverseIterator
<Iterator1
>& aIter1
,
62 const ReverseIterator
<Iterator2
>& aIter2
);
63 template <typename Iterator1
, typename Iterator2
>
64 friend bool operator<(const ReverseIterator
<Iterator1
>& aIter1
,
65 const ReverseIterator
<Iterator2
>& aIter2
);
66 template <typename Iterator1
, typename Iterator2
>
67 friend bool operator<=(const ReverseIterator
<Iterator1
>& aIter1
,
68 const ReverseIterator
<Iterator2
>& aIter2
);
69 template <typename Iterator1
, typename Iterator2
>
70 friend bool operator>(const ReverseIterator
<Iterator1
>& aIter1
,
71 const ReverseIterator
<Iterator2
>& aIter2
);
72 template <typename Iterator1
, typename Iterator2
>
73 friend bool operator>=(const ReverseIterator
<Iterator1
>& aIter1
,
74 const ReverseIterator
<Iterator2
>& aIter2
);
80 template <typename Iterator1
, typename Iterator2
>
81 bool operator==(const ReverseIterator
<Iterator1
>& aIter1
,
82 const ReverseIterator
<Iterator2
>& aIter2
) {
83 return aIter1
.mCurrent
== aIter2
.mCurrent
;
86 template <typename Iterator1
, typename Iterator2
>
87 bool operator!=(const ReverseIterator
<Iterator1
>& aIter1
,
88 const ReverseIterator
<Iterator2
>& aIter2
) {
89 return aIter1
.mCurrent
!= aIter2
.mCurrent
;
92 template <typename Iterator1
, typename Iterator2
>
93 bool operator<(const ReverseIterator
<Iterator1
>& aIter1
,
94 const ReverseIterator
<Iterator2
>& aIter2
) {
95 return aIter1
.mCurrent
> aIter2
.mCurrent
;
98 template <typename Iterator1
, typename Iterator2
>
99 bool operator<=(const ReverseIterator
<Iterator1
>& aIter1
,
100 const ReverseIterator
<Iterator2
>& aIter2
) {
101 return aIter1
.mCurrent
>= aIter2
.mCurrent
;
104 template <typename Iterator1
, typename Iterator2
>
105 bool operator>(const ReverseIterator
<Iterator1
>& aIter1
,
106 const ReverseIterator
<Iterator2
>& aIter2
) {
107 return aIter1
.mCurrent
< aIter2
.mCurrent
;
110 template <typename Iterator1
, typename Iterator2
>
111 bool operator>=(const ReverseIterator
<Iterator1
>& aIter1
,
112 const ReverseIterator
<Iterator2
>& aIter2
) {
113 return aIter1
.mCurrent
<= aIter2
.mCurrent
;
118 template <typename IteratorT
>
119 class IteratorRange
{
121 typedef IteratorT iterator
;
122 typedef IteratorT const_iterator
;
123 typedef ReverseIterator
<IteratorT
> reverse_iterator
;
124 typedef ReverseIterator
<IteratorT
> const_reverse_iterator
;
126 template <typename Iterator1
, typename Iterator2
>
127 MOZ_IMPLICIT
IteratorRange(Iterator1 aIterBegin
, Iterator2 aIterEnd
)
128 : mIterBegin(aIterBegin
), mIterEnd(aIterEnd
) {}
130 template <typename Iterator
>
131 MOZ_IMPLICIT
IteratorRange(const IteratorRange
<Iterator
>& aOther
)
132 : mIterBegin(aOther
.mIterBegin
), mIterEnd(aOther
.mIterEnd
) {}
134 iterator
begin() const { return mIterBegin
; }
135 const_iterator
cbegin() const { return begin(); }
136 iterator
end() const { return mIterEnd
; }
137 const_iterator
cend() const { return end(); }
138 reverse_iterator
rbegin() const { return reverse_iterator(mIterEnd
); }
139 const_reverse_iterator
crbegin() const { return rbegin(); }
140 reverse_iterator
rend() const { return reverse_iterator(mIterBegin
); }
141 const_reverse_iterator
crend() const { return rend(); }
144 IteratorT mIterBegin
;
148 } // namespace detail
150 template <typename Range
>
151 detail::IteratorRange
<typename
Range::reverse_iterator
> Reversed(
153 return {aRange
.rbegin(), aRange
.rend()};
156 template <typename Range
>
157 detail::IteratorRange
<typename
Range::const_reverse_iterator
> Reversed(
158 const Range
& aRange
) {
159 return {aRange
.rbegin(), aRange
.rend()};
162 } // namespace mozilla
164 #endif // mozilla_ReverseIterator_h