On 3/16/26 11:59, Tobias Loew via Boost wrote:
Key Features:
* Type-safety: Prevents accidental mixing of different enum types and disables built-in arithmetic operators for enabled enums to turn logical errors into compilation errors. * Non-intrusive: Can be opted-in for existing enums (both scoped and unscoped) without modifying their definition. Simple macro-based opt-in via BOOST_FLAGS(...) [currently intended name]. * Compile-Time Friendly: Everything is constexpr, making it usable in template arguments. * Zero Overhead: Designed as zero-cost abstraction in optimized builds. * Distinguishes between flag-sets and their negations at the type level (based on a sound mathematical model). * Requires at least C++11, uses newer features if present
While better support for bit flags based on scoped enums is undoubtedly useful, I don't like how verbose the example code is. 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: enum class pizza_topping { tomato, cheese, salami, olives, garlic }; void order_pizza(enum_bitset<pizza_topping> const &toppings) { std::cout << "Pizza ordered with\n"; if (toppings[pizza_toppings::tomato]) { std::cout << "- tomato\n"; } if (toppings[pizza_toppings::cheese]) { std::cout << "- cheese\n"; } if (toppings[pizza_toppings::salami]) { std::cout << "- salami\n"; } if (toppings[pizza_toppings::olives]) { std::cout << "- olives\n"; } if (toppings[pizza_toppings::garlic]) { std::cout << "- garlic\n"; } std::cout << "\n"; } Isn't that so much more readable and compact? -- Rainer Deyke - rainerd@eldwood.com