-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathltuuid.hpp
More file actions
105 lines (89 loc) · 3.19 KB
/
Copy pathltuuid.hpp
File metadata and controls
105 lines (89 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Lightweight UUID generator.
// Only support UUID v4 conforming to RFC 4122.
//
// Copyright (C) 2025, Martin Young <martin_young@live.cn>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//------------------------------------------------------------------------
#pragma once
#include <array>
#include <cstdint>
#include <string_view>
#include <random>
#include <thread>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <charconv>
#ifdef __glibcxx_format
#include <format> // Available when __GNUC__ >= 13
#else
#include <sstream> // For std::stringstream
#include <iomanip> // For std::setw, std::setfill
#endif
namespace impl {
// Random number generation (C++20 uniform initialization)
inline auto& random_engine() noexcept {
thread_local std::mt19937_64 eng{std::random_device{}()};
return eng;
}
}
namespace ltuuid {
//------------------------------------------------------------------------
struct uuid {
uint64_t ab;
uint64_t cd;
auto operator<=>(const uuid&) const = default;
std::string str() const;
#ifdef __glibcxx_format
template<typename FormatContext>
auto format(FormatContext& ctx) const {
return std::format_to(ctx.out(), "{}", str());
}
#else
friend std::ostream& operator<<(std::ostream& os, const uuid& u) {
return os << u.str();
}
#endif
};
//------------------------------------------------------------------------
// Default zero UUID
inline uuid uuid0() noexcept { return {0, 0}; }
// UUID v4 implementation
inline uuid uuid4() noexcept {
static thread_local std::uniform_int_distribution<uint64_t> dist;
return {
(dist(impl::random_engine()) & 0xFFFFFFFFFFFF0FFULL ) | 0x0000000000004000ULL,
(dist(impl::random_engine()) & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL
};
}
// Rebuild UUID from a pair of 64-bit integers
inline uuid rebuild(uint64_t ab, uint64_t cd) noexcept { return {ab, cd}; }
// Rebuild UUID from a std::string
uuid rebuild(std::string_view uustr);
// Rebuild UUID from a std::string without exceptions
inline uuid rebuild_ne(std::string_view uustr) noexcept
{ try{ return rebuild(uustr); } catch(...) { return {0, 0}; } }
} // namespace ltuuid
//------------------------------------------------------------------------
// Formatter specialization for ltuuid::uuid in the std namespace
#ifdef __glibcxx_format
template <>
struct std::formatter<ltuuid::uuid> : std::formatter<std::string> {
template <typename FormatContext>
auto format(const ltuuid::uuid& u, FormatContext& ctx) const {
return std::formatter<std::string>::format(u.str(), ctx);
}
};
#endif