1 // RB tree implementation -*- C++ -*-
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
5 // Free Software Foundation, Inc.
7 // This file is part of the GNU ISO C++ Library. This library is free
8 // software; you can redistribute it and/or modify it under the
9 // terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 3, or (at your option)
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // Under Section 7 of GPL version 3, you are granted additional
19 // permissions described in the GCC Runtime Library Exception, version
20 // 3.1, as published by the Free Software Foundation.
22 // You should have received a copy of the GNU General Public License and
23 // a copy of the GCC Runtime Library Exception along with this program;
24 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 // <http://www.gnu.org/licenses/>.
29 * Copyright (c) 1996,1997
30 * Silicon Graphics Computer Systems, Inc.
32 * Permission to use, copy, modify, distribute and sell this software
33 * and its documentation for any purpose is hereby granted without fee,
34 * provided that the above copyright notice appear in all copies and
35 * that both that copyright notice and this permission notice appear
36 * in supporting documentation. Silicon Graphics makes no
37 * representations about the suitability of this software for any
38 * purpose. It is provided "as is" without express or implied warranty.
42 * Hewlett-Packard Company
44 * Permission to use, copy, modify, distribute and sell this software
45 * and its documentation for any purpose is hereby granted without fee,
46 * provided that the above copyright notice appear in all copies and
47 * that both that copyright notice and this permission notice appear
48 * in supporting documentation. Hewlett-Packard Company makes no
49 * representations about the suitability of this software for any
50 * purpose. It is provided "as is" without express or implied warranty.
55 /** @file bits/stl_tree.h
56 * This is an internal header file, included by other library headers.
57 * Do not attempt to use it directly. @headername{map or set}
63 #include <bits/stl_algobase.h>
64 #include <bits/allocator.h>
65 #include <bits/stl_function.h>
66 #include <bits/cpp_type_traits.h>
68 _GLIBCXX_BEGIN_NAMESPACE(std
)
70 // Red-black tree class, designed for use in implementing STL
71 // associative containers (set, multiset, map, and multimap). The
72 // insertion and deletion algorithms are based on those in Cormen,
73 // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
76 // (1) the header cell is maintained with links not only to the root
77 // but also to the leftmost node of the tree, to enable constant
78 // time begin(), and to the rightmost node of the tree, to enable
79 // linear time performance when used with the generic set algorithms
82 // (2) when a node being deleted has two children its successor node
83 // is relinked into its place, rather than copied, so that the only
84 // iterators invalidated are those referring to the deleted node.
86 enum _Rb_tree_color
{ _S_red
= false, _S_black
= true };
88 struct _Rb_tree_node_base
90 typedef _Rb_tree_node_base
* _Base_ptr
;
91 typedef const _Rb_tree_node_base
* _Const_Base_ptr
;
93 _Rb_tree_color _M_color
;
99 _S_minimum(_Base_ptr __x
)
101 while (__x
->_M_left
!= 0) __x
= __x
->_M_left
;
105 static _Const_Base_ptr
106 _S_minimum(_Const_Base_ptr __x
)
108 while (__x
->_M_left
!= 0) __x
= __x
->_M_left
;
113 _S_maximum(_Base_ptr __x
)
115 while (__x
->_M_right
!= 0) __x
= __x
->_M_right
;
119 static _Const_Base_ptr
120 _S_maximum(_Const_Base_ptr __x
)
122 while (__x
->_M_right
!= 0) __x
= __x
->_M_right
;
127 template<typename _Val
>
128 struct _Rb_tree_node
: public _Rb_tree_node_base
130 typedef _Rb_tree_node
<_Val
>* _Link_type
;
133 #ifdef __GXX_EXPERIMENTAL_CXX0X__
134 template<typename
... _Args
>
135 _Rb_tree_node(_Args
&&... __args
)
136 : _Rb_tree_node_base(),
137 _M_value_field(std::forward
<_Args
>(__args
)...) { }
141 _GLIBCXX_PURE _Rb_tree_node_base
*
142 _Rb_tree_increment(_Rb_tree_node_base
* __x
) throw ();
144 _GLIBCXX_PURE
const _Rb_tree_node_base
*
145 _Rb_tree_increment(const _Rb_tree_node_base
* __x
) throw ();
147 _GLIBCXX_PURE _Rb_tree_node_base
*
148 _Rb_tree_decrement(_Rb_tree_node_base
* __x
) throw ();
150 _GLIBCXX_PURE
const _Rb_tree_node_base
*
151 _Rb_tree_decrement(const _Rb_tree_node_base
* __x
) throw ();
153 template<typename _Tp
>
154 struct _Rb_tree_iterator
156 typedef _Tp value_type
;
157 typedef _Tp
& reference
;
158 typedef _Tp
* pointer
;
160 typedef bidirectional_iterator_tag iterator_category
;
161 typedef ptrdiff_t difference_type
;
163 typedef _Rb_tree_iterator
<_Tp
> _Self
;
164 typedef _Rb_tree_node_base::_Base_ptr _Base_ptr
;
165 typedef _Rb_tree_node
<_Tp
>* _Link_type
;
171 _Rb_tree_iterator(_Link_type __x
)
176 { return static_cast<_Link_type
>(_M_node
)->_M_value_field
; }
180 { return std::__addressof(static_cast<_Link_type
>
181 (_M_node
)->_M_value_field
); }
186 _M_node
= _Rb_tree_increment(_M_node
);
194 _M_node
= _Rb_tree_increment(_M_node
);
201 _M_node
= _Rb_tree_decrement(_M_node
);
209 _M_node
= _Rb_tree_decrement(_M_node
);
214 operator==(const _Self
& __x
) const
215 { return _M_node
== __x
._M_node
; }
218 operator!=(const _Self
& __x
) const
219 { return _M_node
!= __x
._M_node
; }
224 template<typename _Tp
>
225 struct _Rb_tree_const_iterator
227 typedef _Tp value_type
;
228 typedef const _Tp
& reference
;
229 typedef const _Tp
* pointer
;
231 typedef _Rb_tree_iterator
<_Tp
> iterator
;
233 typedef bidirectional_iterator_tag iterator_category
;
234 typedef ptrdiff_t difference_type
;
236 typedef _Rb_tree_const_iterator
<_Tp
> _Self
;
237 typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr
;
238 typedef const _Rb_tree_node
<_Tp
>* _Link_type
;
240 _Rb_tree_const_iterator()
244 _Rb_tree_const_iterator(_Link_type __x
)
247 _Rb_tree_const_iterator(const iterator
& __it
)
248 : _M_node(__it
._M_node
) { }
251 _M_const_cast() const
252 { return iterator(static_cast<typename
iterator::_Link_type
>
253 (const_cast<typename
iterator::_Base_ptr
>(_M_node
))); }
257 { return static_cast<_Link_type
>(_M_node
)->_M_value_field
; }
261 { return std::__addressof(static_cast<_Link_type
>
262 (_M_node
)->_M_value_field
); }
267 _M_node
= _Rb_tree_increment(_M_node
);
275 _M_node
= _Rb_tree_increment(_M_node
);
282 _M_node
= _Rb_tree_decrement(_M_node
);
290 _M_node
= _Rb_tree_decrement(_M_node
);
295 operator==(const _Self
& __x
) const
296 { return _M_node
== __x
._M_node
; }
299 operator!=(const _Self
& __x
) const
300 { return _M_node
!= __x
._M_node
; }
305 template<typename _Val
>
307 operator==(const _Rb_tree_iterator
<_Val
>& __x
,
308 const _Rb_tree_const_iterator
<_Val
>& __y
)
309 { return __x
._M_node
== __y
._M_node
; }
311 template<typename _Val
>
313 operator!=(const _Rb_tree_iterator
<_Val
>& __x
,
314 const _Rb_tree_const_iterator
<_Val
>& __y
)
315 { return __x
._M_node
!= __y
._M_node
; }
318 _Rb_tree_insert_and_rebalance(const bool __insert_left
,
319 _Rb_tree_node_base
* __x
,
320 _Rb_tree_node_base
* __p
,
321 _Rb_tree_node_base
& __header
) throw ();
324 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base
* const __z
,
325 _Rb_tree_node_base
& __header
) throw ();
328 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
329 typename _Compare
, typename _Alloc
= allocator
<_Val
> >
332 typedef typename
_Alloc::template rebind
<_Rb_tree_node
<_Val
> >::other
336 typedef _Rb_tree_node_base
* _Base_ptr
;
337 typedef const _Rb_tree_node_base
* _Const_Base_ptr
;
340 typedef _Key key_type
;
341 typedef _Val value_type
;
342 typedef value_type
* pointer
;
343 typedef const value_type
* const_pointer
;
344 typedef value_type
& reference
;
345 typedef const value_type
& const_reference
;
346 typedef _Rb_tree_node
<_Val
>* _Link_type
;
347 typedef const _Rb_tree_node
<_Val
>* _Const_Link_type
;
348 typedef size_t size_type
;
349 typedef ptrdiff_t difference_type
;
350 typedef _Alloc allocator_type
;
353 _M_get_Node_allocator()
354 { return *static_cast<_Node_allocator
*>(&this->_M_impl
); }
356 const _Node_allocator
&
357 _M_get_Node_allocator() const
358 { return *static_cast<const _Node_allocator
*>(&this->_M_impl
); }
361 get_allocator() const
362 { return allocator_type(_M_get_Node_allocator()); }
367 { return _M_impl
._Node_allocator::allocate(1); }
370 _M_put_node(_Link_type __p
)
371 { _M_impl
._Node_allocator::deallocate(__p
, 1); }
373 #ifndef __GXX_EXPERIMENTAL_CXX0X__
375 _M_create_node(const value_type
& __x
)
377 _Link_type __tmp
= _M_get_node();
379 { get_allocator().construct
380 (std::__addressof(__tmp
->_M_value_field
), __x
); }
384 __throw_exception_again
;
390 _M_destroy_node(_Link_type __p
)
392 get_allocator().destroy(std::__addressof(__p
->_M_value_field
));
396 template<typename
... _Args
>
398 _M_create_node(_Args
&&... __args
)
400 _Link_type __tmp
= _M_get_node();
403 _M_get_Node_allocator().construct(__tmp
,
404 std::forward
<_Args
>(__args
)...);
409 __throw_exception_again
;
415 _M_destroy_node(_Link_type __p
)
417 _M_get_Node_allocator().destroy(__p
);
423 _M_clone_node(_Const_Link_type __x
)
425 _Link_type __tmp
= _M_create_node(__x
->_M_value_field
);
426 __tmp
->_M_color
= __x
->_M_color
;
433 template<typename _Key_compare
,
434 bool _Is_pod_comparator
= __is_pod(_Key_compare
)>
435 struct _Rb_tree_impl
: public _Node_allocator
437 _Key_compare _M_key_compare
;
438 _Rb_tree_node_base _M_header
;
439 size_type _M_node_count
; // Keeps track of size of tree.
442 : _Node_allocator(), _M_key_compare(), _M_header(),
446 _Rb_tree_impl(const _Key_compare
& __comp
, const _Node_allocator
& __a
)
447 : _Node_allocator(__a
), _M_key_compare(__comp
), _M_header(),
455 this->_M_header
._M_color
= _S_red
;
456 this->_M_header
._M_parent
= 0;
457 this->_M_header
._M_left
= &this->_M_header
;
458 this->_M_header
._M_right
= &this->_M_header
;
462 _Rb_tree_impl
<_Compare
> _M_impl
;
467 { return this->_M_impl
._M_header
._M_parent
; }
471 { return this->_M_impl
._M_header
._M_parent
; }
475 { return this->_M_impl
._M_header
._M_left
; }
479 { return this->_M_impl
._M_header
._M_left
; }
483 { return this->_M_impl
._M_header
._M_right
; }
487 { return this->_M_impl
._M_header
._M_right
; }
491 { return static_cast<_Link_type
>(this->_M_impl
._M_header
._M_parent
); }
496 return static_cast<_Const_Link_type
>
497 (this->_M_impl
._M_header
._M_parent
);
502 { return static_cast<_Link_type
>(&this->_M_impl
._M_header
); }
506 { return static_cast<_Const_Link_type
>(&this->_M_impl
._M_header
); }
508 static const_reference
509 _S_value(_Const_Link_type __x
)
510 { return __x
->_M_value_field
; }
513 _S_key(_Const_Link_type __x
)
514 { return _KeyOfValue()(_S_value(__x
)); }
517 _S_left(_Base_ptr __x
)
518 { return static_cast<_Link_type
>(__x
->_M_left
); }
520 static _Const_Link_type
521 _S_left(_Const_Base_ptr __x
)
522 { return static_cast<_Const_Link_type
>(__x
->_M_left
); }
525 _S_right(_Base_ptr __x
)
526 { return static_cast<_Link_type
>(__x
->_M_right
); }
528 static _Const_Link_type
529 _S_right(_Const_Base_ptr __x
)
530 { return static_cast<_Const_Link_type
>(__x
->_M_right
); }
532 static const_reference
533 _S_value(_Const_Base_ptr __x
)
534 { return static_cast<_Const_Link_type
>(__x
)->_M_value_field
; }
537 _S_key(_Const_Base_ptr __x
)
538 { return _KeyOfValue()(_S_value(__x
)); }
541 _S_minimum(_Base_ptr __x
)
542 { return _Rb_tree_node_base::_S_minimum(__x
); }
544 static _Const_Base_ptr
545 _S_minimum(_Const_Base_ptr __x
)
546 { return _Rb_tree_node_base::_S_minimum(__x
); }
549 _S_maximum(_Base_ptr __x
)
550 { return _Rb_tree_node_base::_S_maximum(__x
); }
552 static _Const_Base_ptr
553 _S_maximum(_Const_Base_ptr __x
)
554 { return _Rb_tree_node_base::_S_maximum(__x
); }
557 typedef _Rb_tree_iterator
<value_type
> iterator
;
558 typedef _Rb_tree_const_iterator
<value_type
> const_iterator
;
560 typedef std::reverse_iterator
<iterator
> reverse_iterator
;
561 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
564 #ifdef __GXX_EXPERIMENTAL_CXX0X__
565 template<typename _Arg
>
567 _M_insert_(_Const_Base_ptr __x
, _Const_Base_ptr __y
, _Arg
&& __v
);
569 template<typename _Arg
>
571 _M_insert_lower(_Base_ptr __x
, _Base_ptr __y
, _Arg
&& __v
);
573 template<typename _Arg
>
575 _M_insert_equal_lower(_Arg
&& __x
);
578 _M_insert_(_Const_Base_ptr __x
, _Const_Base_ptr __y
,
579 const value_type
& __v
);
581 // _GLIBCXX_RESOLVE_LIB_DEFECTS
582 // 233. Insertion hints in associative containers.
584 _M_insert_lower(_Base_ptr __x
, _Base_ptr __y
, const value_type
& __v
);
587 _M_insert_equal_lower(const value_type
& __x
);
591 _M_copy(_Const_Link_type __x
, _Link_type __p
);
594 _M_erase(_Link_type __x
);
597 _M_lower_bound(_Link_type __x
, _Link_type __y
,
601 _M_lower_bound(_Const_Link_type __x
, _Const_Link_type __y
,
602 const _Key
& __k
) const;
605 _M_upper_bound(_Link_type __x
, _Link_type __y
,
609 _M_upper_bound(_Const_Link_type __x
, _Const_Link_type __y
,
610 const _Key
& __k
) const;
613 // allocation/deallocation
616 _Rb_tree(const _Compare
& __comp
,
617 const allocator_type
& __a
= allocator_type())
618 : _M_impl(__comp
, __a
) { }
620 _Rb_tree(const _Rb_tree
& __x
)
621 : _M_impl(__x
._M_impl
._M_key_compare
, __x
._M_get_Node_allocator())
623 if (__x
._M_root() != 0)
625 _M_root() = _M_copy(__x
._M_begin(), _M_end());
626 _M_leftmost() = _S_minimum(_M_root());
627 _M_rightmost() = _S_maximum(_M_root());
628 _M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
632 #ifdef __GXX_EXPERIMENTAL_CXX0X__
633 _Rb_tree(_Rb_tree
&& __x
);
637 { _M_erase(_M_begin()); }
640 operator=(const _Rb_tree
& __x
);
645 { return _M_impl
._M_key_compare
; }
650 return iterator(static_cast<_Link_type
>
651 (this->_M_impl
._M_header
._M_left
));
657 return const_iterator(static_cast<_Const_Link_type
>
658 (this->_M_impl
._M_header
._M_left
));
663 { return iterator(static_cast<_Link_type
>(&this->_M_impl
._M_header
)); }
668 return const_iterator(static_cast<_Const_Link_type
>
669 (&this->_M_impl
._M_header
));
674 { return reverse_iterator(end()); }
676 const_reverse_iterator
678 { return const_reverse_iterator(end()); }
682 { return reverse_iterator(begin()); }
684 const_reverse_iterator
686 { return const_reverse_iterator(begin()); }
690 { return _M_impl
._M_node_count
== 0; }
694 { return _M_impl
._M_node_count
; }
698 { return _M_get_Node_allocator().max_size(); }
704 #ifdef __GXX_EXPERIMENTAL_CXX0X__
705 template<typename _Arg
>
707 _M_insert_unique(_Arg
&& __x
);
709 template<typename _Arg
>
711 _M_insert_equal(_Arg
&& __x
);
713 template<typename _Arg
>
715 _M_insert_unique_(const_iterator __position
, _Arg
&& __x
);
717 template<typename _Arg
>
719 _M_insert_equal_(const_iterator __position
, _Arg
&& __x
);
722 _M_insert_unique(const value_type
& __x
);
725 _M_insert_equal(const value_type
& __x
);
728 _M_insert_unique_(const_iterator __position
, const value_type
& __x
);
731 _M_insert_equal_(const_iterator __position
, const value_type
& __x
);
734 template<typename _InputIterator
>
736 _M_insert_unique(_InputIterator __first
, _InputIterator __last
);
738 template<typename _InputIterator
>
740 _M_insert_equal(_InputIterator __first
, _InputIterator __last
);
744 _M_erase_aux(const_iterator __position
);
747 _M_erase_aux(const_iterator __first
, const_iterator __last
);
750 #ifdef __GXX_EXPERIMENTAL_CXX0X__
751 // _GLIBCXX_RESOLVE_LIB_DEFECTS
752 // DR 130. Associative erase should return an iterator.
754 erase(const_iterator __position
)
756 const_iterator __result
= __position
;
758 _M_erase_aux(__position
);
759 return __result
._M_const_cast();
763 erase(const_iterator __position
)
764 { _M_erase_aux(__position
); }
767 erase(const key_type
& __x
);
769 #ifdef __GXX_EXPERIMENTAL_CXX0X__
770 // _GLIBCXX_RESOLVE_LIB_DEFECTS
771 // DR 130. Associative erase should return an iterator.
773 erase(const_iterator __first
, const_iterator __last
)
775 _M_erase_aux(__first
, __last
);
776 return __last
._M_const_cast();
780 erase(const_iterator __first
, const_iterator __last
)
781 { _M_erase_aux(__first
, __last
); }
784 erase(const key_type
* __first
, const key_type
* __last
);
789 _M_erase(_M_begin());
790 _M_leftmost() = _M_end();
792 _M_rightmost() = _M_end();
793 _M_impl
._M_node_count
= 0;
798 find(const key_type
& __k
);
801 find(const key_type
& __k
) const;
804 count(const key_type
& __k
) const;
807 lower_bound(const key_type
& __k
)
808 { return _M_lower_bound(_M_begin(), _M_end(), __k
); }
811 lower_bound(const key_type
& __k
) const
812 { return _M_lower_bound(_M_begin(), _M_end(), __k
); }
815 upper_bound(const key_type
& __k
)
816 { return _M_upper_bound(_M_begin(), _M_end(), __k
); }
819 upper_bound(const key_type
& __k
) const
820 { return _M_upper_bound(_M_begin(), _M_end(), __k
); }
822 pair
<iterator
, iterator
>
823 equal_range(const key_type
& __k
);
825 pair
<const_iterator
, const_iterator
>
826 equal_range(const key_type
& __k
) const;
833 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
834 typename _Compare
, typename _Alloc
>
836 operator==(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
837 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
839 return __x
.size() == __y
.size()
840 && std::equal(__x
.begin(), __x
.end(), __y
.begin());
843 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
844 typename _Compare
, typename _Alloc
>
846 operator<(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
847 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
849 return std::lexicographical_compare(__x
.begin(), __x
.end(),
850 __y
.begin(), __y
.end());
853 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
854 typename _Compare
, typename _Alloc
>
856 operator!=(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
857 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
858 { return !(__x
== __y
); }
860 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
861 typename _Compare
, typename _Alloc
>
863 operator>(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
864 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
865 { return __y
< __x
; }
867 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
868 typename _Compare
, typename _Alloc
>
870 operator<=(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
871 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
872 { return !(__y
< __x
); }
874 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
875 typename _Compare
, typename _Alloc
>
877 operator>=(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
878 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
879 { return !(__x
< __y
); }
881 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
882 typename _Compare
, typename _Alloc
>
884 swap(_Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
885 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
888 #ifdef __GXX_EXPERIMENTAL_CXX0X__
889 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
890 typename _Compare
, typename _Alloc
>
891 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
892 _Rb_tree(_Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>&& __x
)
893 : _M_impl(__x
._M_impl
._M_key_compare
, __x
._M_get_Node_allocator())
895 if (__x
._M_root() != 0)
897 _M_root() = __x
._M_root();
898 _M_leftmost() = __x
._M_leftmost();
899 _M_rightmost() = __x
._M_rightmost();
900 _M_root()->_M_parent
= _M_end();
903 __x
._M_leftmost() = __x
._M_end();
904 __x
._M_rightmost() = __x
._M_end();
906 this->_M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
907 __x
._M_impl
._M_node_count
= 0;
912 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
913 typename _Compare
, typename _Alloc
>
914 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>&
915 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
916 operator=(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
)
920 // Note that _Key may be a constant type.
922 _M_impl
._M_key_compare
= __x
._M_impl
._M_key_compare
;
923 if (__x
._M_root() != 0)
925 _M_root() = _M_copy(__x
._M_begin(), _M_end());
926 _M_leftmost() = _S_minimum(_M_root());
927 _M_rightmost() = _S_maximum(_M_root());
928 _M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
934 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
935 typename _Compare
, typename _Alloc
>
936 #ifdef __GXX_EXPERIMENTAL_CXX0X__
937 template<typename _Arg
>
939 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
940 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
941 #ifdef __GXX_EXPERIMENTAL_CXX0X__
942 _M_insert_(_Const_Base_ptr __x
, _Const_Base_ptr __p
, _Arg
&& __v
)
944 _M_insert_(_Const_Base_ptr __x
, _Const_Base_ptr __p
, const _Val
& __v
)
947 bool __insert_left
= (__x
!= 0 || __p
== _M_end()
948 || _M_impl
._M_key_compare(_KeyOfValue()(__v
),
951 _Link_type __z
= _M_create_node(_GLIBCXX_FORWARD(_Arg
, __v
));
953 _Rb_tree_insert_and_rebalance(__insert_left
, __z
,
954 const_cast<_Base_ptr
>(__p
),
955 this->_M_impl
._M_header
);
956 ++_M_impl
._M_node_count
;
957 return iterator(__z
);
960 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
961 typename _Compare
, typename _Alloc
>
962 #ifdef __GXX_EXPERIMENTAL_CXX0X__
963 template<typename _Arg
>
965 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
966 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
967 #ifdef __GXX_EXPERIMENTAL_CXX0X__
968 _M_insert_lower(_Base_ptr __x
, _Base_ptr __p
, _Arg
&& __v
)
970 _M_insert_lower(_Base_ptr __x
, _Base_ptr __p
, const _Val
& __v
)
973 bool __insert_left
= (__x
!= 0 || __p
== _M_end()
974 || !_M_impl
._M_key_compare(_S_key(__p
),
975 _KeyOfValue()(__v
)));
977 _Link_type __z
= _M_create_node(_GLIBCXX_FORWARD(_Arg
, __v
));
979 _Rb_tree_insert_and_rebalance(__insert_left
, __z
, __p
,
980 this->_M_impl
._M_header
);
981 ++_M_impl
._M_node_count
;
982 return iterator(__z
);
985 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
986 typename _Compare
, typename _Alloc
>
987 #ifdef __GXX_EXPERIMENTAL_CXX0X__
988 template<typename _Arg
>
990 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
991 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
992 #ifdef __GXX_EXPERIMENTAL_CXX0X__
993 _M_insert_equal_lower(_Arg
&& __v
)
995 _M_insert_equal_lower(const _Val
& __v
)
998 _Link_type __x
= _M_begin();
999 _Link_type __y
= _M_end();
1003 __x
= !_M_impl
._M_key_compare(_S_key(__x
), _KeyOfValue()(__v
)) ?
1004 _S_left(__x
) : _S_right(__x
);
1006 return _M_insert_lower(__x
, __y
, _GLIBCXX_FORWARD(_Arg
, __v
));
1009 template<typename _Key
, typename _Val
, typename _KoV
,
1010 typename _Compare
, typename _Alloc
>
1011 typename _Rb_tree
<_Key
, _Val
, _KoV
, _Compare
, _Alloc
>::_Link_type
1012 _Rb_tree
<_Key
, _Val
, _KoV
, _Compare
, _Alloc
>::
1013 _M_copy(_Const_Link_type __x
, _Link_type __p
)
1015 // Structural copy. __x and __p must be non-null.
1016 _Link_type __top
= _M_clone_node(__x
);
1017 __top
->_M_parent
= __p
;
1022 __top
->_M_right
= _M_copy(_S_right(__x
), __top
);
1028 _Link_type __y
= _M_clone_node(__x
);
1030 __y
->_M_parent
= __p
;
1032 __y
->_M_right
= _M_copy(_S_right(__x
), __y
);
1040 __throw_exception_again
;
1045 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1046 typename _Compare
, typename _Alloc
>
1048 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1049 _M_erase(_Link_type __x
)
1051 // Erase without rebalancing.
1054 _M_erase(_S_right(__x
));
1055 _Link_type __y
= _S_left(__x
);
1056 _M_destroy_node(__x
);
1061 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1062 typename _Compare
, typename _Alloc
>
1063 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1064 _Compare
, _Alloc
>::iterator
1065 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1066 _M_lower_bound(_Link_type __x
, _Link_type __y
,
1070 if (!_M_impl
._M_key_compare(_S_key(__x
), __k
))
1071 __y
= __x
, __x
= _S_left(__x
);
1073 __x
= _S_right(__x
);
1074 return iterator(__y
);
1077 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1078 typename _Compare
, typename _Alloc
>
1079 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1080 _Compare
, _Alloc
>::const_iterator
1081 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1082 _M_lower_bound(_Const_Link_type __x
, _Const_Link_type __y
,
1083 const _Key
& __k
) const
1086 if (!_M_impl
._M_key_compare(_S_key(__x
), __k
))
1087 __y
= __x
, __x
= _S_left(__x
);
1089 __x
= _S_right(__x
);
1090 return const_iterator(__y
);
1093 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1094 typename _Compare
, typename _Alloc
>
1095 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1096 _Compare
, _Alloc
>::iterator
1097 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1098 _M_upper_bound(_Link_type __x
, _Link_type __y
,
1102 if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1103 __y
= __x
, __x
= _S_left(__x
);
1105 __x
= _S_right(__x
);
1106 return iterator(__y
);
1109 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1110 typename _Compare
, typename _Alloc
>
1111 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1112 _Compare
, _Alloc
>::const_iterator
1113 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1114 _M_upper_bound(_Const_Link_type __x
, _Const_Link_type __y
,
1115 const _Key
& __k
) const
1118 if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1119 __y
= __x
, __x
= _S_left(__x
);
1121 __x
= _S_right(__x
);
1122 return const_iterator(__y
);
1125 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1126 typename _Compare
, typename _Alloc
>
1127 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1128 _Compare
, _Alloc
>::iterator
,
1129 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1130 _Compare
, _Alloc
>::iterator
>
1131 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1132 equal_range(const _Key
& __k
)
1134 _Link_type __x
= _M_begin();
1135 _Link_type __y
= _M_end();
1138 if (_M_impl
._M_key_compare(_S_key(__x
), __k
))
1139 __x
= _S_right(__x
);
1140 else if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1141 __y
= __x
, __x
= _S_left(__x
);
1144 _Link_type
__xu(__x
), __yu(__y
);
1145 __y
= __x
, __x
= _S_left(__x
);
1146 __xu
= _S_right(__xu
);
1147 return pair
<iterator
,
1148 iterator
>(_M_lower_bound(__x
, __y
, __k
),
1149 _M_upper_bound(__xu
, __yu
, __k
));
1152 return pair
<iterator
, iterator
>(iterator(__y
),
1156 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1157 typename _Compare
, typename _Alloc
>
1158 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1159 _Compare
, _Alloc
>::const_iterator
,
1160 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1161 _Compare
, _Alloc
>::const_iterator
>
1162 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1163 equal_range(const _Key
& __k
) const
1165 _Const_Link_type __x
= _M_begin();
1166 _Const_Link_type __y
= _M_end();
1169 if (_M_impl
._M_key_compare(_S_key(__x
), __k
))
1170 __x
= _S_right(__x
);
1171 else if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1172 __y
= __x
, __x
= _S_left(__x
);
1175 _Const_Link_type
__xu(__x
), __yu(__y
);
1176 __y
= __x
, __x
= _S_left(__x
);
1177 __xu
= _S_right(__xu
);
1178 return pair
<const_iterator
,
1179 const_iterator
>(_M_lower_bound(__x
, __y
, __k
),
1180 _M_upper_bound(__xu
, __yu
, __k
));
1183 return pair
<const_iterator
, const_iterator
>(const_iterator(__y
),
1184 const_iterator(__y
));
1187 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1188 typename _Compare
, typename _Alloc
>
1190 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1191 swap(_Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __t
)
1195 if (__t
._M_root() != 0)
1197 _M_root() = __t
._M_root();
1198 _M_leftmost() = __t
._M_leftmost();
1199 _M_rightmost() = __t
._M_rightmost();
1200 _M_root()->_M_parent
= _M_end();
1203 __t
._M_leftmost() = __t
._M_end();
1204 __t
._M_rightmost() = __t
._M_end();
1207 else if (__t
._M_root() == 0)
1209 __t
._M_root() = _M_root();
1210 __t
._M_leftmost() = _M_leftmost();
1211 __t
._M_rightmost() = _M_rightmost();
1212 __t
._M_root()->_M_parent
= __t
._M_end();
1215 _M_leftmost() = _M_end();
1216 _M_rightmost() = _M_end();
1220 std::swap(_M_root(),__t
._M_root());
1221 std::swap(_M_leftmost(),__t
._M_leftmost());
1222 std::swap(_M_rightmost(),__t
._M_rightmost());
1224 _M_root()->_M_parent
= _M_end();
1225 __t
._M_root()->_M_parent
= __t
._M_end();
1227 // No need to swap header's color as it does not change.
1228 std::swap(this->_M_impl
._M_node_count
, __t
._M_impl
._M_node_count
);
1229 std::swap(this->_M_impl
._M_key_compare
, __t
._M_impl
._M_key_compare
);
1231 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1232 // 431. Swapping containers with unequal allocators.
1233 std::__alloc_swap
<_Node_allocator
>::
1234 _S_do_it(_M_get_Node_allocator(), __t
._M_get_Node_allocator());
1237 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1238 typename _Compare
, typename _Alloc
>
1239 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1240 template<typename _Arg
>
1242 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1243 _Compare
, _Alloc
>::iterator
, bool>
1244 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1245 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1246 _M_insert_unique(_Arg
&& __v
)
1248 _M_insert_unique(const _Val
& __v
)
1251 _Link_type __x
= _M_begin();
1252 _Link_type __y
= _M_end();
1257 __comp
= _M_impl
._M_key_compare(_KeyOfValue()(__v
), _S_key(__x
));
1258 __x
= __comp
? _S_left(__x
) : _S_right(__x
);
1260 iterator __j
= iterator(__y
);
1264 return pair
<iterator
, bool>
1265 (_M_insert_(__x
, __y
, _GLIBCXX_FORWARD(_Arg
, __v
)), true);
1269 if (_M_impl
._M_key_compare(_S_key(__j
._M_node
), _KeyOfValue()(__v
)))
1270 return pair
<iterator
, bool>
1271 (_M_insert_(__x
, __y
, _GLIBCXX_FORWARD(_Arg
, __v
)), true);
1272 return pair
<iterator
, bool>(__j
, false);
1275 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1276 typename _Compare
, typename _Alloc
>
1277 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1278 template<typename _Arg
>
1280 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1281 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1282 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1283 _M_insert_equal(_Arg
&& __v
)
1285 _M_insert_equal(const _Val
& __v
)
1288 _Link_type __x
= _M_begin();
1289 _Link_type __y
= _M_end();
1293 __x
= _M_impl
._M_key_compare(_KeyOfValue()(__v
), _S_key(__x
)) ?
1294 _S_left(__x
) : _S_right(__x
);
1296 return _M_insert_(__x
, __y
, _GLIBCXX_FORWARD(_Arg
, __v
));
1299 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1300 typename _Compare
, typename _Alloc
>
1301 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1302 template<typename _Arg
>
1304 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1305 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1306 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1307 _M_insert_unique_(const_iterator __position
, _Arg
&& __v
)
1309 _M_insert_unique_(const_iterator __position
, const _Val
& __v
)
1313 if (__position
._M_node
== _M_end())
1316 && _M_impl
._M_key_compare(_S_key(_M_rightmost()),
1317 _KeyOfValue()(__v
)))
1318 return _M_insert_(0, _M_rightmost(), _GLIBCXX_FORWARD(_Arg
, __v
));
1320 return _M_insert_unique(_GLIBCXX_FORWARD(_Arg
, __v
)).first
;
1322 else if (_M_impl
._M_key_compare(_KeyOfValue()(__v
),
1323 _S_key(__position
._M_node
)))
1325 // First, try before...
1326 const_iterator __before
= __position
;
1327 if (__position
._M_node
== _M_leftmost()) // begin()
1328 return _M_insert_(_M_leftmost(), _M_leftmost(),
1329 _GLIBCXX_FORWARD(_Arg
, __v
));
1330 else if (_M_impl
._M_key_compare(_S_key((--__before
)._M_node
),
1331 _KeyOfValue()(__v
)))
1333 if (_S_right(__before
._M_node
) == 0)
1334 return _M_insert_(0, __before
._M_node
,
1335 _GLIBCXX_FORWARD(_Arg
, __v
));
1337 return _M_insert_(__position
._M_node
,
1339 _GLIBCXX_FORWARD(_Arg
, __v
));
1342 return _M_insert_unique(_GLIBCXX_FORWARD(_Arg
, __v
)).first
;
1344 else if (_M_impl
._M_key_compare(_S_key(__position
._M_node
),
1345 _KeyOfValue()(__v
)))
1347 // ... then try after.
1348 const_iterator __after
= __position
;
1349 if (__position
._M_node
== _M_rightmost())
1350 return _M_insert_(0, _M_rightmost(),
1351 _GLIBCXX_FORWARD(_Arg
, __v
));
1352 else if (_M_impl
._M_key_compare(_KeyOfValue()(__v
),
1353 _S_key((++__after
)._M_node
)))
1355 if (_S_right(__position
._M_node
) == 0)
1356 return _M_insert_(0, __position
._M_node
,
1357 _GLIBCXX_FORWARD(_Arg
, __v
));
1359 return _M_insert_(__after
._M_node
, __after
._M_node
,
1360 _GLIBCXX_FORWARD(_Arg
, __v
));
1363 return _M_insert_unique(_GLIBCXX_FORWARD(_Arg
, __v
)).first
;
1367 return __position
._M_const_cast();
1370 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1371 typename _Compare
, typename _Alloc
>
1372 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1373 template<typename _Arg
>
1375 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1376 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1377 #ifdef __GXX_EXPERIMENTAL_CXX0X__
1378 _M_insert_equal_(const_iterator __position
, _Arg
&& __v
)
1380 _M_insert_equal_(const_iterator __position
, const _Val
& __v
)
1384 if (__position
._M_node
== _M_end())
1387 && !_M_impl
._M_key_compare(_KeyOfValue()(__v
),
1388 _S_key(_M_rightmost())))
1389 return _M_insert_(0, _M_rightmost(),
1390 _GLIBCXX_FORWARD(_Arg
, __v
));
1392 return _M_insert_equal(_GLIBCXX_FORWARD(_Arg
, __v
));
1394 else if (!_M_impl
._M_key_compare(_S_key(__position
._M_node
),
1395 _KeyOfValue()(__v
)))
1397 // First, try before...
1398 const_iterator __before
= __position
;
1399 if (__position
._M_node
== _M_leftmost()) // begin()
1400 return _M_insert_(_M_leftmost(), _M_leftmost(),
1401 _GLIBCXX_FORWARD(_Arg
, __v
));
1402 else if (!_M_impl
._M_key_compare(_KeyOfValue()(__v
),
1403 _S_key((--__before
)._M_node
)))
1405 if (_S_right(__before
._M_node
) == 0)
1406 return _M_insert_(0, __before
._M_node
,
1407 _GLIBCXX_FORWARD(_Arg
, __v
));
1409 return _M_insert_(__position
._M_node
,
1411 _GLIBCXX_FORWARD(_Arg
, __v
));
1414 return _M_insert_equal(_GLIBCXX_FORWARD(_Arg
, __v
));
1418 // ... then try after.
1419 const_iterator __after
= __position
;
1420 if (__position
._M_node
== _M_rightmost())
1421 return _M_insert_(0, _M_rightmost(),
1422 _GLIBCXX_FORWARD(_Arg
, __v
));
1423 else if (!_M_impl
._M_key_compare(_S_key((++__after
)._M_node
),
1424 _KeyOfValue()(__v
)))
1426 if (_S_right(__position
._M_node
) == 0)
1427 return _M_insert_(0, __position
._M_node
,
1428 _GLIBCXX_FORWARD(_Arg
, __v
));
1430 return _M_insert_(__after
._M_node
, __after
._M_node
,
1431 _GLIBCXX_FORWARD(_Arg
, __v
));
1434 return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg
, __v
));
1438 template<typename _Key
, typename _Val
, typename _KoV
,
1439 typename _Cmp
, typename _Alloc
>
1442 _Rb_tree
<_Key
, _Val
, _KoV
, _Cmp
, _Alloc
>::
1443 _M_insert_unique(_II __first
, _II __last
)
1445 for (; __first
!= __last
; ++__first
)
1446 _M_insert_unique_(end(), *__first
);
1449 template<typename _Key
, typename _Val
, typename _KoV
,
1450 typename _Cmp
, typename _Alloc
>
1453 _Rb_tree
<_Key
, _Val
, _KoV
, _Cmp
, _Alloc
>::
1454 _M_insert_equal(_II __first
, _II __last
)
1456 for (; __first
!= __last
; ++__first
)
1457 _M_insert_equal_(end(), *__first
);
1460 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1461 typename _Compare
, typename _Alloc
>
1463 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1464 _M_erase_aux(const_iterator __position
)
1467 static_cast<_Link_type
>(_Rb_tree_rebalance_for_erase
1468 (const_cast<_Base_ptr
>(__position
._M_node
),
1469 this->_M_impl
._M_header
));
1470 _M_destroy_node(__y
);
1471 --_M_impl
._M_node_count
;
1474 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1475 typename _Compare
, typename _Alloc
>
1477 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1478 _M_erase_aux(const_iterator __first
, const_iterator __last
)
1480 if (__first
== begin() && __last
== end())
1483 while (__first
!= __last
)
1487 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1488 typename _Compare
, typename _Alloc
>
1489 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::size_type
1490 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1491 erase(const _Key
& __x
)
1493 pair
<iterator
, iterator
> __p
= equal_range(__x
);
1494 const size_type __old_size
= size();
1495 erase(__p
.first
, __p
.second
);
1496 return __old_size
- size();
1499 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1500 typename _Compare
, typename _Alloc
>
1502 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1503 erase(const _Key
* __first
, const _Key
* __last
)
1505 while (__first
!= __last
)
1509 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1510 typename _Compare
, typename _Alloc
>
1511 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1512 _Compare
, _Alloc
>::iterator
1513 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1514 find(const _Key
& __k
)
1516 iterator __j
= _M_lower_bound(_M_begin(), _M_end(), __k
);
1517 return (__j
== end()
1518 || _M_impl
._M_key_compare(__k
,
1519 _S_key(__j
._M_node
))) ? end() : __j
;
1522 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1523 typename _Compare
, typename _Alloc
>
1524 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1525 _Compare
, _Alloc
>::const_iterator
1526 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1527 find(const _Key
& __k
) const
1529 const_iterator __j
= _M_lower_bound(_M_begin(), _M_end(), __k
);
1530 return (__j
== end()
1531 || _M_impl
._M_key_compare(__k
,
1532 _S_key(__j
._M_node
))) ? end() : __j
;
1535 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1536 typename _Compare
, typename _Alloc
>
1537 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::size_type
1538 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1539 count(const _Key
& __k
) const
1541 pair
<const_iterator
, const_iterator
> __p
= equal_range(__k
);
1542 const size_type __n
= std::distance(__p
.first
, __p
.second
);
1546 _GLIBCXX_PURE
unsigned int
1547 _Rb_tree_black_count(const _Rb_tree_node_base
* __node
,
1548 const _Rb_tree_node_base
* __root
) throw ();
1550 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1551 typename _Compare
, typename _Alloc
>
1553 _Rb_tree
<_Key
,_Val
,_KeyOfValue
,_Compare
,_Alloc
>::__rb_verify() const
1555 if (_M_impl
._M_node_count
== 0 || begin() == end())
1556 return _M_impl
._M_node_count
== 0 && begin() == end()
1557 && this->_M_impl
._M_header
._M_left
== _M_end()
1558 && this->_M_impl
._M_header
._M_right
== _M_end();
1560 unsigned int __len
= _Rb_tree_black_count(_M_leftmost(), _M_root());
1561 for (const_iterator __it
= begin(); __it
!= end(); ++__it
)
1563 _Const_Link_type __x
= static_cast<_Const_Link_type
>(__it
._M_node
);
1564 _Const_Link_type __L
= _S_left(__x
);
1565 _Const_Link_type __R
= _S_right(__x
);
1567 if (__x
->_M_color
== _S_red
)
1568 if ((__L
&& __L
->_M_color
== _S_red
)
1569 || (__R
&& __R
->_M_color
== _S_red
))
1572 if (__L
&& _M_impl
._M_key_compare(_S_key(__x
), _S_key(__L
)))
1574 if (__R
&& _M_impl
._M_key_compare(_S_key(__R
), _S_key(__x
)))
1577 if (!__L
&& !__R
&& _Rb_tree_black_count(__x
, _M_root()) != __len
)
1581 if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
1583 if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
1588 _GLIBCXX_END_NAMESPACE