summaryrefslogtreecommitdiff
path: root/src/common/intrusive_red_black_tree.h
diff options
context:
space:
mode:
authorGravatar Lioncash2021-01-12 02:47:36 -0500
committerGravatar Lioncash2021-01-12 16:46:36 -0500
commitb15e1a35011629c3b31edd10c1d10b8d7fafcb2c (patch)
tree6bb48e8e2f65ed47436c4279f0732e45c2041007 /src/common/intrusive_red_black_tree.h
parentcommon/tree: Remove unused splay tree defines (diff)
downloadyuzu-b15e1a35011629c3b31edd10c1d10b8d7fafcb2c.tar.gz
yuzu-b15e1a35011629c3b31edd10c1d10b8d7fafcb2c.tar.xz
yuzu-b15e1a35011629c3b31edd10c1d10b8d7fafcb2c.zip
common/tree: Convert defines over to templates
Reworks the tree header to operate off of templates as opposed to a series of defines. This allows all tree facilities to obey namespacing rules, and also allows this code to be used within modules once compiler support is in place. This also gets rid to use a macro to define functions and structs for necessary data types. With templates, these will be generated when they're actually used, eliminating the need for the separate declaration.
Diffstat (limited to 'src/common/intrusive_red_black_tree.h')
-rw-r--r--src/common/intrusive_red_black_tree.h99
1 files changed, 37 insertions, 62 deletions
diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h
index fb55de94e..c0bbcd457 100644
--- a/src/common/intrusive_red_black_tree.h
+++ b/src/common/intrusive_red_black_tree.h
@@ -16,17 +16,30 @@ class IntrusiveRedBlackTreeImpl;
16} 16}
17 17
18struct IntrusiveRedBlackTreeNode { 18struct IntrusiveRedBlackTreeNode {
19public:
20 using EntryType = RBEntry<IntrusiveRedBlackTreeNode>;
21
22 constexpr IntrusiveRedBlackTreeNode() = default;
23
24 void SetEntry(const EntryType& new_entry) {
25 entry = new_entry;
26 }
27
28 [[nodiscard]] EntryType& GetEntry() {
29 return entry;
30 }
31
32 [[nodiscard]] const EntryType& GetEntry() const {
33 return entry;
34 }
19 35
20private: 36private:
21 RB_ENTRY(IntrusiveRedBlackTreeNode) entry{}; 37 EntryType entry{};
22 38
23 friend class impl::IntrusiveRedBlackTreeImpl; 39 friend class impl::IntrusiveRedBlackTreeImpl;
24 40
25 template <class, class, class> 41 template <class, class, class>
26 friend class IntrusiveRedBlackTree; 42 friend class IntrusiveRedBlackTree;
27
28public:
29 constexpr IntrusiveRedBlackTreeNode() = default;
30}; 43};
31 44
32template <class T, class Traits, class Comparator> 45template <class T, class Traits, class Comparator>
@@ -35,17 +48,12 @@ class IntrusiveRedBlackTree;
35namespace impl { 48namespace impl {
36 49
37class IntrusiveRedBlackTreeImpl { 50class IntrusiveRedBlackTreeImpl {
38
39private: 51private:
40 template <class, class, class> 52 template <class, class, class>
41 friend class ::Common::IntrusiveRedBlackTree; 53 friend class ::Common::IntrusiveRedBlackTree;
42 54
43private: 55 using RootType = RBHead<IntrusiveRedBlackTreeNode>;
44 RB_HEAD(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode); 56 RootType root;
45 using RootType = IntrusiveRedBlackTreeRoot;
46
47private:
48 IntrusiveRedBlackTreeRoot root;
49 57
50public: 58public:
51 template <bool Const> 59 template <bool Const>
@@ -121,57 +129,45 @@ public:
121 } 129 }
122 }; 130 };
123 131
124protected:
125 // Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot.
126 RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry);
127
128private: 132private:
129 // Define accessors using RB_* functions. 133 // Define accessors using RB_* functions.
130 constexpr void InitializeImpl() {
131 RB_INIT(&this->root);
132 }
133
134 bool EmptyImpl() const { 134 bool EmptyImpl() const {
135 return RB_EMPTY(&this->root); 135 return root.IsEmpty();
136 } 136 }
137 137
138 IntrusiveRedBlackTreeNode* GetMinImpl() const { 138 IntrusiveRedBlackTreeNode* GetMinImpl() const {
139 return RB_MIN(IntrusiveRedBlackTreeRoot, 139 return RB_MIN(const_cast<RootType*>(&root));
140 const_cast<IntrusiveRedBlackTreeRoot*>(&this->root));
141 } 140 }
142 141
143 IntrusiveRedBlackTreeNode* GetMaxImpl() const { 142 IntrusiveRedBlackTreeNode* GetMaxImpl() const {
144 return RB_MAX(IntrusiveRedBlackTreeRoot, 143 return RB_MAX(const_cast<RootType*>(&root));
145 const_cast<IntrusiveRedBlackTreeRoot*>(&this->root));
146 } 144 }
147 145
148 IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) { 146 IntrusiveRedBlackTreeNode* RemoveImpl(IntrusiveRedBlackTreeNode* node) {
149 return RB_REMOVE(IntrusiveRedBlackTreeRoot, &this->root, node); 147 return RB_REMOVE(&root, node);
150 } 148 }
151 149
152public: 150public:
153 static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) { 151 static IntrusiveRedBlackTreeNode* GetNext(IntrusiveRedBlackTreeNode* node) {
154 return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node); 152 return RB_NEXT(node);
155 } 153 }
156 154
157 static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) { 155 static IntrusiveRedBlackTreeNode* GetPrev(IntrusiveRedBlackTreeNode* node) {
158 return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node); 156 return RB_PREV(node);
159 } 157 }
160 158
161 static IntrusiveRedBlackTreeNode const* GetNext(const IntrusiveRedBlackTreeNode* node) { 159 static const IntrusiveRedBlackTreeNode* GetNext(const IntrusiveRedBlackTreeNode* node) {
162 return static_cast<const IntrusiveRedBlackTreeNode*>( 160 return static_cast<const IntrusiveRedBlackTreeNode*>(
163 GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); 161 GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node)));
164 } 162 }
165 163
166 static IntrusiveRedBlackTreeNode const* GetPrev(const IntrusiveRedBlackTreeNode* node) { 164 static const IntrusiveRedBlackTreeNode* GetPrev(const IntrusiveRedBlackTreeNode* node) {
167 return static_cast<const IntrusiveRedBlackTreeNode*>( 165 return static_cast<const IntrusiveRedBlackTreeNode*>(
168 GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node))); 166 GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node)));
169 } 167 }
170 168
171public: 169public:
172 constexpr IntrusiveRedBlackTreeImpl() : root() { 170 constexpr IntrusiveRedBlackTreeImpl() {}
173 this->InitializeImpl();
174 }
175 171
176 // Iterator accessors. 172 // Iterator accessors.
177 iterator begin() { 173 iterator begin() {
@@ -269,8 +265,6 @@ private:
269 ImplType impl{}; 265 ImplType impl{};
270 266
271public: 267public:
272 struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot {};
273
274 template <bool Const> 268 template <bool Const>
275 class Iterator; 269 class Iterator;
276 270
@@ -363,11 +357,6 @@ public:
363 }; 357 };
364 358
365private: 359private:
366 // Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot.
367 RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode,
368 entry, CompareImpl, LightCompareImpl);
369
370private:
371 static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs, 360 static int CompareImpl(const IntrusiveRedBlackTreeNode* lhs,
372 const IntrusiveRedBlackTreeNode* rhs) { 361 const IntrusiveRedBlackTreeNode* rhs) {
373 return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs)); 362 return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
@@ -379,41 +368,27 @@ private:
379 368
380 // Define accessors using RB_* functions. 369 // Define accessors using RB_* functions.
381 IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { 370 IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) {
382 return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, 371 return RB_INSERT(&impl.root, node, CompareImpl);
383 static_cast<IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root),
384 node);
385 } 372 }
386 373
387 IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { 374 IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const {
388 return RB_FIND( 375 return RB_FIND(const_cast<ImplType::RootType*>(&impl.root),
389 IntrusiveRedBlackTreeRootWithCompare, 376 const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
390 const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
391 static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
392 const_cast<IntrusiveRedBlackTreeNode*>(node));
393 } 377 }
394 378
395 IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { 379 IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const {
396 return RB_NFIND( 380 return RB_NFIND(const_cast<ImplType::RootType*>(&impl.root),
397 IntrusiveRedBlackTreeRootWithCompare, 381 const_cast<IntrusiveRedBlackTreeNode*>(node), CompareImpl);
398 const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
399 static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
400 const_cast<IntrusiveRedBlackTreeNode*>(node));
401 } 382 }
402 383
403 IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const { 384 IntrusiveRedBlackTreeNode* FindLightImpl(const_light_pointer lelm) const {
404 return RB_FIND_LIGHT( 385 return RB_FIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root),
405 IntrusiveRedBlackTreeRootWithCompare, 386 static_cast<const void*>(lelm), LightCompareImpl);
406 const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
407 static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
408 static_cast<const void*>(lelm));
409 } 387 }
410 388
411 IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const { 389 IntrusiveRedBlackTreeNode* NFindLightImpl(const_light_pointer lelm) const {
412 return RB_NFIND_LIGHT( 390 return RB_NFIND_LIGHT(const_cast<ImplType::RootType*>(&impl.root),
413 IntrusiveRedBlackTreeRootWithCompare, 391 static_cast<const void*>(lelm), LightCompareImpl);
414 const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
415 static_cast<const IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root)),
416 static_cast<const void*>(lelm));
417 } 392 }
418 393
419public: 394public: