Am 17.03.26 um 05:25 schrieb Rainer Deyke via Boost:
I've considered an alternate solution to the same problem based on a wrapper around std::bitset.
template<typename Enum> class enum_bitset { public: auto operator[](Enum idx) { return this->data_store[static_cast<std::size_t>(idx)]; } // ...and all of the other member functions... private: std::bitset<...> data_store; };
This has the advantage of getting rid of all of the ugly boost::flags::nth_bits and boost::flags::anys in the example code: I was also thinking about that: Having to initialize an enum with powers-of-2 is a pitfall, although very common for flags. Maybe you already have flags.
Imagine writing a C++ wrapper around the Windows flags posted in the example. There being able to reuse the actual values can be very useful: enum class BS { Notify = BS_NOTIFY, Foo = BS_FOO, Bar = BS_Bar }; But for greenfield implementations I like not having the boilerplate of having to initialize enumerators. On the other hand it makes them stick out as flags. FWIW: Both approaches seem to get optimized to literally the same code. Random example: https://godbolt.org/z/Yjea7qzfv What I am missing though are predefined bitsets: With the pizza example you can have `Topping::Cheese` in an enum class but no good way to have `Topping::All` or `Topping::Vegetarian`, e.g. for `bool isVegan(... toppings) { return toppings & ~Topping::NonVegan; } Of course you can define such as (constexpr) constants, but not anymore inside the bitset class, i.e. Topping, but only on the namespace as "AllToppings" or subclassing. I have also used bits and bitsets in switch-case constructs, bit std::bitset::to_(u)ulong is only constexpr in C++23 So I had use for both variants. Maybe they can be consolidated: template<typename Enum, bool isDense=true> class enum_bitset I see use for that in Boost as it seems to be common enough to avoid having to reimplement it Best, Alex