Cemu/src/Common/enumFlags.h
oltolm de4bf7c2c1
Some checks failed
Build check / build (push) Has been cancelled
Generate translation template / generate-pot (push) Has been cancelled
refactor: use concepts instead of SFINAE (#1652)
2025-08-25 01:33:46 +02:00

135 lines
3.9 KiB
C++

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