1*38fd1498Szrj // RB tree utilities implementation -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2003-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /* 26*38fd1498Szrj * 27*38fd1498Szrj * Copyright (c) 1996,1997 28*38fd1498Szrj * Silicon Graphics Computer Systems, Inc. 29*38fd1498Szrj * 30*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 31*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 32*38fd1498Szrj * provided that the above copyright notice appear in all copies and 33*38fd1498Szrj * that both that copyright notice and this permission notice appear 34*38fd1498Szrj * in supporting documentation. Silicon Graphics makes no 35*38fd1498Szrj * representations about the suitability of this software for any 36*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 37*38fd1498Szrj * 38*38fd1498Szrj * 39*38fd1498Szrj * Copyright (c) 1994 40*38fd1498Szrj * Hewlett-Packard Company 41*38fd1498Szrj * 42*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 43*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 44*38fd1498Szrj * provided that the above copyright notice appear in all copies and 45*38fd1498Szrj * that both that copyright notice and this permission notice appear 46*38fd1498Szrj * in supporting documentation. Hewlett-Packard Company makes no 47*38fd1498Szrj * representations about the suitability of this software for any 48*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 49*38fd1498Szrj * 50*38fd1498Szrj * 51*38fd1498Szrj */ 52*38fd1498Szrj 53*38fd1498Szrj #include <bits/stl_tree.h> 54*38fd1498Szrj 55*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 56*38fd1498Szrj { 57*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 58*38fd1498Szrj 59*38fd1498Szrj static _Rb_tree_node_base* local_Rb_tree_increment(_Rb_tree_node_base * __x)60*38fd1498Szrj local_Rb_tree_increment(_Rb_tree_node_base* __x) throw () 61*38fd1498Szrj { 62*38fd1498Szrj if (__x->_M_right != 0) 63*38fd1498Szrj { 64*38fd1498Szrj __x = __x->_M_right; 65*38fd1498Szrj while (__x->_M_left != 0) 66*38fd1498Szrj __x = __x->_M_left; 67*38fd1498Szrj } 68*38fd1498Szrj else 69*38fd1498Szrj { 70*38fd1498Szrj _Rb_tree_node_base* __y = __x->_M_parent; 71*38fd1498Szrj while (__x == __y->_M_right) 72*38fd1498Szrj { 73*38fd1498Szrj __x = __y; 74*38fd1498Szrj __y = __y->_M_parent; 75*38fd1498Szrj } 76*38fd1498Szrj if (__x->_M_right != __y) 77*38fd1498Szrj __x = __y; 78*38fd1498Szrj } 79*38fd1498Szrj return __x; 80*38fd1498Szrj } 81*38fd1498Szrj 82*38fd1498Szrj _Rb_tree_node_base* _Rb_tree_increment(_Rb_tree_node_base * __x)83*38fd1498Szrj _Rb_tree_increment(_Rb_tree_node_base* __x) throw () 84*38fd1498Szrj { 85*38fd1498Szrj return local_Rb_tree_increment(__x); 86*38fd1498Szrj } 87*38fd1498Szrj 88*38fd1498Szrj const _Rb_tree_node_base* _Rb_tree_increment(const _Rb_tree_node_base * __x)89*38fd1498Szrj _Rb_tree_increment(const _Rb_tree_node_base* __x) throw () 90*38fd1498Szrj { 91*38fd1498Szrj return local_Rb_tree_increment(const_cast<_Rb_tree_node_base*>(__x)); 92*38fd1498Szrj } 93*38fd1498Szrj 94*38fd1498Szrj static _Rb_tree_node_base* local_Rb_tree_decrement(_Rb_tree_node_base * __x)95*38fd1498Szrj local_Rb_tree_decrement(_Rb_tree_node_base* __x) throw () 96*38fd1498Szrj { 97*38fd1498Szrj if (__x->_M_color == _S_red 98*38fd1498Szrj && __x->_M_parent->_M_parent == __x) 99*38fd1498Szrj __x = __x->_M_right; 100*38fd1498Szrj else if (__x->_M_left != 0) 101*38fd1498Szrj { 102*38fd1498Szrj _Rb_tree_node_base* __y = __x->_M_left; 103*38fd1498Szrj while (__y->_M_right != 0) 104*38fd1498Szrj __y = __y->_M_right; 105*38fd1498Szrj __x = __y; 106*38fd1498Szrj } 107*38fd1498Szrj else 108*38fd1498Szrj { 109*38fd1498Szrj _Rb_tree_node_base* __y = __x->_M_parent; 110*38fd1498Szrj while (__x == __y->_M_left) 111*38fd1498Szrj { 112*38fd1498Szrj __x = __y; 113*38fd1498Szrj __y = __y->_M_parent; 114*38fd1498Szrj } 115*38fd1498Szrj __x = __y; 116*38fd1498Szrj } 117*38fd1498Szrj return __x; 118*38fd1498Szrj } 119*38fd1498Szrj 120*38fd1498Szrj _Rb_tree_node_base* _Rb_tree_decrement(_Rb_tree_node_base * __x)121*38fd1498Szrj _Rb_tree_decrement(_Rb_tree_node_base* __x) throw () 122*38fd1498Szrj { 123*38fd1498Szrj return local_Rb_tree_decrement(__x); 124*38fd1498Szrj } 125*38fd1498Szrj 126*38fd1498Szrj const _Rb_tree_node_base* _Rb_tree_decrement(const _Rb_tree_node_base * __x)127*38fd1498Szrj _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw () 128*38fd1498Szrj { 129*38fd1498Szrj return local_Rb_tree_decrement(const_cast<_Rb_tree_node_base*>(__x)); 130*38fd1498Szrj } 131*38fd1498Szrj 132*38fd1498Szrj static void local_Rb_tree_rotate_left(_Rb_tree_node_base * const __x,_Rb_tree_node_base * & __root)133*38fd1498Szrj local_Rb_tree_rotate_left(_Rb_tree_node_base* const __x, 134*38fd1498Szrj _Rb_tree_node_base*& __root) 135*38fd1498Szrj { 136*38fd1498Szrj _Rb_tree_node_base* const __y = __x->_M_right; 137*38fd1498Szrj 138*38fd1498Szrj __x->_M_right = __y->_M_left; 139*38fd1498Szrj if (__y->_M_left !=0) 140*38fd1498Szrj __y->_M_left->_M_parent = __x; 141*38fd1498Szrj __y->_M_parent = __x->_M_parent; 142*38fd1498Szrj 143*38fd1498Szrj if (__x == __root) 144*38fd1498Szrj __root = __y; 145*38fd1498Szrj else if (__x == __x->_M_parent->_M_left) 146*38fd1498Szrj __x->_M_parent->_M_left = __y; 147*38fd1498Szrj else 148*38fd1498Szrj __x->_M_parent->_M_right = __y; 149*38fd1498Szrj __y->_M_left = __x; 150*38fd1498Szrj __x->_M_parent = __y; 151*38fd1498Szrj } 152*38fd1498Szrj 153*38fd1498Szrj #if !_GLIBCXX_INLINE_VERSION 154*38fd1498Szrj /* Static keyword was missing on _Rb_tree_rotate_left. 155*38fd1498Szrj Export the symbol for backward compatibility until 156*38fd1498Szrj next ABI change. */ 157*38fd1498Szrj void _Rb_tree_rotate_left(_Rb_tree_node_base * const __x,_Rb_tree_node_base * & __root)158*38fd1498Szrj _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, 159*38fd1498Szrj _Rb_tree_node_base*& __root) 160*38fd1498Szrj { local_Rb_tree_rotate_left (__x, __root); } 161*38fd1498Szrj #endif 162*38fd1498Szrj 163*38fd1498Szrj static void local_Rb_tree_rotate_right(_Rb_tree_node_base * const __x,_Rb_tree_node_base * & __root)164*38fd1498Szrj local_Rb_tree_rotate_right(_Rb_tree_node_base* const __x, 165*38fd1498Szrj _Rb_tree_node_base*& __root) 166*38fd1498Szrj { 167*38fd1498Szrj _Rb_tree_node_base* const __y = __x->_M_left; 168*38fd1498Szrj 169*38fd1498Szrj __x->_M_left = __y->_M_right; 170*38fd1498Szrj if (__y->_M_right != 0) 171*38fd1498Szrj __y->_M_right->_M_parent = __x; 172*38fd1498Szrj __y->_M_parent = __x->_M_parent; 173*38fd1498Szrj 174*38fd1498Szrj if (__x == __root) 175*38fd1498Szrj __root = __y; 176*38fd1498Szrj else if (__x == __x->_M_parent->_M_right) 177*38fd1498Szrj __x->_M_parent->_M_right = __y; 178*38fd1498Szrj else 179*38fd1498Szrj __x->_M_parent->_M_left = __y; 180*38fd1498Szrj __y->_M_right = __x; 181*38fd1498Szrj __x->_M_parent = __y; 182*38fd1498Szrj } 183*38fd1498Szrj 184*38fd1498Szrj #if !_GLIBCXX_INLINE_VERSION 185*38fd1498Szrj /* Static keyword was missing on _Rb_tree_rotate_right 186*38fd1498Szrj Export the symbol for backward compatibility until 187*38fd1498Szrj next ABI change. */ 188*38fd1498Szrj void _Rb_tree_rotate_right(_Rb_tree_node_base * const __x,_Rb_tree_node_base * & __root)189*38fd1498Szrj _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, 190*38fd1498Szrj _Rb_tree_node_base*& __root) 191*38fd1498Szrj { local_Rb_tree_rotate_right (__x, __root); } 192*38fd1498Szrj #endif 193*38fd1498Szrj 194*38fd1498Szrj void _Rb_tree_insert_and_rebalance(const bool __insert_left,_Rb_tree_node_base * __x,_Rb_tree_node_base * __p,_Rb_tree_node_base & __header)195*38fd1498Szrj _Rb_tree_insert_and_rebalance(const bool __insert_left, 196*38fd1498Szrj _Rb_tree_node_base* __x, 197*38fd1498Szrj _Rb_tree_node_base* __p, 198*38fd1498Szrj _Rb_tree_node_base& __header) throw () 199*38fd1498Szrj { 200*38fd1498Szrj _Rb_tree_node_base *& __root = __header._M_parent; 201*38fd1498Szrj 202*38fd1498Szrj // Initialize fields in new node to insert. 203*38fd1498Szrj __x->_M_parent = __p; 204*38fd1498Szrj __x->_M_left = 0; 205*38fd1498Szrj __x->_M_right = 0; 206*38fd1498Szrj __x->_M_color = _S_red; 207*38fd1498Szrj 208*38fd1498Szrj // Insert. 209*38fd1498Szrj // Make new node child of parent and maintain root, leftmost and 210*38fd1498Szrj // rightmost nodes. 211*38fd1498Szrj // N.B. First node is always inserted left. 212*38fd1498Szrj if (__insert_left) 213*38fd1498Szrj { 214*38fd1498Szrj __p->_M_left = __x; // also makes leftmost = __x when __p == &__header 215*38fd1498Szrj 216*38fd1498Szrj if (__p == &__header) 217*38fd1498Szrj { 218*38fd1498Szrj __header._M_parent = __x; 219*38fd1498Szrj __header._M_right = __x; 220*38fd1498Szrj } 221*38fd1498Szrj else if (__p == __header._M_left) 222*38fd1498Szrj __header._M_left = __x; // maintain leftmost pointing to min node 223*38fd1498Szrj } 224*38fd1498Szrj else 225*38fd1498Szrj { 226*38fd1498Szrj __p->_M_right = __x; 227*38fd1498Szrj 228*38fd1498Szrj if (__p == __header._M_right) 229*38fd1498Szrj __header._M_right = __x; // maintain rightmost pointing to max node 230*38fd1498Szrj } 231*38fd1498Szrj // Rebalance. 232*38fd1498Szrj while (__x != __root 233*38fd1498Szrj && __x->_M_parent->_M_color == _S_red) 234*38fd1498Szrj { 235*38fd1498Szrj _Rb_tree_node_base* const __xpp = __x->_M_parent->_M_parent; 236*38fd1498Szrj 237*38fd1498Szrj if (__x->_M_parent == __xpp->_M_left) 238*38fd1498Szrj { 239*38fd1498Szrj _Rb_tree_node_base* const __y = __xpp->_M_right; 240*38fd1498Szrj if (__y && __y->_M_color == _S_red) 241*38fd1498Szrj { 242*38fd1498Szrj __x->_M_parent->_M_color = _S_black; 243*38fd1498Szrj __y->_M_color = _S_black; 244*38fd1498Szrj __xpp->_M_color = _S_red; 245*38fd1498Szrj __x = __xpp; 246*38fd1498Szrj } 247*38fd1498Szrj else 248*38fd1498Szrj { 249*38fd1498Szrj if (__x == __x->_M_parent->_M_right) 250*38fd1498Szrj { 251*38fd1498Szrj __x = __x->_M_parent; 252*38fd1498Szrj local_Rb_tree_rotate_left(__x, __root); 253*38fd1498Szrj } 254*38fd1498Szrj __x->_M_parent->_M_color = _S_black; 255*38fd1498Szrj __xpp->_M_color = _S_red; 256*38fd1498Szrj local_Rb_tree_rotate_right(__xpp, __root); 257*38fd1498Szrj } 258*38fd1498Szrj } 259*38fd1498Szrj else 260*38fd1498Szrj { 261*38fd1498Szrj _Rb_tree_node_base* const __y = __xpp->_M_left; 262*38fd1498Szrj if (__y && __y->_M_color == _S_red) 263*38fd1498Szrj { 264*38fd1498Szrj __x->_M_parent->_M_color = _S_black; 265*38fd1498Szrj __y->_M_color = _S_black; 266*38fd1498Szrj __xpp->_M_color = _S_red; 267*38fd1498Szrj __x = __xpp; 268*38fd1498Szrj } 269*38fd1498Szrj else 270*38fd1498Szrj { 271*38fd1498Szrj if (__x == __x->_M_parent->_M_left) 272*38fd1498Szrj { 273*38fd1498Szrj __x = __x->_M_parent; 274*38fd1498Szrj local_Rb_tree_rotate_right(__x, __root); 275*38fd1498Szrj } 276*38fd1498Szrj __x->_M_parent->_M_color = _S_black; 277*38fd1498Szrj __xpp->_M_color = _S_red; 278*38fd1498Szrj local_Rb_tree_rotate_left(__xpp, __root); 279*38fd1498Szrj } 280*38fd1498Szrj } 281*38fd1498Szrj } 282*38fd1498Szrj __root->_M_color = _S_black; 283*38fd1498Szrj } 284*38fd1498Szrj 285*38fd1498Szrj _Rb_tree_node_base* _Rb_tree_rebalance_for_erase(_Rb_tree_node_base * const __z,_Rb_tree_node_base & __header)286*38fd1498Szrj _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, 287*38fd1498Szrj _Rb_tree_node_base& __header) throw () 288*38fd1498Szrj { 289*38fd1498Szrj _Rb_tree_node_base *& __root = __header._M_parent; 290*38fd1498Szrj _Rb_tree_node_base *& __leftmost = __header._M_left; 291*38fd1498Szrj _Rb_tree_node_base *& __rightmost = __header._M_right; 292*38fd1498Szrj _Rb_tree_node_base* __y = __z; 293*38fd1498Szrj _Rb_tree_node_base* __x = 0; 294*38fd1498Szrj _Rb_tree_node_base* __x_parent = 0; 295*38fd1498Szrj 296*38fd1498Szrj if (__y->_M_left == 0) // __z has at most one non-null child. y == z. 297*38fd1498Szrj __x = __y->_M_right; // __x might be null. 298*38fd1498Szrj else 299*38fd1498Szrj if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. 300*38fd1498Szrj __x = __y->_M_left; // __x is not null. 301*38fd1498Szrj else 302*38fd1498Szrj { 303*38fd1498Szrj // __z has two non-null children. Set __y to 304*38fd1498Szrj __y = __y->_M_right; // __z's successor. __x might be null. 305*38fd1498Szrj while (__y->_M_left != 0) 306*38fd1498Szrj __y = __y->_M_left; 307*38fd1498Szrj __x = __y->_M_right; 308*38fd1498Szrj } 309*38fd1498Szrj if (__y != __z) 310*38fd1498Szrj { 311*38fd1498Szrj // relink y in place of z. y is z's successor 312*38fd1498Szrj __z->_M_left->_M_parent = __y; 313*38fd1498Szrj __y->_M_left = __z->_M_left; 314*38fd1498Szrj if (__y != __z->_M_right) 315*38fd1498Szrj { 316*38fd1498Szrj __x_parent = __y->_M_parent; 317*38fd1498Szrj if (__x) __x->_M_parent = __y->_M_parent; 318*38fd1498Szrj __y->_M_parent->_M_left = __x; // __y must be a child of _M_left 319*38fd1498Szrj __y->_M_right = __z->_M_right; 320*38fd1498Szrj __z->_M_right->_M_parent = __y; 321*38fd1498Szrj } 322*38fd1498Szrj else 323*38fd1498Szrj __x_parent = __y; 324*38fd1498Szrj if (__root == __z) 325*38fd1498Szrj __root = __y; 326*38fd1498Szrj else if (__z->_M_parent->_M_left == __z) 327*38fd1498Szrj __z->_M_parent->_M_left = __y; 328*38fd1498Szrj else 329*38fd1498Szrj __z->_M_parent->_M_right = __y; 330*38fd1498Szrj __y->_M_parent = __z->_M_parent; 331*38fd1498Szrj std::swap(__y->_M_color, __z->_M_color); 332*38fd1498Szrj __y = __z; 333*38fd1498Szrj // __y now points to node to be actually deleted 334*38fd1498Szrj } 335*38fd1498Szrj else 336*38fd1498Szrj { // __y == __z 337*38fd1498Szrj __x_parent = __y->_M_parent; 338*38fd1498Szrj if (__x) 339*38fd1498Szrj __x->_M_parent = __y->_M_parent; 340*38fd1498Szrj if (__root == __z) 341*38fd1498Szrj __root = __x; 342*38fd1498Szrj else 343*38fd1498Szrj if (__z->_M_parent->_M_left == __z) 344*38fd1498Szrj __z->_M_parent->_M_left = __x; 345*38fd1498Szrj else 346*38fd1498Szrj __z->_M_parent->_M_right = __x; 347*38fd1498Szrj if (__leftmost == __z) 348*38fd1498Szrj { 349*38fd1498Szrj if (__z->_M_right == 0) // __z->_M_left must be null also 350*38fd1498Szrj __leftmost = __z->_M_parent; 351*38fd1498Szrj // makes __leftmost == _M_header if __z == __root 352*38fd1498Szrj else 353*38fd1498Szrj __leftmost = _Rb_tree_node_base::_S_minimum(__x); 354*38fd1498Szrj } 355*38fd1498Szrj if (__rightmost == __z) 356*38fd1498Szrj { 357*38fd1498Szrj if (__z->_M_left == 0) // __z->_M_right must be null also 358*38fd1498Szrj __rightmost = __z->_M_parent; 359*38fd1498Szrj // makes __rightmost == _M_header if __z == __root 360*38fd1498Szrj else // __x == __z->_M_left 361*38fd1498Szrj __rightmost = _Rb_tree_node_base::_S_maximum(__x); 362*38fd1498Szrj } 363*38fd1498Szrj } 364*38fd1498Szrj if (__y->_M_color != _S_red) 365*38fd1498Szrj { 366*38fd1498Szrj while (__x != __root && (__x == 0 || __x->_M_color == _S_black)) 367*38fd1498Szrj if (__x == __x_parent->_M_left) 368*38fd1498Szrj { 369*38fd1498Szrj _Rb_tree_node_base* __w = __x_parent->_M_right; 370*38fd1498Szrj if (__w->_M_color == _S_red) 371*38fd1498Szrj { 372*38fd1498Szrj __w->_M_color = _S_black; 373*38fd1498Szrj __x_parent->_M_color = _S_red; 374*38fd1498Szrj local_Rb_tree_rotate_left(__x_parent, __root); 375*38fd1498Szrj __w = __x_parent->_M_right; 376*38fd1498Szrj } 377*38fd1498Szrj if ((__w->_M_left == 0 || 378*38fd1498Szrj __w->_M_left->_M_color == _S_black) && 379*38fd1498Szrj (__w->_M_right == 0 || 380*38fd1498Szrj __w->_M_right->_M_color == _S_black)) 381*38fd1498Szrj { 382*38fd1498Szrj __w->_M_color = _S_red; 383*38fd1498Szrj __x = __x_parent; 384*38fd1498Szrj __x_parent = __x_parent->_M_parent; 385*38fd1498Szrj } 386*38fd1498Szrj else 387*38fd1498Szrj { 388*38fd1498Szrj if (__w->_M_right == 0 389*38fd1498Szrj || __w->_M_right->_M_color == _S_black) 390*38fd1498Szrj { 391*38fd1498Szrj __w->_M_left->_M_color = _S_black; 392*38fd1498Szrj __w->_M_color = _S_red; 393*38fd1498Szrj local_Rb_tree_rotate_right(__w, __root); 394*38fd1498Szrj __w = __x_parent->_M_right; 395*38fd1498Szrj } 396*38fd1498Szrj __w->_M_color = __x_parent->_M_color; 397*38fd1498Szrj __x_parent->_M_color = _S_black; 398*38fd1498Szrj if (__w->_M_right) 399*38fd1498Szrj __w->_M_right->_M_color = _S_black; 400*38fd1498Szrj local_Rb_tree_rotate_left(__x_parent, __root); 401*38fd1498Szrj break; 402*38fd1498Szrj } 403*38fd1498Szrj } 404*38fd1498Szrj else 405*38fd1498Szrj { 406*38fd1498Szrj // same as above, with _M_right <-> _M_left. 407*38fd1498Szrj _Rb_tree_node_base* __w = __x_parent->_M_left; 408*38fd1498Szrj if (__w->_M_color == _S_red) 409*38fd1498Szrj { 410*38fd1498Szrj __w->_M_color = _S_black; 411*38fd1498Szrj __x_parent->_M_color = _S_red; 412*38fd1498Szrj local_Rb_tree_rotate_right(__x_parent, __root); 413*38fd1498Szrj __w = __x_parent->_M_left; 414*38fd1498Szrj } 415*38fd1498Szrj if ((__w->_M_right == 0 || 416*38fd1498Szrj __w->_M_right->_M_color == _S_black) && 417*38fd1498Szrj (__w->_M_left == 0 || 418*38fd1498Szrj __w->_M_left->_M_color == _S_black)) 419*38fd1498Szrj { 420*38fd1498Szrj __w->_M_color = _S_red; 421*38fd1498Szrj __x = __x_parent; 422*38fd1498Szrj __x_parent = __x_parent->_M_parent; 423*38fd1498Szrj } 424*38fd1498Szrj else 425*38fd1498Szrj { 426*38fd1498Szrj if (__w->_M_left == 0 || __w->_M_left->_M_color == _S_black) 427*38fd1498Szrj { 428*38fd1498Szrj __w->_M_right->_M_color = _S_black; 429*38fd1498Szrj __w->_M_color = _S_red; 430*38fd1498Szrj local_Rb_tree_rotate_left(__w, __root); 431*38fd1498Szrj __w = __x_parent->_M_left; 432*38fd1498Szrj } 433*38fd1498Szrj __w->_M_color = __x_parent->_M_color; 434*38fd1498Szrj __x_parent->_M_color = _S_black; 435*38fd1498Szrj if (__w->_M_left) 436*38fd1498Szrj __w->_M_left->_M_color = _S_black; 437*38fd1498Szrj local_Rb_tree_rotate_right(__x_parent, __root); 438*38fd1498Szrj break; 439*38fd1498Szrj } 440*38fd1498Szrj } 441*38fd1498Szrj if (__x) __x->_M_color = _S_black; 442*38fd1498Szrj } 443*38fd1498Szrj return __y; 444*38fd1498Szrj } 445*38fd1498Szrj 446*38fd1498Szrj unsigned int _Rb_tree_black_count(const _Rb_tree_node_base * __node,const _Rb_tree_node_base * __root)447*38fd1498Szrj _Rb_tree_black_count(const _Rb_tree_node_base* __node, 448*38fd1498Szrj const _Rb_tree_node_base* __root) throw () 449*38fd1498Szrj { 450*38fd1498Szrj if (__node == 0) 451*38fd1498Szrj return 0; 452*38fd1498Szrj unsigned int __sum = 0; 453*38fd1498Szrj do 454*38fd1498Szrj { 455*38fd1498Szrj if (__node->_M_color == _S_black) 456*38fd1498Szrj ++__sum; 457*38fd1498Szrj if (__node == __root) 458*38fd1498Szrj break; 459*38fd1498Szrj __node = __node->_M_parent; 460*38fd1498Szrj } 461*38fd1498Szrj while (1); 462*38fd1498Szrj return __sum; 463*38fd1498Szrj } 464*38fd1498Szrj 465*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 466*38fd1498Szrj } // namespace 467