* opts.c (decode_options): Enable unit-at-a-time at -O2.
[official-gcc.git] / libstdc++-v3 / src / stl_tree.cc
blobeac141f0f79049b6d1c2c1216dde365eea35064c
1 // RB tree utilities implementation -*- C++ -*-
3 // Copyright (C) 2003 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
32 * Copyright (c) 1996,1997
33 * Silicon Graphics Computer Systems, Inc.
35 * Permission to use, copy, modify, distribute and sell this software
36 * and its documentation for any purpose is hereby granted without fee,
37 * provided that the above copyright notice appear in all copies and
38 * that both that copyright notice and this permission notice appear
39 * in supporting documentation. Silicon Graphics makes no
40 * representations about the suitability of this software for any
41 * purpose. It is provided "as is" without express or implied warranty.
44 * Copyright (c) 1994
45 * Hewlett-Packard Company
47 * Permission to use, copy, modify, distribute and sell this software
48 * and its documentation for any purpose is hereby granted without fee,
49 * provided that the above copyright notice appear in all copies and
50 * that both that copyright notice and this permission notice appear
51 * in supporting documentation. Hewlett-Packard Company makes no
52 * representations about the suitability of this software for any
53 * purpose. It is provided "as is" without express or implied warranty.
58 #include <bits/stl_tree.h>
60 namespace std
62 _Rb_tree_node_base*
63 _Rb_tree_increment(_Rb_tree_node_base* __x)
65 if (__x->_M_right != 0)
67 __x = __x->_M_right;
68 while (__x->_M_left != 0)
69 __x = __x->_M_left;
71 else
73 _Rb_tree_node_base* __y = __x->_M_parent;
74 while (__x == __y->_M_right)
76 __x = __y;
77 __y = __y->_M_parent;
79 if (__x->_M_right != __y)
80 __x = __y;
82 return __x;
85 _Rb_tree_node_base*
86 _Rb_tree_decrement(_Rb_tree_node_base* __x)
88 if (__x->_M_color == _S_red
89 && __x->_M_parent->_M_parent == __x)
90 __x = __x->_M_right;
91 else if (__x->_M_left != 0)
93 _Rb_tree_node_base* __y = __x->_M_left;
94 while (__y->_M_right != 0)
95 __y = __y->_M_right;
96 __x = __y;
98 else
100 _Rb_tree_node_base* __y = __x->_M_parent;
101 while (__x == __y->_M_left)
103 __x = __y;
104 __y = __y->_M_parent;
106 __x = __y;
108 return __x;
111 void
112 _Rb_tree_rotate_left(_Rb_tree_node_base* const __x,
113 _Rb_tree_node_base*& __root)
115 _Rb_tree_node_base* const __y = __x->_M_right;
117 __x->_M_right = __y->_M_left;
118 if (__y->_M_left !=0)
119 __y->_M_left->_M_parent = __x;
120 __y->_M_parent = __x->_M_parent;
122 if (__x == __root)
123 __root = __y;
124 else if (__x == __x->_M_parent->_M_left)
125 __x->_M_parent->_M_left = __y;
126 else
127 __x->_M_parent->_M_right = __y;
128 __y->_M_left = __x;
129 __x->_M_parent = __y;
132 void
133 _Rb_tree_rotate_right(_Rb_tree_node_base* const __x,
134 _Rb_tree_node_base*& __root)
136 _Rb_tree_node_base* const __y = __x->_M_left;
138 __x->_M_left = __y->_M_right;
139 if (__y->_M_right != 0)
140 __y->_M_right->_M_parent = __x;
141 __y->_M_parent = __x->_M_parent;
143 if (__x == __root)
144 __root = __y;
145 else if (__x == __x->_M_parent->_M_right)
146 __x->_M_parent->_M_right = __y;
147 else
148 __x->_M_parent->_M_left = __y;
149 __y->_M_right = __x;
150 __x->_M_parent = __y;
153 void
154 _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
156 __x->_M_color = _S_red;
158 while (__x != __root
159 && __x->_M_parent->_M_color == _S_red)
161 _Rb_tree_node_base* const __xpp = __x->_M_parent->_M_parent;
163 if (__x->_M_parent == __xpp->_M_left)
165 _Rb_tree_node_base* const __y = __xpp->_M_right;
166 if (__y && __y->_M_color == _S_red)
168 __x->_M_parent->_M_color = _S_black;
169 __y->_M_color = _S_black;
170 __xpp->_M_color = _S_red;
171 __x = __xpp;
173 else
175 if (__x == __x->_M_parent->_M_right)
177 __x = __x->_M_parent;
178 _Rb_tree_rotate_left(__x, __root);
180 __x->_M_parent->_M_color = _S_black;
181 __xpp->_M_color = _S_red;
182 _Rb_tree_rotate_right(__xpp, __root);
185 else
187 _Rb_tree_node_base* const __y = __xpp->_M_left;
188 if (__y && __y->_M_color == _S_red)
190 __x->_M_parent->_M_color = _S_black;
191 __y->_M_color = _S_black;
192 __xpp->_M_color = _S_red;
193 __x = __xpp;
195 else
197 if (__x == __x->_M_parent->_M_left)
199 __x = __x->_M_parent;
200 _Rb_tree_rotate_right(__x, __root);
202 __x->_M_parent->_M_color = _S_black;
203 __xpp->_M_color = _S_red;
204 _Rb_tree_rotate_left(__xpp, __root);
208 __root->_M_color = _S_black;
211 _Rb_tree_node_base*
212 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
213 _Rb_tree_node_base& __header)
215 _Rb_tree_node_base *& __root = __header._M_parent;
216 _Rb_tree_node_base *& __leftmost = __header._M_left;
217 _Rb_tree_node_base *& __rightmost = __header._M_right;
218 _Rb_tree_node_base* __y = __z;
219 _Rb_tree_node_base* __x = 0;
220 _Rb_tree_node_base* __x_parent = 0;
222 if (__y->_M_left == 0) // __z has at most one non-null child. y == z.
223 __x = __y->_M_right; // __x might be null.
224 else
225 if (__y->_M_right == 0) // __z has exactly one non-null child. y == z.
226 __x = __y->_M_left; // __x is not null.
227 else
229 // __z has two non-null children. Set __y to
230 __y = __y->_M_right; // __z's successor. __x might be null.
231 while (__y->_M_left != 0)
232 __y = __y->_M_left;
233 __x = __y->_M_right;
235 if (__y != __z)
237 // relink y in place of z. y is z's successor
238 __z->_M_left->_M_parent = __y;
239 __y->_M_left = __z->_M_left;
240 if (__y != __z->_M_right)
242 __x_parent = __y->_M_parent;
243 if (__x) __x->_M_parent = __y->_M_parent;
244 __y->_M_parent->_M_left = __x; // __y must be a child of _M_left
245 __y->_M_right = __z->_M_right;
246 __z->_M_right->_M_parent = __y;
248 else
249 __x_parent = __y;
250 if (__root == __z)
251 __root = __y;
252 else if (__z->_M_parent->_M_left == __z)
253 __z->_M_parent->_M_left = __y;
254 else
255 __z->_M_parent->_M_right = __y;
256 __y->_M_parent = __z->_M_parent;
257 std::swap(__y->_M_color, __z->_M_color);
258 __y = __z;
259 // __y now points to node to be actually deleted
261 else
262 { // __y == __z
263 __x_parent = __y->_M_parent;
264 if (__x)
265 __x->_M_parent = __y->_M_parent;
266 if (__root == __z)
267 __root = __x;
268 else
269 if (__z->_M_parent->_M_left == __z)
270 __z->_M_parent->_M_left = __x;
271 else
272 __z->_M_parent->_M_right = __x;
273 if (__leftmost == __z)
274 if (__z->_M_right == 0) // __z->_M_left must be null also
275 __leftmost = __z->_M_parent;
276 // makes __leftmost == _M_header if __z == __root
277 else
278 __leftmost = _Rb_tree_node_base::_S_minimum(__x);
279 if (__rightmost == __z)
280 if (__z->_M_left == 0) // __z->_M_right must be null also
281 __rightmost = __z->_M_parent;
282 // makes __rightmost == _M_header if __z == __root
283 else // __x == __z->_M_left
284 __rightmost = _Rb_tree_node_base::_S_maximum(__x);
286 if (__y->_M_color != _S_red)
288 while (__x != __root && (__x == 0 || __x->_M_color == _S_black))
289 if (__x == __x_parent->_M_left)
291 _Rb_tree_node_base* __w = __x_parent->_M_right;
292 if (__w->_M_color == _S_red)
294 __w->_M_color = _S_black;
295 __x_parent->_M_color = _S_red;
296 _Rb_tree_rotate_left(__x_parent, __root);
297 __w = __x_parent->_M_right;
299 if ((__w->_M_left == 0 ||
300 __w->_M_left->_M_color == _S_black) &&
301 (__w->_M_right == 0 ||
302 __w->_M_right->_M_color == _S_black))
304 __w->_M_color = _S_red;
305 __x = __x_parent;
306 __x_parent = __x_parent->_M_parent;
308 else
310 if (__w->_M_right == 0
311 || __w->_M_right->_M_color == _S_black)
313 __w->_M_left->_M_color = _S_black;
314 __w->_M_color = _S_red;
315 _Rb_tree_rotate_right(__w, __root);
316 __w = __x_parent->_M_right;
318 __w->_M_color = __x_parent->_M_color;
319 __x_parent->_M_color = _S_black;
320 if (__w->_M_right)
321 __w->_M_right->_M_color = _S_black;
322 _Rb_tree_rotate_left(__x_parent, __root);
323 break;
326 else
328 // same as above, with _M_right <-> _M_left.
329 _Rb_tree_node_base* __w = __x_parent->_M_left;
330 if (__w->_M_color == _S_red)
332 __w->_M_color = _S_black;
333 __x_parent->_M_color = _S_red;
334 _Rb_tree_rotate_right(__x_parent, __root);
335 __w = __x_parent->_M_left;
337 if ((__w->_M_right == 0 ||
338 __w->_M_right->_M_color == _S_black) &&
339 (__w->_M_left == 0 ||
340 __w->_M_left->_M_color == _S_black))
342 __w->_M_color = _S_red;
343 __x = __x_parent;
344 __x_parent = __x_parent->_M_parent;
346 else
348 if (__w->_M_left == 0 || __w->_M_left->_M_color == _S_black)
350 __w->_M_right->_M_color = _S_black;
351 __w->_M_color = _S_red;
352 _Rb_tree_rotate_left(__w, __root);
353 __w = __x_parent->_M_left;
355 __w->_M_color = __x_parent->_M_color;
356 __x_parent->_M_color = _S_black;
357 if (__w->_M_left)
358 __w->_M_left->_M_color = _S_black;
359 _Rb_tree_rotate_right(__x_parent, __root);
360 break;
363 if (__x) __x->_M_color = _S_black;
365 return __y;
368 unsigned int
369 _Rb_tree_black_count(const _Rb_tree_node_base* __node,
370 const _Rb_tree_node_base* __root)
372 if (__node == 0)
373 return 0;
374 unsigned int __sum = 0;
377 if (__node->_M_color == _S_black)
378 ++__sum;
379 if (__node == __root)
380 break;
381 __node = __node->_M_parent;
383 while (1);
384 return __sum;
386 } // namespace std