More util::uuid functions: create from string, check for/convert to RFC 4122

This commit is contained in:
Nikita Lisitsa 2023-08-23 00:04:05 +03:00
parent 8a7891d561
commit 2d2362d85c
2 changed files with 76 additions and 1 deletions

View file

@ -4,15 +4,66 @@
#include <array>
#include <cstdint>
#include <string_view>
#include <iostream>
namespace psemek::util
{
using uuid = std::array<std::uint64_t, 2>;
struct uuid
{
std::uint64_t values[2];
constexpr std::uint64_t & operator[](std::size_t i)
{
return values[i];
}
constexpr std::uint64_t const & operator[](std::size_t i) const
{
return values[i];
}
constexpr friend bool operator == (uuid const &, uuid const &) = default;
constexpr friend std::strong_ordering operator <=> (uuid const &, uuid const &) = default;
};
static_assert(sizeof(uuid) == 16);
static_assert(alignof(uuid) == 8);
constexpr bool is_rfc_4122(uuid const & uuid)
{
return ((uuid[0] & 0x00f0000000000000ull) == 0x0040000000000000ull)
&& ((uuid[1] & 0x00000000000000c0ull) == 0x0000000000000080ull);
}
constexpr uuid make_rfc_4122(uuid uuid)
{
uuid[0] = (uuid[0] & 0xff0fffffffffffffull) | 0x0040000000000000ull;
uuid[1] = (uuid[1] & 0xffffffffffffff3full) | 0x0000000000000080ull;
return uuid;
}
// TODO: use SHA-1 or something like that?
constexpr uuid make_uuid(std::string_view str)
{
struct char_hash
{
constexpr std::size_t operator()(char c) const noexcept
{
return static_cast<std::size_t>(c);
}
};
uuid result{0x6eb49abceae6db24ull, 0x476c4c69fd7925a7ull};
hash_sequence(result[0], str.begin(), str.end(), char_hash{});
hash_sequence(result[1], str.begin(), str.end(), char_hash{});
make_rfc_4122(result);
return result;
}
std::ostream & operator << (std::ostream & os, uuid const & uuid);
}
namespace std

24
libs/util/source/uuid.cpp Normal file
View file

@ -0,0 +1,24 @@
#include <psemek/util/uuid.hpp>
#include <iomanip>
namespace psemek::util
{
std::ostream & operator << (std::ostream & os, uuid const & uuid)
{
os << std::hex << std::setfill('0') << std::left;
os << std::setw(8) << (uuid[0] & 0x00000000ffffffffull);
os << std::setw(1) << '-';
os << std::setw(4) << ((uuid[0] & 0x0000ffff00000000ull) >> 32);
os << std::setw(1) << '-';
os << std::setw(4) << ((uuid[0] & 0xffff000000000000ull) >> 48);
os << std::setw(1) << '-';
os << std::setw(4) << (uuid[1] & 0x000000000000ffffull);
os << std::setw(1) << '-';
os << std::setw(12) << ((uuid[1] & 0xffffffffffff0000ull) >> 16);
return os;
}
}