Bug 1610775 [wpt PR 21336] - Update urllib3 to 1.25.8, a=testonly
[gecko.git] / mfbt / ReverseIterator.h
blobfda74dc43e2fd5f40581c080012820d6459c7fb3
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"
17 namespace mozilla {
19 template <typename IteratorT>
20 class ReverseIterator {
21 public:
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;
31 return *--tmp;
34 /* Increments and decrements operators */
36 ReverseIterator& operator++() {
37 --mCurrent;
38 return *this;
40 ReverseIterator& operator--() {
41 ++mCurrent;
42 return *this;
44 ReverseIterator operator++(int) {
45 auto ret = *this;
46 mCurrent--;
47 return ret;
49 ReverseIterator operator--(int) {
50 auto ret = *this;
51 mCurrent++;
52 return ret;
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);
76 private:
77 IteratorT mCurrent;
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;
116 namespace detail {
118 template <typename IteratorT>
119 class IteratorRange {
120 public:
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(); }
143 private:
144 IteratorT mIterBegin;
145 IteratorT mIterEnd;
148 } // namespace detail
150 template <typename Range>
151 detail::IteratorRange<typename Range::reverse_iterator> Reversed(
152 Range& aRange) {
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