mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
178 lines
3.6 KiB
C++
178 lines
3.6 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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 <stdint.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_*/
|