Skip to content

Instantly share code, notes, and snippets.

@codebrainz
Created February 26, 2020 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codebrainz/530933472f15696a508631c306d82c6c to your computer and use it in GitHub Desktop.
Save codebrainz/530933472f15696a508631c306d82c6c to your computer and use it in GitHub Desktop.
For using C++ enum class values as bit flags.
#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