#pragma once #include // enum flag helpers template struct EnableBitMaskOperators { static const bool enable = false; }; template typename std::enable_if::enable, TEnum>::type operator &(TEnum lhs, TEnum rhs) { return static_cast (static_cast::type>(lhs) & static_cast::type>(rhs)); } template typename std::enable_if::enable, TEnum>::type operator |(TEnum lhs, TEnum rhs) { return static_cast (static_cast::type>(lhs) | static_cast::type>(rhs)); } template typename std::enable_if::enable, TEnum>::type operator ^(TEnum lhs, TEnum rhs) { return static_cast (static_cast::type>(lhs) ^ static_cast::type>(rhs)); } template typename std::enable_if::enable, TEnum>::type operator ~(TEnum rhs) { return static_cast (~static_cast::type>(rhs)); } template typename std::enable_if::enable, TEnum>::type& operator &=(TEnum& lhs, TEnum rhs) { lhs = static_cast (static_cast::type>(lhs) & static_cast::type>(rhs)); return lhs; } template typename std::enable_if::enable, TEnum>::type& operator |=(TEnum& lhs, TEnum rhs) { lhs = static_cast (static_cast::type>(lhs) | static_cast::type>(rhs)); return lhs; } template typename std::enable_if::enable, TEnum>::type& operator ^=(TEnum& lhs, TEnum rhs) { lhs = static_cast (static_cast::type>(lhs) ^ static_cast::type>(rhs)); return lhs; } template::enable>> constexpr bool operator==(TEnum lhs, std::underlying_type_t rhs) { return static_cast>(lhs) == rhs; } template::enable>> constexpr bool operator!=(TEnum lhs, std::underlying_type_t rhs) { return static_cast>(lhs) != rhs; } #define ENABLE_BITMASK_OPERATORS(x) template<> struct EnableBitMaskOperators { static const bool enable = true; }; template struct EnableEnumIterators { static const bool enable = false; }; template typename std::enable_if::enable, TEnum>::type& operator++(TEnum& lhs) { lhs = static_cast(static_cast::type>(lhs) + 1); return lhs; } template typename std::enable_if::enable, TEnum>::type operator*(TEnum rhs) { return rhs; } template typename std::enable_if::enable, TEnum>::type begin(TEnum value) { return EnableEnumIterators::begin; } template typename std::enable_if::enable, TEnum>::type rbegin(TEnum value) { return EnableEnumIterators::rbegin; } template typename std::enable_if::enable, TEnum>::type end(TEnum r) { return EnableEnumIterators::end; } template typename std::enable_if::enable, TEnum>::type rend(TEnum r) { return EnableEnumIterators::rend; } #define ENABLE_ENUM_ITERATORS(x, first_value, last_value) template<> struct EnableEnumIterators {\ static const bool enable = true;\ static const x begin = first_value;\ static const x rbegin = last_value;\ static const x end = static_cast(static_cast::type>(last_value) + 1);\ static const x rend = static_cast(static_cast::type>(first_value) - 1);\ }; // todo: rend type must be signed?