summaryrefslogtreecommitdiff
path: root/src/common/intrusive_red_black_tree.h
diff options
context:
space:
mode:
authorGravatar bunnei2022-03-10 22:55:05 -0800
committerGravatar bunnei2022-03-14 18:14:53 -0700
commit69c2faeb6acf6b4fcf5c60dbe1828e2ea4980fbe (patch)
tree8e5b41dc53e436a95f6d65ff7fd05faaad88597f /src/common/intrusive_red_black_tree.h
parentMerge pull request #8008 from ameerj/rescale-offsets-array (diff)
downloadyuzu-69c2faeb6acf6b4fcf5c60dbe1828e2ea4980fbe.tar.gz
yuzu-69c2faeb6acf6b4fcf5c60dbe1828e2ea4980fbe.tar.xz
yuzu-69c2faeb6acf6b4fcf5c60dbe1828e2ea4980fbe.zip
common: intrusive_red_black_tree: Various updates.
Diffstat (limited to 'src/common/intrusive_red_black_tree.h')
-rw-r--r--src/common/intrusive_red_black_tree.h391
1 files changed, 210 insertions, 181 deletions
diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h
index 3173cc449..b296b639e 100644
--- a/src/common/intrusive_red_black_tree.h
+++ b/src/common/intrusive_red_black_tree.h
@@ -4,6 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/alignment.h"
8#include "common/common_funcs.h"
7#include "common/parent_of_member.h" 9#include "common/parent_of_member.h"
8#include "common/tree.h" 10#include "common/tree.h"
9 11
@@ -15,32 +17,33 @@ class IntrusiveRedBlackTreeImpl;
15 17
16} 18}
17 19
20#pragma pack(push, 4)
18struct IntrusiveRedBlackTreeNode { 21struct IntrusiveRedBlackTreeNode {
22 YUZU_NON_COPYABLE(IntrusiveRedBlackTreeNode);
23
19public: 24public:
20 using EntryType = RBEntry<IntrusiveRedBlackTreeNode>; 25 using RBEntry = freebsd::RBEntry<IntrusiveRedBlackTreeNode>;
21 26
22 constexpr IntrusiveRedBlackTreeNode() = default; 27private:
28 RBEntry m_entry;
23 29
24 void SetEntry(const EntryType& new_entry) { 30public:
25 entry = new_entry; 31 explicit IntrusiveRedBlackTreeNode() = default;
26 }
27 32
28 [[nodiscard]] EntryType& GetEntry() { 33 [[nodiscard]] constexpr RBEntry& GetRBEntry() {
29 return entry; 34 return m_entry;
30 } 35 }
31 36 [[nodiscard]] constexpr const RBEntry& GetRBEntry() const {
32 [[nodiscard]] const EntryType& GetEntry() const { 37 return m_entry;
33 return entry;
34 } 38 }
35 39
36private: 40 constexpr void SetRBEntry(const RBEntry& entry) {
37 EntryType entry{}; 41 m_entry = entry;
38 42 }
39 friend class impl::IntrusiveRedBlackTreeImpl;
40
41 template <class, class, class>
42 friend class IntrusiveRedBlackTree;
43}; 43};
44static_assert(sizeof(IntrusiveRedBlackTreeNode) ==
45 3 * sizeof(void*) + std::max<size_t>(sizeof(freebsd::RBColor), 4));
46#pragma pack(pop)
44 47
45template <class T, class Traits, class Comparator> 48template <class T, class Traits, class Comparator>
46class IntrusiveRedBlackTree; 49class IntrusiveRedBlackTree;
@@ -48,12 +51,17 @@ class IntrusiveRedBlackTree;
48namespace impl { 51namespace impl {
49 52
50class IntrusiveRedBlackTreeImpl { 53class IntrusiveRedBlackTreeImpl {
54 YUZU_NON_COPYABLE(IntrusiveRedBlackTreeImpl);
55
51private: 56private:
52 template <class, class, class> 57 template <class, class, class>
53 friend class ::Common::IntrusiveRedBlackTree; 58 friend class ::Common::IntrusiveRedBlackTree;
54 59
55 using RootType = RBHead<IntrusiveRedBlackTreeNode>; 60private:
56 RootType root; 61 using RootType = freebsd::RBHead<IntrusiveRedBlackTreeNode>;
62
63private:
64 RootType m_root;
57 65
58public: 66public:
59 template <bool Const> 67 template <bool Const>
@@ -81,149 +89,150 @@ public:
81 IntrusiveRedBlackTreeImpl::reference>; 89 IntrusiveRedBlackTreeImpl::reference>;
82 90
83 private: 91 private:
84 pointer node; 92 pointer m_node;
85 93
86 public: 94 public:
87 explicit Iterator(pointer n) : node(n) {} 95 constexpr explicit Iterator(pointer n) : m_node(n) {}
88 96
89 bool operator==(const Iterator& rhs) const { 97 constexpr bool operator==(const Iterator& rhs) const {
90 return this->node == rhs.node; 98 return m_node == rhs.m_node;
91 } 99 }
92 100
93 bool operator!=(const Iterator& rhs) const { 101 constexpr bool operator!=(const Iterator& rhs) const {
94 return !(*this == rhs); 102 return !(*this == rhs);
95 } 103 }
96 104
97 pointer operator->() const { 105 constexpr pointer operator->() const {
98 return this->node; 106 return m_node;
99 } 107 }
100 108
101 reference operator*() const { 109 constexpr reference operator*() const {
102 return *this->node; 110 return *m_node;
103 } 111 }
104 112
105 Iterator& operator++() { 113 constexpr Iterator& operator++() {
106 this->node = GetNext(this->node); 114 m_node = GetNext(m_node);
107 return *this; 115 return *this;
108 } 116 }
109 117
110 Iterator& operator--() { 118 constexpr Iterator& operator--() {
111 this->node = GetPrev(this->node); 119 m_node = GetPrev(m_node);
112 return *this; 120 return *this;
113 } 121 }
114 122
115 Iterator operator++(int) { 123 constexpr Iterator operator++(int) {
116 const Iterator it{*this}; 124 const Iterator it{*this};
117 ++(*this); 125 ++(*this);
118 return it; 126 return it;
119 } 127 }
120 128
121 Iterator operator--(int) { 129 constexpr Iterator operator--(int) {
122 const Iterator it{*this}; 130 const Iterator it{*this};
123 --(*this); 131 --(*this);
124 return it; 132 return it;
125 } 133 }
126 134
127 operator Iterator<true>() const { 135 constexpr operator Iterator<true>() const {
128 return Iterator<true>(this->node); 136 return Iterator<true>(m_node);
129 } 137 }
130 }; 138 };
131 139
132private: 140private:
133 // Define accessors using RB_* functions. 141 constexpr bool EmptyImpl() const {
134 bool EmptyImpl() const { 142 return m_root.IsEmpty();
135 return root.IsEmpty();
136 } 143 }
137 144
138 IntrusiveRedBlackTreeNode* GetMinImpl() const { 145 constexpr IntrusiveRedBlackTreeNode* GetMinImpl() const {
139 return RB_MIN(const_cast<RootType*>(&root)); 146 return freebsd::RB_MIN(const_cast<RootType&>(m_root));
140 } 147 }
141 148
142 IntrusiveRedBlackTreeNode* GetMaxImpl() const { 149 constexpr IntrusiveRedBlackTreeNode* GetMaxImpl() const {
143 return RB_MAX(const_cast<RootType*>(&root)); 150 return freebsd::RB_MAX(const_cast<RootType&>(m_root));
144 } 151 }
145 152
146 IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) { 153 constexpr IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) {
147 return RB_REMOVE(&root, node); 154 return freebsd::RB_REMOVE(m_root, node);
148 } 155 }
149 156
150public: 157public:
151 static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) { 158 static constexpr IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) {
152 return RB_NEXT(node); 159 return freebsd::RB_NEXT(node);
153 } 160 }
154 161
155 static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) { 162 static constexpr IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) {
156 return RB_PREV(node); 163 return freebsd::RB_PREV(node);
157 } 164 }
158 165
159 static const IntrusiveRedBlackTreeNode* GetNext(const IntrusiveRedBlackTreeNode* node) { 166 static constexpr IntrusiveRedBlackTreeNode const* GetNext(
167 IntrusiveRedBlackTreeNode const* node) {
160 return static_cast<const IntrusiveRedBlackTreeNode*>( 168 return static_cast<const IntrusiveRedBlackTreeNode*>(
161 GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); 169 GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node)));
162 } 170 }
163 171
164 static const IntrusiveRedBlackTreeNode* GetPrev(const IntrusiveRedBlackTreeNode* node) { 172 static constexpr IntrusiveRedBlackTreeNode const* GetPrev(
173 IntrusiveRedBlackTreeNode const* node) {
165 return static_cast<const IntrusiveRedBlackTreeNode*>( 174 return static_cast<const IntrusiveRedBlackTreeNode*>(
166 GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node))); 175 GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node)));
167 } 176 }
168 177
169public: 178public:
170 constexpr IntrusiveRedBlackTreeImpl() {} 179 constexpr IntrusiveRedBlackTreeImpl() = default;
171 180
172 // Iterator accessors. 181 // Iterator accessors.
173 iterator begin() { 182 constexpr iterator begin() {
174 return iterator(this->GetMinImpl()); 183 return iterator(this->GetMinImpl());
175 } 184 }
176 185
177 const_iterator begin() const { 186 constexpr const_iterator begin() const {
178 return const_iterator(this->GetMinImpl()); 187 return const_iterator(this->GetMinImpl());
179 } 188 }
180 189
181 iterator end() { 190 constexpr iterator end() {
182 return iterator(static_cast<IntrusiveRedBlackTreeNode*>(nullptr)); 191 return iterator(static_cast<IntrusiveRedBlackTreeNode*>(nullptr));
183 } 192 }
184 193
185 const_iterator end() const { 194 constexpr const_iterator end() const {
186 return const_iterator(static_cast<const IntrusiveRedBlackTreeNode*>(nullptr)); 195 return const_iterator(static_cast<const IntrusiveRedBlackTreeNode*>(nullptr));
187 } 196 }
188 197
189 const_iterator cbegin() const { 198 constexpr const_iterator cbegin() const {
190 return this->begin(); 199 return this->begin();
191 } 200 }
192 201
193 const_iterator cend() const { 202 constexpr const_iterator cend() const {
194 return this->end(); 203 return this->end();
195 } 204 }
196 205
197 iterator iterator_to(reference ref) { 206 constexpr iterator iterator_to(reference ref) {
198 return iterator(&ref); 207 return iterator(std::addressof(ref));
199 } 208 }
200 209
201 const_iterator iterator_to(const_reference ref) const { 210 constexpr const_iterator iterator_to(const_reference ref) const {
202 return const_iterator(&ref); 211 return const_iterator(std::addressof(ref));
203 } 212 }
204 213
205 // Content management. 214 // Content management.
206 bool empty() const { 215 constexpr bool empty() const {
207 return this->EmptyImpl(); 216 return this->EmptyImpl();
208 } 217 }
209 218
210 reference back() { 219 constexpr reference back() {
211 return *this->GetMaxImpl(); 220 return *this->GetMaxImpl();
212 } 221 }
213 222
214 const_reference back() const { 223 constexpr const_reference back() const {
215 return *this->GetMaxImpl(); 224 return *this->GetMaxImpl();
216 } 225 }
217 226
218 reference front() { 227 constexpr reference front() {
219 return *this->GetMinImpl(); 228 return *this->GetMinImpl();
220 } 229 }
221 230
222 const_reference front() const { 231 constexpr const_reference front() const {
223 return *this->GetMinImpl(); 232 return *this->GetMinImpl();
224 } 233 }
225 234
226 iterator erase(iterator it) { 235 constexpr iterator erase(iterator it) {
227 auto cur = std::addressof(*it); 236 auto cur = std::addressof(*it);
228 auto next = GetNext(cur); 237 auto next = GetNext(cur);
229 this->RemoveImpl(cur); 238 this->RemoveImpl(cur);
@@ -234,16 +243,16 @@ public:
234} // namespace impl 243} // namespace impl
235 244
236template <typename T> 245template <typename T>
237concept HasLightCompareType = requires { 246concept HasRedBlackKeyType = requires {
238 { std::is_same<typename T::LightCompareType, void>::value } -> std::convertible_to<bool>; 247 { std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
239}; 248};
240 249
241namespace impl { 250namespace impl {
242 251
243 template <typename T, typename Default> 252 template <typename T, typename Default>
244 consteval auto* GetLightCompareType() { 253 consteval auto* GetRedBlackKeyType() {
245 if constexpr (HasLightCompareType<T>) { 254 if constexpr (HasRedBlackKeyType<T>) {
246 return static_cast<typename T::LightCompareType*>(nullptr); 255 return static_cast<typename T::RedBlackKeyType*>(nullptr);
247 } else { 256 } else {
248 return static_cast<Default*>(nullptr); 257 return static_cast<Default*>(nullptr);
249 } 258 }
@@ -252,16 +261,17 @@ namespace impl {
252} // namespace impl 261} // namespace impl
253 262
254template <typename T, typename Default> 263template <typename T, typename Default>
255using LightCompareType = std::remove_pointer_t<decltype(impl::GetLightCompareType<T, Default>())>; 264using RedBlackKeyType = std::remove_pointer_t<decltype(impl::GetRedBlackKeyType<T, Default>())>;
256 265
257template <class T, class Traits, class Comparator> 266template <class T, class Traits, class Comparator>
258class IntrusiveRedBlackTree { 267class IntrusiveRedBlackTree {
268 YUZU_NON_COPYABLE(IntrusiveRedBlackTree);
259 269
260public: 270public:
261 using ImplType = impl::IntrusiveRedBlackTreeImpl; 271 using ImplType = impl::IntrusiveRedBlackTreeImpl;
262 272
263private: 273private:
264 ImplType impl{}; 274 ImplType m_impl;
265 275
266public: 276public:
267 template <bool Const> 277 template <bool Const>
@@ -277,9 +287,9 @@ public:
277 using iterator = Iterator<false>; 287 using iterator = Iterator<false>;
278 using const_iterator = Iterator<true>; 288 using const_iterator = Iterator<true>;
279 289
280 using light_value_type = LightCompareType<Comparator, value_type>; 290 using key_type = RedBlackKeyType<Comparator, value_type>;
281 using const_light_pointer = const light_value_type*; 291 using const_key_pointer = const key_type*;
282 using const_light_reference = const light_value_type&; 292 using const_key_reference = const key_type&;
283 293
284 template <bool Const> 294 template <bool Const>
285 class Iterator { 295 class Iterator {
@@ -298,183 +308,201 @@ public:
298 IntrusiveRedBlackTree::reference>; 308 IntrusiveRedBlackTree::reference>;
299 309
300 private: 310 private:
301 ImplIterator iterator; 311 ImplIterator m_impl;
302 312
303 private: 313 private:
304 explicit Iterator(ImplIterator it) : iterator(it) {} 314 constexpr explicit Iterator(ImplIterator it) : m_impl(it) {}
305 315
306 explicit Iterator(typename std::conditional<Const, ImplType::const_iterator, 316 constexpr explicit Iterator(typename ImplIterator::pointer p) : m_impl(p) {}
307 ImplType::iterator>::type::pointer ptr)
308 : iterator(ptr) {}
309 317
310 ImplIterator GetImplIterator() const { 318 constexpr ImplIterator GetImplIterator() const {
311 return this->iterator; 319 return m_impl;
312 } 320 }
313 321
314 public: 322 public:
315 bool operator==(const Iterator& rhs) const { 323 constexpr bool operator==(const Iterator& rhs) const {
316 return this->iterator == rhs.iterator; 324 return m_impl == rhs.m_impl;
317 } 325 }
318 326
319 bool operator!=(const Iterator& rhs) const { 327 constexpr bool operator!=(const Iterator& rhs) const {
320 return !(*this == rhs); 328 return !(*this == rhs);
321 } 329 }
322 330
323 pointer operator->() const { 331 constexpr pointer operator->() const {
324 return Traits::GetParent(std::addressof(*this->iterator)); 332 return Traits::GetParent(std::addressof(*m_impl));
325 } 333 }
326 334
327 reference operator*() const { 335 constexpr reference operator*() const {
328 return *Traits::GetParent(std::addressof(*this->iterator)); 336 return *Traits::GetParent(std::addressof(*m_impl));
329 } 337 }
330 338
331 Iterator& operator++() { 339 constexpr Iterator& operator++() {
332 ++this->iterator; 340 ++m_impl;
333 return *this; 341 return *this;
334 } 342 }
335 343
336 Iterator& operator--() { 344 constexpr Iterator& operator--() {
337 --this->iterator; 345 --m_impl;
338 return *this; 346 return *this;
339 } 347 }
340 348
341 Iterator operator++(int) { 349 constexpr Iterator operator++(int) {
342 const Iterator it{*this}; 350 const Iterator it{*this};
343 ++this->iterator; 351 ++m_impl;
344 return it; 352 return it;
345 } 353 }
346 354
347 Iterator operator--(int) { 355 constexpr Iterator operator--(int) {
348 const Iterator it{*this}; 356 const Iterator it{*this};
349 --this->iterator; 357 --m_impl;
350 return it; 358 return it;
351 } 359 }
352 360
353 operator Iterator<true>() const { 361 constexpr operator Iterator<true>() const {
354 return Iterator<true>(this->iterator); 362 return Iterator<true>(m_impl);
355 } 363 }
356 }; 364 };
357 365
358private: 366private:
359 static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs, 367 static constexpr int CompareImpl(const IntrusiveRedBlackTreeNode* lhs,
360 const IntrusiveRedBlackTreeNode* rhs) { 368 const IntrusiveRedBlackTreeNode* rhs) {
361 return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs)); 369 return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
362 } 370 }
363 371
364 static int LightCompareImpl(const void* elm, const IntrusiveRedBlackTreeNode* rhs) { 372 static constexpr int CompareKeyImpl(const_key_reference key,
365 return Comparator::Compare(*static_cast<const_light_pointer>(elm), *Traits::GetParent(rhs)); 373 const IntrusiveRedBlackTreeNode* rhs) {
374 return Comparator::Compare(key, *Traits::GetParent(rhs));
366 } 375 }
367 376
368 // Define accessors using RB_* functions. 377 // Define accessors using RB_* functions.
369 IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { 378 constexpr IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) {
370 return RB_INSERT(&impl.root, node, CompareImpl); 379 return freebsd::RB_INSERT(m_impl.m_root, node, CompareImpl);
371 } 380 }
372 381
373 IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { 382 constexpr IntrusiveRedBlackTreeNode* FindImpl(IntrusiveRedBlackTreeNode const* node) const {
374 return RB_FIND(const_cast<ImplType::RootType*>(&impl.root), 383 return freebsd::RB_FIND(const_cast<ImplType::RootType&>(m_impl.m_root),
375 const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl); 384 const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
376 } 385 }
377 386
378 IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { 387 constexpr IntrusiveRedBlackTreeNode* NFindImpl(IntrusiveRedBlackTreeNode const* node) const {
379 return RB_NFIND(const_cast<ImplType::RootType*>(&impl.root), 388 return freebsd::RB_NFIND(const_cast<ImplType::RootType&>(m_impl.m_root),
380 const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl); 389 const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
381 } 390 }
382 391
383 IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const { 392 constexpr IntrusiveRedBlackTreeNode* FindKeyImpl(const_key_reference key) const {
384 return RB_FIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root), 393 return freebsd::RB_FIND_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
385 static_cast<const void*>(lelm), LightCompareImpl); 394 CompareKeyImpl);
386 } 395 }
387 396
388 IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const { 397 constexpr IntrusiveRedBlackTreeNode* NFindKeyImpl(const_key_reference key) const {
389 return RB_NFIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root), 398 return freebsd::RB_NFIND_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
390 static_cast<const void*>(lelm), LightCompareImpl); 399 CompareKeyImpl);
400 }
401
402 constexpr IntrusiveRedBlackTreeNode* FindExistingImpl(
403 IntrusiveRedBlackTreeNode const* node) const {
404 return freebsd::RB_FIND_EXISTING(const_cast<ImplType::RootType&>(m_impl.m_root),
405 const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
406 }
407
408 constexpr IntrusiveRedBlackTreeNode* FindExistingKeyImpl(const_key_reference key) const {
409 return freebsd::RB_FIND_EXISTING_KEY(const_cast<ImplType::RootType&>(m_impl.m_root), key,
410 CompareKeyImpl);
391 } 411 }
392 412
393public: 413public:
394 constexpr IntrusiveRedBlackTree() = default; 414 constexpr IntrusiveRedBlackTree() = default;
395 415
396 // Iterator accessors. 416 // Iterator accessors.
397 iterator begin() { 417 constexpr iterator begin() {
398 return iterator(this->impl.begin()); 418 return iterator(m_impl.begin());
399 } 419 }
400 420
401 const_iterator begin() const { 421 constexpr const_iterator begin() const {
402 return const_iterator(this->impl.begin()); 422 return const_iterator(m_impl.begin());
403 } 423 }
404 424
405 iterator end() { 425 constexpr iterator end() {
406 return iterator(this->impl.end()); 426 return iterator(m_impl.end());
407 } 427 }
408 428
409 const_iterator end() const { 429 constexpr const_iterator end() const {
410 return const_iterator(this->impl.end()); 430 return const_iterator(m_impl.end());
411 } 431 }
412 432
413 const_iterator cbegin() const { 433 constexpr const_iterator cbegin() const {
414 return this->begin(); 434 return this->begin();
415 } 435 }
416 436
417 const_iterator cend() const { 437 constexpr const_iterator cend() const {
418 return this->end(); 438 return this->end();
419 } 439 }
420 440
421 iterator iterator_to(reference ref) { 441 constexpr iterator iterator_to(reference ref) {
422 return iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref)))); 442 return iterator(m_impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
423 } 443 }
424 444
425 const_iterator iterator_to(const_reference ref) const { 445 constexpr const_iterator iterator_to(const_reference ref) const {
426 return const_iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref)))); 446 return const_iterator(m_impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
427 } 447 }
428 448
429 // Content management. 449 // Content management.
430 bool empty() const { 450 constexpr bool empty() const {
431 return this->impl.empty(); 451 return m_impl.empty();
432 } 452 }
433 453
434 reference back() { 454 constexpr reference back() {
435 return *Traits::GetParent(std::addressof(this->impl.back())); 455 return *Traits::GetParent(std::addressof(m_impl.back()));
436 } 456 }
437 457
438 const_reference back() const { 458 constexpr const_reference back() const {
439 return *Traits::GetParent(std::addressof(this->impl.back())); 459 return *Traits::GetParent(std::addressof(m_impl.back()));
440 } 460 }
441 461
442 reference front() { 462 constexpr reference front() {
443 return *Traits::GetParent(std::addressof(this->impl.front())); 463 return *Traits::GetParent(std::addressof(m_impl.front()));
444 } 464 }
445 465
446 const_reference front() const { 466 constexpr const_reference front() const {
447 return *Traits::GetParent(std::addressof(this->impl.front())); 467 return *Traits::GetParent(std::addressof(m_impl.front()));
448 } 468 }
449 469
450 iterator erase(iterator it) { 470 constexpr iterator erase(iterator it) {
451 return iterator(this->impl.erase(it.GetImplIterator())); 471 return iterator(m_impl.erase(it.GetImplIterator()));
452 } 472 }
453 473
454 iterator insert(reference ref) { 474 constexpr iterator insert(reference ref) {
455 ImplType::pointer node = Traits::GetNode(std::addressof(ref)); 475 ImplType::pointer node = Traits::GetNode(std::addressof(ref));
456 this->InsertImpl(node); 476 this->InsertImpl(node);
457 return iterator(node); 477 return iterator(node);
458 } 478 }
459 479
460 iterator find(const_reference ref) const { 480 constexpr iterator find(const_reference ref) const {
461 return iterator(this->FindImpl(Traits::GetNode(std::addressof(ref)))); 481 return iterator(this->FindImpl(Traits::GetNode(std::addressof(ref))));
462 } 482 }
463 483
464 iterator nfind(const_reference ref) const { 484 constexpr iterator nfind(const_reference ref) const {
465 return iterator(this->NFindImpl(Traits::GetNode(std::addressof(ref)))); 485 return iterator(this->NFindImpl(Traits::GetNode(std::addressof(ref))));
466 } 486 }
467 487
468 iterator find_light(const_light_reference ref) const { 488 constexpr iterator find_key(const_key_reference ref) const {
469 return iterator(this->FindLightImpl(std::addressof(ref))); 489 return iterator(this->FindKeyImpl(ref));
490 }
491
492 constexpr iterator nfind_key(const_key_reference ref) const {
493 return iterator(this->NFindKeyImpl(ref));
494 }
495
496 constexpr iterator find_existing(const_reference ref) const {
497 return iterator(this->FindExistingImpl(Traits::GetNode(std::addressof(ref))));
470 } 498 }
471 499
472 iterator nfind_light(const_light_reference ref) const { 500 constexpr iterator find_existing_key(const_key_reference ref) const {
473 return iterator(this->NFindLightImpl(std::addressof(ref))); 501 return iterator(this->FindExistingKeyImpl(ref));
474 } 502 }
475}; 503};
476 504
477template <auto T, class Derived = impl::GetParentType<T>> 505template <auto T, class Derived = Common::impl::GetParentType<T>>
478class IntrusiveRedBlackTreeMemberTraits; 506class IntrusiveRedBlackTreeMemberTraits;
479 507
480template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived> 508template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
@@ -498,19 +526,16 @@ private:
498 return std::addressof(parent->*Member); 526 return std::addressof(parent->*Member);
499 } 527 }
500 528
501 static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) { 529 static Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
502 return GetParentPointer<Member, Derived>(node); 530 return Common::GetParentPointer<Member, Derived>(node);
503 } 531 }
504 532
505 static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { 533 static Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
506 return GetParentPointer<Member, Derived>(node); 534 return Common::GetParentPointer<Member, Derived>(node);
507 } 535 }
508
509private:
510 static constexpr TypedStorage<Derived> DerivedStorage = {};
511}; 536};
512 537
513template <auto T, class Derived = impl::GetParentType<T>> 538template <auto T, class Derived = Common::impl::GetParentType<T>>
514class IntrusiveRedBlackTreeMemberTraitsDeferredAssert; 539class IntrusiveRedBlackTreeMemberTraitsDeferredAssert;
515 540
516template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived> 541template <class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
@@ -521,11 +546,6 @@ public:
521 IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert, Comparator>; 546 IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraitsDeferredAssert, Comparator>;
522 using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl; 547 using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
523 548
524 static constexpr bool IsValid() {
525 TypedStorage<Derived> DerivedStorage = {};
526 return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage);
527 }
528
529private: 549private:
530 template <class, class, class> 550 template <class, class, class>
531 friend class IntrusiveRedBlackTree; 551 friend class IntrusiveRedBlackTree;
@@ -540,30 +560,36 @@ private:
540 return std::addressof(parent->*Member); 560 return std::addressof(parent->*Member);
541 } 561 }
542 562
543 static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) { 563 static Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
544 return GetParentPointer<Member, Derived>(node); 564 return Common::GetParentPointer<Member, Derived>(node);
545 } 565 }
546 566
547 static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { 567 static Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
548 return GetParentPointer<Member, Derived>(node); 568 return Common::GetParentPointer<Member, Derived>(node);
549 } 569 }
550}; 570};
551 571
552template <class Derived> 572template <class Derived>
553class IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode { 573class alignas(void*) IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode {
554public: 574public:
575 using IntrusiveRedBlackTreeNode::IntrusiveRedBlackTreeNode;
576
555 constexpr Derived* GetPrev() { 577 constexpr Derived* GetPrev() {
556 return static_cast<Derived*>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); 578 return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode*>(
579 impl::IntrusiveRedBlackTreeImpl::GetPrev(this)));
557 } 580 }
558 constexpr const Derived* GetPrev() const { 581 constexpr const Derived* GetPrev() const {
559 return static_cast<const Derived*>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); 582 return static_cast<const Derived*>(static_cast<const IntrusiveRedBlackTreeBaseNode*>(
583 impl::IntrusiveRedBlackTreeImpl::GetPrev(this)));
560 } 584 }
561 585
562 constexpr Derived* GetNext() { 586 constexpr Derived* GetNext() {
563 return static_cast<Derived*>(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); 587 return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode*>(
588 impl::IntrusiveRedBlackTreeImpl::GetNext(this)));
564 } 589 }
565 constexpr const Derived* GetNext() const { 590 constexpr const Derived* GetNext() const {
566 return static_cast<const Derived*>(impl::IntrusiveRedBlackTreeImpl::GetNext(this)); 591 return static_cast<const Derived*>(static_cast<const IntrusiveRedBlackTreeBaseNode*>(
592 impl::IntrusiveRedBlackTreeImpl::GetNext(this)));
567 } 593 }
568}; 594};
569 595
@@ -581,19 +607,22 @@ private:
581 friend class impl::IntrusiveRedBlackTreeImpl; 607 friend class impl::IntrusiveRedBlackTreeImpl;
582 608
583 static constexpr IntrusiveRedBlackTreeNode* GetNode(Derived* parent) { 609 static constexpr IntrusiveRedBlackTreeNode* GetNode(Derived* parent) {
584 return static_cast<IntrusiveRedBlackTreeNode*>(parent); 610 return static_cast<IntrusiveRedBlackTreeNode*>(
611 static_cast<IntrusiveRedBlackTreeBaseNode<Derived>*>(parent));
585 } 612 }
586 613
587 static constexpr IntrusiveRedBlackTreeNode const* GetNode(Derived const* parent) { 614 static constexpr IntrusiveRedBlackTreeNode const* GetNode(Derived const* parent) {
588 return static_cast<const IntrusiveRedBlackTreeNode*>(parent); 615 return static_cast<const IntrusiveRedBlackTreeNode*>(
616 static_cast<const IntrusiveRedBlackTreeBaseNode<Derived>*>(parent));
589 } 617 }
590 618
591 static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) { 619 static constexpr Derived* GetParent(IntrusiveRedBlackTreeNode* node) {
592 return static_cast<Derived*>(node); 620 return static_cast<Derived*>(static_cast<IntrusiveRedBlackTreeBaseNode<Derived>*>(node));
593 } 621 }
594 622
595 static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { 623 static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
596 return static_cast<const Derived*>(node); 624 return static_cast<const Derived*>(
625 static_cast<const IntrusiveRedBlackTreeBaseNode<Derived>*>(node));
597 } 626 }
598}; 627};
599 628