28template <
typename ENUM, std::
size_t BITS>
class EnumSet {
29 static_assert(BITS > 0);
35 std::conditional_t<(BITS <= 64), common::BitSet<BITS>, std::bitset<BITS>>;
36 using enumerationType = ENUM;
38 constexpr EnumSet() {}
39 constexpr EnumSet(
const std::initializer_list<enumerationType> &enums) {
40 for (
auto it{enums.begin()}; it != enums.end(); ++it) {
44 constexpr EnumSet(
const EnumSet &) =
default;
45 constexpr EnumSet(EnumSet &&) =
default;
47 constexpr EnumSet &operator=(
const EnumSet &) =
default;
48 constexpr EnumSet &operator=(EnumSet &&) =
default;
50 const bitsetType &bitset()
const {
return bitset_; }
52 constexpr EnumSet &operator&=(
const EnumSet &that) {
53 bitset_ &= that.bitset_;
56 constexpr EnumSet &operator&=(EnumSet &&that) {
57 bitset_ &= that.bitset_;
60 constexpr EnumSet &operator|=(
const EnumSet &that) {
61 bitset_ |= that.bitset_;
64 constexpr EnumSet &operator|=(EnumSet &&that) {
65 bitset_ |= that.bitset_;
68 constexpr EnumSet &operator^=(
const EnumSet &that) {
69 bitset_ ^= that.bitset_;
72 constexpr EnumSet &operator^=(EnumSet &&that) {
73 bitset_ ^= that.bitset_;
77 constexpr EnumSet operator~()
const {
79 result.bitset_ = ~bitset_;
82 constexpr EnumSet operator&(
const EnumSet &that)
const {
83 EnumSet result{*
this};
84 result.bitset_ &= that.bitset_;
87 constexpr EnumSet operator&(EnumSet &&that)
const {
88 EnumSet result{*
this};
89 result.bitset_ &= that.bitset_;
92 constexpr EnumSet operator|(
const EnumSet &that)
const {
93 EnumSet result{*
this};
94 result.bitset_ |= that.bitset_;
97 constexpr EnumSet operator|(EnumSet &&that)
const {
98 EnumSet result{*
this};
99 result.bitset_ |= that.bitset_;
102 constexpr EnumSet operator^(
const EnumSet &that)
const {
103 EnumSet result{*
this};
104 result.bitset_ ^= that.bitset_;
107 constexpr EnumSet operator^(EnumSet &&that)
const {
108 EnumSet result{*
this};
109 result.bitset_ ^= that.bitset_;
113 constexpr EnumSet operator+(enumerationType v)
const {
114 return {*
this | EnumSet{v}};
116 constexpr EnumSet operator-(enumerationType v)
const {
117 return {*
this & ~EnumSet{v}};
120 constexpr bool operator==(
const EnumSet &that)
const {
121 return bitset_ == that.bitset_;
123 constexpr bool operator==(EnumSet &&that)
const {
124 return bitset_ == that.bitset_;
126 constexpr bool operator!=(
const EnumSet &that)
const {
127 return bitset_ != that.bitset_;
129 constexpr bool operator!=(EnumSet &&that)
const {
130 return bitset_ != that.bitset_;
135 static constexpr std::size_t max_size() {
return BITS; }
136 constexpr bool test(enumerationType x)
const {
137 return bitset_.test(
static_cast<std::size_t
>(x));
139 constexpr bool all()
const {
return bitset_.all(); }
140 constexpr bool any()
const {
return bitset_.any(); }
141 constexpr bool none()
const {
return bitset_.none(); }
145 constexpr std::size_t count()
const {
return bitset_.count(); }
146 constexpr std::size_t count(enumerationType x)
const {
147 return test(x) ? 1 : 0;
150 constexpr EnumSet &set() {
154 constexpr EnumSet &set(enumerationType x,
bool value =
true) {
155 bitset_.set(
static_cast<std::size_t
>(x), value);
158 constexpr EnumSet &reset() {
162 constexpr EnumSet &reset(enumerationType x) {
163 bitset_.reset(
static_cast<std::size_t
>(x));
166 constexpr EnumSet &flip() {
170 constexpr EnumSet &flip(enumerationType x) {
171 bitset_.flip(
static_cast<std::size_t
>(x));
175 constexpr bool empty()
const {
return none(); }
176 void clear() { reset(); }
177 void insert(enumerationType x) { set(x); }
178 void emplace(enumerationType x) { set(x); }
179 void erase(enumerationType x) { reset(x); }
181 constexpr std::optional<enumerationType> LeastElement()
const {
184 }
else if constexpr (std::is_same_v<bitsetType, common::BitSet<BITS>>) {
185 return {
static_cast<enumerationType
>(bitset_.LeastElement().value())};
188 for (std::size_t j{0}; j < BITS; ++j) {
189 auto enumerator{
static_cast<enumerationType
>(j)};
190 if (bitset_.test(j)) {
194 die(
"EnumSet::LeastElement(): no bit found in non-empty std::bitset");
198 template <
typename FUNC>
void IterateOverMembers(
const FUNC &f)
const {
200 while (
auto least{copy.LeastElement()}) {
206 template <
typename STREAM>
208 STREAM &o, std::string_view EnumToString(enumerationType))
const {
210 IterateOverMembers([&](
auto e) {
211 o << sep << EnumToString(e);
214 return o << (sep ==
'{' ?
"{}" :
"}");
218 bitsetType bitset_{};