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