I usually use c ++ 11 enum class instead of old enums, because many enums may contain the same value

but as we know, they do not have the bit operators out of the box, so we should set them manually

under windows it's already done for us with this macro in windows.h header:

```
DEFINE_ENUM_FLAG_OPERATORS
```

but then I encountered another problem

if I use these enumerations as flags, I can put a lot of values in the falg file using the bitwise operator | , but to test if the flag contains a value that I can not check with the bit-level operator like this:

```
if (flags & value) {...}
```

I could, however, write a model function like this one to test:

```
template
constexpr bool has_value(T flags, T value)
{
return (std::underlying_type_t)flags & (std::underlying_type_t)value;
}
```

but I would really like to use the old format to test the values in the flags

I already found a solution on github which included all the emums chosen in a class called flags and which was used like the old ones but with the safety type of enum classes

Since I do not want to use templates for this purpose and I just want the & operator to give me a bool value in if expressions, I've used another class containing the enum value and can be converted to bool. That's 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)enum_value != 0; }
};
inline constexpr EnumBool##x operator&(const x lhs, const x rhs)
{
return EnumBool##x((x)((std::underlying_type_t)lhs & (std::underlying_type_t)rhs));
}
inline constexpr x operator|(const x lhs, const x rhs)
{
return (x)((std::underlying_type_t)lhs | (std::underlying_type_t)rhs);
}
inline constexpr x operator^(const x lhs, const x rhs)
{
return (x)((std::underlying_type_t)lhs ^ (std::underlying_type_t)rhs);
}
inline constexpr x operator~(const x lhs)
{
return (x)(~(std::underlying_type_t)lhs);
}
inline constexpr x& operator|=(x& lhs, const x rhs)
{
lhs = (x)((std::underlying_type_t)lhs | (std::underlying_type_t)rhs);
return lhs;
}
inline constexpr x& operator&=(x& lhs, const x rhs)
{
lhs = (x)((std::underlying_type_t)lhs & (std::underlying_type_t)rhs);
return lhs;
}
inline constexpr x& operator^=(x& lhs, const x rhs)
{
lhs = (x)((std::underlying_type_t)lhs ^ (std::underlying_type_t)rhs);
return lhs;
}
inline constexpr bool operator==(const x lhs, const x rhs)
{
return (std::underlying_type_t)lhs == (std::underlying_type_t)rhs;
}
inline constexpr bool operator!=(const x lhs, const x rhs)
{
return (std::underlying_type_t)lhs != (std::underlying_type_t)rhs;
}
inline constexpr bool operator>(const x lhs, const x rhs)
{
return (std::underlying_type_t)lhs > (std::underlying_type_t)rhs;
}
inline constexpr bool operator<(const x lhs, const x rhs)
{
return (std::underlying_type_t)lhs < (std::underlying_type_t)rhs;
}
inline constexpr bool operator>=(const x lhs, const x rhs)
{
return (std::underlying_type_t)lhs >= (std::underlying_type_t)rhs;
}
inline constexpr bool operator<=(const x lhs, const x rhs)
{
return (std::underlying_type_t)lhs <= (std::underlying_type_t)rhs;
}
```