xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/src/c++98/tree.cc (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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