Bug 1499346 [wpt PR 13540] - Use a common blank reference for wpt/css., a=testonly
[gecko.git] / mfbt / EnumeratedRange.h
blobb158f8a3ac1ca5fa5fb8f7c1d319e369dc989756
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 /* Iterator over contiguous enum values */
9 /*
10 * Implements generator functions that create a range to iterate over the values
11 * of a scoped or unscoped enum. Unlike IntegerRange, which can only function on
12 * the underlying integral type, the elements of the generated sequence will
13 * have the type of the enum in question.
15 * Note that the enum values should be contiguous in the iterated range;
16 * unfortunately there exists no way for EnumeratedRange to enforce this
17 * either dynamically or at compile time.
20 #ifndef mozilla_EnumeratedRange_h
21 #define mozilla_EnumeratedRange_h
23 #include <type_traits>
25 #include "mozilla/ReverseIterator.h"
27 namespace mozilla {
29 namespace detail {
31 template<typename EnumTypeT>
32 class EnumeratedIterator
34 public:
35 typedef typename std::underlying_type<EnumTypeT>::type IntTypeT;
37 template<typename EnumType>
38 explicit EnumeratedIterator(EnumType aCurrent)
39 : mCurrent(aCurrent) { }
41 template<typename EnumType>
42 explicit EnumeratedIterator(const EnumeratedIterator<EnumType>& aOther)
43 : mCurrent(aOther.mCurrent) { }
45 EnumTypeT operator*() const { return mCurrent; }
47 /* Increment and decrement operators */
49 EnumeratedIterator& operator++()
51 mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
52 return *this;
54 EnumeratedIterator& operator--()
56 mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
57 return *this;
59 EnumeratedIterator operator++(int)
61 auto ret = *this;
62 mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
63 return ret;
65 EnumeratedIterator operator--(int)
67 auto ret = *this;
68 mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
69 return ret;
72 /* Comparison operators */
74 template<typename EnumType>
75 friend bool operator==(const EnumeratedIterator<EnumType>& aIter1,
76 const EnumeratedIterator<EnumType>& aIter2);
77 template<typename EnumType>
78 friend bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
79 const EnumeratedIterator<EnumType>& aIter2);
80 template<typename EnumType>
81 friend bool operator<(const EnumeratedIterator<EnumType>& aIter1,
82 const EnumeratedIterator<EnumType>& aIter2);
83 template<typename EnumType>
84 friend bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
85 const EnumeratedIterator<EnumType>& aIter2);
86 template<typename EnumType>
87 friend bool operator>(const EnumeratedIterator<EnumType>& aIter1,
88 const EnumeratedIterator<EnumType>& aIter2);
89 template<typename EnumType>
90 friend bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
91 const EnumeratedIterator<EnumType>& aIter2);
93 private:
94 EnumTypeT mCurrent;
97 template<typename EnumType>
98 bool operator==(const EnumeratedIterator<EnumType>& aIter1,
99 const EnumeratedIterator<EnumType>& aIter2)
101 return aIter1.mCurrent == aIter2.mCurrent;
104 template<typename EnumType>
105 bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
106 const EnumeratedIterator<EnumType>& aIter2)
108 return aIter1.mCurrent != aIter2.mCurrent;
111 template<typename EnumType>
112 bool operator<(const EnumeratedIterator<EnumType>& aIter1,
113 const EnumeratedIterator<EnumType>& aIter2)
115 return aIter1.mCurrent < aIter2.mCurrent;
118 template<typename EnumType>
119 bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
120 const EnumeratedIterator<EnumType>& aIter2)
122 return aIter1.mCurrent <= aIter2.mCurrent;
125 template<typename EnumType>
126 bool operator>(const EnumeratedIterator<EnumType>& aIter1,
127 const EnumeratedIterator<EnumType>& aIter2)
129 return aIter1.mCurrent > aIter2.mCurrent;
132 template<typename EnumType>
133 bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
134 const EnumeratedIterator<EnumType>& aIter2)
136 return aIter1.mCurrent >= aIter2.mCurrent;
139 template<typename EnumTypeT>
140 class EnumeratedRange
142 public:
143 typedef EnumeratedIterator<EnumTypeT> iterator;
144 typedef EnumeratedIterator<EnumTypeT> const_iterator;
145 typedef ReverseIterator<iterator> reverse_iterator;
146 typedef ReverseIterator<const_iterator> const_reverse_iterator;
148 template<typename EnumType>
149 EnumeratedRange(EnumType aBegin, EnumType aEnd)
150 : mBegin(aBegin), mEnd(aEnd) { }
152 iterator begin() const { return iterator(mBegin); }
153 const_iterator cbegin() const { return begin(); }
154 iterator end() const { return iterator(mEnd); }
155 const_iterator cend() const { return end(); }
156 reverse_iterator rbegin() const { return reverse_iterator(mEnd); }
157 const_reverse_iterator crbegin() const { return rbegin(); }
158 reverse_iterator rend() const { return reverse_iterator(mBegin); }
159 const_reverse_iterator crend() const { return rend(); }
161 private:
162 EnumTypeT mBegin;
163 EnumTypeT mEnd;
166 } // namespace detail
168 #ifdef __GNUC__
169 // Enums can have an unsigned underlying type, which makes some of the
170 // comparisons below always true or always false. Temporarily disable
171 // -Wtype-limits to avoid breaking -Werror builds.
172 # pragma GCC diagnostic push
173 # pragma GCC diagnostic ignored "-Wtype-limits"
174 #endif
176 // Create a range to iterate from aBegin to aEnd, exclusive.
177 template<typename EnumType>
178 inline detail::EnumeratedRange<EnumType>
179 MakeEnumeratedRange(EnumType aBegin, EnumType aEnd)
181 MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!");
182 return detail::EnumeratedRange<EnumType>(aBegin, aEnd);
185 // Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0)
186 // should exist, but note that there is no way for us to ensure that it does!
187 template<typename EnumType>
188 inline detail::EnumeratedRange<EnumType>
189 MakeEnumeratedRange(EnumType aEnd)
191 return MakeEnumeratedRange(EnumType(0), aEnd);
194 #ifdef __GNUC__
195 # pragma GCC diagnostic pop
196 #endif
198 } // namespace mozilla
200 #endif // mozilla_EnumeratedRange_h