Changeset 73e3791 in mainline
- Timestamp:
- 2018-07-05T21:41:23Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 27f1bc0
- Parents:
- 6175b78
- git-author:
- Dzejrou <dzejrou@…> (2018-05-13 22:57:14)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:23)
- Location:
- uspace/lib/cpp/include/internal
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/internal/rbtree.hpp
r6175b78 r73e3791 41 41 class KeyComp, class Alloc, class Size, 42 42 class Iterator, class ConstIterator, 43 class Policy 43 class Policy, class Node 44 44 > 45 45 class rbtree … … 53 53 using key_extract = KeyExtractor; 54 54 55 using iterator 56 using const_iterator 55 using iterator = Iterator; 56 using const_iterator = ConstIterator; 57 57 58 58 using reverse_iterator = std::reverse_iterator<iterator>; 59 59 using const_reverse_iterator = std::reverse_iterator<const_iterator>; 60 60 61 using node_type = rbtree_node<value_type>;61 using node_type = Node; 62 62 63 63 rbtree(const key_compare& kcmp = key_compare{}) … … 100 100 bool empty() const noexcept 101 101 { 102 return size_ ;102 return size_ == 0U; 103 103 } 104 104 … … 202 202 203 203 node = delete_node(node); 204 return iterator{const_cast<node_type*>(node), node == nullptr}; 204 if (!node) 205 return iterator{find_largest_(), true}; 206 else 207 return iterator{const_cast<node_type*>(node), false}; 205 208 } 206 209 … … 322 325 parent = current; 323 326 if (key_compare_(key, key_extractor_(current->value))) 324 current = current->left ;327 current = current->left(); 325 328 else if (key_compare_(key_extractor_(current->value), key)) 326 current = current->right ;329 current = current->right(); 327 330 else 328 331 return current; … … 337 340 if (!node) 338 341 return nullptr; 342 if (auto tmp = node->get_node_for_deletion(); tmp != nullptr) 343 { 344 /** 345 * This will kick in multi containers, 346 * we popped one node from a list of nodes 347 * with equivalent keys and we can delete it 348 * and return the original as it is still 349 * in place. 350 */ 351 delete tmp; 352 353 return node; 354 } 339 355 340 356 --size_; 341 357 358 if (node == root_) 359 { 360 delete node; 361 root_ = nullptr; 362 363 return nullptr; 364 } 365 342 366 auto succ = node->successor(); 343 if (node->left && node->right)367 if (node->left() && node->right()) 344 368 { 345 369 node->swap(succ); 346 347 // Succ has at most one child. 348 delete_node(succ); 349 350 return node; 351 } 352 353 auto child = node->right ? node->right : node->left; 370 if (succ && !succ->parent()) 371 root_ = succ; 372 373 // Node now has at most one child. 374 // Also: If succ was nullptr, the swap 375 // didn't do anything and we can 376 // safely delete node. 377 return delete_node(node); 378 } 379 380 auto child = node->right() ? node->right() : node->left(); 354 381 if (!child) 355 382 { … … 362 389 { 363 390 // Replace with the child. 364 child->parent = node->parent;391 child->parent(node->parent()); 365 392 if (node->is_left_child()) 366 child->parent ->left = child;393 child->parent()->left(child); 367 394 else if (node->is_right_child()) 368 child->parent ->right = child;395 child->parent()->right(child); 369 396 370 397 // Repair if needed. … … 380 407 void insert_node(node_type* node, node_type* parent) 381 408 { 382 if (!node) 383 return; 384 385 ++size_; 386 if (!parent) 387 { 388 node->color = rbcolor::black; 389 root_ = node; 390 } 391 else 392 { 393 if (keys_comp(get_key(node->value), parent->value)) 394 parent->add_left_child(node); 395 else 396 parent->add_right_child(node); 397 398 repair_after_insert_(node); 399 update_root_(node); 400 } 409 Policy::insert(*this, node, parent); 401 410 } 402 411 … … 413 422 { 414 423 if (key_compare_(key, key_extractor_(current->value))) 415 current = current->left ;424 current = current->left(); 416 425 else if (key_compare_(key_extractor_(current->value), key)) 417 current = current->right ;426 current = current->right(); 418 427 else 419 428 return current; … … 445 454 446 455 root_ = const_cast<node_type*>(node); 447 while (root_->parent )448 root_ = root_->parent ;456 while (root_->parent()) 457 root_ = root_->parent(); 449 458 } 450 459 -
uspace/lib/cpp/include/internal/rbtree_iterators.hpp
r6175b78 r73e3791 45 45 */ 46 46 47 template<class Value, class Reference, class Pointer, class Size >47 template<class Value, class Reference, class Pointer, class Size, class Node> 48 48 class rbtree_iterator 49 49 { … … 57 57 using iterator_category = bidirectional_iterator_tag; 58 58 59 rbtree_iterator(rbtree_node<value_type>* current = nullptr, bool end = true) 59 using node_type = Node; 60 61 rbtree_iterator(node_type* current = nullptr, bool end = true) 60 62 : current_{current}, end_{end} 61 63 { /* DUMMY BODY */ } … … 78 80 if (current_) 79 81 { 80 auto bckp = current_;81 if ( current_->right)82 current_ = current_->right->find_smallest();82 auto next = current_->successor(); 83 if (next) 84 current_ = next; 83 85 else 84 { 85 while (!current_->is_left_child()) 86 { 87 current_ = current_->parent; 88 89 if (!current_ || !current_->parent) 90 { 91 /** 92 * We've gone back to root without 93 * being a left child, which means we 94 * were the last node. 95 */ 96 end_ = true; 97 current_ = bckp; 98 99 return *this; 100 } 101 } 102 103 /** 104 * Now we are a left child, 105 * so the next node we have to visit 106 * is our parent. 107 */ 108 current_ = current_->parent; 109 } 86 end_ = true; 110 87 } 111 88 … … 132 109 if (current_) 133 110 { 134 if (current_->left) 135 current_ = current_->left->find_largest(); 136 else if (current_->parent) 137 { 138 while (current_->is_left_child()) 139 current_ = current_->parent; 140 141 /** 142 * We know parent exists here 143 * because we went up from the 144 * left and stopped being left 145 * child (if at any point we happened 146 * to become root then this branch 147 * wouldn't happen). 148 */ 149 current_ = current_->parent; 150 } 151 else // We are root without a left child. 111 auto next = current_->predecessor(); 112 if (next) 113 current_ = next; 114 else 152 115 end_ = true; 153 116 } … … 164 127 } 165 128 166 const rbtree_node<value_type>* node() const129 const node_type* node() const 167 130 { 168 131 return current_; 169 132 } 170 133 171 rbtree_node<value_type>* node()134 node_type* node() 172 135 { 173 136 return current_; … … 180 143 181 144 private: 182 rbtree_node<value_type>* current_;145 node_type* current_; 183 146 bool end_; 184 147 … … 197 160 }; 198 161 199 template<class Val, class Ref, class Ptr, class Sz >200 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz >& lhs,201 const rbtree_iterator<Val, Ref, Ptr, Sz >& rhs)162 template<class Val, class Ref, class Ptr, class Sz, class N> 163 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs, 164 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs) 202 165 { 203 166 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end()); 204 167 } 205 168 206 template<class Val, class Ref, class Ptr, class Sz >207 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz >& lhs,208 const rbtree_iterator<Val, Ref, Ptr, Sz >& rhs)169 template<class Val, class Ref, class Ptr, class Sz, class N> 170 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs, 171 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs) 209 172 { 210 173 return !(lhs == rhs); 211 174 } 212 175 213 template<class Value, class ConstReference, class ConstPointer, class Size >176 template<class Value, class ConstReference, class ConstPointer, class Size, class Node> 214 177 class rbtree_const_iterator 215 178 { 216 179 using non_const_iterator_type = rbtree_iterator< 217 180 Value, get_non_const_ref_t<ConstReference>, 218 get_non_const_ptr_t<ConstPointer>, Size 181 get_non_const_ptr_t<ConstPointer>, Size, Node 219 182 >; 220 183 … … 228 191 using iterator_category = bidirectional_iterator_tag; 229 192 230 rbtree_const_iterator(const rbtree_node<value_type>* current = nullptr, bool end = true) 193 using node_type = Node; 194 195 rbtree_const_iterator(const node_type* current = nullptr, bool end = true) 231 196 : current_{current}, end_{end} 232 197 { /* DUMMY BODY */ } … … 261 226 if (current_) 262 227 { 263 auto bckp = current_;264 if ( current_->right)265 current_ = current_->right->find_smallest();228 auto next = current_->successor(); 229 if (next) 230 current_ = next; 266 231 else 267 { 268 while (!current_->is_left_child()) 269 { 270 current_ = current_->parent; 271 272 if (!current_->parent) 273 { 274 /** 275 * We've gone back to root without 276 * being a left child, which means we 277 * were the last node. 278 */ 279 end_ = true; 280 current_ = bckp; 281 282 return *this; 283 } 284 } 285 286 /** 287 * Now we are a left child, 288 * so the next node we have to visit 289 * is our parent. 290 */ 291 current_ = current_->parent; 292 } 232 end_ = true; 293 233 } 294 234 … … 315 255 if (current_) 316 256 { 317 if (current_->left) 318 current_ = current_->left->find_largest(); 319 else if (current_->parent) 320 { 321 while (current_->is_left_child()) 322 current_ = current_->parent; 323 324 /** 325 * We know parent exists here 326 * because we went up from the 327 * left and stopped being left 328 * child (if at any point we happened 329 * to become root then this branch 330 * wouldn't happen). 331 */ 332 current_ = current_->parent; 333 } 334 else // We are root without a left child. 335 current_ = nullptr; 257 auto next = current_->predecessor(); 258 if (next) 259 current_ = next; 260 else 261 end_ = true; 336 262 } 337 263 … … 347 273 } 348 274 349 const rbtree_node<value_type>* node() const275 const node_type* node() const 350 276 { 351 277 return current_; … … 358 284 359 285 private: 360 const rbtree_node<value_type>* current_;286 const node_type* current_; 361 287 bool end_; 362 288 … … 375 301 }; 376 302 377 template<class Val, class CRef, class CPtr, class Sz >378 bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz >& lhs,379 const rbtree_const_iterator<Val, CRef, CPtr, Sz >& rhs)303 template<class Val, class CRef, class CPtr, class Sz, class N> 304 bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs, 305 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs) 380 306 { 381 307 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end()); 382 308 } 383 309 384 template<class Val, class CRef, class CPtr, class Sz >385 bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz >& lhs,386 const rbtree_const_iterator<Val, CRef, CPtr, Sz >& rhs)310 template<class Val, class CRef, class CPtr, class Sz, class N> 311 bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs, 312 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs) 387 313 { 388 314 return !(lhs == rhs); 389 315 } 390 316 391 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz >392 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz >& lhs,393 const rbtree_const_iterator<Val, CRef, CPtr, Sz >& rhs)317 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N> 318 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs, 319 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs) 394 320 { 395 321 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end()); 396 322 } 397 323 398 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz >399 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz >& lhs,400 const rbtree_const_iterator<Val, CRef, CPtr, Sz >& rhs)324 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N> 325 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs, 326 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs) 401 327 { 402 328 return !(lhs == rhs); 403 329 } 404 330 405 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz >406 bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz >& lhs,407 const rbtree_iterator<Val, Ref, Ptr, Sz >& rhs)331 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N> 332 bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs, 333 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs) 408 334 { 409 335 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end()); 410 336 } 411 337 412 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz >413 bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz >& lhs,414 const rbtree_iterator<Val, Ref, Ptr, Sz >& rhs)338 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N> 339 bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs, 340 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs) 415 341 { 416 342 return !(lhs == rhs); -
uspace/lib/cpp/include/internal/rbtree_node.hpp
r6175b78 r73e3791 30 30 #define LIBCPP_INTERNAL_RBTREE_NODE 31 31 32 #include <cassert> 32 33 #include <utility> 33 34 … … 39 40 }; 40 41 41 template<class T>42 struct rbtree_ node42 template<class Node> 43 struct rbtree_utils 43 44 { 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; 45 static Node* grandparent(Node* node) 46 { 47 if (node && node->parent()) 48 return node->parent->parent(); 61 49 else 62 50 return nullptr; 63 51 } 64 52 65 rbtree_node* brother() const66 { 67 if ( parent)68 { 69 if ( this == parent->left)70 return parent->right;71 else 72 return parent->left;53 static Node* brother(Node* node) 54 { 55 if (node && node->parent()) 56 { 57 if (node == node->parent->left()) 58 return node->parent->right(); 59 else 60 return node->parent->left(); 73 61 } 74 62 else … … 76 64 } 77 65 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; 66 static Node* uncle(Node* node) 67 { 68 auto gp = grandparent(node); 69 if (gp) 70 { 71 if (node->parent() == gp->left()) 72 return gp->right(); 73 else 74 return gp->left(); 86 75 } 87 76 else … … 89 78 } 90 79 91 bool is_left_child() const 92 { 93 if (parent) 94 return parent->left == this; 80 static bool is_left_child(const Node* node) 81 { 82 if (!node) 83 return false; 84 85 if (node->parent()) 86 return node->parent()->left() == node; 95 87 else 96 88 return false; 97 89 } 98 90 99 bool is_right_child() const 100 { 101 if (parent) 102 return parent->right == this; 91 static bool is_right_child(const Node* node) 92 { 93 if (!node) 94 return false; 95 96 if (node->parent()) 97 return node->parent()->right() == node; 103 98 else 104 99 return false; 105 100 } 106 101 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(); 102 static void rotate_left(Node* node) 103 { 104 // TODO: implement 105 } 106 107 static void rotate_right(Node* node) 108 { 109 // TODO: implement 110 } 111 112 static Node* find_smallest(Node* node) 113 { 114 return const_cast<Node*>(find_smallest(const_cast<const Node*>(node))); 115 } 116 117 static const Node* find_smallest(const Node* node) 118 { 119 if (!node) 120 return nullptr; 121 122 while (node->left()) 123 node = node->left(); 124 125 return node; 126 } 127 128 static Node* find_largest(Node* node) 129 { 130 return const_cast<Node*>(find_largest(const_cast<const Node*>(node))); 131 } 132 133 static const Node* find_largest(const Node* node) 134 { 135 if (!node) 136 return nullptr; 137 138 while (node->right()) 139 node = node->right(); 140 141 return node; 142 } 143 144 static Node* successor(Node* node) 145 { 146 return const_cast<Node*>(successor(const_cast<const Node*>(node))); 147 } 148 149 static const Node* successor(const Node* node) 150 { 151 if (!node) 152 return nullptr; 153 154 if (node->right()) 155 return find_smallest(node->right()); 157 156 else 158 157 { 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) 158 while (node && !is_left_child(node)) 159 node = node->parent(); 160 161 if (node) 162 return node->parent(); 163 else 164 return node; 165 } 166 } 167 168 static Node* predecessor(Node* node) 169 { 170 return const_cast<Node*>(predecessor(const_cast<const Node*>(node))); 171 } 172 173 static const Node* predecessor(const Node* node) 174 { 175 if (!node) 176 return nullptr; 177 178 if (node->left()) 179 return find_largest(node->left()); 180 else 181 { 182 while (node && is_left_child(node)) 183 node = node->parent(); 184 185 if (node) 186 return node->parent(); 187 else 188 return node; 189 } 190 } 191 192 static void add_left_child(Node* node, Node* child) 193 { 194 if (!node || !child) 170 195 return; 171 196 172 left = node;173 node->parent = this;174 } 175 176 void add_right_child(rbtree_node* node)177 { 178 if ( right)197 node->left(child); 198 child->parent(node); 199 } 200 201 static void add_right_child(Node* node, Node* child) 202 { 203 if (!node || !child) 179 204 return; 180 205 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 } 206 node->right(child); 207 child->parent(node); 208 } 209 210 static void swap(Node* node1, Node* node2) 211 { 212 if (!node1 || !node2) 213 return; 214 215 auto parent1 = node1->parent(); 216 auto left1 = node1->left(); 217 auto right1 = node1->right(); 218 auto is_right1 = is_right_child(node1); 219 220 auto parent2 = node2->parent(); 221 auto left2 = node2->left(); 222 auto right2 = node2->right(); 223 auto is_right2 = is_right_child(node2); 224 225 assimilate(node1, parent2, left2, right2, is_right2); 226 assimilate(node2, parent1, left1, right1, is_right1); 227 } 228 229 static void assimilate( 230 Node* node, Node* p, Node* l, Node* r, bool is_r 231 ) 232 { 233 if (!node) 234 return; 235 236 node->parent(p); 237 if (node->parent()) 238 { 239 if (is_r) 240 node->parent()->right(node); 241 else 242 node->parent()->left(node); 243 } 244 245 node->left(l); 246 if (node->left()) 247 node->left()->parent(node); 248 249 node->right(r); 250 if (node->right()) 251 node->right()->parent(node); 252 } 253 }; 254 255 template<class T> 256 struct rbtree_single_node 257 { 258 using utils = rbtree_utils<rbtree_single_node<T>>; 259 260 public: 261 T value; 262 rbcolor color; 263 264 template<class... Args> 265 rbtree_single_node(Args&&... args) 266 : value{forward<Args>(args)...}, color{rbcolor::red}, 267 parent_{}, left_{}, right_{} 268 { /* DUMMY BODY */ } 269 270 rbtree_single_node* parent() const 271 { 272 return parent_; 273 } 274 275 void parent(rbtree_single_node* node) 276 { 277 parent_ = node; 278 } 279 280 rbtree_single_node* left() const 281 { 282 return left_; 283 } 284 285 void left(rbtree_single_node* node) 286 { 287 left_ = node; 288 } 289 290 rbtree_single_node* right() const 291 { 292 return right_; 293 } 294 295 void right(rbtree_single_node* node) 296 { 297 right_ = node; 298 } 299 300 rbtree_single_node* grandparent() 301 { 302 return utils::grandparent(this); 303 } 304 305 rbtree_single_node* brother() 306 { 307 return utils::brother(this); 308 } 309 310 rbtree_single_node* uncle() 311 { 312 return utils::uncle(this); 313 } 314 315 bool is_left_child() const 316 { 317 return utils::is_left_child(this); 318 } 319 320 bool is_right_child() const 321 { 322 return utils::is_right_child(this); 323 } 324 325 void rotate_left() 326 { 327 utils::rotate_left(this); 328 } 329 330 void rotate_right() 331 { 332 utils::rotate_right(this); 333 } 334 335 rbtree_single_node* find_smallest() 336 { 337 return utils::find_smallest(this); 338 } 339 340 const rbtree_single_node* find_smallest() const 341 { 342 return utils::find_smallest(this); 343 } 344 345 rbtree_single_node* find_largest() 346 { 347 return utils::find_largest(this); 348 } 349 350 const rbtree_single_node* find_largest() const 351 { 352 return utils::find_largest(this); 353 } 354 355 rbtree_single_node* successor() 356 { 357 return utils::successor(this); 358 } 359 360 const rbtree_single_node* successor() const 361 { 362 return utils::successor(this); 363 } 364 365 rbtree_single_node* predecessor() 366 { 367 return utils::predecessor(this); 368 } 369 370 const rbtree_single_node* predecessor() const 371 { 372 return utils::predecessor(this); 373 } 374 375 void add_left_child(rbtree_single_node* node) 376 { 377 utils::add_left_child(this, node); 378 } 379 380 void add_right_child(rbtree_single_node* node) 381 { 382 utils::add_right_child(this, node); 383 } 384 385 void swap(rbtree_single_node* other) 386 { 387 utils::swap(this, other); 388 } 389 390 void unlink() 391 { 392 if (is_left_child()) 393 parent_->left_ = nullptr; 394 else if (is_right_child()) 395 parent_->right_ = nullptr; 396 } 397 398 rbtree_single_node* get_node_for_deletion() 399 { 400 return nullptr; 401 } 402 403 ~rbtree_single_node() 404 { 405 parent_ = nullptr; 406 if (left_) 407 delete left_; 408 if (right_) 409 delete right_; 410 } 411 412 private: 413 rbtree_single_node* parent_; 414 rbtree_single_node* left_; 415 rbtree_single_node* right_; 416 }; 417 418 template<class T> 419 struct rbtree_multi_node 420 { 421 using utils = rbtree_utils<rbtree_multi_node<T>>; 422 423 public: 424 T value; 425 rbcolor color; 426 427 template<class... Args> 428 rbtree_multi_node(Args&&... args) 429 : value{forward<Args>(args)...}, color{rbcolor::red}, 430 parent_{}, left_{}, right_{}, next_{}, first_{this} 431 { /* DUMMY BODY */ } 432 433 rbtree_multi_node* parent() const 434 { 435 return parent_; 436 } 437 438 void parent(rbtree_multi_node* node) 439 { 440 parent_ = node; 441 442 auto tmp = first_; 443 while (tmp) 444 { 445 tmp->parent_ = node; 446 tmp = tmp->next_; 447 } 448 } 449 450 rbtree_multi_node* left() const 451 { 452 return left_; 453 } 454 455 void left(rbtree_multi_node* node) 456 { 457 left_ = node; 458 459 auto tmp = first_; 460 while (tmp) 461 { 462 tmp->left_ = node; 463 tmp = tmp->next_; 464 } 465 } 466 467 rbtree_multi_node* right() const 468 { 469 return right_; 470 } 471 472 void right(rbtree_multi_node* node) 473 { 474 right_ = node; 475 476 auto tmp = first_; 477 while (tmp) 478 { 479 tmp->right_ = node; 480 tmp = tmp->next_; 481 } 482 } 483 484 rbtree_multi_node* grandparent() 485 { 486 return utils::grandparent(this); 487 } 488 489 rbtree_multi_node* brother() 490 { 491 return utils::brother(this); 492 } 493 494 rbtree_multi_node* uncle() 495 { 496 return utils::uncle(this); 497 } 498 499 bool is_left_child() const 500 { 501 return utils::is_left_child(this); 502 } 503 504 bool is_right_child() 505 { 506 return utils::is_right_child(this); 507 } 508 509 void rotate_left() 510 { 511 utils::rotate_left(this); 512 } 513 514 void rotate_right() 515 { 516 utils::rotate_right(this); 517 } 518 519 rbtree_multi_node* find_smallest() 520 { 521 return utils::find_smallest(this); 522 } 523 524 const rbtree_multi_node* find_smallest() const 525 { 526 return utils::find_smallest(this); 527 } 528 529 rbtree_multi_node* find_largest() 530 { 531 return utils::find_largest(this); 532 } 533 534 const rbtree_multi_node* find_largest() const 535 { 536 return utils::find_largest(this); 537 } 538 539 rbtree_multi_node* successor() 540 { 541 return const_cast< 542 rbtree_multi_node* 543 >(const_cast<const rbtree_multi_node*>(this)->successor()); 544 } 545 546 const rbtree_multi_node* successor() const 547 { 548 if (next_) 549 return next_; 550 else 551 return utils::successor(this); 552 } 553 554 rbtree_multi_node* predecessor() 555 { 556 return const_cast< 557 rbtree_multi_node* 558 >(const_cast<const rbtree_multi_node*>(this)->predecessor()); 559 } 560 561 const rbtree_multi_node* predecessor() const 562 { 563 return utils::predecessor(this); 564 } 565 566 void add_left_child(rbtree_multi_node* node) 567 { 568 utils::add_left_child(this, node); 569 } 570 571 void add_right_child(rbtree_multi_node* node) 572 { 573 utils::add_right_child(this, node); 574 } 575 576 void swap(rbtree_multi_node* other) 577 { 578 utils::swap(this, other); 579 } 580 581 rbtree_multi_node<T>* get_node_for_deletion() 582 { 583 if (next_) 584 { 585 auto tmp = next_; 586 while (tmp && tmp->next_ != this) 587 tmp = tmp->next_; 588 589 return tmp; // This will get deleted. 590 } 591 else 592 return nullptr; 593 } 594 595 void unlink() 596 { 597 if (is_left_child()) 598 parent->left_ = nullptr; 599 else if (is_right_child()) 600 parent->right_ = nullptr; 601 } 602 603 void add(rbtree_multi_node* node) 604 { 605 if (next_) 606 next_->add(node); 607 else 608 { 609 next_ = node; 610 next_->first_ = first_; 611 next_->parent_ = parent_; 612 next_->left_ = left_; 613 next_->right_ = right_; 614 } 615 } 616 617 ~rbtree_multi_node() 618 { 619 parent_ = nullptr; 620 if (left_) 621 delete left_; 622 if (right) 623 delete right_; 624 625 // TODO: delete the list 626 } 627 628 private: 629 rbtree_multi_node* parent_; 630 rbtree_multi_node* left_; 631 rbtree_multi_node* right_; 632 633 rbtree_multi_node* next_; 634 rbtree_multi_node* first_; 202 635 }; 203 636 } -
uspace/lib/cpp/include/internal/rbtree_policies.hpp
r6175b78 r73e3791 59 59 static typename Tree::iterator lower_bound(const Tree& tree, const Key& key) 60 60 { 61 using iterator = typename Tree::iterator; 61 using iterator = typename Tree::iterator; 62 using node_type = typename Tree::node_type; 62 63 63 64 auto it = lower_bound_const(tree, key); 64 65 65 return iterator{ it.node(), it.end()};66 return iterator{const_cast<node_type*>(it.node()), it.end()}; 66 67 } 67 68 … … 101 102 static typename Tree::iterator upper_bound(const Tree& tree, const Key& key) 102 103 { 103 using iterator = typename Tree::iterator; 104 using iterator = typename Tree::iterator; 105 using node_type = typename Tree::node_type; 104 106 105 107 auto it = upper_bound_const(tree, key); 106 108 107 return iterator{ it.node(), it.end()};109 return iterator{const_cast<node_type*>(it.node()), it.end()}; 108 110 } 109 111 … … 113 115 /** 114 116 * If key isn't in the tree, we get it's 115 * successor or tree.end(). If key is 116 * in the tree, we get it. 117 * In the first case, the successor is also 118 * the upper bound, so we just return it, 119 * otherwise (as long as it != end()) we 120 * increment. 117 * predecessor or tree.end(). If key is 118 * in the tree, we get it. So unless it 119 * is equal to end(), we can increment it 120 * to get the upper bound. 121 121 */ 122 122 auto it = lower_bound_const(tree, key); 123 123 if (it == tree.end()) 124 124 return it; 125 else if (tree.keys_equal(key, *it))125 else 126 126 return ++it; 127 else128 return it;129 127 } 130 128 … … 176 174 177 175 auto node = new node_type{move(val)}; 178 tree.insert_node(node, parent); 179 180 return make_pair(iterator{node, false}, true); 176 177 return insert(tree, node, parent); 181 178 } 182 179 … … 194 191 195 192 auto node = new node_type{val}; 196 tree.insert_node(node, parent); 197 198 return make_pair(iterator{node, false}, true); 193 194 return insert(tree, node, parent); 199 195 } 200 196 … … 212 208 213 209 auto node = new node_type{forward<Value>(val)}; 214 tree.insert_node(node, parent); 210 211 return insert(tree, node, parent); 212 } 213 214 template<class Tree> 215 static pair< 216 typename Tree::iterator, bool 217 > insert( 218 Tree& tree, typename Tree::node_type* node, 219 typename Tree::node_type* parent 220 ) 221 { 222 using iterator = typename Tree::iterator; 223 224 if (!node) 225 return make_pair(tree.end(), false); 226 227 ++tree.size_; 228 if (!parent) 229 { 230 node->color = rbcolor::black; 231 tree.root_ = node; 232 } 233 else 234 { 235 if (tree.keys_comp(tree.get_key(node->value), parent->value)) 236 parent->add_left_child(node); 237 else 238 parent->add_right_child(node); 239 240 tree.repair_after_insert_(node); 241 tree.update_root_(node); 242 } 215 243 216 244 return make_pair(iterator{node, false}, true); … … 308 336 /** 309 337 * If key isn't in the tree, we get it's 310 * successor or tree.end(). If key is 311 * in the tree, we get it. 312 * In the first case, the successor is also 313 * the upper bound, so we just return it, 314 * otherwise (as long as it != end()) we 315 * increment. 338 * predecessor or tree.end(). If key is 339 * in the tree, we get it. So unless it 340 * is equal to end(), we keep incrementing 341 * until we get to the next key. 316 342 */ 317 343 auto it = lower_bound(tree, key); … … 320 346 else if (tree.keys_equal(tree.get_key(*it), key)) 321 347 { 322 while ( tree.keys_equal(tree.get_key(*it), key))348 while (it != tree.end() && tree.keys_equal(tree.get_key(*it), key)) 323 349 ++it; 324 350 … … 384 410 385 411 template<class Tree> 386 static typename Tree::iterator insert(Tree& tree, typename Tree::node_type* node) 387 { 388 using iterator = typename Tree::iterator; 412 static typename Tree::iterator insert( 413 Tree& tree, typename Tree::node_type* node, 414 typename Tree::node_type* = nullptr 415 ) 416 { 417 using iterator = typename Tree::iterator; 418 419 if (!node) 420 return tree.end(); 389 421 390 422 auto parent = tree.find_parent_for_insertion(tree.get_key(node->value)); 391 tree.insert_node(node, parent); 423 424 ++tree.size_; 425 if (!parent) 426 { 427 node->color = rbcolor::black; 428 tree.root_ = node; 429 } 430 else 431 { 432 if (tree.keys_comp(tree.get_key(node->value), parent->value)) 433 parent->add_left_child(node); 434 else if (tree.keys_comp(tree.get_key(parent->value), node->value)) 435 parent->add_right_child(node); 436 else 437 { 438 parent->add(node); // List of nodes with equivalent keys. 439 tree.update_root_(parent); 440 441 return iterator{node, false}; 442 } 443 444 tree.repair_after_insert_(node); 445 tree.update_root_(node); 446 } 392 447 393 448 return iterator{node, false};
Note:
See TracChangeset
for help on using the changeset viewer.