Using the enum class with std :: bitset

First of all, I want a regular enumeration instead of a bit based enumeration, because the number of different enumerations will be outside the bounds of the integral type. I also want to take advantage of security like the C ++ 11 enum class . A natural choice for this would be std::bitset , however I don't know how to link the two together.

Do you need custom bitset ? How to get around the implementation of this class?

+4
source share
1 answer

Since enum class es are wrappers for enumerations, you can attribute them to the base type. And using some kind of private inheritance, you can selectively import some functions from the stdlib C ++ classes without worrying about the Liskov principle. The result is a clearer code. Using these functions, we can wrap std::bitset . The following code contains only a subset of the functionalities, but it can be expanded further.

The problem with the maximum value is that you cannot get the maximum value of the enum class (or am I mistaken?). So I added EnumTraits . Users now need to specialize EnumTraits with a const max value equal to the maximum enum value before the class will be used.

 #include <bitset> #include <type_traits> template<typename T> struct EnumTraits; template<typename T> class EnumClassBitset { private: std::bitset<static_cast<typename std::underlying_type<T>::type>(EnumTraits<T>::max)> c; typename std::underlying_type<T>::type get_value(T v) const { return static_cast<typename std::underlying_type<T>::type>(v); } public: EnumClassBitset() : c() { } bool test(T pos) const { return c.test(get_value(pos)); } EnumClassBitset& reset(T pos) { c.reset(get_value(pos)); return *this; } EnumClassBitset& flip(T pos) { c.flip(get_value(pos)); return *this; } }; enum class BitFlags { False, True, FileNotFound, Write, Read, MaxVal }; template<> struct EnumTraits<BitFlags> { static const BitFlags max = BitFlags::MaxVal; }; #include <iostream> int main() { EnumClassBitset<BitFlags> f; f.flip(BitFlags::True); f.flip(BitFlags::FileNotFound); //f.flip(2); //fails to compile std::cout << "Is False? " << f.test(BitFlags::False) << "\n"; std::cout << "Is True? " << f.test(BitFlags::True) << "\n"; std::cout << "Is FileNotFound? " << f.test(BitFlags::FileNotFound) << "\n"; std::cout << "Is Write? " << f.test(BitFlags::Write) << "\n"; std::cout << "Is Read? " << f.test(BitFlags::Read) << "\n"; } 

Since enum , unfortunately, does not have much functionality, and, moreover, C ++ 11 with enum class es does not improve the situation, some programmers use a static map wrapped in a class. Definitely a good read.

+8
source

Source: https://habr.com/ru/post/1488556/


All Articles