Core: Make Uuid constexpr

This commit is contained in:
SirLynix 2022-12-29 12:13:18 +01:00
parent 9a553e5e9d
commit 763bef3fdd
3 changed files with 103 additions and 93 deletions

View File

@ -19,39 +19,36 @@ namespace Nz
class NAZARA_CORE_API Uuid class NAZARA_CORE_API Uuid
{ {
public: public:
inline Uuid(); constexpr Uuid();
inline Uuid(const std::array<UInt8, 16> uuid); constexpr Uuid(const std::array<UInt8, 16>& uuid);
Uuid(const Uuid&) = default; Uuid(const Uuid&) = default;
Uuid(Uuid&& generator) = default; Uuid(Uuid&&) = default;
~Uuid() = default; ~Uuid() = default;
inline bool IsNull() const; constexpr bool IsNull() const;
inline const std::array<UInt8, 16>& ToArray() const; constexpr const std::array<UInt8, 16>& ToArray() const;
inline std::string ToString() const; inline std::string ToString() const;
std::array<char, 37> ToStringArray() const; std::array<char, 37> ToStringArray() const;
Uuid& operator=(const Uuid&) = default; Uuid& operator=(const Uuid&) = default;
Uuid& operator=(Uuid&&) = default; Uuid& operator=(Uuid&&) = default;
static Uuid FromString(std::string_view str); static constexpr Uuid FromString(std::string_view str);
static Uuid Generate(); static Uuid Generate();
private: private:
std::array<UInt8, 16> m_uuid; std::array<UInt8, 16> m_uuid;
}; };
NAZARA_CORE_API std::ostream& operator<<(std::ostream& out, const Uuid& uuid); inline std::ostream& operator<<(std::ostream& out, const Uuid& uuid);
inline bool operator==(const Uuid& lhs, const Uuid& rhs); constexpr bool operator==(const Uuid& lhs, const Uuid& rhs);
inline bool operator!=(const Uuid& lhs, const Uuid& rhs); constexpr bool operator!=(const Uuid& lhs, const Uuid& rhs);
inline bool operator<(const Uuid& lhs, const Uuid& rhs); constexpr bool operator<(const Uuid& lhs, const Uuid& rhs);
inline bool operator<=(const Uuid& lhs, const Uuid& rhs); constexpr bool operator<=(const Uuid& lhs, const Uuid& rhs);
inline bool operator>(const Uuid& lhs, const Uuid& rhs); constexpr bool operator>(const Uuid& lhs, const Uuid& rhs);
inline bool operator>=(const Uuid& lhs, const Uuid& rhs); constexpr bool operator>=(const Uuid& lhs, const Uuid& rhs);
}
namespace Nz
{
inline bool Serialize(SerializationContext& context, const Uuid& value, TypeTag<Uuid>); inline bool Serialize(SerializationContext& context, const Uuid& value, TypeTag<Uuid>);
inline bool Unserialize(SerializationContext& context, Uuid* value, TypeTag<Uuid>); inline bool Unserialize(SerializationContext& context, Uuid* value, TypeTag<Uuid>);
} }

View File

@ -7,23 +7,45 @@
namespace Nz namespace Nz
{ {
inline Uuid::Uuid() namespace Detail
{ {
m_uuid.fill(0); constexpr bool ParseHexadecimalPair(Pointer<const char>& str, UInt8& number)
{
number = 0;
for (UInt8 mul : { UInt8(0x10), UInt8(1) })
{
if (*str >= '0' && *str <= '9')
number += (*str - '0') * mul;
else if (((*str & 0x5F) >= 'A' && (*str & 0x5F) <= 'F'))
number += ((*str & 0x5F) - 'A' + 10) * mul;
else
return false;
str++;
} }
inline Uuid::Uuid(const std::array<UInt8, 16> uuid) : return true;
}
}
constexpr Uuid::Uuid() :
m_uuid{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
{
}
constexpr Uuid::Uuid(const std::array<UInt8, 16>& uuid) :
m_uuid(uuid) m_uuid(uuid)
{ {
} }
inline bool Uuid::IsNull() const constexpr bool Uuid::IsNull() const
{ {
Uuid nullUuid; Uuid nullUuid;
return *this == nullUuid; return *this == nullUuid;
} }
inline const std::array<UInt8, 16>& Uuid::ToArray() const constexpr const std::array<UInt8, 16>& Uuid::ToArray() const
{ {
return m_uuid; return m_uuid;
} }
@ -35,39 +57,80 @@ namespace Nz
return std::string(uuidStr.data(), uuidStr.size() - 1); return std::string(uuidStr.data(), uuidStr.size() - 1);
} }
bool operator==(const Uuid& lhs, const Uuid& rhs) constexpr Uuid Uuid::FromString(std::string_view str)
{ {
return lhs.ToArray() == rhs.ToArray(); if (str.size() != 36)
return {};
const char* ptr = str.data();
std::array<UInt8, 16> uuid = { 0 };
UInt8* uuidPart = &uuid[0];
bool first = true;
for (std::size_t groupSize : { 4, 2, 2, 2, 6 })
{
if (!first && *ptr++ != '-')
return {};
first = false;
for (std::size_t i = 0; i < groupSize; ++i)
{
if (!Detail::ParseHexadecimalPair(ptr, *uuidPart++))
return {};
}
} }
bool operator!=(const Uuid& lhs, const Uuid& rhs) return Uuid{ uuid };
{
return lhs.ToArray() != rhs.ToArray();
} }
bool operator<(const Uuid& lhs, const Uuid& rhs) constexpr bool operator==(const Uuid& lhs, const Uuid& rhs)
{ {
return lhs.ToArray() < rhs.ToArray(); const std::array<UInt8, 16>& lhsArray = lhs.ToArray();
const std::array<UInt8, 16>& rhsArray = rhs.ToArray();
for (std::size_t i = 0; i < lhsArray.size(); ++i)
{
if (lhsArray[i] != rhsArray[i])
return false;
} }
bool operator<=(const Uuid& lhs, const Uuid& rhs) return true;
{
return lhs.ToArray() <= rhs.ToArray();
} }
bool operator>(const Uuid& lhs, const Uuid& rhs) constexpr bool operator!=(const Uuid& lhs, const Uuid& rhs)
{ {
return lhs.ToArray() > rhs.ToArray(); return !(lhs == rhs);
} }
bool operator>=(const Uuid& lhs, const Uuid& rhs) constexpr bool operator<(const Uuid& lhs, const Uuid& rhs)
{ {
return lhs.ToArray() >= rhs.ToArray(); const std::array<UInt8, 16>& lhsArray = lhs.ToArray();
const std::array<UInt8, 16>& rhsArray = rhs.ToArray();
for (std::size_t i = 0; i < lhsArray.size(); ++i)
{
if (lhsArray[i] != rhsArray[i])
return lhsArray[i] < rhsArray[i];
}
return false;
}
constexpr bool operator<=(const Uuid& lhs, const Uuid& rhs)
{
return !(rhs < lhs);
}
constexpr bool operator>(const Uuid& lhs, const Uuid& rhs)
{
return rhs < lhs;
}
constexpr bool operator>=(const Uuid& lhs, const Uuid& rhs)
{
return !(lhs < rhs);
} }
}
namespace Nz
{
bool Serialize(SerializationContext& context, const Uuid& value, TypeTag<Uuid>) bool Serialize(SerializationContext& context, const Uuid& value, TypeTag<Uuid>)
{ {
const std::array<Nz::UInt8, 16>& array = value.ToArray(); const std::array<Nz::UInt8, 16>& array = value.ToArray();
@ -86,6 +149,13 @@ namespace Nz
*value = Uuid(array); *value = Uuid(array);
return true; return true;
} }
std::ostream& operator<<(std::ostream& out, const Uuid& guid)
{
std::array<char, 37> uuidStr = guid.ToStringArray();
return out << uuidStr.data();
}
} }
namespace std namespace std

View File

@ -15,28 +15,6 @@
namespace Nz namespace Nz
{ {
namespace
{
bool ParseHexadecimalPair(Pointer<const char>& str, UInt8& number)
{
number = 0;
for (UInt8 mul : { UInt8(0x10), UInt8(1) })
{
if (*str >= '0' && *str <= '9')
number += (*str - '0') * mul;
else if (((*str & 0x5F) >= 'A' && (*str & 0x5F) <= 'F'))
number += ((*str & 0x5F) - 'A' + 10) * mul;
else
return false;
str++;
}
return true;
}
}
std::array<char, 37> Uuid::ToStringArray() const std::array<char, 37> Uuid::ToStringArray() const
{ {
std::array<char, 37> uuidStr; //< Including \0 std::array<char, 37> uuidStr; //< Including \0
@ -47,34 +25,6 @@ namespace Nz
return uuidStr; return uuidStr;
} }
Uuid Uuid::FromString(std::string_view str)
{
if (str.size() != 36)
return {};
const char* ptr = str.data();
std::array<UInt8, 16> uuid;
UInt8* uuidPart = &uuid[0];
bool first = true;
for (std::size_t groupSize : { 4, 2, 2, 2, 6 })
{
if (!first && *ptr++ != '-')
return {};
first = false;
for (std::size_t i = 0; i < groupSize; ++i)
{
if (!ParseHexadecimalPair(ptr, *uuidPart++))
return {};
}
}
return Uuid{ uuid };
}
Uuid Uuid::Generate() Uuid Uuid::Generate()
{ {
std::array<UInt8, 16> uuid; std::array<UInt8, 16> uuid;
@ -105,11 +55,4 @@ namespace Nz
return uuid; return uuid;
} }
std::ostream& operator<<(std::ostream& out, const Uuid& guid)
{
std::array<char, 37> uuidStr = guid.ToStringArray();
return out << uuidStr.data();
}
} }