-
-
Save retep998/393c5f42156f835b9e0b739f4b4e8a98 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
#ifdef __cplusplus | |
// Define operator overloads to enable bit operations on enum values that are | |
// used to define flags. Use DEFINE_ENUM_FLAG_OPERATORS(YOUR_TYPE) to enable these | |
// operators on YOUR_TYPE. | |
// Moved here from objbase.w. | |
// Templates are defined here in order to avoid a dependency on C++ <type_traits> header file, | |
// or on compiler-specific contructs. | |
extern "C++" { | |
template <size_t S> | |
struct _ENUM_FLAG_INTEGER_FOR_SIZE; | |
template <> | |
struct _ENUM_FLAG_INTEGER_FOR_SIZE<1> | |
{ | |
typedef INT8 type; | |
}; | |
template <> | |
struct _ENUM_FLAG_INTEGER_FOR_SIZE<2> | |
{ | |
typedef INT16 type; | |
}; | |
template <> | |
struct _ENUM_FLAG_INTEGER_FOR_SIZE<4> | |
{ | |
typedef INT32 type; | |
}; | |
template <> | |
struct _ENUM_FLAG_INTEGER_FOR_SIZE<8> | |
{ | |
typedef INT64 type; | |
}; | |
// used as an approximation of std::underlying_type<T> | |
template <class T> | |
struct _ENUM_FLAG_SIZED_INTEGER | |
{ | |
typedef typename _ENUM_FLAG_INTEGER_FOR_SIZE<sizeof(T)>::type type; | |
}; | |
} | |
#if _MSC_VER >= 1900 | |
#define _ENUM_FLAG_CONSTEXPR constexpr | |
#else | |
#define _ENUM_FLAG_CONSTEXPR | |
#endif | |
#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \ | |
extern "C++" { \ | |
inline _ENUM_FLAG_CONSTEXPR ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) throw() { return ENUMTYPE(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)a) | ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \ | |
inline ENUMTYPE &operator |= (ENUMTYPE &a, ENUMTYPE b) throw() { return (ENUMTYPE &)(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type &)a) |= ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \ | |
inline _ENUM_FLAG_CONSTEXPR ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) throw() { return ENUMTYPE(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)a) & ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \ | |
inline ENUMTYPE &operator &= (ENUMTYPE &a, ENUMTYPE b) throw() { return (ENUMTYPE &)(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type &)a) &= ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \ | |
inline _ENUM_FLAG_CONSTEXPR ENUMTYPE operator ~ (ENUMTYPE a) throw() { return ENUMTYPE(~((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)a)); } \ | |
inline _ENUM_FLAG_CONSTEXPR ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) throw() { return ENUMTYPE(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)a) ^ ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \ | |
inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) throw() { return (ENUMTYPE &)(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type &)a) ^= ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment