Sen API
Sen Libraries
Loading...
Searching...
No Matches
uuid.h
Go to the documentation of this file.
1// === uuid.h ==========================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_CORE_BASE_UUID_H
9#define SEN_CORE_BASE_UUID_H
10
11// sen
13#include "sen/core/base/span.h"
15
16// std
17#include <array>
18#include <cstdint>
19#include <cstring>
20#include <random>
21#include <string>
22#include <string_view>
23
24namespace sen
25{
28
30enum class UuidVariant
31{
32 ncs = 0,
33 rfc = 1,
36};
37
48
50class Uuid
51{
52 SEN_COPY_MOVE(Uuid)
53
54public:
55 static constexpr std::size_t byteCount = 16;
56
57public:
58 // Constructs an empty (nil) UUID.
59 constexpr Uuid() noexcept = default;
60
63 constexpr Uuid(uint64_t hi, uint64_t lo) noexcept: hi_(hi), lo_(lo) {}
64
67 explicit Uuid(Span<const uint8_t> bytes) noexcept;
68
69 ~Uuid() = default;
70
71public:
73 [[nodiscard]] constexpr bool isNil() const noexcept { return (hi_ | lo_) == 0; }
74
76 [[nodiscard]] constexpr UuidVariant getVariant() const noexcept;
77
79 [[nodiscard]] constexpr UuidVersion getVersion() const noexcept;
80
82 [[nodiscard]] constexpr uint64_t getHash() const noexcept { return hi_ ^ lo_; }
83
85 [[nodiscard]] constexpr uint32_t getHash32() const noexcept;
86
87 [[nodiscard]] std::array<uint8_t, byteCount> bytes() const noexcept;
88
90 [[nodiscard]] std::string toString() const;
91
93 [[nodiscard]] bool isValid(std::string_view s) noexcept;
94
97 [[nodiscard]] Uuid fromString(std::string_view s) noexcept;
98
100 void copy(std::array<uint8_t, byteCount>& arr) const { arr = bytes(); }
101
103 void copy(StaticVector<uint8_t, byteCount>& vec) const;
104
106 void swap(Uuid& other) noexcept;
107
108private:
109 friend constexpr bool operator==(const Uuid& lhs, const Uuid& rhs) noexcept;
110 friend constexpr bool operator!=(const Uuid& lhs, const Uuid& rhs) noexcept;
111 friend constexpr bool operator<(const Uuid& lhs, const Uuid& rhs) noexcept;
112
113private:
114 uint64_t hi_ {};
115 uint64_t lo_ {};
116};
117
118// --------------------------------------------------------------------------------------------------------------------------
119// Inline implementation
120// --------------------------------------------------------------------------------------------------------------------------
121
122[[nodiscard]] constexpr bool operator==(const Uuid& lhs, const Uuid& rhs) noexcept
123{
124 return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
125}
126
127[[nodiscard]] constexpr bool operator!=(const Uuid& lhs, const Uuid& rhs) noexcept { return !(lhs == rhs); }
128
129[[nodiscard]] constexpr bool operator<(const Uuid& lhs, const Uuid& rhs) noexcept
130{
131 return (lhs.hi_ < rhs.hi_) || (lhs.hi_ == rhs.hi_ && lhs.lo_ < rhs.lo_);
132}
133
135{
136 SEN_ASSERT(bytes.size() >= 16);
137 std::memcpy(&hi_, bytes.data(), sizeof(uint64_t));
138 std::memcpy(&lo_, bytes.data() + sizeof(uint64_t), sizeof(uint64_t));
139}
140
141constexpr uint32_t Uuid::getHash32() const noexcept
142{
143 uint64_t h = getHash();
144 return static_cast<uint32_t>(h ^ (h >> 32));
145}
146
147constexpr UuidVariant Uuid::getVariant() const noexcept
148{
149 auto b = static_cast<uint8_t>(lo_ >> 56);
150
151 if ((b & 0x80) == 0)
152 {
153 return UuidVariant::ncs;
154 }
155
156 if ((b & 0xC0) == 0x80)
157 {
158 return UuidVariant::rfc;
159 }
160
161 if ((b & 0xE0) == 0xC0)
162 {
164 }
165
167}
168
169constexpr UuidVersion Uuid::getVersion() const noexcept
170{
171 uint8_t v = static_cast<uint8_t>(hi_ >> 12) & 0xF;
172
173 switch (v)
174 {
175 case 1:
177 case 2:
179 case 3:
181 case 4:
183 case 5:
185 default:
186 return UuidVersion::none;
187 }
188}
189
190inline std::array<uint8_t, Uuid::byteCount> Uuid::bytes() const noexcept
191{
192 std::array<uint8_t, byteCount> out {};
193 std::memcpy(out.data(), &hi_, 8U);
194 std::memcpy(out.data() + 8U, &lo_, 8U);
195 return out;
196}
197
198inline void Uuid::swap(Uuid& other) noexcept
199{
200 std::swap(hi_, other.hi_);
201 std::swap(lo_, other.lo_);
202}
203
205{
206 vec.resize(byteCount);
207 memcpy(vec.data(), bytes().data(), byteCount);
208}
209
210// --------------------------------------------------------------------------------------------------------------------------
211// UuidRandomGenerator
212// --------------------------------------------------------------------------------------------------------------------------
213
215{
216public:
217 UuidRandomGenerator(): engine_(std::random_device {}()) {}
218
219 explicit UuidRandomGenerator(uint64_t seed): engine_(seed) {}
220
222 {
223 uint64_t hi = dist_(engine_);
224 uint64_t lo = dist_(engine_);
225
226 hi &= 0xFFFFFFFFFFFF0FFFULL;
227 hi |= 0x0000000000004000ULL;
228
229 lo &= 0x3FFFFFFFFFFFFFFFULL;
230 lo |= 0x8000000000000000ULL;
231
232 return {hi, lo};
233 }
234
235private:
236 std::mt19937_64 engine_;
237 std::uniform_int_distribution<uint64_t> dist_;
238};
239
240std::ostream& operator<<(std::ostream& s, const Uuid& id);
241} // namespace sen
242
243// --------------------------------------------------------------------------------------------------------------------------
244// Hashing support
245// --------------------------------------------------------------------------------------------------------------------------
246
247namespace std
248{
249template <>
250struct hash<sen::Uuid>
251{
252 size_t operator()(const sen::Uuid& uuid) const noexcept { return uuid.getHash(); }
253};
254} // namespace std
255
256#endif // SEN_CORE_BASE_UUID_H
Contiguous view of elements of type T. Inspired by http://www.open-std.org/jtc1/sc22/wg21/docs/papers...
Definition span.h:34
Maybe resize(size_type newSize, const T &value) noexcept(nothrowCopyAndDes)
Changes the size of the container to newSize. If need to be appended, elements are copy-constructed f...
Definition static_vector.h:1098
const_pointer data() const noexcept
Direct access to the underlying storage. Complexity: constant.
Definition static_vector.h:128
Stack-based, exception-free and resizable vector with fixed-capacity.
Definition static_vector.h:571
Universal Unique Identifier.
Definition uuid.h:51
#define SEN_ASSERT(expr)
Checks an intermediate result produced by a procedure (not an input or output). NOLINTNEXTLINE.
Definition assert.h:39
size_t operator()(const sen::Uuid &uuid) const noexcept
Definition uuid.h:252
bool isValid(std::string_view s) noexcept
True if the UUID is well-formed.
std::string toString() const
Builds a string out of this UUID.
friend constexpr bool operator==(const Uuid &lhs, const Uuid &rhs) noexcept
Definition uuid.h:122
void copy(std::array< uint8_t, byteCount > &arr) const
Copy this std::array of bytes into the UUID.
Definition uuid.h:100
friend constexpr bool operator!=(const Uuid &lhs, const Uuid &rhs) noexcept
Definition uuid.h:127
constexpr UuidVariant getVariant() const noexcept
The variant of the UUID according to the spec.
Definition uuid.h:147
UuidRandomGenerator()
Definition uuid.h:217
constexpr bool operator!=(const Span< T > &lhs, const Span< T > &rhs) noexcept
Definition span.h:190
static constexpr std::size_t byteCount
Definition uuid.h:55
std::array< uint8_t, byteCount > bytes() const noexcept
Definition uuid.h:190
constexpr bool operator==(const Span< T > &lhs, const Span< T > &rhs) noexcept
Definition span.h:184
Uuid fromString(std::string_view s) noexcept
Parses a string and generates a UUD. Returns a Nil UUID in case of error.
constexpr uint32_t getHash32() const noexcept
Computes a 32-bit hash of the UUID.
Definition uuid.h:141
constexpr Uuid() noexcept=default
constexpr bool isNil() const noexcept
True if all zeroes.
Definition uuid.h:73
constexpr bool operator<(const Uuid &lhs, const Uuid &rhs) noexcept
Definition uuid.h:129
constexpr uint64_t getHash() const noexcept
Computes a 64-bit hash of the UUID.
Definition uuid.h:82
UuidVariant
Indicated by a bit pattern in octet 8, marked with N in xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx.
Definition uuid.h:31
Uuid operator()()
Definition uuid.h:221
void swap(Uuid &other) noexcept
Swap the internal data.
Definition uuid.h:198
UuidVersion
Indicated by a bit pattern in octet 6, marked with M in xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx.
Definition uuid.h:40
std::ostream & operator<<(std::ostream &s, const Uuid &id)
constexpr UuidVersion getVersion() const noexcept
The version of the UUID according to the spec.
Definition uuid.h:169
UuidRandomGenerator(uint64_t seed)
Definition uuid.h:219
friend constexpr bool operator<(const Uuid &lhs, const Uuid &rhs) noexcept
Definition uuid.h:129
~Uuid()=default
@ ncs
NCS backward compatibility.
Definition uuid.h:32
@ rfc
RFC 4122/DCE 1.1.
Definition uuid.h:33
@ microsoft
Microsoft Corporation backward compatibility.
Definition uuid.h:34
@ reserved
reserved for possible future definition
Definition uuid.h:35
@ nameBasedSha1
The name-based version specified in RFS 4122 with SHA1 hashing.
Definition uuid.h:46
@ none
Only possible for nil or invalid uuids.
Definition uuid.h:41
@ dceSecurity
DCE Security version, with embedded POSIX UIDs.
Definition uuid.h:43
@ timeBased
The time-based version specified in RFC 4122.
Definition uuid.h:42
@ nameBasedMd5
The name-based version specified in RFS 4122 with MD5 hashing.
Definition uuid.h:44
@ randomNumberBased
The randomly or pseudo-randomly generated version specified in RFS 4122.
Definition uuid.h:45
Definition assert.h:17
STL namespace.