source: mainline/uspace/lib/cpp/include/internal/rbtree_node.hpp@ 49fbfb5

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

cpp: added some more functionality to rbtree_node

  • Property mode set to 100644
File size: 5.4 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 rbtree_node* find_largest()
127 {
128 auto res = this;
129 while (res->right)
130 res = res->right;
131
132 return res;
133 }
134
135 rbtree_node* successor()
136 {
137 if (right)
138 return right->find_smallest();
139 else
140 {
141 auto current = this;
142 while (!current->is_left_child())
143 current = current->parent;
144
145 return current->parent;
146 }
147 }
148
149 void add_left_child(rbtree_node* node)
150 {
151 if (left)
152 return;
153
154 left = node;
155 node->parent = this;
156 }
157
158 void add_right_child(rbtree_node* node)
159 {
160 if (right)
161 return;
162
163 right = node;
164 node->parent = this;
165 }
166
167 void swap(rbtree_node* other)
168 {
169 /**
170 * Parent can be null so we check both ways.
171 */
172 if (is_left_child())
173 parent->left = other;
174 else if (is_right_child())
175 parent->right = other;
176
177 if (other->is_left_child())
178 other->parent->left = this;
179 else if (other->is_right_child())
180 other->parent->right = this;
181
182 if (left)
183 left->parent = other;
184 if (right)
185 right->parent = other;
186 if (other->left)
187 other->left->parent = this;
188 if (other->right)
189 other->right->parent = this;
190
191 std::swap(parent, other->parent);
192 std::swap(left, other->left);
193 std::swap(right, other->right);
194 }
195
196 void unlink()
197 {
198 if (is_left_child())
199 parent->left = nullptr;
200 else if (is_right_child())
201 parent->right = nullptr;
202 }
203
204 ~rbtree_node()
205 {
206 // TODO: delete recursively or iteratively?
207 }
208 };
209}
210
211#endif
Note: See TracBrowser for help on using the repository browser.