Bug 1601406 [wpt PR 20618] - Advertise DocumentPolicy & Network Err when receive...
[gecko.git] / mfbt / EnumeratedRange.h
blob3f9a845941d36b1cccefbfcf3e5b8d229582df3e
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 {
33 public:
34 typedef typename std::underlying_type<EnumTypeT>::type IntTypeT;
36 template <typename EnumType>
37 explicit EnumeratedIterator(EnumType aCurrent) : mCurrent(aCurrent) {}
39 template <typename EnumType>
40 explicit EnumeratedIterator(const EnumeratedIterator<EnumType>& aOther)
41 : mCurrent(aOther.mCurrent) {}
43 EnumTypeT operator*() const { return mCurrent; }
45 /* Increment and decrement operators */
47 EnumeratedIterator& operator++() {
48 mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
49 return *this;
51 EnumeratedIterator& operator--() {
52 mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
53 return *this;
55 EnumeratedIterator operator++(int) {
56 auto ret = *this;
57 mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
58 return ret;
60 EnumeratedIterator operator--(int) {
61 auto ret = *this;
62 mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
63 return ret;
66 /* Comparison operators */
68 template <typename EnumType>
69 friend bool operator==(const EnumeratedIterator<EnumType>& aIter1,
70 const EnumeratedIterator<EnumType>& aIter2);
71 template <typename EnumType>
72 friend bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
73 const EnumeratedIterator<EnumType>& aIter2);
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);
87 private:
88 EnumTypeT mCurrent;
91 template <typename EnumType>
92 bool operator==(const EnumeratedIterator<EnumType>& aIter1,
93 const EnumeratedIterator<EnumType>& aIter2) {
94 return aIter1.mCurrent == aIter2.mCurrent;
97 template <typename EnumType>
98 bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
99 const EnumeratedIterator<EnumType>& aIter2) {
100 return aIter1.mCurrent != aIter2.mCurrent;
103 template <typename EnumType>
104 bool operator<(const EnumeratedIterator<EnumType>& aIter1,
105 const EnumeratedIterator<EnumType>& aIter2) {
106 return aIter1.mCurrent < aIter2.mCurrent;
109 template <typename EnumType>
110 bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
111 const EnumeratedIterator<EnumType>& aIter2) {
112 return aIter1.mCurrent <= aIter2.mCurrent;
115 template <typename EnumType>
116 bool operator>(const EnumeratedIterator<EnumType>& aIter1,
117 const EnumeratedIterator<EnumType>& aIter2) {
118 return aIter1.mCurrent > aIter2.mCurrent;
121 template <typename EnumType>
122 bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
123 const EnumeratedIterator<EnumType>& aIter2) {
124 return aIter1.mCurrent >= aIter2.mCurrent;
127 template <typename EnumTypeT>
128 class EnumeratedRange {
129 public:
130 typedef EnumeratedIterator<EnumTypeT> iterator;
131 typedef EnumeratedIterator<EnumTypeT> const_iterator;
132 typedef ReverseIterator<iterator> reverse_iterator;
133 typedef ReverseIterator<const_iterator> const_reverse_iterator;
135 template <typename EnumType>
136 EnumeratedRange(EnumType aBegin, EnumType aEnd)
137 : mBegin(aBegin), mEnd(aEnd) {}
139 iterator begin() const { return iterator(mBegin); }
140 const_iterator cbegin() const { return begin(); }
141 iterator end() const { return iterator(mEnd); }
142 const_iterator cend() const { return end(); }
143 reverse_iterator rbegin() const { return reverse_iterator(mEnd); }
144 const_reverse_iterator crbegin() const { return rbegin(); }
145 reverse_iterator rend() const { return reverse_iterator(mBegin); }
146 const_reverse_iterator crend() const { return rend(); }
148 private:
149 EnumTypeT mBegin;
150 EnumTypeT mEnd;
153 } // namespace detail
155 #ifdef __GNUC__
156 // Enums can have an unsigned underlying type, which makes some of the
157 // comparisons below always true or always false. Temporarily disable
158 // -Wtype-limits to avoid breaking -Werror builds.
159 # pragma GCC diagnostic push
160 # pragma GCC diagnostic ignored "-Wtype-limits"
161 #endif
163 // Create a range to iterate from aBegin to aEnd, exclusive.
164 template <typename EnumType>
165 inline detail::EnumeratedRange<EnumType> MakeEnumeratedRange(EnumType aBegin,
166 EnumType aEnd) {
167 MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!");
168 return detail::EnumeratedRange<EnumType>(aBegin, aEnd);
171 // Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0)
172 // should exist, but note that there is no way for us to ensure that it does!
173 template <typename EnumType>
174 inline detail::EnumeratedRange<EnumType> MakeEnumeratedRange(EnumType aEnd) {
175 return MakeEnumeratedRange(EnumType(0), aEnd);
178 #ifdef __GNUC__
179 # pragma GCC diagnostic pop
180 #endif
182 } // namespace mozilla
184 #endif // mozilla_EnumeratedRange_h