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]] static bool isValid(std::string_view s) noexcept;
94
97 [[nodiscard]] static 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 // Checked rather than trusted: a replaced check handler returns, which the assertion tests rely
138 // on, and the copies below read 16 bytes whatever the span holds. Leaves a nil Uuid.
139 if (bytes.size() < 2U * sizeof(uint64_t))
140 {
141 return;
142 }
143 std::memcpy(&hi_, bytes.data(), sizeof(uint64_t));
144 std::memcpy(&lo_, bytes.data() + sizeof(uint64_t), sizeof(uint64_t));
145}
146
147constexpr uint32_t Uuid::getHash32() const noexcept
148{
149 uint64_t h = getHash();
150 return static_cast<uint32_t>(h ^ (h >> 32U));
151}
152
153constexpr UuidVariant Uuid::getVariant() const noexcept
154{
155 auto b = static_cast<uint8_t>(lo_ >> 56U);
156
157 if ((b & 0x80U) == 0U)
158 {
159 return UuidVariant::ncs;
160 }
161
162 if ((b & 0xC0U) == 0x80U)
163 {
164 return UuidVariant::rfc;
165 }
166
167 if ((b & 0xE0U) == 0xC0U)
168 {
170 }
171
173}
174
175constexpr UuidVersion Uuid::getVersion() const noexcept
176{
177 uint8_t v = static_cast<uint8_t>(hi_ >> 12U) & 0xFU;
178
179 switch (v)
180 {
181 case 1:
183 case 2:
185 case 3:
187 case 4:
189 case 5:
191 default:
192 return UuidVersion::none;
193 }
194}
195
196inline std::array<uint8_t, Uuid::byteCount> Uuid::bytes() const noexcept
197{
198 std::array<uint8_t, byteCount> out {};
199 std::memcpy(out.data(), &hi_, 8U);
200 std::memcpy(out.data() + 8U, &lo_, 8U);
201 return out;
202}
203
204inline void Uuid::swap(Uuid& other) noexcept
205{
206 std::swap(hi_, other.hi_);
207 std::swap(lo_, other.lo_);
208}
209
211{
212 vec.resize(byteCount);
213 memcpy(vec.data(), bytes().data(), byteCount);
214}
215
216// --------------------------------------------------------------------------------------------------------------------------
217// UuidRandomGenerator
218// --------------------------------------------------------------------------------------------------------------------------
219
221{
222public:
223 UuidRandomGenerator(): engine_(std::random_device {}()) {}
224
225 explicit UuidRandomGenerator(uint64_t seed): engine_(seed) {}
226
228 {
229 uint64_t hi = dist_(engine_);
230 uint64_t lo = dist_(engine_);
231
232 hi &= 0xFFFFFFFFFFFF0FFFULL;
233 hi |= 0x0000000000004000ULL;
234
235 lo &= 0x3FFFFFFFFFFFFFFFULL;
236 lo |= 0x8000000000000000ULL;
237
238 return {hi, lo};
239 }
240
241private:
242 std::mt19937_64 engine_;
243 std::uniform_int_distribution<uint64_t> dist_;
244};
245
246std::ostream& operator<<(std::ostream& s, const Uuid& id);
247} // namespace sen
248
249// --------------------------------------------------------------------------------------------------------------------------
250// Hashing support
251// --------------------------------------------------------------------------------------------------------------------------
252
253namespace std
254{
255template <>
256struct hash<sen::Uuid>
257{
258 size_t operator()(const sen::Uuid& uuid) const noexcept { return uuid.getHash(); }
259};
260} // namespace std
261
262#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:1144
const_pointer data() const noexcept
Direct access to the underlying storage. Complexity: constant.
Definition static_vector.h:131
Stack-based, exception-free and resizable vector with fixed-capacity.
Definition static_vector.h:574
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
std::enable_if_t< HasOperator< T >::lt, bool > operator<(const StaticVector< T, size > &lhs, const StaticVector< T, size > &rhs) noexcept(noexcept(std::declval< const T & >()< std::declval< const T & >()))
Lexicographically compares two StaticVector objects.
Definition static_vector.h:678
size_t operator()(const sen::Uuid &uuid) const noexcept
Definition uuid.h:258
static Uuid fromString(std::string_view s) noexcept
Parses a string and generates a UUID. Returns a Nil UUID in case of error.
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:153
UuidRandomGenerator()
Definition uuid.h:223
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:196
static bool isValid(std::string_view s) noexcept
True if the UUID is well-formed. Static: it inspects the string, not this UUID.
constexpr bool operator==(const Span< T > &lhs, const Span< T > &rhs) noexcept
Definition span.h:184
constexpr uint32_t getHash32() const noexcept
Computes a 32-bit hash of the UUID.
Definition uuid.h:147
constexpr Uuid() noexcept=default
constexpr bool isNil() const noexcept
True if all zeroes.
Definition uuid.h:73
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:227
void swap(Uuid &other) noexcept
Swap the internal data.
Definition uuid.h:204
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:175
UuidRandomGenerator(uint64_t seed)
Definition uuid.h:225
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.