Core/Flags: Reworked Flags class
This commit is contained in:
parent
f2506ee918
commit
3589a2bc8e
|
|
@ -10,7 +10,7 @@ Nazara Engine:
|
|||
- Fix reflection sometimes being enabled by default for Materials
|
||||
- Fix built-in unserialization of std::string which was corruption memory
|
||||
- Fix Buffer::Destroy() not really destroying buffer
|
||||
|
||||
- ⚠️ Reworked Flags class, replaced EnumAsFlags<E>::value by IsEnumFlag<E>::value, EnumAsFlags<E> no longer need to contains a `value` field. The `max` field can also be of the same type as the enum.
|
||||
|
||||
Nazara Development Kit:
|
||||
- Added ImageWidget (#139)
|
||||
|
|
|
|||
|
|
@ -94,8 +94,7 @@ namespace Nz
|
|||
template<>
|
||||
struct EnumAsFlags<OpenMode>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
static constexpr int max = OpenMode_Max;
|
||||
static constexpr OpenMode max = OpenMode_Max;
|
||||
};
|
||||
|
||||
using OpenModeFlags = Flags<OpenMode>;
|
||||
|
|
@ -198,8 +197,7 @@ namespace Nz
|
|||
template<>
|
||||
struct EnumAsFlags<StreamOption>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
static constexpr int max = StreamOption_Max;
|
||||
static constexpr StreamOption max = StreamOption_Max;
|
||||
};
|
||||
|
||||
using StreamOptionFlags = Flags<StreamOption>;
|
||||
|
|
|
|||
|
|
@ -16,18 +16,34 @@ namespace Nz
|
|||
template<typename E>
|
||||
struct EnumAsFlags
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
static constexpr int max = 0;
|
||||
};
|
||||
|
||||
// From: https://stackoverflow.com/questions/11927032/sfinae-check-for-static-member-using-decltype
|
||||
template <typename T>
|
||||
class IsEnumFlag
|
||||
{
|
||||
template<typename U, typename = typename std::enable_if<!std::is_member_pointer<decltype(&EnumAsFlags<U>::max)>::value>::type>
|
||||
static std::true_type check(int);
|
||||
|
||||
template <typename> static std::false_type check(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(check<T>(0))::value;
|
||||
};
|
||||
|
||||
template<typename E>
|
||||
class Flags
|
||||
{
|
||||
static_assert(std::is_enum<E>::value, "Type must be an enumeration");
|
||||
static_assert(EnumAsFlags<E>::value, "Enum has not been enabled as flags by an EnumAsFlags specialization");
|
||||
static_assert(IsEnumFlag<E>::value, "Enum has not been enabled as flags by an EnumAsFlags specialization");
|
||||
|
||||
static constexpr std::size_t MaxValue = static_cast<std::size_t>(EnumAsFlags<E>::max);
|
||||
|
||||
using BitField16 = typename std::conditional<(MaxValue > 8), UInt16, UInt8>::type;
|
||||
using BitField32 = typename std::conditional<(MaxValue > 16), UInt32, BitField16>::type;
|
||||
|
||||
public:
|
||||
using BitField = typename std::conditional<(EnumAsFlags<E>::max > 32), UInt64, UInt32>::type;
|
||||
using BitField = typename std::conditional<(MaxValue > 32), UInt64, BitField32>::type;
|
||||
|
||||
constexpr Flags(BitField value = 0);
|
||||
constexpr Flags(E enumVal);
|
||||
|
|
@ -49,7 +65,7 @@ namespace Nz
|
|||
|
||||
static constexpr BitField GetFlagValue(E enumValue);
|
||||
|
||||
static constexpr BitField ValueMask = ((BitField(1) << (EnumAsFlags<E>::max + 1)) - 1);
|
||||
static constexpr BitField ValueMask = ((BitField(1) << (MaxValue + 1)) - 1);
|
||||
|
||||
private:
|
||||
BitField m_value;
|
||||
|
|
@ -58,10 +74,10 @@ namespace Nz
|
|||
// Little hack to have them in both Nz and global scope
|
||||
namespace FlagsOperators
|
||||
{
|
||||
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator~(E lhs);
|
||||
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator|(E lhs, E rhs);
|
||||
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator&(E lhs, E rhs);
|
||||
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator^(E lhs, E rhs);
|
||||
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator~(E lhs);
|
||||
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator|(E lhs, E rhs);
|
||||
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator&(E lhs, E rhs);
|
||||
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator^(E lhs, E rhs);
|
||||
}
|
||||
|
||||
using namespace FlagsOperators;
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ namespace Nz
|
|||
* Returns a Flags object with all state enabled except for the enum one.
|
||||
*/
|
||||
template<typename E>
|
||||
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator~(E lhs)
|
||||
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator~(E lhs)
|
||||
{
|
||||
return ~Flags<E>(lhs);
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ namespace Nz
|
|||
* Returns a Flags object with combined states from the two enumeration values.
|
||||
*/
|
||||
template<typename E>
|
||||
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator|(E lhs, E rhs)
|
||||
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator|(E lhs, E rhs)
|
||||
{
|
||||
return Flags<E>(lhs) | rhs;
|
||||
}
|
||||
|
|
@ -253,7 +253,7 @@ namespace Nz
|
|||
* In this case, only one flag will be enabled if both enumeration values are the same.
|
||||
*/
|
||||
template<typename E>
|
||||
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator&(E lhs, E rhs)
|
||||
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator&(E lhs, E rhs)
|
||||
{
|
||||
return Flags<E>(lhs) & rhs;
|
||||
}
|
||||
|
|
@ -269,7 +269,7 @@ namespace Nz
|
|||
* In this case, two flags will be enabled if both the enumeration values are different.
|
||||
*/
|
||||
template<typename E>
|
||||
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator^(E lhs, E rhs)
|
||||
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator^(E lhs, E rhs)
|
||||
{
|
||||
return Flags<E>(lhs) ^ rhs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,21 +70,21 @@ namespace Nz
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
|
||||
std::enable_if_t<std::is_enum<T>::value && !IsEnumFlag<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
|
||||
{
|
||||
using UnderlyingT = std::underlying_type_t<T>;
|
||||
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), TypeTag<UnderlyingT>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
|
||||
std::enable_if_t<std::is_enum<T>::value && !IsEnumFlag<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
|
||||
{
|
||||
using UnderlyingT = std::underlying_type_t<T>;
|
||||
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), static_cast<UnderlyingT>(defValue), TypeTag<UnderlyingT>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
|
||||
std::enable_if_t<std::is_enum<T>::value && IsEnumFlag<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
|
||||
{
|
||||
using UnderlyingT = std::underlying_type_t<T>;
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ namespace Nz
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
|
||||
std::enable_if_t<std::is_enum<T>::value && IsEnumFlag<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
|
||||
{
|
||||
using UnderlyingT = std::underlying_type_t<T>;
|
||||
|
||||
|
|
@ -186,14 +186,14 @@ namespace Nz
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T>)
|
||||
std::enable_if_t<std::is_enum<T>::value && !IsEnumFlag<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T>)
|
||||
{
|
||||
using EnumT = typename std::underlying_type<T>::type;
|
||||
return LuaImplReplyVal(instance, static_cast<EnumT>(val), TypeTag<EnumT>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T>)
|
||||
std::enable_if_t<std::is_enum<T>::value && IsEnumFlag<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T>)
|
||||
{
|
||||
Flags<T> flags(val);
|
||||
return LuaImplReplyVal(instance, flags, TypeTag<decltype(flags)>());
|
||||
|
|
@ -202,7 +202,7 @@ namespace Nz
|
|||
template<typename E>
|
||||
int LuaImplReplyVal(const LuaState& instance, Flags<E> val, TypeTag<Flags<E>>)
|
||||
{
|
||||
instance.PushInteger(UInt32(val));
|
||||
instance.PushInteger(Flags<E>::BitField(val));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ namespace Nz
|
|||
template<>
|
||||
struct EnumAsFlags<ENetPacketFlag>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
static constexpr int max = ENetPacketFlag_UnreliableFragment;
|
||||
static constexpr ENetPacketFlag max = ENetPacketFlag_UnreliableFragment;
|
||||
};
|
||||
|
||||
using ENetPacketFlags = Flags<ENetPacketFlag>;
|
||||
|
|
|
|||
|
|
@ -102,8 +102,7 @@ namespace Nz
|
|||
template<>
|
||||
struct EnumAsFlags<SocketPollEvent>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
static constexpr int max = SocketPollEvent_Max;
|
||||
static constexpr SocketPollEvent max = SocketPollEvent_Max;
|
||||
};
|
||||
|
||||
using SocketPollEventFlags = Flags<SocketPollEvent>;
|
||||
|
|
|
|||
|
|
@ -73,8 +73,7 @@ namespace Nz
|
|||
template<>
|
||||
struct EnumAsFlags<WindowStyle>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
static constexpr int max = WindowStyle_Max;
|
||||
static constexpr WindowStyle max = WindowStyle_Max;
|
||||
};
|
||||
|
||||
using WindowStyleFlags = Flags<WindowStyle>;
|
||||
|
|
|
|||
|
|
@ -64,8 +64,7 @@ namespace Nz
|
|||
template<>
|
||||
struct EnumAsFlags<BufferUsage>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
static constexpr int max = BufferUsage_Max;
|
||||
static constexpr BufferUsage max = BufferUsage_Max;
|
||||
};
|
||||
|
||||
using BufferUsageFlags = Flags<BufferUsage>;
|
||||
|
|
|
|||
|
|
@ -69,12 +69,12 @@ namespace Nz
|
|||
std::vector<Frame> m_frames;
|
||||
std::vector<Joint> m_joints;
|
||||
Stream& m_stream;
|
||||
StreamOptionFlags m_streamFlags;
|
||||
String m_currentLine;
|
||||
bool m_keepLastLine;
|
||||
unsigned int m_frameIndex;
|
||||
unsigned int m_frameRate;
|
||||
unsigned int m_lineCount;
|
||||
unsigned int m_streamFlags;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,11 +75,11 @@ namespace Nz
|
|||
std::vector<Joint> m_joints;
|
||||
std::vector<Mesh> m_meshes;
|
||||
Stream& m_stream;
|
||||
StreamOptionFlags m_streamFlags;
|
||||
String m_currentLine;
|
||||
bool m_keepLastLine;
|
||||
unsigned int m_lineCount;
|
||||
unsigned int m_meshIndex;
|
||||
unsigned int m_streamFlags;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ namespace Nz
|
|||
{
|
||||
MD5AnimParser::MD5AnimParser(Stream& stream) :
|
||||
m_stream(stream),
|
||||
m_streamFlags(stream.GetStreamOptions()), //< Saves stream flags
|
||||
m_keepLastLine(false),
|
||||
m_frameIndex(0),
|
||||
m_frameRate(0),
|
||||
m_lineCount(0),
|
||||
m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags
|
||||
m_lineCount(0)
|
||||
{
|
||||
m_stream.EnableTextMode(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ namespace Nz
|
|||
{
|
||||
MD5MeshParser::MD5MeshParser(Stream& stream) :
|
||||
m_stream(stream),
|
||||
m_streamFlags(stream.GetStreamOptions()), //< Saves stream flags
|
||||
m_keepLastLine(false),
|
||||
m_lineCount(0),
|
||||
m_meshIndex(0),
|
||||
m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags
|
||||
m_meshIndex(0)
|
||||
{
|
||||
m_stream.EnableTextMode(true);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue