Last active
September 28, 2018 09:12
-
-
Save drodil/e885508f52fb4224f515310e64a468d0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <bitset> | |
#include <type_traits> | |
namespace test { | |
// Allows ~ operator for any enum class in the same namespace | |
template<class Enum, class = typename std::enable_if<std::is_enum<Enum>::value, Enum>::type> | |
inline Enum operator~(Enum a) { | |
return static_cast<Enum>(~static_cast<typename std::underlying_type<Enum>::type>(a)); | |
} | |
// Allows | operator for any enum class in the same namespace | |
template<class Enum, class = typename std::enable_if<std::is_enum<Enum>::value, Enum>::type> | |
inline Enum operator|(Enum a, Enum b) { | |
return static_cast<Enum>(static_cast<typename std::underlying_type<Enum>::type>(a) | | |
static_cast<typename std::underlying_type<Enum>::type>(b)); | |
} | |
// Allows & operator for any enum class in the same namespace | |
template<class Enum, class = typename std::enable_if<std::is_enum<Enum>::value, Enum>::type> | |
inline Enum operator&(Enum a, Enum b) { | |
return static_cast<Enum>(static_cast<typename std::underlying_type<Enum>::type>(a) & | |
static_cast<typename std::underlying_type<Enum>::type>(b)); | |
} | |
// Allows ^ operator for any enum class in the same namespace | |
template<class Enum, class = typename std::enable_if<std::is_enum<Enum>::value, Enum>::type> | |
inline Enum operator^(Enum a, Enum b) { | |
return static_cast<Enum>(static_cast<typename std::underlying_type<Enum>::type>(a) ^ | |
static_cast<typename std::underlying_type<Enum>::type>(b)); | |
} | |
// Allows |= operator for any enum class in the same namespace | |
template<class Enum, class = typename std::enable_if<std::is_enum<Enum>::value, Enum>::type> | |
inline Enum& operator|=(Enum& a, Enum b) { | |
return static_cast<Enum&>(static_cast<typename std::underlying_type<Enum>::type&>(a) |= | |
static_cast<typename std::underlying_type<Enum>::type&>(b)); | |
} | |
// Allows &= operator for any enum class in the same namespace | |
template<class Enum, class = typename std::enable_if<std::is_enum<Enum>::value, Enum>::type> | |
inline Enum& operator&=(Enum& a, Enum b) { | |
return static_cast<Enum&>(static_cast<typename std::underlying_type<Enum>::type&>(a) &= | |
static_cast<typename std::underlying_type<Enum>::type&>(b)); | |
} | |
// Allows ^= operator for any enum class in the same namespace | |
template<class Enum, class = typename std::enable_if<std::is_enum<Enum>::value, Enum>::type> | |
inline Enum& operator^=(Enum& a, Enum b) { | |
return static_cast<Enum&>(static_cast<typename std::underlying_type<Enum>::type&>(a) ^= | |
static_cast<typename std::underlying_type<Enum>::type&>(a)); | |
} | |
// Enum class that is inside the same namespace as templates | |
enum class TestEnum { | |
None = 1, First = 2 | |
}; | |
} | |
// Global enum class outside the test namespace | |
enum class OutsideEnum { | |
Second = 2, Third = 3 | |
}; | |
int main() { | |
std::bitset<8> firstCompliment(static_cast<int>(~test::TestEnum::First)); | |
std::cout << "First compliment: " << firstCompliment << std::endl; | |
// This is outside the namespace so it will produce compilation error: | |
// error: no match for 'operator|' (operand types are 'OutsideEnum' and 'OutsideEnum') | |
// OutsideEnum outsideEnum = OutsideEnum::Second | OutsideEnum::Third; | |
std::bitset<8> noneAndFirst(static_cast<int>(test::TestEnum::None | test::TestEnum::First)); | |
std::cout << "None | Second: " << noneAndFirst << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment