@see online demo cpp.sh/2kiuy
@see inspiring blog post
@output
Has read permission
Has execute permission
@see online demo cpp.sh/2kiuy
@see inspiring blog post
@output
Has read permission
Has execute permission
| // Example program | |
| #include <iostream> | |
| #include <string> | |
| template<typename Enum> | |
| struct EnableBitMaskOperators | |
| { | |
| static const bool enable = false; | |
| }; | |
| #define ENABLE_BITMASK_OPERATORS(x) \ | |
| template<> \ | |
| struct EnableBitMaskOperators<x> \ | |
| { \ | |
| static const bool enable = true; \ | |
| }; | |
| template<typename Enum> | |
| typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type | |
| operator &(Enum lhs, Enum rhs) | |
| { | |
| using underlying = typename std::underlying_type<Enum>::type; | |
| return static_cast<Enum> ( | |
| static_cast<underlying>(lhs) & | |
| static_cast<underlying>(rhs) | |
| ); | |
| } | |
| template<typename Enum> | |
| typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type | |
| operator ^(Enum lhs, Enum rhs) | |
| { | |
| using underlying = typename std::underlying_type<Enum>::type; | |
| return static_cast<Enum> ( | |
| static_cast<underlying>(lhs) ^ | |
| static_cast<underlying>(rhs) | |
| ); | |
| } | |
| template<typename Enum> | |
| typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type | |
| operator ~(Enum rhs) | |
| { | |
| using underlying = typename std::underlying_type<Enum>::type; | |
| return static_cast<Enum> ( | |
| ~static_cast<underlying>(rhs) | |
| ); | |
| } | |
| template<typename Enum> | |
| typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type | |
| operator |(Enum lhs, Enum rhs) | |
| { | |
| using underlying = typename std::underlying_type<Enum>::type; | |
| return static_cast<Enum> ( | |
| static_cast<underlying>(lhs) | | |
| static_cast<underlying>(rhs) | |
| ); | |
| } | |
| template<typename Enum> | |
| typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type& | |
| operator &=(Enum& lhs, Enum rhs) | |
| { | |
| using underlying = typename std::underlying_type<Enum>::type; | |
| lhs = static_cast<Enum> ( | |
| static_cast<underlying>(lhs) & | |
| static_cast<underlying>(rhs) | |
| ); | |
| return lhs; | |
| } | |
| template<typename Enum> | |
| typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type& | |
| operator ^=(Enum& lhs, Enum rhs) | |
| { | |
| using underlying = typename std::underlying_type<Enum>::type; | |
| lhs = static_cast<Enum> ( | |
| static_cast<underlying>(lhs) ^ | |
| static_cast<underlying>(rhs) | |
| ); | |
| return lhs; | |
| } | |
| template<typename Enum> | |
| typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum&>::type | |
| operator |=(Enum& lhs, Enum rhs) | |
| { | |
| using underlying = typename std::underlying_type<Enum>::type; | |
| lhs = static_cast<Enum> ( | |
| static_cast<underlying>(lhs) | | |
| static_cast<underlying>(rhs) | |
| ); | |
| return lhs; | |
| } | |
| enum class Permissions | |
| { | |
| Readable = 0x4, | |
| Writable = 0x2, | |
| Executable = 0x1 | |
| }; | |
| ENABLE_BITMASK_OPERATORS(Permissions) | |
| int main() | |
| { | |
| Permissions p = Permissions::Readable | Permissions::Writable; // Set default permissions | |
| p |= Permissions::Executable; // Add permission | |
| p &= ~Permissions::Writable; // Remove permission | |
| bool hasReadPermission = static_cast<bool>(p & Permissions::Readable); | |
| bool hasWritePermission = static_cast<bool>(p & Permissions::Writable); | |
| bool hasExecutePermission = static_cast<bool>(p & Permissions::Executable); | |
| if (hasReadPermission) { | |
| std::cout << "Has read permission" << "\n"; | |
| } | |
| if (hasWritePermission) { | |
| std::cout << "Has write permission" << "\n"; | |
| } | |
| if (hasExecutePermission) { | |
| std::cout << "Has execute permission" << "\n"; | |
| } | |
| } |