Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_tree.cc
Go to the documentation of this file.
1
44
45
46template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
47__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
48__rb_tree (const key_compare &__cmp /* = key_compare () */,
49 const allocator_type &__alloc /* = allocator_type () */)
50 : allocator_type (__alloc),
51 _C_buf_list (0),
52 _C_end (0),
53 _C_size (0),
54 _C_cmp (__cmp)
55{
56 _C_init ();
57}
58
59
60template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
61__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>&
62__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
63operator= (const __rb_tree &__x)
64{
65 if (this != &__x) {
66 erase (begin (), end ());
67
68 // set the root of the tree
69 _C_end->_C_parent = _C_copy (__x._C_end->_C_parent, _C_end);
70
71 if (_C_link_t () == _C_end->_C_parent) {
72 // set the child pointers of an empty tree to point to the header
73 _C_end->_C_child [0] =
74 _C_end->_C_child [1] = _C_end;
75 }
76 else {
77 // set the leftmost and the rightmost nodes
78 _C_end->_C_child [0] = _C_node_t::_C_min (_C_end->_C_parent);
79 _C_end->_C_child [1] = _C_node_t::_C_max (_C_end->_C_parent);
80 }
81 _C_size = __x._C_size;
82 _C_cmp = __x._C_cmp;
83 }
84 return *this;
85}
86
87
88template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
89__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
90__rb_tree (const __rb_tree &__lnk)
91 : allocator_type (__lnk.get_allocator ()), _C_buf_list (0), _C_end (0),
92 _C_size (__lnk._C_size),
93 _C_cmp (__lnk._C_cmp)
94{
95 _C_free_list = _C_next_avail = _C_last = 0;
96 _C_end = _C_get_node ();
97 _C_end->_C_color = _C_node_t::_C_red;
98 _TRY {
99 _C_end->_C_parent = _C_copy (__lnk._C_end->_C_parent, _C_end);
100 }
101 _CATCH (...) {
102 _C_deallocate_buffers ();
103 _RETHROW;
104 }
105 if (_C_link_t () == _C_end->_C_parent) {
106 _C_end->_C_child [0] =
107 _C_end->_C_child [1] = _C_end;
108 }
109 else {
110 _C_end->_C_child [0] = _C_node_t::_C_min (_C_end->_C_parent);
111 _C_end->_C_child [1] = _C_node_t::_C_max (_C_end->_C_parent);
112 }
113}
114
115
116template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
117__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
118~__rb_tree ()
119{
120 if (_C_link_t () != _C_end) {
121 erase (begin (), end ());
122 _C_put_node (_C_end, false);
123 _C_deallocate_buffers ();
124 }
125}
126
127
128template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
129void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
130_C_add_new_buffer ()
131{
132 const size_type __bufsize =
133 _C_buf_ptr_t () == _C_buf_list ? 0 : _C_buf_list->size;
134
135 size_type __newsize = _RWSTD_NEW_CAPACITY (__rb_tree, this, __bufsize);
136 if (__newsize <= __bufsize)
137 __newsize = __bufsize + 1;
138
139 _C_buf_ptr_t __buf =
140 _C_buf_alloc_t (*this).allocate (size_type (1), (void*)_C_buf_list);
141
142 _TRY {
143 __buf->_C_buffer =
144 _C_node_alloc_t (*this).allocate (__newsize, (void*)_C_last);
145 }
146 _CATCH (...) {
147 _C_buf_alloc_t (*this).deallocate (__buf, 1);
148 _RETHROW;
149 }
150 __buf->_C_next_buffer = _C_buf_list;
151 __buf->size = __newsize;
152 _C_buf_list = __buf;
153 _C_next_avail = _C_buf_list->_C_buffer;
154 _C_last = _C_next_avail + __newsize;
155}
156
157
158template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
159void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
160_C_deallocate_buffers ()
161{
162 while ((void*)_C_buf_list) {
163 _C_buf_ptr_t __tmp = _C_buf_list;
164 _C_buf_list = (_C_buf_ptr_t)(_C_buf_list->_C_next_buffer);
165 _C_node_alloc_t(*this).deallocate(__tmp->_C_buffer,__tmp->size);
166 _C_buf_alloc_t(*this).deallocate(__tmp,1);
167 }
168}
169
170
171template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
172typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
173__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
174_C_insert (_C_link_t __x, _C_link_t __y, const value_type &__v)
175{
176 _C_link_t __z = _C_get_node (__v);
177 ++_C_size;
178
179 // for notational convenience
180 const typename _C_node_t::_C_color_t _Red = _C_node_t::_C_red;
181 const typename _C_node_t::_C_color_t _Black = _C_node_t::_C_black;
182 const _C_link_t _Null = _C_link_t ();
183
184 if ( __y == _C_end || _Null != __x
185 || _C_cmp (_KeyOf()(__v), __y->_C_key ())) {
186
187 __y->_C_child [0] = __z;
188 if (__y == _C_end) {
189
190 // set the root node and the rightmost node
191 _C_end->_C_parent = __z;
192 _C_end->_C_child [1] = __z;
193 }
194 else if (__y == _C_end->_C_child [0]) {
195 // set the leftmost node
196 _C_end->_C_child [0] = __z;
197 }
198 }
199 else {
200 __y->_C_child [1] = __z;
201 if (__y == _C_end->_C_child [1]) {
202 // set the rightmost node
203 _C_end->_C_child [1] = __z;
204 }
205 }
206
207 __z->_C_parent = __y;
208 __x = __z; // recolor and rebalance the tree
209
210 while ( __x != _C_end->_C_parent
211 && __x->_C_parent->_C_color == _Red) {
212
213#ifndef _RWSTD_NO_OPTIMIZE_SPEED
214
215 if (__x->_C_parent == __x->_C_parent->_C_parent->_C_child [0]) {
216
217 __y = __x->_C_parent->_C_parent->_C_child [1];
218
219 if (_Null != __y && __y->_C_color == _Red) {
220 __x->_C_parent->_C_color = _Black;
221 __y->_C_color = _Black;
222 __x->_C_parent->_C_parent->_C_color = _Red;
223 __x = __x->_C_parent->_C_parent;
224 }
225 else {
226 if (__x == __x->_C_parent->_C_child [1]) {
227 __x = __x->_C_parent;
228 _C_rol (__x);
229 }
230 __x->_C_parent->_C_color = _Black;
231 __x->_C_parent->_C_parent->_C_color = _Red;
232 _C_ror (__x->_C_parent->_C_parent);
233 }
234 }
235 else {
236 __y = __x->_C_parent->_C_parent->_C_child [0];
237
238 if (_Null != __y && __y->_C_color == _Red) {
239 __x->_C_parent->_C_color = _Black;
240 __y->_C_color = _Black;
241 __x->_C_parent->_C_parent->_C_color = _Red;
242 __x = __x->_C_parent->_C_parent;
243 }
244 else {
245 if (__x == __x->_C_parent->_C_child [0]) {
246 __x = __x->_C_parent;
247 _C_ror (__x);
248 }
249 __x->_C_parent->_C_color = _Black;
250 __x->_C_parent->_C_parent->_C_color = _Red;
251 _C_rol (__x->_C_parent->_C_parent);
252 }
253 }
254
255#else // if defined (_RWSTD_NO_OPTIMIZE_SPEED)
256
257 const bool __left =
258 __x->_C_parent == __x->_C_parent->_C_parent->_C_child [0];
259 const bool __right = !__left;
260
261 __y = __x->_C_parent->_C_parent->_C_child [__left];
262
263 if (_Null != __y && _Red == __y->_C_color) {
264 __y->_C_color =
265 __x->_C_parent->_C_color = _Black;
266 __x->_C_parent->_C_parent->_C_color = _Red;
267 __x = __x->_C_parent->_C_parent;
268 }
269 else {
270 if (__x == __x->_C_parent->_C_child [__left]) {
271 __x = __x->_C_parent;
272 _C_rotate (__x, __right);
273 }
274 __x->_C_parent->_C_color = _Black;
275 __x->_C_parent->_C_parent->_C_color = _Red;
276 _C_rotate (__x->_C_parent->_C_parent, __left);
277 }
278
279#endif // _RWSTD_NO_OPTIMIZE_SPEED
280
281 }
282
283 // set the color of the root node
284 _C_end->_C_parent->_C_color = _Black;
285
286 return _C_make_iter (__z);
287}
288
289
290template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
291void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
292_C_insert (const value_type &__v, _STD::pair<iterator, bool> &__ret,
293 bool __dup)
294{
295 _C_link_t __y = _C_end; // end
296 _C_link_t __x = _C_end->_C_parent; // root node
297
298 bool __right = true;
299
300 while (_C_link_t () != __x) {
301 __y = __x;
302 __right = _C_cmp (_KeyOf ()(__v), __x->_C_key ());
303 __x = __x->_C_child [!__right];
304 }
305
306 typedef _STD::pair<iterator, bool> _IterPair;
307
308 if (__dup) {
309 // allow insertion of duplicate keys
310 __ret = _IterPair (_C_insert (__x, __y, __v), true);
311 return;
312 }
313
314 iterator __j = _C_make_iter (__y);
315 if (__right) {
316 if (__j == begin ()) {
317 __ret = _IterPair (_C_insert (__x, __y, __v), true);
318 return;
319 }
320 --__j;
321 }
322
323 if (_C_cmp (_ITER_NODE (__j)->_C_key (), _KeyOf ()(__v)))
324 __ret = _IterPair (_C_insert (__x, __y, __v), true);
325 else
326 __ret = _IterPair (__j, false);
327}
328
329
330template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
331typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
332__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
333insert (iterator __it, const value_type &__v, bool __dup)
334{
335 _RWSTD_ASSERT_RANGE (begin (), __it);
336
337#ifdef _RWSTDDEBUG
338
339 { // verify the consistency of the tree
340 size_type __two_logN = 0;
341 for (size_type __i = size () + 1; __i >>= 1; ++__two_logN);
342
343 __two_logN *= 2;
344
345 const size_type __depth = _C_depth ();
346 _RWSTD_ASSERT (__depth <= __two_logN);
347 }
348
349#endif // _RWSTDDEBUG
350
351 const _C_link_t __hint = _ITER_NODE (__it);
352
353 // if __hint is the right most child, or tree is empty
354 if (__hint == _C_end->_C_child [1]) {
355
356 // if tree is not empty and __key is greater
357 // then insert on the right
358 if (_C_size && _C_cmp (__hint->_C_key (), _KeyOf ()(__v)))
359 return _C_insert (0, __hint, __v);
360
361 // otherwise just insert
362 return insert (__v, __dup).first;
363 }
364
365 // if __hint is past the end and __key is greater,
366 // then insert on the right
367 if (__hint == _C_end) {
368 if (_C_cmp (__hint->_C_child [1]->_C_key(), _KeyOf ()(__v)))
369 return _C_insert (0, __hint->_C_child [1], __v);
370 return insert (__v, __dup).first;
371 }
372
373 // if __hint is the left most child and __key is less
374 // then insert on the left
375 if (__hint == _C_end->_C_child [0]) {
376 if (_C_cmp (_KeyOf ()(__v), __hint->_C_key ()))
377 return _C_insert (__hint, __hint, __v);
378 return insert (__v, __dup).first;
379 }
380
381 const iterator __prev = __it++;
382
383 // if __v falls between __prev and __it, then insert it there
384 if ( _C_cmp (_ITER_NODE (__prev)->_C_key (), _KeyOf ()(__v))
385 && _C_cmp (_KeyOf ()(__v), _ITER_NODE (__it)->_C_key ())) {
386
387 // if there is no right child of __prev, then __prev is the
388 // left child of __it and we insert to right of __prev
389 if (_C_link_t () == _ITER_NODE (__prev)->_C_child [1])
390 return _C_insert (0, _ITER_NODE (__prev), __v);
391
392 // otherwise we insert on the left of __it
393 return _C_insert (_ITER_NODE (__it), _ITER_NODE (__it), __v);
394 }
395
396 // otherwise, do a full traversal
397 return insert (__v, __dup).first;
398}
399
400
401template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
402typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
403__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::erase (iterator __it)
404{
405 _RWSTD_ASSERT_RANGE (begin (), __it);
406
407#ifdef _RWSTDDEBUG
408
409 { // verify the consistency of the tree
410 size_type __two_logN = 0;
411 for (size_type __i = size () + 1; __i >>= 1; ++__two_logN);
412
413 __two_logN *= 2;
414
415 const size_type __depth = _C_depth ();
416 _RWSTD_ASSERT (__depth <= __two_logN);
417 }
418
419#endif // _RWSTDDEBUG
420
421 if (__it == end ())
422 return end ();
423
424 // for notational convenience
425 const typename _C_node_t::_C_color_t _Red = _C_node_t::_C_red;
426 const typename _C_node_t::_C_color_t _Black = _C_node_t::_C_black;
427 const _C_link_t _Null = _C_link_t ();
428
429 // returned iterator pointing to the element just past `it'
430 const iterator __next = ++iterator (__it);
431
432 _C_link_t __z (_ITER_NODE (__it)); // `it's node
433 _C_link_t __y (__z); // node to be erased
434 _C_link_t __x;
435
436 _C_link_t __x_parent = 0;
437
438
439 _RWSTD_ASSERT (_Null != __z);
440
441 if (_Null == __y->_C_child [0]) {
442 // __z might have one non-null child. x
443 // holds that child (might be null though).
444 __x = __y->_C_child [1];
445 }
446 else if (_Null == __y->_C_child [1]) {
447 // __z HAS one non-null child and __x points to it now.
448 __x = __y->_C_child [0];
449 }
450 else {
451 // __z has two non-null children; make __y point to its immediate
452 // predecessor; __x will point to that predecessor's immediate
453 // predecessor.
454 __y = _C_node_t::_C_min (__y->_C_child [1]);
455 __x = __y->_C_child [1];
456 }
457
458
459 if (__y != __z) {
460 // __y != __z ( means __y is in __z's left subtree )
461
462 // __y REPLACES __z
463
464 // relink `y' in place of `z' (at this point __y
465 // is __z's immediate predecessor)
466 __z->_C_child [0]->_C_parent = __y;
467 __y->_C_child [0] = __z->_C_child [0];
468
469 if (__y != __z->_C_child [1]) {
470 // __y is predecessor but is not __z's direct child (right)
471
472 // save y's former parent
473 __x_parent = __y->_C_parent;
474
475 if (_Null != __x)
476 // if __x exists, __x's parent becomes __y's parent
477 __x->_C_parent = __y->_C_parent;
478
479 // __y's former parent becomes __x's parent
480 __y->_C_parent->_C_child [0] = __x;
481
482 // __y's right child gets __z's former right child
483 __y->_C_child [1] = __z->_C_child [1];
484
485 // __z's former right child gets __y as parent
486 __z->_C_child [1]->_C_parent = __y;
487 }
488 else {
489
490 // in the case when __y is a direct child of __z,
491 // save __y value as __x's parent
492 __x_parent = __y;
493
494 }
495
496 if (_C_end->_C_parent == __z) {
497 // when deleted (__z) is root/end, then __y replaces root/end
498 _C_end->_C_parent = __y;
499 }
500 else {
501 // nice shot;
502 // when __z is not root/end, then its parent's
503 // child on __z's side becomes __y
504 __z->_C_parent->_C_child [__z->_C_parent->_C_child [0] != __z]
505 = __y;
506 }
507
508 // Finally, y's parent changes to be z's parent;
509 // y is completely severed from its place
510 __y->_C_parent = __z->_C_parent;
511
512 // swap y and z colors
513 _STD::swap (__y->_C_color, __z->_C_color);
514
515 // __y now points to the deleted node
516 __y = __z;
517 }
518 else {
519 // (__y == __z) ( __z has had only one child (or maybe none) )
520
521 // __x REPLACES __z
522
523 // save __y's/__z's parent (will later become x's parent)
524 __x_parent = __y->_C_parent;
525
526 if (_Null != __x) {
527 // for a non-null __x, set its parent to point to __y's parent
528 __x->_C_parent = __y->_C_parent;
529 }
530
531 if (_C_end->_C_parent == __z) {
532 // if __z was root, __x becomes new root...
533 _C_end->_C_parent = __x;
534 }
535 else
536 // ... otherwise, __x simply replaces __z and as such,
537 // __z's parent gets __x as right *or* left child
538 __z->_C_parent->_C_child [__z->_C_parent->_C_child [0] != __z]
539 = __x;
540
541 // ADJUST TREE'S CORNERS
542 if (_C_end->_C_child [0] == __z) {
543 // __z is the left corner of the tree (smallest element)
544
545 if (_Null == __z->_C_child [1])
546 // when __z leaves the tree, leftmost will be invalidated;
547 // adjust left corner to point to __z's parent
548 _C_end->_C_child [0] = __z->_C_parent;
549 else {
550 // finding the successor of __z when __z's right subtree
551 // is not null; leftmost becomes that minimum/sucessor
552 _C_end->_C_child [0] = _C_node_t::_C_min (__x);
553 }
554 }
555
556 if (_C_end->_C_child [1] == __z) {
557 // __z is in the right corner of the tree
558
559 if (_Null == __z->_C_child [0])
560 // when __z leaves the tree, right corner will be invalidated;
561 // adjust right corner to point to __z's parent
562 _C_end->_C_child [1] = __z->_C_parent;
563 else {
564 // otherwise, find z's predecessor in z's
565 // left subtree; that becomes the new rightmost element
566 _C_end->_C_child [1] = _C_node_t::_C_max (__x);
567 }
568 }
569 }
570
571
572 // COLOR SWAPPING
573 // (At this point __y has replaced __z and __z has been removed.)
574
575 if (__y->_C_color != _Red) {
576
577 // __y's color is not red; had it been red, we would have been
578 // done because it would not have altered the "blackness"
579
580
581 // At the loop's beginning, __x can be one of the two:
582 // 1. either the strict predecessor of __z's strict predecessor
583 // and in this case is down the subtree on z's left
584 // 2. is the node that replaced __z when __z has had only one
585 // child; that child has replaced __z and its changes
586 // will be propagated upward
587
588
589 while ( __x != _C_end->_C_parent
590 && (_Null == __x || __x->_C_color == _Black)) {
591
592#ifndef _RWSTD_NO_OPTIMIZE_SPEED
593
594 if (__x == __x_parent->_C_child [0]) {
595
596 // X ON THE LEFT SIDE OF ITS PARENT
597
598 // __w is __x's brother/sibling
599 _C_link_t __w = __x_parent->_C_child [1];
600
601 if (_Red == __w->_C_color) {
602 __w->_C_color = _Black;
603 __x_parent->_C_color = _Red;
604
605 _C_rol (__x_parent);
606
607 __w = __x_parent->_C_child [1];
608 }
609
610 if ((_Null == __w->_C_child [0] ||
611 _Black == __w->_C_child [0]->_C_color) &&
612 (_Null == __w->_C_child [1] ||
613 _Black == __w->_C_child [1]->_C_color)) {
614 // __x's sibling (__w) has black children (or null);
615 // color __x's sibling as RED and move up in the tree
616 __w->_C_color = _Red;
617 __x = __x_parent;
618 __x_parent = __x_parent->_C_parent;
619 }
620 else {
621 // __w (__x's sibling) has a child which is RED
622
623 if (_Null == __w->_C_child [1] ||
624 _Black == __w->_C_child [1]->_C_color) {
625
626 // __w's left is RED
627
628 if (_Null != __w->_C_child [0])
629 // the left RED child becomes BLACK
630 __w->_C_child [0]->_C_color = _Black;
631
632 // __w (x's sibling) becomes RED - color propagates up
633 __w->_C_color = _Red;
634
635 _C_ror (__w);
636
637 __w = __x_parent->_C_child [1];
638 }
639
640 __w->_C_color = __x_parent->_C_color;
641 __x_parent->_C_color = _Black;
642
643 if (_Null != __w->_C_child [1])
644 __w->_C_child [1]->_C_color = _Black;
645
646 _C_rol (__x_parent);
647
648 break;
649 }
650 }
651 else {
652
653 // same as the if clause with "right" and "left" exchanged
654
655 _C_link_t __w = __x_parent->_C_child [0];
656
657 if (_Red == __w->_C_color) {
658 __w->_C_color = _Black;
659 __x_parent->_C_color = _Red;
660
661 _C_ror (__x_parent);
662
663 __w = __x_parent->_C_child [0];
664 }
665
666 if ((_Null == __w->_C_child [1] ||
667 _Black == __w->_C_child [1]->_C_color) &&
668 (_Null == __w->_C_child [0] ||
669 _Black == __w->_C_child [0]->_C_color)) {
670 __w->_C_color = _Red;
671 __x = __x_parent;
672 __x_parent = __x_parent->_C_parent;
673 }
674 else {
675 if (_Null == __w->_C_child [0] ||
676 _Black == __w->_C_child [0]->_C_color) {
677 if (_Null != __w->_C_child [1])
678 __w->_C_child [1]->_C_color = _Black;
679
680 __w->_C_color = _Red;
681
682 _C_rol (__w);
683
684 __w = __x_parent->_C_child [0];
685 }
686
687 __w->_C_color = __x_parent->_C_color;
688 __x_parent->_C_color = _Black;
689
690 if (_Null != __w->_C_child [0])
691 __w->_C_child [0]->_C_color = _Black;
692
693 _C_ror (__x_parent);
694
695 break;
696 }
697 }
698
699#else // if defined (_RWSTD_NO_OPTIMIZE_SPEED)
700
701 const bool __left = (__x == __x_parent->_C_child [0]);
702 const bool __right = !__left;
703
704 _C_link_t __w = __x_parent->_C_child [__left];
705
706 if (_Red == __w->_C_color) {
707 __w->_C_color = _Black;
708 __x_parent->_C_color = _Red;
709
710 // rotate right if `x' is a right child, otherwise right
711 _C_rotate (__x_parent, __right);
712 __w = __x_parent->_C_child [__left];
713 }
714
715 if ((_Null == __w->_C_child [__right] ||
716 _Black == __w->_C_child [__right]->_C_color) &&
717 (_Null == __w->_C_child [__left ] ||
718 _Black == __w->_C_child [__left ]->_C_color)) {
719 __w->_C_color = _Red;
720 __x = __x_parent;
721 __x_parent = __x->_C_parent;
722 }
723 else {
724 if (_Null == __w->_C_child [__left] ||
725 _Black == __w->_C_child [__left]->_C_color) {
726
727 if (_Null != __w->_C_child [__right])
728 __w->_C_child [__right]->_C_color = _Black;
729
730 __w->_C_color = _Red;
731 _C_rotate (__w, __left);
732 __w = __x_parent->_C_child [__left];
733 }
734
735 if (_Null != __w) {
736 __w->_C_color = __x_parent->_C_color;
737 __x_parent->_C_color = _Black;
738
739 if (_Null != __w->_C_child [__left])
740 __w->_C_child [__left]->_C_color = _Black;
741
742 _C_rotate (__x_parent, __right);
743 }
744 break;
745 }
746
747#endif // _RWSTD_NO_OPTIMIZE_SPEED
748
749 }
750
751 if (_Null != __x)
752 __x->_C_color = _Black;
753
754 }
755
756 _C_put_node (__y);
757
758 --_C_size;
759
760 return __next;
761}
762
763
764template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
765typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::size_type
766__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
767erase (const key_type &__x)
768{
769 const _STD::pair<iterator, iterator> __p = equal_range(__x);
770
771 const size_type __n = _DISTANCE (__p.first, __p.second, size_type);
772
773 erase (__p.first, __p.second);
774
775 return __n;
776}
777
778
779template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
780typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::_C_link_t
781__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
782_C_copy (_C_link_t __x, _C_link_t __p)
783{
784 // recursive structural copy
785 _C_link_t __res = __x;
786
787 while (_C_link_t () != __x) {
788 const _C_link_t __y = _C_get_node (__x->_C_value);
789 if (__res == __x)
790 __res = __y; // save for return value
791
792 __y->_C_color = __x->_C_color;
793 __y->_C_parent = __p;
794 __p->_C_child [0] = __y;
795 __y->_C_child [1] = _C_copy (__x->_C_child [1], __y);
796 __p = __y;
797 __x = __x->_C_child [0];
798 }
799 __p->_C_child [0] = 0;
800
801 return __res;
802}
803
804
805template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
806void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
807_C_erase (_C_link_t __x)
808{
809 // recursively erase without rebalancing
810
811 while (_C_link_t () != __x) {
812 _C_erase (__x->_C_child [1]);
813 _C_link_t __y = __x->_C_child [0];
814 _C_put_node (__x);
815 __x = __y;
816 }
817}
818
819
820template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
821typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
822__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
823erase (iterator __first, iterator __last)
824{
825 _RWSTD_ASSERT_RANGE (begin (), __first);
826 _RWSTD_ASSERT_RANGE (__first, __last);
827
828 iterator __tmp;
829
830 if (__first == begin () && __last == end () && _C_size) {
831 // erase the root node
832 _C_erase (_C_end->_C_parent);
833
834 // set the parent pointer of an empty tree to null
835 _C_end->_C_parent = 0;
836
837 // set the child pointers of an empty tree to end()
838 _C_end->_C_child [0] =
839 _C_end->_C_child [1] = _C_end;
840
841 // set the size of the tree to 0
842 _C_size = 0;
843
844 // return end()
845 __tmp = end ();
846 } else
847 for (__tmp = end (); !(__first == __last); __tmp = erase (__first++));
848
849 return __tmp;
850}
851
852
853template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
854typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
855__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
856find (const key_type &__k)
857{
858 const iterator __j = lower_bound (__k);
859
860 return __j == end () || _C_cmp (__k, _ITER_NODE (__j)->_C_key ()) ?
861 end () : __j;
862}
863
864
865template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
866typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
867__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
868lower_bound (const key_type &__k)
869{
870 _C_link_t __y = _C_end;
871
872 for (_C_link_t __x = __y->_C_parent; _C_link_t () != __x; ) {
873 if (_C_cmp (__x->_C_key (), __k)) {
874 __x = __x->_C_child [1];
875 }
876 else {
877 __y = __x;
878 __x = __x->_C_child [0];
879 }
880 }
881
882 return _C_make_iter (__y);
883}
884
885
886template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
887typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
888__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
889upper_bound (const key_type &__k)
890{
891 _C_link_t __y = _C_end;
892
893 for (_C_link_t __x = __y->_C_parent; _C_link_t () != __x; ) {
894 if (_C_cmp (__k, __x->_C_key ())) {
895 __y = __x;
896 __x = __x->_C_child [0];
897 }
898 else
899 __x = __x->_C_child [1];
900 }
901
902 return _C_make_iter (__y);
903}
904
905
906template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
907typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::size_type
908__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
909_C_depth (const_iterator __it, size_type *__rank /* = 0 */) const
910{
911 // for notational convenience
912 const typename _C_node_t::_C_color_t _Black = _C_node_t::_C_black;
913 const _C_link_t _Null = _C_link_t ();
914
915 const _C_link_t __node = _ITER_NODE (__it);
916
917 if (_Null == __node)
918 return 0;
919
920#ifdef _RWSTDDEBUG
921
922 const typename _C_node_t::_C_color_t _Red = _C_node_t::_C_red;
923
924 if (_Red == __node->_C_color) {
925
926 // both children of every red node must be black
927
928 const bool __left_child_black =
929 _Null == __node->_C_child [0]
930 || _Black == __node->_C_child [0]->_C_color;
931
932 const bool __right_child_black =
933 _Null == __node->_C_child [1]
934 || _Black == __node->_C_child [1]->_C_color;
935
936 _RWSTD_ASSERT (__left_child_black);
937 _RWSTD_ASSERT (__right_child_black);
938 }
939
940#endif // _RWDSDEBUG
941
942 // every simple path from every node must contain the same number
943 // of black nodes; that means that every black node must either
944 // have zero or two children (of either color), or a single red
945 // child
946
947 size_type __ranks [2];
948
949 if ( _Null == __node->_C_child [0]
950 || _Black == __node->_C_child [0]->_C_color)
951 __ranks [0] = 1;
952 else
953 __ranks [0] = 0;
954
955 if ( _Null == __node->_C_child [1]
956 || _Black == __node->_C_child [1]->_C_color)
957 __ranks [1] = 1;
958 else
959 __ranks [1] = 0;
960
961 const size_type __depth [] = {
962 _Null == __node->_C_child [0] ?
963 0 : 1 + _C_depth (_C_make_iter (__node->_C_child [0]), __ranks + 0),
964 _Null == __node->_C_child [1] ?
965 0 : 1 + _C_depth (_C_make_iter (__node->_C_child [1]), __ranks + 1)
966 };
967
968 _RWSTD_ASSERT (__ranks [0] == __ranks [1]);
969
970 if (__rank)
971 *__rank += __ranks [0];
972
973 return __depth [__depth [0] < __depth [1]];
974}
975
976
977template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
978typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::size_type
979__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
980_C_level (const_iterator __it) const
981{
982 if (_ITER_NODE (__it) == _C_end->_C_parent)
983 return 0;
984
985 return 1 + _C_level (_C_make_iter (_ITER_NODE (__it)->_C_parent));
986}
987
988
989} // namespace __rw
const int end
#define _RETHROW
Definition _defs.h:853
#define _TRY
Definition _defs.h:850
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_NEW_CAPACITY(ignore, what, from)
Definition _defs.h:462
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _DISTANCE(first, last, ignore)
Definition _defs.h:1225
#define _CATCH(ex)
Definition _defs.h:851
#define _RWSTD_ASSERT_RANGE(ign1, ign2)
Definition _defs.h:1247
#define _ITER_NODE(it)