Bug 877527
[gecko.git] / mfbt / EnumSet.h
blobb18b0056691c9bf8f4205ce89f36da7609ddce46
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* A set abstraction for enumeration values. */
8 #ifndef mozilla_EnumSet_h
9 #define mozilla_EnumSet_h
11 #include "mozilla/Assertions.h"
12 #include "mozilla/StandardInteger.h"
14 namespace mozilla {
16 /**
17 * EnumSet<T> is a set of values defined by an enumeration. It is implemented
18 * using a 32 bit mask for each value so it will only work for enums with an int
19 * representation less than 32. It works both for enum and enum class types.
21 template<typename T>
22 class EnumSet
24 public:
25 EnumSet()
26 : mBitField(0)
27 { }
29 EnumSet(T aEnum)
30 : mBitField(aEnum)
31 { }
33 EnumSet(T aEnum1, T aEnum2)
34 : mBitField(bitFor(aEnum1) |
35 bitFor(aEnum2))
36 { }
38 EnumSet(T aEnum1, T aEnum2, T aEnum3)
39 : mBitField(bitFor(aEnum1) |
40 bitFor(aEnum2) |
41 bitFor(aEnum3))
42 { }
44 EnumSet(T aEnum1, T aEnum2, T aEnum3, T aEnum4)
45 : mBitField(bitFor(aEnum1) |
46 bitFor(aEnum2) |
47 bitFor(aEnum3) |
48 bitFor(aEnum4))
49 { }
51 EnumSet(const EnumSet& aEnumSet)
52 : mBitField(aEnumSet.mBitField)
53 { }
55 /**
56 * Add an element
58 void operator+=(T aEnum) {
59 mBitField |= bitFor(aEnum);
62 /**
63 * Add an element
65 EnumSet<T> operator+(T aEnum) const {
66 EnumSet<T> result(*this);
67 result += aEnum;
68 return result;
71 /**
72 * Union
74 void operator+=(const EnumSet<T> aEnumSet) {
75 mBitField |= aEnumSet.mBitField;
78 /**
79 * Union
81 EnumSet<T> operator+(const EnumSet<T> aEnumSet) const {
82 EnumSet<T> result(*this);
83 result += aEnumSet;
84 return result;
87 /**
88 * Remove an element
90 void operator-=(T aEnum) {
91 mBitField &= ~(bitFor(aEnum));
94 /**
95 * Remove an element
97 EnumSet<T> operator-(T aEnum) const {
98 EnumSet<T> result(*this);
99 result -= aEnum;
100 return result;
104 * Remove a set of elements
106 void operator-=(const EnumSet<T> aEnumSet) {
107 mBitField &= ~(aEnumSet.mBitField);
111 * Remove a set of elements
113 EnumSet<T> operator-(const EnumSet<T> aEnumSet) const {
114 EnumSet<T> result(*this);
115 result -= aEnumSet;
116 return result;
120 * Intersection
122 void operator&=(const EnumSet<T> aEnumSet) {
123 mBitField &= aEnumSet.mBitField;
127 * Intersection
129 EnumSet<T> operator&(const EnumSet<T> aEnumSet) const {
130 EnumSet<T> result(*this);
131 result &= aEnumSet;
132 return result;
136 * Equality
139 bool operator==(const EnumSet<T> aEnumSet) const {
140 return mBitField == aEnumSet.mBitField;
144 * Test is an element is contained in the set
146 bool contains(T aEnum) const {
147 return mBitField & bitFor(aEnum);
151 * Return the number of elements in the set
154 uint8_t size() {
155 uint8_t count = 0;
156 for (uint32_t bitField = mBitField; bitField; bitField >>= 1) {
157 if (bitField & 1)
158 count++;
160 return count;
163 private:
164 static uint32_t bitFor(T aEnum) {
165 uint32_t bitNumber(aEnum);
166 MOZ_ASSERT(bitNumber < 32);
167 return 1U << bitNumber;
170 uint32_t mBitField;
173 } // namespace mozilla
175 #endif // mozilla_EnumSet_h_