| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| /* A set abstraction for enumeration values. */ |
| |
| #ifndef mozilla_EnumSet_h |
| #define mozilla_EnumSet_h |
| |
| #include "mozilla/Assertions.h" |
| #include "mozilla/StandardInteger.h" |
| |
| namespace mozilla { |
| |
| /** |
| * EnumSet<T> is a set of values defined by an enumeration. It is implemented |
| * using a 32 bit mask for each value so it will only work for enums with an int |
| * representation less than 32. It works both for enum and enum class types. |
| */ |
| template<typename T> |
| class EnumSet |
| { |
| public: |
| EnumSet() |
| : mBitField(0) |
| { } |
| |
| EnumSet(T aEnum) |
| : mBitField(aEnum) |
| { } |
| |
| EnumSet(T aEnum1, T aEnum2) |
| : mBitField(bitFor(aEnum1) | |
| bitFor(aEnum2)) |
| { } |
| |
| EnumSet(T aEnum1, T aEnum2, T aEnum3) |
| : mBitField(bitFor(aEnum1) | |
| bitFor(aEnum2) | |
| bitFor(aEnum3)) |
| { } |
| |
| EnumSet(T aEnum1, T aEnum2, T aEnum3, T aEnum4) |
| : mBitField(bitFor(aEnum1) | |
| bitFor(aEnum2) | |
| bitFor(aEnum3) | |
| bitFor(aEnum4)) |
| { } |
| |
| EnumSet(const EnumSet& aEnumSet) |
| : mBitField(aEnumSet.mBitField) |
| { } |
| |
| /** |
| * Add an element |
| */ |
| void operator+=(T aEnum) { |
| mBitField |= bitFor(aEnum); |
| } |
| |
| /** |
| * Add an element |
| */ |
| EnumSet<T> operator+(T aEnum) const { |
| EnumSet<T> result(*this); |
| result += aEnum; |
| return result; |
| } |
| |
| /** |
| * Union |
| */ |
| void operator+=(const EnumSet<T> aEnumSet) { |
| mBitField |= aEnumSet.mBitField; |
| } |
| |
| /** |
| * Union |
| */ |
| EnumSet<T> operator+(const EnumSet<T> aEnumSet) const { |
| EnumSet<T> result(*this); |
| result += aEnumSet; |
| return result; |
| } |
| |
| /** |
| * Remove an element |
| */ |
| void operator-=(T aEnum) { |
| mBitField &= ~(bitFor(aEnum)); |
| } |
| |
| /** |
| * Remove an element |
| */ |
| EnumSet<T> operator-(T aEnum) const { |
| EnumSet<T> result(*this); |
| result -= aEnum; |
| return result; |
| } |
| |
| /** |
| * Remove a set of elements |
| */ |
| void operator-=(const EnumSet<T> aEnumSet) { |
| mBitField &= ~(aEnumSet.mBitField); |
| } |
| |
| /** |
| * Remove a set of elements |
| */ |
| EnumSet<T> operator-(const EnumSet<T> aEnumSet) const { |
| EnumSet<T> result(*this); |
| result -= aEnumSet; |
| return result; |
| } |
| |
| /** |
| * Intersection |
| */ |
| void operator&=(const EnumSet<T> aEnumSet) { |
| mBitField &= aEnumSet.mBitField; |
| } |
| |
| /** |
| * Intersection |
| */ |
| EnumSet<T> operator&(const EnumSet<T> aEnumSet) const { |
| EnumSet<T> result(*this); |
| result &= aEnumSet; |
| return result; |
| } |
| |
| /** |
| * Equality |
| */ |
| |
| bool operator==(const EnumSet<T> aEnumSet) const { |
| return mBitField == aEnumSet.mBitField; |
| } |
| |
| /** |
| * Test is an element is contained in the set |
| */ |
| bool contains(T aEnum) const { |
| return mBitField & bitFor(aEnum); |
| } |
| |
| /** |
| * Return the number of elements in the set |
| */ |
| |
| uint8_t size() { |
| uint8_t count = 0; |
| for (uint32_t bitField = mBitField; bitField; bitField >>= 1) { |
| if (bitField & 1) |
| count++; |
| } |
| return count; |
| } |
| |
| private: |
| static uint32_t bitFor(T aEnum) { |
| uint32_t bitNumber(aEnum); |
| MOZ_ASSERT(bitNumber < 32); |
| return 1U << bitNumber; |
| } |
| |
| uint32_t mBitField; |
| }; |
| |
| } // namespace mozilla |
| |
| #endif // mozilla_EnumSet_h_ |