xref: /third_party/node/deps/v8/src/base/enum-set.h (revision 1cb0ef41)
1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_BASE_ENUM_SET_H_
6#define V8_BASE_ENUM_SET_H_
7
8#include <type_traits>
9
10#include "src/base/logging.h"
11
12namespace v8 {
13namespace base {
14
15// A poor man's version of STL's bitset: A bit set of enums E (without explicit
16// values), fitting into an integral type T.
17template <class E, class T = int>
18class 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
76  static constexpr EnumSet FromIntegral(T bits) { return EnumSet{bits}; }
77
78 private:
79  explicit constexpr EnumSet(T bits) : bits_(bits) {}
80
81  static constexpr T Mask(E element) {
82    DCHECK_GT(sizeof(T) * 8, static_cast<size_t>(element));
83    return T{1} << static_cast<typename std::underlying_type<E>::type>(element);
84  }
85
86  T bits_ = 0;
87};
88
89}  // namespace base
90}  // namespace v8
91
92#endif  // V8_BASE_ENUM_SET_H_
93