Commit | Line | Data |
---|---|---|
638a0d12 | 1 | /* |
12958bb9 SM |
2 | * SPDX-FileCopyrightText: 2020-2023 Philippe Proulx <pproulx@efficios.com> |
3 | * SPDX-FileCopyrightText: 2022 Francis Deslauriers <francis.deslauriers@efficios.com> | |
638a0d12 SM |
4 | * |
5 | * SPDX-License-Identifier: MIT | |
6 | */ | |
7 | ||
094bf3f2 SM |
8 | #ifndef BABELTRACE_CPP_COMMON_BT2C_UUID_HPP |
9 | #define BABELTRACE_CPP_COMMON_BT2C_UUID_HPP | |
638a0d12 SM |
10 | |
11 | #include <algorithm> | |
12 | #include <array> | |
12958bb9 | 13 | #include <cstdint> |
638a0d12 SM |
14 | #include <string> |
15 | ||
16 | #include "common/assert.h" | |
17 | #include "common/uuid.h" | |
82d339d7 | 18 | #include "cpp-common/bt2c/c-string-view.hpp" |
c802cacb | 19 | |
094bf3f2 | 20 | namespace bt2c { |
638a0d12 | 21 | |
12958bb9 SM |
22 | class Uuid; |
23 | ||
24 | /* | |
25 | * A view on existing UUID data. | |
26 | * | |
27 | * A `UuidView` object doesn't contain its UUID data: see `Uuid` for a | |
28 | * UUID data container. | |
29 | */ | |
30 | class UuidView final | |
31 | { | |
32 | public: | |
33 | using Val = std::uint8_t; | |
34 | using ConstIter = const Val *; | |
35 | ||
36 | public: | |
37 | explicit UuidView(const Val * const uuid) noexcept : _mUuid {uuid} | |
38 | { | |
39 | BT_ASSERT_DBG(uuid); | |
40 | } | |
41 | ||
42 | explicit UuidView(const Uuid& uuid) noexcept; | |
43 | UuidView(const UuidView&) noexcept = default; | |
44 | UuidView& operator=(const UuidView&) noexcept = default; | |
45 | ||
46 | UuidView& operator=(const Val * const uuid) noexcept | |
47 | { | |
48 | _mUuid = uuid; | |
49 | return *this; | |
50 | } | |
51 | ||
52 | operator Uuid() const noexcept; | |
53 | ||
54 | std::string str() const | |
55 | { | |
56 | std::string s; | |
57 | ||
58 | s.resize(BT_UUID_STR_LEN); | |
59 | bt_uuid_to_str(_mUuid, &s[0]); | |
60 | ||
61 | return s; | |
62 | } | |
63 | ||
64 | bool operator==(const UuidView& other) const noexcept | |
65 | { | |
66 | return bt_uuid_compare(_mUuid, other._mUuid) == 0; | |
67 | } | |
68 | ||
69 | bool operator!=(const UuidView& other) const noexcept | |
70 | { | |
71 | return !(*this == other); | |
72 | } | |
73 | ||
74 | bool operator<(const UuidView& other) const noexcept | |
75 | { | |
76 | return bt_uuid_compare(_mUuid, other._mUuid) < 0; | |
77 | } | |
78 | ||
79 | static constexpr std::size_t size() noexcept | |
80 | { | |
81 | return BT_UUID_LEN; | |
82 | } | |
83 | ||
84 | const Val *data() const noexcept | |
85 | { | |
86 | return _mUuid; | |
87 | } | |
88 | ||
89 | Val operator[](const std::size_t index) const noexcept | |
90 | { | |
91 | return _mUuid[index]; | |
92 | } | |
93 | ||
94 | ConstIter begin() const noexcept | |
95 | { | |
96 | return _mUuid; | |
97 | } | |
98 | ||
99 | ConstIter end() const noexcept | |
100 | { | |
101 | return _mUuid + this->size(); | |
102 | } | |
103 | ||
104 | bool isNil() const noexcept | |
105 | { | |
106 | return std::all_of(this->begin(), this->end(), [](const std::uint8_t byte) { | |
107 | return byte == 0; | |
108 | }); | |
109 | } | |
110 | ||
111 | private: | |
112 | const Val *_mUuid; | |
113 | }; | |
114 | ||
638a0d12 SM |
115 | /* |
116 | * A universally unique identifier. | |
117 | * | |
118 | * A `Uuid` object contains its UUID data: see `UuidView` to have a | |
119 | * UUID view on existing UUID data. | |
120 | */ | |
121 | class Uuid final | |
122 | { | |
123 | public: | |
124 | using Val = UuidView::Val; | |
125 | using ConstIter = UuidView::ConstIter; | |
126 | ||
127 | public: | |
128 | /* | |
129 | * Builds a nil UUID. | |
130 | */ | |
131 | explicit Uuid() noexcept = default; | |
132 | ||
133 | explicit Uuid(const Val * const uuid) noexcept | |
134 | { | |
135 | this->_setFromPtr(uuid); | |
136 | } | |
137 | ||
82d339d7 | 138 | explicit Uuid(const bt2c::CStringView str) noexcept |
638a0d12 | 139 | { |
82d339d7 | 140 | const auto ret = bt_uuid_from_str(str.data(), _mUuid.data()); |
638a0d12 SM |
141 | BT_ASSERT(ret == 0); |
142 | } | |
143 | ||
638a0d12 SM |
144 | explicit Uuid(const UuidView& view) noexcept : Uuid {view.data()} |
145 | { | |
146 | } | |
147 | ||
148 | Uuid(const Uuid&) noexcept = default; | |
149 | Uuid& operator=(const Uuid&) noexcept = default; | |
150 | ||
151 | Uuid& operator=(const Val * const uuid) noexcept | |
152 | { | |
153 | this->_setFromPtr(uuid); | |
154 | return *this; | |
155 | } | |
156 | ||
157 | static Uuid generate() noexcept | |
158 | { | |
159 | bt_uuid_t uuidGen; | |
160 | ||
161 | bt_uuid_generate(uuidGen); | |
162 | return Uuid {uuidGen}; | |
163 | } | |
164 | ||
165 | std::string str() const | |
166 | { | |
167 | return this->_view().str(); | |
168 | } | |
169 | ||
170 | bool operator==(const Uuid& other) const noexcept | |
171 | { | |
172 | return this->_view() == other._view(); | |
173 | } | |
174 | ||
175 | bool operator!=(const Uuid& other) const noexcept | |
176 | { | |
177 | return this->_view() != other._view(); | |
178 | } | |
179 | ||
180 | bool operator<(const Uuid& other) const noexcept | |
181 | { | |
182 | return this->_view() < other._view(); | |
183 | } | |
184 | ||
185 | /* | |
186 | * The returned UUID view must not outlive the UUID object. | |
187 | */ | |
188 | operator UuidView() const noexcept | |
189 | { | |
190 | return this->_view(); | |
191 | } | |
192 | ||
193 | static constexpr std::size_t size() noexcept | |
194 | { | |
195 | return UuidView::size(); | |
196 | } | |
197 | ||
198 | const Val *data() const noexcept | |
199 | { | |
200 | return _mUuid.data(); | |
201 | } | |
202 | ||
203 | Val operator[](const std::size_t index) const noexcept | |
204 | { | |
205 | return this->_view()[index]; | |
206 | } | |
207 | ||
208 | ConstIter begin() const noexcept | |
209 | { | |
210 | return this->_view().begin(); | |
211 | } | |
212 | ||
213 | ConstIter end() const noexcept | |
214 | { | |
215 | return this->_view().end(); | |
216 | } | |
217 | ||
218 | bool isNil() const noexcept | |
219 | { | |
220 | return this->_view().isNil(); | |
221 | } | |
222 | ||
223 | private: | |
224 | /* | |
225 | * std::copy_n() won't throw when simply copying bytes below, | |
226 | * therefore this method won't throw. | |
227 | */ | |
228 | void _setFromPtr(const Val * const uuid) noexcept | |
229 | { | |
230 | BT_ASSERT(uuid); | |
231 | std::copy_n(uuid, BT_UUID_LEN, std::begin(_mUuid)); | |
232 | } | |
233 | ||
234 | UuidView _view() const noexcept | |
235 | { | |
236 | return UuidView {_mUuid.data()}; | |
237 | } | |
238 | ||
239 | std::array<Val, UuidView::size()> _mUuid = {}; | |
240 | }; | |
241 | ||
12958bb9 SM |
242 | inline UuidView::UuidView(const Uuid& uuid) noexcept : _mUuid {uuid.data()} |
243 | { | |
244 | } | |
245 | ||
246 | inline UuidView::operator Uuid() const noexcept | |
247 | { | |
248 | return Uuid {*this}; | |
249 | } | |
250 | ||
094bf3f2 | 251 | } /* namespace bt2c */ |
638a0d12 | 252 | |
094bf3f2 | 253 | #endif /* BABELTRACE_CPP_COMMON_BT2C_UUID_HPP */ |