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