mfbt/EnumSet.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:aa3fab428fd6
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/. */
6
7 /* A set abstraction for enumeration values. */
8
9 #ifndef mozilla_EnumSet_h
10 #define mozilla_EnumSet_h
11
12 #include "mozilla/Assertions.h"
13
14 #include <stdint.h>
15
16 namespace mozilla {
17
18 /**
19 * EnumSet<T> is a set of values defined by an enumeration. It is implemented
20 * using a 32 bit mask for each value so it will only work for enums with an int
21 * representation less than 32. It works both for enum and enum class types.
22 */
23 template<typename T>
24 class EnumSet
25 {
26 public:
27 EnumSet()
28 : mBitField(0)
29 { }
30
31 EnumSet(T aEnum)
32 : mBitField(aEnum)
33 { }
34
35 EnumSet(T aEnum1, T aEnum2)
36 : mBitField(bitFor(aEnum1) |
37 bitFor(aEnum2))
38 { }
39
40 EnumSet(T aEnum1, T aEnum2, T aEnum3)
41 : mBitField(bitFor(aEnum1) |
42 bitFor(aEnum2) |
43 bitFor(aEnum3))
44 { }
45
46 EnumSet(T aEnum1, T aEnum2, T aEnum3, T aEnum4)
47 : mBitField(bitFor(aEnum1) |
48 bitFor(aEnum2) |
49 bitFor(aEnum3) |
50 bitFor(aEnum4))
51 { }
52
53 EnumSet(const EnumSet& aEnumSet)
54 : mBitField(aEnumSet.mBitField)
55 { }
56
57 /**
58 * Add an element
59 */
60 void operator+=(T aEnum) {
61 mBitField |= bitFor(aEnum);
62 }
63
64 /**
65 * Add an element
66 */
67 EnumSet<T> operator+(T aEnum) const {
68 EnumSet<T> result(*this);
69 result += aEnum;
70 return result;
71 }
72
73 /**
74 * Union
75 */
76 void operator+=(const EnumSet<T> aEnumSet) {
77 mBitField |= aEnumSet.mBitField;
78 }
79
80 /**
81 * Union
82 */
83 EnumSet<T> operator+(const EnumSet<T> aEnumSet) const {
84 EnumSet<T> result(*this);
85 result += aEnumSet;
86 return result;
87 }
88
89 /**
90 * Remove an element
91 */
92 void operator-=(T aEnum) {
93 mBitField &= ~(bitFor(aEnum));
94 }
95
96 /**
97 * Remove an element
98 */
99 EnumSet<T> operator-(T aEnum) const {
100 EnumSet<T> result(*this);
101 result -= aEnum;
102 return result;
103 }
104
105 /**
106 * Remove a set of elements
107 */
108 void operator-=(const EnumSet<T> aEnumSet) {
109 mBitField &= ~(aEnumSet.mBitField);
110 }
111
112 /**
113 * Remove a set of elements
114 */
115 EnumSet<T> operator-(const EnumSet<T> aEnumSet) const {
116 EnumSet<T> result(*this);
117 result -= aEnumSet;
118 return result;
119 }
120
121 /**
122 * Intersection
123 */
124 void operator&=(const EnumSet<T> aEnumSet) {
125 mBitField &= aEnumSet.mBitField;
126 }
127
128 /**
129 * Intersection
130 */
131 EnumSet<T> operator&(const EnumSet<T> aEnumSet) const {
132 EnumSet<T> result(*this);
133 result &= aEnumSet;
134 return result;
135 }
136
137 /**
138 * Equality
139 */
140
141 bool operator==(const EnumSet<T> aEnumSet) const {
142 return mBitField == aEnumSet.mBitField;
143 }
144
145 /**
146 * Test is an element is contained in the set
147 */
148 bool contains(T aEnum) const {
149 return mBitField & bitFor(aEnum);
150 }
151
152 /**
153 * Return the number of elements in the set
154 */
155
156 uint8_t size() {
157 uint8_t count = 0;
158 for (uint32_t bitField = mBitField; bitField; bitField >>= 1) {
159 if (bitField & 1)
160 count++;
161 }
162 return count;
163 }
164
165 private:
166 static uint32_t bitFor(T aEnum) {
167 uint32_t bitNumber(aEnum);
168 MOZ_ASSERT(bitNumber < 32);
169 return 1U << bitNumber;
170 }
171
172 uint32_t mBitField;
173 };
174
175 } // namespace mozilla
176
177 #endif /* mozilla_EnumSet_h_*/

mercurial