I use c++ 11 enum class usually instead of the old enums because many enums can contain the same value but as known they don't have the bitwise operators out of the box so we should define them manually
in windows it's already done for us with this macro in windows.h header :
DEFINE_ENUM_FLAG_OPERATORS
but I then encountered another problem
if I use these enum as flags I can put many values in the falg using bitwise operator | , but to test if the flag contains a value I can't check with bitwise operator & like this :
if (flags & value) {...}
I could however write a template function like this to test :
template <class T> constexpr bool has_value(T flags, T value) { return (std::underlying_type_t<T>)flags & (std::underlying_type_t<T>)value; }
but I really would like to use the old format to test for values in the flags I already found a solution on github which wrapped all chosen emums in a class called flags and it was used like the old ones but with the type safety of enum classes
As I don't want to use templates for this purpose and I want only operator & to give me a bool value in if expressions , I used another class that holds the enum value and can be converted to bool and this is what I wrote
#define OVERLOAD_ENUM_OPERATORS(x) \ class EnumBool##x \ { \ x enum_value; \ public: \ constexpr EnumBool##x(const x e_val) : enum_value(e_val) {} \ constexpr operator x() const { return enum_value; } \ explicit operator bool() const { return (std::underlying_type_t<x>)enum_value != 0; } \ }; \ inline constexpr EnumBool##x operator&(const x lhs, const x rhs) \ { \ return EnumBool##x((x)((std::underlying_type_t<x>)lhs & (std::underlying_type_t<x>)rhs)); \ } \ inline constexpr x operator|(const x lhs, const x rhs) \ { \ return (x)((std::underlying_type_t<x>)lhs | (std::underlying_type_t<x>)rhs); \ } \ inline constexpr x operator^(const x lhs, const x rhs) \ { \ return (x)((std::underlying_type_t<x>)lhs ^ (std::underlying_type_t<x>)rhs);\ } \ inline constexpr x operator~(const x lhs) \ { \ return (x)(~(std::underlying_type_t<x>)lhs);\ } \ inline constexpr x& operator|=(x& lhs, const x rhs) \ { \ lhs = (x)((std::underlying_type_t<x>)lhs | (std::underlying_type_t<x>)rhs); \ return lhs; \ } \ inline constexpr x& operator&=(x& lhs, const x rhs) \ { \ lhs = (x)((std::underlying_type_t<x>)lhs & (std::underlying_type_t<x>)rhs); \ return lhs; \ } \ inline constexpr x& operator^=(x& lhs, const x rhs) \ { \ lhs = (x)((std::underlying_type_t<x>)lhs ^ (std::underlying_type_t<x>)rhs); \ return lhs; \ } \ inline constexpr bool operator==(const x lhs, const x rhs) \ { \ return (std::underlying_type_t<x>)lhs == (std::underlying_type_t<x>)rhs; \ } \ inline constexpr bool operator!=(const x lhs, const x rhs) \ { \ return (std::underlying_type_t<x>)lhs != (std::underlying_type_t<x>)rhs; \ } \ inline constexpr bool operator>(const x lhs, const x rhs) \ { \ return (std::underlying_type_t<x>)lhs > (std::underlying_type_t<x>)rhs; \ } \ inline constexpr bool operator<(const x lhs, const x rhs) \ { \ return (std::underlying_type_t<x>)lhs < (std::underlying_type_t<x>)rhs; \ } \ inline constexpr bool operator>=(const x lhs, const x rhs) \ { \ return (std::underlying_type_t<x>)lhs >= (std::underlying_type_t<x>)rhs; \ } \ inline constexpr bool operator<=(const x lhs, const x rhs) \ { \ return (std::underlying_type_t<x>)lhs <= (std::underlying_type_t<x>)rhs; \ }