Skip to content

Instantly share code, notes, and snippets.

@drodil
Last active September 28, 2018 09:12
Show Gist options
  • Save drodil/e885508f52fb4224f515310e64a468d0 to your computer and use it in GitHub Desktop.
Save drodil/e885508f52fb4224f515310e64a468d0 to your computer and use it in GitHub Desktop.
#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