Skip to content

Instantly share code, notes, and snippets.

@hesiod
Last active April 28, 2017 19:52
Show Gist options
  • Save hesiod/957a020d819ca93dcde5747d139286e3 to your computer and use it in GitHub Desktop.
Save hesiod/957a020d819ca93dcde5747d139286e3 to your computer and use it in GitHub Desktop.
Make C++11 (and later) scoped enums (enum classes) behave like bitfields
/* Make C++11 (and later) scoped enums (enum classes) behave like bitfields, i.e. allow bitwise OR/AND (&/|)
*
* Based on and expanded from:
* https://softwareengineering.stackexchange.com/questions/194412/using-scoped-enums-for-bit-flags-in-c/204566#204566
*
* For the legally inclined:
* LICENSE: Software Engineering SE answers are CC BY-SA 2.5, so my modifications are CC BY-SA 2.5 as well
*/
#include <type_traits>
#if __cplusplus < 201103L
#error "C++11 required"
#elif __cplusplus < 201402L
// underlying_type_t was introduced in C++14
template<class T>
using underlying_type_t = typename std::underlying_type<T>::type;
#endif
#define ENUM_OP(opspec) template<typename T> static inline \
T operator opspec(const T& lhs, const T& rhs) { \
using B = typename std::underlying_type_t<T>; \
return static_cast<T>(static_cast<B>(lhs) | static_cast<B>(rhs)); }
#define ENUM_ASSIGN_OP(opspec) template<typename T> static inline \
T& operator opspec ## =(T& lhs, const T& rhs) { \
lhs = lhs opspec rhs; return lhs; }
#define ENUM_OPS(opspec) ENUM_OP(opspec) ENUM_ASSIGN_OP(opspec)
// Provides |, |= on enums
ENUM_OPS(|)
// Provides &, &= on enums
ENUM_OPS(&)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment