Created
February 26, 2020 02:21
-
-
Save codebrainz/530933472f15696a508631c306d82c6c to your computer and use it in GitHub Desktop.
For using C++ enum class values as bit flags.
This file contains 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
#pragma once | |
#include <type_traits> | |
template <typename E> | |
struct enable_enum_flags { | |
static constexpr const bool value = false; | |
}; | |
template <typename E> | |
typename std::enable_if<enable_enum_flags<E>::value, E>::type // | | |
operator|(E lhs, E rhs) { | |
using UT = std::underlying_type_t<E>; | |
return static_cast<E>(static_cast<UT>(lhs) | static_cast<UT>(rhs)); | |
} | |
template <typename E> | |
typename std::enable_if<enable_enum_flags<E>::value, E>::type // & | |
operator&(E lhs, E rhs) { | |
using UT = std::underlying_type_t<E>; | |
return static_cast<E>(static_cast<UT>(lhs) & static_cast<UT>(rhs)); | |
} | |
template <typename E> | |
typename std::enable_if<enable_enum_flags<E>::value, E>::type // ^ | |
operator^(E lhs, E rhs) { | |
using UT = std::underlying_type_t<E>; | |
return static_cast<E>(static_cast<UT>(lhs) ^ static_cast<UT>(rhs)); | |
} | |
template <typename E> | |
typename std::enable_if<enable_enum_flags<E>::value, E>::type // ~ | |
operator~(E lhs) { | |
using UT = std::underlying_type_t<E>; | |
return static_cast<E>(~static_cast<UT>(lhs)); | |
} | |
template <typename E> | |
typename std::enable_if<enable_enum_flags<E>::value, E &>::type // |= | |
operator|=(E &lhs, E rhs) { | |
using UT = std::underlying_type_t<E>; | |
lhs = static_cast<E>(static_cast<UT>(lhs) | static_cast<UT>(rhs)); | |
return lhs; | |
} | |
template <typename E> | |
typename std::enable_if<enable_enum_flags<E>::value, E &>::type // &= | |
operator&=(E &lhs, E rhs) { | |
using UT = std::underlying_type_t<E>; | |
lhs = static_cast<E>(static_cast<UT>(lhs) & static_cast<UT>(rhs)); | |
return lhs; | |
} | |
template <typename E> | |
typename std::enable_if<enable_enum_flags<E>::value, E &>::type // ^= | |
operator^=(E &lhs, E rhs) { | |
using UT = std::underlying_type_t<E>; | |
lhs = static_cast<E>(static_cast<UT>(lhs) ^ static_cast<UT>(rhs)); | |
return lhs; | |
} | |
// Don't use this inside a namespace | |
#define ENABLE_ENUM_FLAGS(T) \ | |
template <> \ | |
struct enable_enum_flags<T> { \ | |
static constexpr const bool value = true; \ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment