diff --git a/libs/util/include/psemek/util/uuid.hpp b/libs/util/include/psemek/util/uuid.hpp index 3987444f..cef791de 100644 --- a/libs/util/include/psemek/util/uuid.hpp +++ b/libs/util/include/psemek/util/uuid.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace psemek::util { @@ -44,6 +46,8 @@ namespace psemek::util return uuid; } + // Make a version 3 UUID (name-based, using MD5) + // NB: the namespace UUID is omitted (empty) // TODO: use SHA-1 or something like that? constexpr uuid make_uuid(std::string_view str) { @@ -76,4 +80,21 @@ namespace std } }; + template + struct formatter<::psemek::util::uuid, Char> + { + constexpr auto parse(std::format_parse_context & ctx) + { + return ctx.begin(); + } + + template + auto format(::psemek::util::uuid const & uuid, FormatContext & ctx) const + { + auto x0 = std::byteswap(uuid[0]); + auto x1 = std::byteswap(uuid[1]); + return std::format_to(ctx.out(), "{:08x}-{:04x}-{:04x}-{:04x}-{:012x}", x0 & 0xffffffffull, (x0 >> 4) & 0xfffful, (x0 >> 6) & 0xfffful, x1 & 0xfffful, (x1 >> 2) & 0xffffffffffffull); + } + }; + } diff --git a/libs/util/source/uuid.cpp b/libs/util/source/uuid.cpp index 1505ebf6..8c87fdd6 100644 --- a/libs/util/source/uuid.cpp +++ b/libs/util/source/uuid.cpp @@ -7,16 +7,19 @@ namespace psemek::util std::ostream & operator << (std::ostream & os, uuid const & uuid) { + auto x0 = std::byteswap(uuid[0]); + auto x1 = std::byteswap(uuid[1]); + os << std::hex << std::setfill('0') << std::left; - os << std::setw(8) << (uuid[0] & 0x00000000ffffffffull); + os << std::setw(8) << (x0 & 0xffffffffull); os << std::setw(1) << '-'; - os << std::setw(4) << ((uuid[0] & 0x0000ffff00000000ull) >> 32); + os << std::setw(4) << ((x0 >> 4) & 0xfffful); os << std::setw(1) << '-'; - os << std::setw(4) << ((uuid[0] & 0xffff000000000000ull) >> 48); + os << std::setw(4) << ((x0 >> 6) & 0xfffful); os << std::setw(1) << '-'; - os << std::setw(4) << (uuid[1] & 0x000000000000ffffull); + os << std::setw(4) << (x1 & 0xfffful); os << std::setw(1) << '-'; - os << std::setw(12) << ((uuid[1] & 0xffffffffffff0000ull) >> 16); + os << std::setw(12) << ((x1 >> 2) & 0xffffffffffffull); return os; }