#pragma once #include #define MAKE_FLAGS_ENUM(n) \ template <> \ struct ki::is_flags_enum : std::true_type {} #define SET_FLAG(v, f) v |= f #define UNSET_FLAG(v, f) v &= ~f #define FLAG_IS_SET(v, f) (v & f) == f namespace ki { template struct is_flags_enum : std::false_type {}; template < typename EnumT, typename = typename std::enable_if::value>::type > constexpr EnumT operator|(EnumT lhs, EnumT rhs) { using type = typename std::underlying_type::type; return static_cast( static_cast(lhs) | static_cast(rhs) ); } template < typename EnumT, typename = typename std::enable_if::value>::type > constexpr EnumT operator&(EnumT lhs, EnumT rhs) { using type = typename std::underlying_type::type; return static_cast( static_cast(lhs) & static_cast(rhs) ); } template < typename EnumT, typename = typename std::enable_if::value>::type > constexpr EnumT operator~(EnumT lhs) { using type = typename std::underlying_type::type; return static_cast(~static_cast(lhs)); } template < typename EnumT, typename = typename std::enable_if::value>::type > EnumT &operator|=(EnumT &lhs, EnumT rhs) { return lhs = lhs | rhs; } template < typename EnumT, typename = typename std::enable_if::value>::type > EnumT &operator&=(EnumT &lhs, EnumT rhs) { return lhs = lhs & rhs; } }