Bug 1642744 [wpt PR 23920] - [ScrollTimeline] Update compositor timeline from blink...
[gecko.git] / mfbt / ReverseIterator.h
blobdee2e7318caea1d0370664987712c7fddee8cc40
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 <utility>
16 #include "mozilla/Attributes.h"
18 namespace mozilla {
20 template <typename IteratorT>
21 class ReverseIterator {
22 public:
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;
32 return *--tmp;
35 /* Increments and decrements operators */
37 ReverseIterator& operator++() {
38 --mCurrent;
39 return *this;
41 ReverseIterator& operator--() {
42 ++mCurrent;
43 return *this;
45 ReverseIterator operator++(int) {
46 auto ret = *this;
47 mCurrent--;
48 return ret;
50 ReverseIterator operator--(int) {
51 auto ret = *this;
52 mCurrent++;
53 return ret;
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);
77 private:
78 IteratorT mCurrent;
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;
117 namespace detail {
119 template <typename IteratorT>
120 class IteratorRange {
121 public:
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(); }
144 private:
145 IteratorT mIterBegin;
146 IteratorT mIterEnd;
149 } // namespace detail
151 template <typename Range>
152 detail::IteratorRange<typename Range::reverse_iterator> Reversed(
153 Range& aRange) {
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