Last active
April 13, 2023 00:01
-
-
Save kennykerr/6c948882de395c25b3218ad8d4daf362 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string_view> | |
#include <exception> | |
#include <assert.h> | |
using namespace std::literals; | |
struct guid | |
{ | |
uint32_t Data1; | |
uint16_t Data2; | |
uint16_t Data3; | |
uint8_t Data4[8]; | |
}; | |
constexpr bool operator==(guid const& left, guid const& right) noexcept | |
{ | |
return left.Data1 == right.Data1 && | |
left.Data2 == right.Data2 && | |
left.Data3 == right.Data3 && | |
left.Data4[0] == right.Data4[0] && | |
left.Data4[1] == right.Data4[1] && | |
left.Data4[2] == right.Data4[2] && | |
left.Data4[3] == right.Data4[3] && | |
left.Data4[4] == right.Data4[4] && | |
left.Data4[5] == right.Data4[5] && | |
left.Data4[6] == right.Data4[6] && | |
left.Data4[7] == right.Data4[7]; | |
} | |
constexpr uint32_t to_uint(char const value) noexcept | |
{ | |
if (value >= '0' && value <= '9') | |
{ | |
return value - '0'; | |
} | |
if (value >= 'A' && value <= 'F') | |
{ | |
return 10 + value - 'A'; | |
} | |
if (value >= 'a' && value <= 'f') | |
{ | |
return 10 + value - 'a'; | |
} | |
std::terminate(); | |
} | |
constexpr guid make_guid(std::string_view const& value) noexcept | |
{ | |
if (value.size() != 36 || value[8] != '-' || value[13] != '-' || value[18] != '-' || value[23] != '-') | |
{ | |
std::terminate(); | |
} | |
return | |
{ | |
((to_uint(value[0]) * 16 + to_uint(value[1])) << 24) + | |
((to_uint(value[2]) * 16 + to_uint(value[3])) << 16) + | |
((to_uint(value[4]) * 16 + to_uint(value[5])) << 8) + | |
(to_uint(value[6]) * 16 + to_uint(value[7])), | |
static_cast<uint16_t>(((to_uint(value[9]) * 16 + to_uint(value[10])) << 8) + | |
(to_uint(value[11]) * 16 + to_uint(value[12]))), | |
static_cast<uint16_t>(((to_uint(value[14]) * 16 + to_uint(value[15])) << 8) + | |
(to_uint(value[16]) * 16 + to_uint(value[17]))), | |
{ | |
static_cast<uint8_t>(to_uint(value[19]) * 16 + to_uint(value[20])), | |
static_cast<uint8_t>(to_uint(value[21]) * 16 + to_uint(value[22])), | |
static_cast<uint8_t>(to_uint(value[24]) * 16 + to_uint(value[25])), | |
static_cast<uint8_t>(to_uint(value[26]) * 16 + to_uint(value[27])), | |
static_cast<uint8_t>(to_uint(value[28]) * 16 + to_uint(value[29])), | |
static_cast<uint8_t>(to_uint(value[30]) * 16 + to_uint(value[31])), | |
static_cast<uint8_t>(to_uint(value[32]) * 16 + to_uint(value[33])), | |
static_cast<uint8_t>(to_uint(value[34]) * 16 + to_uint(value[35])), | |
} | |
}; | |
} | |
static constexpr guid a | |
{ 0x8aa90cad, 0xfed1, 0x4c54, { 0x89, 0xdb, 0x9b, 0x75, 0x22, 0xd8, 0xaa, 0x92 } }; | |
static constexpr guid b | |
{ make_guid("8AA90CAD-fed1-4c54-89db-9B7522D8AA92"sv) }; | |
static_assert(a == b); | |
int main() | |
{ | |
assert(a == b); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Question: Based on the Wikipedia description here:
https://en.wikipedia.org/wiki/Universally_unique_identifier
in the test case above, the first 2 bits of 0x89 (10001001) identify this as "variant 1", which means that the integers should be stored in big-endian order, yes? The MSVC compiler on Intel will assemble the integers in little-endian order. The endianness doesn't matter if the UUIDs are all generated, stored, compared, etc., within a homogeneous MSVC environment, but might matter in some kind of heterogeneous environment -- maybe sending and receiving UUIDs generated on various platforms across the network. If I understand the Wikipedia article correctly, and if the article is correct, either:
Yes? No?