| 16 | // values), fitting into an integral type T. |
| 17 | template <class E, class T = int> |
| 18 | class EnumSet { |
| 19 | static_assert(std::is_enum<E>::value, "EnumSet can only be used with enums"); |
| 20 | |
| 21 | public: |
| 22 | constexpr EnumSet() = default; |
| 23 | |
| 24 | explicit constexpr EnumSet(std::initializer_list<E> init) { |
| 25 | T bits = 0; |
| 26 | for (E e : init) bits |= Mask(e); |
| 27 | bits_ = bits; |
| 28 | } |
| 29 | |
| 30 | constexpr bool empty() const { return bits_ == 0; } |
| 31 | constexpr bool contains(E element) const { |
| 32 | return (bits_ & Mask(element)) != 0; |
| 33 | } |
| 34 | constexpr bool contains_any(EnumSet set) const { |
| 35 | return (bits_ & set.bits_) != 0; |
| 36 | } |
| 37 | void Add(E element) { bits_ |= Mask(element); } |
| 38 | void Add(EnumSet set) { bits_ |= set.bits_; } |
| 39 | void Remove(E element) { bits_ &= ~Mask(element); } |
| 40 | void Remove(EnumSet set) { bits_ &= ~set.bits_; } |
| 41 | void RemoveAll() { bits_ = 0; } |
| 42 | void Intersect(EnumSet set) { bits_ &= set.bits_; } |
| 43 | constexpr T ToIntegral() const { return bits_; } |
| 44 | |
| 45 | constexpr bool operator==(EnumSet set) const { return bits_ == set.bits_; } |
| 46 | constexpr bool operator!=(EnumSet set) const { return bits_ != set.bits_; } |
| 47 | |
| 48 | constexpr EnumSet operator|(EnumSet set) const { |
| 49 | return EnumSet(bits_ | set.bits_); |
| 50 | } |
| 51 | constexpr EnumSet operator&(EnumSet set) const { |
| 52 | return EnumSet(bits_ & set.bits_); |
| 53 | } |
| 54 | constexpr EnumSet operator-(EnumSet set) const { |
| 55 | return EnumSet(bits_ & ~set.bits_); |
| 56 | } |
| 57 | |
| 58 | EnumSet& operator|=(EnumSet set) { return *this = *this | set; } |
| 59 | EnumSet& operator&=(EnumSet set) { return *this = *this & set; } |
| 60 | EnumSet& operator-=(EnumSet set) { return *this = *this - set; } |
| 61 | |
| 62 | constexpr EnumSet operator|(E element) const { |
| 63 | return EnumSet(bits_ | Mask(element)); |
| 64 | } |
| 65 | constexpr EnumSet operator&(E element) const { |
| 66 | return EnumSet(bits_ & Mask(element)); |
| 67 | } |
| 68 | constexpr EnumSet operator-(E element) const { |
| 69 | return EnumSet(bits_ & ~Mask(element)); |
| 70 | } |
| 71 | |
| 72 | EnumSet& operator|=(E element) { return *this = *this | element; } |
| 73 | EnumSet& operator&=(E element) { return *this = *this & element; } |
| 74 | EnumSet& operator-=(E element) { return *this = *this - element; } |
| 75 | |