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 reflection sometimes being enabled by default for Materials
|
||||||
- Fix built-in unserialization of std::string which was corruption memory
|
- Fix built-in unserialization of std::string which was corruption memory
|
||||||
- Fix Buffer::Destroy() not really destroying buffer
|
- 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:
|
Nazara Development Kit:
|
||||||
- Added ImageWidget (#139)
|
- Added ImageWidget (#139)
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,7 @@ namespace Nz
|
||||||
template<>
|
template<>
|
||||||
struct EnumAsFlags<OpenMode>
|
struct EnumAsFlags<OpenMode>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr OpenMode max = OpenMode_Max;
|
||||||
static constexpr int max = OpenMode_Max;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using OpenModeFlags = Flags<OpenMode>;
|
using OpenModeFlags = Flags<OpenMode>;
|
||||||
|
|
@ -198,8 +197,7 @@ namespace Nz
|
||||||
template<>
|
template<>
|
||||||
struct EnumAsFlags<StreamOption>
|
struct EnumAsFlags<StreamOption>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr StreamOption max = StreamOption_Max;
|
||||||
static constexpr int max = StreamOption_Max;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using StreamOptionFlags = Flags<StreamOption>;
|
using StreamOptionFlags = Flags<StreamOption>;
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,34 @@ namespace Nz
|
||||||
template<typename E>
|
template<typename E>
|
||||||
struct EnumAsFlags
|
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>
|
template<typename E>
|
||||||
class Flags
|
class Flags
|
||||||
{
|
{
|
||||||
static_assert(std::is_enum<E>::value, "Type must be an enumeration");
|
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:
|
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(BitField value = 0);
|
||||||
constexpr Flags(E enumVal);
|
constexpr Flags(E enumVal);
|
||||||
|
|
@ -49,7 +65,7 @@ namespace Nz
|
||||||
|
|
||||||
static constexpr BitField GetFlagValue(E enumValue);
|
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:
|
private:
|
||||||
BitField m_value;
|
BitField m_value;
|
||||||
|
|
@ -58,10 +74,10 @@ namespace Nz
|
||||||
// Little hack to have them in both Nz and global scope
|
// Little hack to have them in both Nz and global scope
|
||||||
namespace FlagsOperators
|
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<IsEnumFlag<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<IsEnumFlag<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, 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, E rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace FlagsOperators;
|
using namespace FlagsOperators;
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ namespace Nz
|
||||||
* Returns a Flags object with all state enabled except for the enum one.
|
* Returns a Flags object with all state enabled except for the enum one.
|
||||||
*/
|
*/
|
||||||
template<typename E>
|
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);
|
return ~Flags<E>(lhs);
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +237,7 @@ namespace Nz
|
||||||
* Returns a Flags object with combined states from the two enumeration values.
|
* Returns a Flags object with combined states from the two enumeration values.
|
||||||
*/
|
*/
|
||||||
template<typename E>
|
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;
|
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.
|
* In this case, only one flag will be enabled if both enumeration values are the same.
|
||||||
*/
|
*/
|
||||||
template<typename E>
|
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;
|
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.
|
* In this case, two flags will be enabled if both the enumeration values are different.
|
||||||
*/
|
*/
|
||||||
template<typename E>
|
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;
|
return Flags<E>(lhs) ^ rhs;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,21 +70,21 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
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>;
|
using UnderlyingT = std::underlying_type_t<T>;
|
||||||
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), TypeTag<UnderlyingT>());
|
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), TypeTag<UnderlyingT>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
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>;
|
using UnderlyingT = std::underlying_type_t<T>;
|
||||||
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), static_cast<UnderlyingT>(defValue), TypeTag<UnderlyingT>());
|
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), static_cast<UnderlyingT>(defValue), TypeTag<UnderlyingT>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
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>;
|
using UnderlyingT = std::underlying_type_t<T>;
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
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>;
|
using UnderlyingT = std::underlying_type_t<T>;
|
||||||
|
|
||||||
|
|
@ -186,14 +186,14 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
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;
|
using EnumT = typename std::underlying_type<T>::type;
|
||||||
return LuaImplReplyVal(instance, static_cast<EnumT>(val), TypeTag<EnumT>());
|
return LuaImplReplyVal(instance, static_cast<EnumT>(val), TypeTag<EnumT>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
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);
|
Flags<T> flags(val);
|
||||||
return LuaImplReplyVal(instance, flags, TypeTag<decltype(flags)>());
|
return LuaImplReplyVal(instance, flags, TypeTag<decltype(flags)>());
|
||||||
|
|
@ -202,7 +202,7 @@ namespace Nz
|
||||||
template<typename E>
|
template<typename E>
|
||||||
int LuaImplReplyVal(const LuaState& instance, Flags<E> val, TypeTag<Flags<E>>)
|
int LuaImplReplyVal(const LuaState& instance, Flags<E> val, TypeTag<Flags<E>>)
|
||||||
{
|
{
|
||||||
instance.PushInteger(UInt32(val));
|
instance.PushInteger(Flags<E>::BitField(val));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,7 @@ namespace Nz
|
||||||
template<>
|
template<>
|
||||||
struct EnumAsFlags<ENetPacketFlag>
|
struct EnumAsFlags<ENetPacketFlag>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr ENetPacketFlag max = ENetPacketFlag_UnreliableFragment;
|
||||||
static constexpr int max = ENetPacketFlag_UnreliableFragment;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using ENetPacketFlags = Flags<ENetPacketFlag>;
|
using ENetPacketFlags = Flags<ENetPacketFlag>;
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,7 @@ namespace Nz
|
||||||
template<>
|
template<>
|
||||||
struct EnumAsFlags<SocketPollEvent>
|
struct EnumAsFlags<SocketPollEvent>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr SocketPollEvent max = SocketPollEvent_Max;
|
||||||
static constexpr int max = SocketPollEvent_Max;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using SocketPollEventFlags = Flags<SocketPollEvent>;
|
using SocketPollEventFlags = Flags<SocketPollEvent>;
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,7 @@ namespace Nz
|
||||||
template<>
|
template<>
|
||||||
struct EnumAsFlags<WindowStyle>
|
struct EnumAsFlags<WindowStyle>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr WindowStyle max = WindowStyle_Max;
|
||||||
static constexpr int max = WindowStyle_Max;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using WindowStyleFlags = Flags<WindowStyle>;
|
using WindowStyleFlags = Flags<WindowStyle>;
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,7 @@ namespace Nz
|
||||||
template<>
|
template<>
|
||||||
struct EnumAsFlags<BufferUsage>
|
struct EnumAsFlags<BufferUsage>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr BufferUsage max = BufferUsage_Max;
|
||||||
static constexpr int max = BufferUsage_Max;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using BufferUsageFlags = Flags<BufferUsage>;
|
using BufferUsageFlags = Flags<BufferUsage>;
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,12 @@ namespace Nz
|
||||||
std::vector<Frame> m_frames;
|
std::vector<Frame> m_frames;
|
||||||
std::vector<Joint> m_joints;
|
std::vector<Joint> m_joints;
|
||||||
Stream& m_stream;
|
Stream& m_stream;
|
||||||
|
StreamOptionFlags m_streamFlags;
|
||||||
String m_currentLine;
|
String m_currentLine;
|
||||||
bool m_keepLastLine;
|
bool m_keepLastLine;
|
||||||
unsigned int m_frameIndex;
|
unsigned int m_frameIndex;
|
||||||
unsigned int m_frameRate;
|
unsigned int m_frameRate;
|
||||||
unsigned int m_lineCount;
|
unsigned int m_lineCount;
|
||||||
unsigned int m_streamFlags;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,11 @@ namespace Nz
|
||||||
std::vector<Joint> m_joints;
|
std::vector<Joint> m_joints;
|
||||||
std::vector<Mesh> m_meshes;
|
std::vector<Mesh> m_meshes;
|
||||||
Stream& m_stream;
|
Stream& m_stream;
|
||||||
|
StreamOptionFlags m_streamFlags;
|
||||||
String m_currentLine;
|
String m_currentLine;
|
||||||
bool m_keepLastLine;
|
bool m_keepLastLine;
|
||||||
unsigned int m_lineCount;
|
unsigned int m_lineCount;
|
||||||
unsigned int m_meshIndex;
|
unsigned int m_meshIndex;
|
||||||
unsigned int m_streamFlags;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
MD5AnimParser::MD5AnimParser(Stream& stream) :
|
MD5AnimParser::MD5AnimParser(Stream& stream) :
|
||||||
m_stream(stream),
|
m_stream(stream),
|
||||||
|
m_streamFlags(stream.GetStreamOptions()), //< Saves stream flags
|
||||||
m_keepLastLine(false),
|
m_keepLastLine(false),
|
||||||
m_frameIndex(0),
|
m_frameIndex(0),
|
||||||
m_frameRate(0),
|
m_frameRate(0),
|
||||||
m_lineCount(0),
|
m_lineCount(0)
|
||||||
m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags
|
|
||||||
{
|
{
|
||||||
m_stream.EnableTextMode(true);
|
m_stream.EnableTextMode(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ namespace Nz
|
||||||
{
|
{
|
||||||
MD5MeshParser::MD5MeshParser(Stream& stream) :
|
MD5MeshParser::MD5MeshParser(Stream& stream) :
|
||||||
m_stream(stream),
|
m_stream(stream),
|
||||||
|
m_streamFlags(stream.GetStreamOptions()), //< Saves stream flags
|
||||||
m_keepLastLine(false),
|
m_keepLastLine(false),
|
||||||
m_lineCount(0),
|
m_lineCount(0),
|
||||||
m_meshIndex(0),
|
m_meshIndex(0)
|
||||||
m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags
|
|
||||||
{
|
{
|
||||||
m_stream.EnableTextMode(true);
|
m_stream.EnableTextMode(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue