source: mainline/uspace/lib/cpp/include/internal/rbtree_node.hpp@ 614b07e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 614b07e was cacb5d0, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added more node operations, changed swap to value swap instead of link swap which was buggy and probably slower when move semantics are in the play

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_INTERNAL_RBTREE_NODE
30#define LIBCPP_INTERNAL_RBTREE_NODE
31
32#include <utility>
33
34namespace std::aux
35{
36 enum class rbcolor
37 {
38 red, black
39 };
40
41 template<class T>
42 struct rbtree_node
43 {
44 T value;
45 rbcolor color;
46
47 rbtree_node* parent;
48 rbtree_node* left;
49 rbtree_node* right;
50
51 template<class... Args>
52 rbtree_node(Args&&... args)
53 : value{forward<Args>(args)...}, color{rbcolor::red},
54 parent{}, left{}, right{}
55 { /* DUMMY BODY */ }
56
57 rbtree_node* grandparent() const
58 {
59 if (parent)
60 return parent->parent;
61 else
62 return nullptr;
63 }
64
65 rbtree_node* brother() const
66 {
67 if (parent)
68 {
69 if (this == parent->left)
70 return parent->right;
71 else
72 return parent->left;
73 }
74 else
75 return nullptr;
76 }
77
78 rbtree_node* uncle() const
79 {
80 if (grandparent())
81 {
82 if (parent == grandparent()->left)
83 return grandparent()->right;
84 else
85 return grandparent()->left;
86 }
87 else
88 return nullptr;
89 }
90
91 bool is_left_child() const
92 {
93 if (parent)
94 return parent->left == this;
95 else
96 return false;
97 }
98
99 bool is_right_child() const
100 {
101 if (parent)
102 return parent->right == this;
103 else
104 return false;
105 }
106
107 void rotate_left()
108 {
109 // TODO:
110 }
111
112 void rotate_right()
113 {
114 // TODO:
115 }
116
117 rbtree_node* find_smallest()
118 {
119 auto res = this;
120 while (res->left)
121 res = res->left;
122
123 return res;
124 }
125
126 const rbtree_node* find_smallest() const
127 {
128 auto res = this;
129 while (res->left)
130 res = res->left;
131
132 return res;
133 }
134
135 rbtree_node* find_largest()
136 {
137 auto res = this;
138 while (res->right)
139 res = res->right;
140
141 return res;
142 }
143
144 const rbtree_node* find_largest() const
145 {
146 auto res = this;
147 while (res->right)
148 res = res->right;
149
150 return res;
151 }
152
153 rbtree_node* successor() const
154 {
155 if (right)
156 return right->find_smallest();
157 else
158 {
159 auto current = this;
160 while (!current->is_left_child())
161 current = current->parent;
162
163 return current->parent;
164 }
165 }
166
167 void add_left_child(rbtree_node* node)
168 {
169 if (left)
170 return;
171
172 left = node;
173 node->parent = this;
174 }
175
176 void add_right_child(rbtree_node* node)
177 {
178 if (right)
179 return;
180
181 right = node;
182 node->parent = this;
183 }
184
185 void swap(rbtree_node* other)
186 {
187 std::swap(value, other->value);
188 }
189
190 void unlink()
191 {
192 if (is_left_child())
193 parent->left = nullptr;
194 else if (is_right_child())
195 parent->right = nullptr;
196 }
197
198 ~rbtree_node()
199 {
200 // TODO: delete recursively or iteratively?
201 }
202 };
203}
204
205#endif
Note: See TracBrowser for help on using the repository browser.