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