|
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_*/ |