22 enum class Variant :
u8 {
26 enum class Version :
u8 {
37 constexpr explicit UUID(ByteArray bytes) { *
this = util::bit_cast<UUID>(bytes); }
39 constexpr auto null() const ->
bool {
return *
this ==
UUID(); }
46 return util::bit_cast<ByteArray>(a) == util::bit_cast<ByteArray>(b);
49 return util::bit_cast<ByteArray>(a) <=> util::bit_cast<ByteArray>(b);
52 constexpr auto variant() const ->
Variant {
return Variant(m_clock_seq_hi_and_res >> 5); }
53 constexpr auto version() const -> Version {
return Version(m_time_hi_and_version >> 4); }
55 constexpr void set_to_standard_variant() {
56 m_clock_seq_hi_and_res &= 0b11000000;
57 m_clock_seq_hi_and_res |= 0b10000000;
60 constexpr void set_version(Version type) {
61 m_time_hi_and_version &= 0b00001111;
65 constexpr auto is_little_endian() const ->
bool {
return variant() == Variant::LittleEndian; }
67 template<concepts::Encoding Enc>
74#pragma GCC diagnostic push
75#pragma GCC diagnostic ignored "-Wstringop-overflow"
80 auto output_digit = [&](
u8 digit) {
82 buffer[index++] = char(digit - 10 +
'a');
84 buffer[index++] = char(digit +
'0');
88 auto output_byte = [&](
auto byte) {
89 output_digit(
byte >> 4);
90 output_digit(
byte & 0xF);
93 auto output = [&](
auto value,
auto bytes) {
94 u64 mask = 0xFF << 8 * (bytes - 1);
95 for (; bytes > 0; bytes--) {
96 u8 byte = (value & mask) >> 8 * (bytes - 1);
103 if (uuid.is_little_endian()) {
108 buffer[index++] =
'-';
109 if (uuid.is_little_endian()) {
114 buffer[index++] =
'-';
115 if (uuid.is_little_endian()) {
120 buffer[index++] =
'-';
121 output_byte(uuid.m_clock_seq_hi_and_res);
122 output_byte(uuid.m_clock_seq_low);
123 buffer[index++] =
'-';
131#pragma GCC diagnostic pop
140 auto valid_hex = (
'0'_m -
'9'_m ||
'a'_m -
'f'_m ||
'A'_m -
'F'_m);
148 << []<
typename Context>(
152 auto encoding = context.encoding();
154 auto [a, b, c, d, e] = results;
158 encoding::unicode_code_point_unwrap(encoding, a.end()) });
162 encoding::unicode_code_point_unwrap(encoding, b.end()) });
166 encoding::unicode_code_point_unwrap(encoding, c.end()) });
170 encoding::unicode_code_point_unwrap(encoding, d.end()) });
174 encoding::unicode_code_point_unwrap(encoding, e.end()) });
176 auto result =
UUID {};
177 result.m_time_low = m_time_low;
178 result.m_time_mid = m_time_mid;
179 result.m_time_hi_and_version = time_hi;
180 result.m_clock_seq_hi_and_res = clock_seq >> 8;
181 result.m_clock_seq_low = clock_seq & 0xFF;
182 result.m_node[0] =
Byte((m_node & 0x0000FF0000000000) >> 40);
183 result.m_node[1] =
Byte((m_node & 0x000000FF00000000) >> 32);
184 result.m_node[2] =
Byte((m_node & 0x00000000FF000000) >> 24);
185 result.m_node[3] =
Byte((m_node & 0x0000000000FF0000) >> 16);
186 result.m_node[4] =
Byte((m_node & 0x000000000000FF00) >> 8);
187 result.m_node[5] =
Byte((m_node & 0x00000000000000FF) >> 0);
189 if (result.is_little_endian()) {
202 u32 m_time_low { 0 };
203 u16 m_time_mid { 0 };
204 u16 m_time_hi_and_version { 0 };
205 u8 m_clock_seq_hi_and_res { 0 };
206 u8 m_clock_seq_low { 0 };
212 template<concepts::UniformRandomBitGenerator RNG>
215 auto bytes = UUID::ByteArray {};
216 for (
auto&
byte : bytes) {
217 byte =
Byte(distribution(rng));
220 auto result =
UUID(bytes);
221 result.set_version(UUID::Version::Random);
222 result.set_to_standard_variant();
232inline namespace literals {
247#if !defined(DI_NO_GLOBALS) && !defined(DI_NO_GLOBAL_UUID_LITERALS)
Definition string_view_impl_forward_declaration.h:7
Definition format_parse_context.h:14
constexpr void clear()
Definition uuid.h:40
constexpr friend auto operator<=>(UUID a, UUID b) -> strong_ordering
Definition uuid.h:48
constexpr friend auto tag_invoke(types::Tag< parser::create_parser_in_place >, InPlaceType< UUID >)
Definition uuid.h:139
constexpr friend auto tag_invoke(types::Tag< format::formatter_in_place >, InPlaceType< UUID >, FormatParseContext< Enc > &parse_context, bool debug)
Definition uuid.h:68
constexpr UUID(ByteArray bytes)
Definition uuid.h:37
constexpr friend auto operator==(UUID a, UUID b) -> bool
Definition uuid.h:45
constexpr auto null() const -> bool
Definition uuid.h:39
Definition variant_forward_declaration.h:6
Definition operations.h:34
Definition format_context.h:9
string::StringViewImpl< string::TransparentEncoding > TransparentStringView
Definition string_view.h:13
constexpr auto match_one
Definition match_one.h:27
constexpr auto run_parser_unchecked
Definition run_parser_unchecked.h:16
constexpr auto integer
Definition integer.h:212
constexpr auto parse_unchecked
Definition parse_unchecked.h:25
constexpr auto match_exactly
Definition match_exactly.h:56
std::byte byte
Definition byte.h:64
std::byte Byte
Definition byte.h:63
size_t usize
Definition integers.h:33
__UINT64_TYPE__ u64
Definition integers.h:12
__UINT8_TYPE__ u8
Definition integers.h:9
__UINT32_TYPE__ u32
Definition integers.h:11
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
__UINT16_TYPE__ u16
Definition integers.h:10
constexpr auto to_underlying
Definition to_underlying.h:15
constexpr auto generate_uuid
Definition uuid.h:228
Definition zstring_parser.h:9
constexpr auto host_to_big_endian
Definition big_endian.h:21
constexpr auto little_endian_to_host
Definition little_endian.h:22
constexpr auto size
Definition size.h:54
constexpr auto data
Definition data.h:51
constexpr auto minus
Definition minus.h:15
constexpr auto big_endian_to_host
Definition big_endian.h:22
constexpr auto host_to_little_endian
Definition little_endian.h:21
Definition in_place_type.h:5
constexpr auto operator()(RNG &&rng) const -> UUID
Definition uuid.h:213
Definition span_fixed_size.h:37