1 // RB tree implementation -*- C++ -*-
3 // Copyright (C) 2001-2015 Free Software Foundation, Inc.
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 3, or (at your option)
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 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
27 * Copyright (c) 1996,1997
28 * Silicon Graphics Computer Systems, Inc.
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Silicon Graphics makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
40 * Hewlett-Packard Company
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Hewlett-Packard Company makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
53 /** @file bits/stl_tree.h
54 * This is an internal header file, included by other library headers.
55 * Do not attempt to use it directly. @headername{map,set}
61 #pragma GCC system_header
63 #include <bits/stl_algobase.h>
64 #include <bits/allocator.h>
65 #include <bits/stl_function.h>
66 #include <bits/cpp_type_traits.h>
67 #include <ext/alloc_traits.h>
68 #if __cplusplus >= 201103L
69 #include <ext/aligned_buffer.h>
72 namespace std
_GLIBCXX_VISIBILITY(default)
74 _GLIBCXX_BEGIN_NAMESPACE_VERSION
76 // Red-black tree class, designed for use in implementing STL
77 // associative containers (set, multiset, map, and multimap). The
78 // insertion and deletion algorithms are based on those in Cormen,
79 // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
82 // (1) the header cell is maintained with links not only to the root
83 // but also to the leftmost node of the tree, to enable constant
84 // time begin(), and to the rightmost node of the tree, to enable
85 // linear time performance when used with the generic set algorithms
88 // (2) when a node being deleted has two children its successor node
89 // is relinked into its place, rather than copied, so that the only
90 // iterators invalidated are those referring to the deleted node.
92 enum _Rb_tree_color
{ _S_red
= false, _S_black
= true };
94 struct _Rb_tree_node_base
96 typedef _Rb_tree_node_base
* _Base_ptr
;
97 typedef const _Rb_tree_node_base
* _Const_Base_ptr
;
99 _Rb_tree_color _M_color
;
105 _S_minimum(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
107 while (__x
->_M_left
!= 0) __x
= __x
->_M_left
;
111 static _Const_Base_ptr
112 _S_minimum(_Const_Base_ptr __x
) _GLIBCXX_NOEXCEPT
114 while (__x
->_M_left
!= 0) __x
= __x
->_M_left
;
119 _S_maximum(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
121 while (__x
->_M_right
!= 0) __x
= __x
->_M_right
;
125 static _Const_Base_ptr
126 _S_maximum(_Const_Base_ptr __x
) _GLIBCXX_NOEXCEPT
128 while (__x
->_M_right
!= 0) __x
= __x
->_M_right
;
133 template<typename _Val
>
134 struct _Rb_tree_node
: public _Rb_tree_node_base
136 typedef _Rb_tree_node
<_Val
>* _Link_type
;
138 #if __cplusplus < 201103L
143 { return std::__addressof(_M_value_field
); }
147 { return std::__addressof(_M_value_field
); }
149 __gnu_cxx::__aligned_membuf
<_Val
> _M_storage
;
153 { return _M_storage
._M_ptr(); }
157 { return _M_storage
._M_ptr(); }
161 _GLIBCXX_PURE _Rb_tree_node_base
*
162 _Rb_tree_increment(_Rb_tree_node_base
* __x
) throw ();
164 _GLIBCXX_PURE
const _Rb_tree_node_base
*
165 _Rb_tree_increment(const _Rb_tree_node_base
* __x
) throw ();
167 _GLIBCXX_PURE _Rb_tree_node_base
*
168 _Rb_tree_decrement(_Rb_tree_node_base
* __x
) throw ();
170 _GLIBCXX_PURE
const _Rb_tree_node_base
*
171 _Rb_tree_decrement(const _Rb_tree_node_base
* __x
) throw ();
173 template<typename _Tp
>
174 struct _Rb_tree_iterator
176 typedef _Tp value_type
;
177 typedef _Tp
& reference
;
178 typedef _Tp
* pointer
;
180 typedef bidirectional_iterator_tag iterator_category
;
181 typedef ptrdiff_t difference_type
;
183 typedef _Rb_tree_iterator
<_Tp
> _Self
;
184 typedef _Rb_tree_node_base::_Base_ptr _Base_ptr
;
185 typedef _Rb_tree_node
<_Tp
>* _Link_type
;
187 _Rb_tree_iterator() _GLIBCXX_NOEXCEPT
191 _Rb_tree_iterator(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
195 operator*() const _GLIBCXX_NOEXCEPT
196 { return *static_cast<_Link_type
>(_M_node
)->_M_valptr(); }
199 operator->() const _GLIBCXX_NOEXCEPT
200 { return static_cast<_Link_type
> (_M_node
)->_M_valptr(); }
203 operator++() _GLIBCXX_NOEXCEPT
205 _M_node
= _Rb_tree_increment(_M_node
);
210 operator++(int) _GLIBCXX_NOEXCEPT
213 _M_node
= _Rb_tree_increment(_M_node
);
218 operator--() _GLIBCXX_NOEXCEPT
220 _M_node
= _Rb_tree_decrement(_M_node
);
225 operator--(int) _GLIBCXX_NOEXCEPT
228 _M_node
= _Rb_tree_decrement(_M_node
);
233 operator==(const _Self
& __x
) const _GLIBCXX_NOEXCEPT
234 { return _M_node
== __x
._M_node
; }
237 operator!=(const _Self
& __x
) const _GLIBCXX_NOEXCEPT
238 { return _M_node
!= __x
._M_node
; }
243 template<typename _Tp
>
244 struct _Rb_tree_const_iterator
246 typedef _Tp value_type
;
247 typedef const _Tp
& reference
;
248 typedef const _Tp
* pointer
;
250 typedef _Rb_tree_iterator
<_Tp
> iterator
;
252 typedef bidirectional_iterator_tag iterator_category
;
253 typedef ptrdiff_t difference_type
;
255 typedef _Rb_tree_const_iterator
<_Tp
> _Self
;
256 typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr
;
257 typedef const _Rb_tree_node
<_Tp
>* _Link_type
;
259 _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT
263 _Rb_tree_const_iterator(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
266 _Rb_tree_const_iterator(const iterator
& __it
) _GLIBCXX_NOEXCEPT
267 : _M_node(__it
._M_node
) { }
270 _M_const_cast() const _GLIBCXX_NOEXCEPT
271 { return iterator(const_cast<typename
iterator::_Base_ptr
>(_M_node
)); }
274 operator*() const _GLIBCXX_NOEXCEPT
275 { return *static_cast<_Link_type
>(_M_node
)->_M_valptr(); }
278 operator->() const _GLIBCXX_NOEXCEPT
279 { return static_cast<_Link_type
>(_M_node
)->_M_valptr(); }
282 operator++() _GLIBCXX_NOEXCEPT
284 _M_node
= _Rb_tree_increment(_M_node
);
289 operator++(int) _GLIBCXX_NOEXCEPT
292 _M_node
= _Rb_tree_increment(_M_node
);
297 operator--() _GLIBCXX_NOEXCEPT
299 _M_node
= _Rb_tree_decrement(_M_node
);
304 operator--(int) _GLIBCXX_NOEXCEPT
307 _M_node
= _Rb_tree_decrement(_M_node
);
312 operator==(const _Self
& __x
) const _GLIBCXX_NOEXCEPT
313 { return _M_node
== __x
._M_node
; }
316 operator!=(const _Self
& __x
) const _GLIBCXX_NOEXCEPT
317 { return _M_node
!= __x
._M_node
; }
322 template<typename _Val
>
324 operator==(const _Rb_tree_iterator
<_Val
>& __x
,
325 const _Rb_tree_const_iterator
<_Val
>& __y
) _GLIBCXX_NOEXCEPT
326 { return __x
._M_node
== __y
._M_node
; }
328 template<typename _Val
>
330 operator!=(const _Rb_tree_iterator
<_Val
>& __x
,
331 const _Rb_tree_const_iterator
<_Val
>& __y
) _GLIBCXX_NOEXCEPT
332 { return __x
._M_node
!= __y
._M_node
; }
335 _Rb_tree_insert_and_rebalance(const bool __insert_left
,
336 _Rb_tree_node_base
* __x
,
337 _Rb_tree_node_base
* __p
,
338 _Rb_tree_node_base
& __header
) throw ();
341 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base
* const __z
,
342 _Rb_tree_node_base
& __header
) throw ();
345 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
346 typename _Compare
, typename _Alloc
= allocator
<_Val
> >
349 typedef typename
__gnu_cxx::__alloc_traits
<_Alloc
>::template
350 rebind
<_Rb_tree_node
<_Val
> >::other _Node_allocator
;
352 typedef __gnu_cxx::__alloc_traits
<_Node_allocator
> _Alloc_traits
;
355 typedef _Rb_tree_node_base
* _Base_ptr
;
356 typedef const _Rb_tree_node_base
* _Const_Base_ptr
;
357 typedef _Rb_tree_node
<_Val
>* _Link_type
;
358 typedef const _Rb_tree_node
<_Val
>* _Const_Link_type
;
361 // Functor recycling a pool of nodes and using allocation once the pool
363 struct _Reuse_or_alloc_node
365 _Reuse_or_alloc_node(_Rb_tree
& __t
)
366 : _M_root(__t
._M_root()), _M_nodes(__t
._M_rightmost()), _M_t(__t
)
370 _M_root
->_M_parent
= 0;
372 if (_M_nodes
->_M_left
)
373 _M_nodes
= _M_nodes
->_M_left
;
379 #if __cplusplus >= 201103L
380 _Reuse_or_alloc_node(const _Reuse_or_alloc_node
&) = delete;
383 ~_Reuse_or_alloc_node()
384 { _M_t
._M_erase(static_cast<_Link_type
>(_M_root
)); }
386 template<typename _Arg
>
388 #if __cplusplus < 201103L
389 operator()(const _Arg
& __arg
)
391 operator()(_Arg
&& __arg
)
394 _Link_type __node
= static_cast<_Link_type
>(_M_extract());
397 _M_t
._M_destroy_node(__node
);
398 _M_t
._M_construct_node(__node
, _GLIBCXX_FORWARD(_Arg
, __arg
));
402 return _M_t
._M_create_node(_GLIBCXX_FORWARD(_Arg
, __arg
));
412 _Base_ptr __node
= _M_nodes
;
413 _M_nodes
= _M_nodes
->_M_parent
;
416 if (_M_nodes
->_M_right
== __node
)
418 _M_nodes
->_M_right
= 0;
420 if (_M_nodes
->_M_left
)
422 _M_nodes
= _M_nodes
->_M_left
;
424 while (_M_nodes
->_M_right
)
425 _M_nodes
= _M_nodes
->_M_right
;
427 if (_M_nodes
->_M_left
)
428 _M_nodes
= _M_nodes
->_M_left
;
431 else // __node is on the left.
432 _M_nodes
->_M_left
= 0;
445 // Functor similar to the previous one but without any pool of nodes to
449 _Alloc_node(_Rb_tree
& __t
)
452 template<typename _Arg
>
454 #if __cplusplus < 201103L
455 operator()(const _Arg
& __arg
) const
457 operator()(_Arg
&& __arg
) const
459 { return _M_t
._M_create_node(_GLIBCXX_FORWARD(_Arg
, __arg
)); }
466 typedef _Key key_type
;
467 typedef _Val value_type
;
468 typedef value_type
* pointer
;
469 typedef const value_type
* const_pointer
;
470 typedef value_type
& reference
;
471 typedef const value_type
& const_reference
;
472 typedef size_t size_type
;
473 typedef ptrdiff_t difference_type
;
474 typedef _Alloc allocator_type
;
477 _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
478 { return *static_cast<_Node_allocator
*>(&this->_M_impl
); }
480 const _Node_allocator
&
481 _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
482 { return *static_cast<const _Node_allocator
*>(&this->_M_impl
); }
485 get_allocator() const _GLIBCXX_NOEXCEPT
486 { return allocator_type(_M_get_Node_allocator()); }
491 { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
494 _M_put_node(_Link_type __p
) _GLIBCXX_NOEXCEPT
495 { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p
, 1); }
497 #if __cplusplus < 201103L
499 _M_construct_node(_Link_type __node
, const value_type
& __x
)
502 { get_allocator().construct(__node
->_M_valptr(), __x
); }
506 __throw_exception_again
;
511 _M_create_node(const value_type
& __x
)
513 _Link_type __tmp
= _M_get_node();
514 _M_construct_node(__tmp
, __x
);
519 _M_destroy_node(_Link_type __p
)
520 { get_allocator().destroy(__p
->_M_valptr()); }
522 template<typename
... _Args
>
524 _M_construct_node(_Link_type __node
, _Args
&&... __args
)
528 ::new(__node
) _Rb_tree_node
<_Val
>;
529 _Alloc_traits::construct(_M_get_Node_allocator(),
531 std::forward
<_Args
>(__args
)...);
535 __node
->~_Rb_tree_node
<_Val
>();
537 __throw_exception_again
;
541 template<typename
... _Args
>
543 _M_create_node(_Args
&&... __args
)
545 _Link_type __tmp
= _M_get_node();
546 _M_construct_node(__tmp
, std::forward
<_Args
>(__args
)...);
551 _M_destroy_node(_Link_type __p
) noexcept
553 _Alloc_traits::destroy(_M_get_Node_allocator(), __p
->_M_valptr());
554 __p
->~_Rb_tree_node
<_Val
>();
559 _M_drop_node(_Link_type __p
) _GLIBCXX_NOEXCEPT
561 _M_destroy_node(__p
);
565 template<typename _NodeGen
>
567 _M_clone_node(_Const_Link_type __x
, _NodeGen
& __node_gen
)
569 _Link_type __tmp
= __node_gen(*__x
->_M_valptr());
570 __tmp
->_M_color
= __x
->_M_color
;
577 // Unused _Is_pod_comparator is kept as it is part of mangled name.
578 template<typename _Key_compare
,
579 bool /* _Is_pod_comparator */ = __is_pod(_Key_compare
)>
580 struct _Rb_tree_impl
: public _Node_allocator
582 _Key_compare _M_key_compare
;
583 _Rb_tree_node_base _M_header
;
584 size_type _M_node_count
; // Keeps track of size of tree.
587 : _Node_allocator(), _M_key_compare(), _M_header(),
591 _Rb_tree_impl(const _Key_compare
& __comp
, const _Node_allocator
& __a
)
592 : _Node_allocator(__a
), _M_key_compare(__comp
), _M_header(),
596 #if __cplusplus >= 201103L
597 _Rb_tree_impl(const _Key_compare
& __comp
, _Node_allocator
&& __a
)
598 : _Node_allocator(std::move(__a
)), _M_key_compare(__comp
),
599 _M_header(), _M_node_count(0)
606 this->_M_header
._M_parent
= 0;
607 this->_M_header
._M_left
= &this->_M_header
;
608 this->_M_header
._M_right
= &this->_M_header
;
609 this->_M_node_count
= 0;
616 this->_M_header
._M_color
= _S_red
;
617 this->_M_header
._M_parent
= 0;
618 this->_M_header
._M_left
= &this->_M_header
;
619 this->_M_header
._M_right
= &this->_M_header
;
623 _Rb_tree_impl
<_Compare
> _M_impl
;
627 _M_root() _GLIBCXX_NOEXCEPT
628 { return this->_M_impl
._M_header
._M_parent
; }
631 _M_root() const _GLIBCXX_NOEXCEPT
632 { return this->_M_impl
._M_header
._M_parent
; }
635 _M_leftmost() _GLIBCXX_NOEXCEPT
636 { return this->_M_impl
._M_header
._M_left
; }
639 _M_leftmost() const _GLIBCXX_NOEXCEPT
640 { return this->_M_impl
._M_header
._M_left
; }
643 _M_rightmost() _GLIBCXX_NOEXCEPT
644 { return this->_M_impl
._M_header
._M_right
; }
647 _M_rightmost() const _GLIBCXX_NOEXCEPT
648 { return this->_M_impl
._M_header
._M_right
; }
651 _M_begin() _GLIBCXX_NOEXCEPT
652 { return static_cast<_Link_type
>(this->_M_impl
._M_header
._M_parent
); }
655 _M_begin() const _GLIBCXX_NOEXCEPT
657 return static_cast<_Const_Link_type
>
658 (this->_M_impl
._M_header
._M_parent
);
662 _M_end() _GLIBCXX_NOEXCEPT
663 { return &this->_M_impl
._M_header
; }
666 _M_end() const _GLIBCXX_NOEXCEPT
667 { return &this->_M_impl
._M_header
; }
669 static const_reference
670 _S_value(_Const_Link_type __x
)
671 { return *__x
->_M_valptr(); }
674 _S_key(_Const_Link_type __x
)
675 { return _KeyOfValue()(_S_value(__x
)); }
678 _S_left(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
679 { return static_cast<_Link_type
>(__x
->_M_left
); }
681 static _Const_Link_type
682 _S_left(_Const_Base_ptr __x
) _GLIBCXX_NOEXCEPT
683 { return static_cast<_Const_Link_type
>(__x
->_M_left
); }
686 _S_right(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
687 { return static_cast<_Link_type
>(__x
->_M_right
); }
689 static _Const_Link_type
690 _S_right(_Const_Base_ptr __x
) _GLIBCXX_NOEXCEPT
691 { return static_cast<_Const_Link_type
>(__x
->_M_right
); }
693 static const_reference
694 _S_value(_Const_Base_ptr __x
)
695 { return *static_cast<_Const_Link_type
>(__x
)->_M_valptr(); }
698 _S_key(_Const_Base_ptr __x
)
699 { return _KeyOfValue()(_S_value(__x
)); }
702 _S_minimum(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
703 { return _Rb_tree_node_base::_S_minimum(__x
); }
705 static _Const_Base_ptr
706 _S_minimum(_Const_Base_ptr __x
) _GLIBCXX_NOEXCEPT
707 { return _Rb_tree_node_base::_S_minimum(__x
); }
710 _S_maximum(_Base_ptr __x
) _GLIBCXX_NOEXCEPT
711 { return _Rb_tree_node_base::_S_maximum(__x
); }
713 static _Const_Base_ptr
714 _S_maximum(_Const_Base_ptr __x
) _GLIBCXX_NOEXCEPT
715 { return _Rb_tree_node_base::_S_maximum(__x
); }
718 typedef _Rb_tree_iterator
<value_type
> iterator
;
719 typedef _Rb_tree_const_iterator
<value_type
> const_iterator
;
721 typedef std::reverse_iterator
<iterator
> reverse_iterator
;
722 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
725 pair
<_Base_ptr
, _Base_ptr
>
726 _M_get_insert_unique_pos(const key_type
& __k
);
728 pair
<_Base_ptr
, _Base_ptr
>
729 _M_get_insert_equal_pos(const key_type
& __k
);
731 pair
<_Base_ptr
, _Base_ptr
>
732 _M_get_insert_hint_unique_pos(const_iterator __pos
,
733 const key_type
& __k
);
735 pair
<_Base_ptr
, _Base_ptr
>
736 _M_get_insert_hint_equal_pos(const_iterator __pos
,
737 const key_type
& __k
);
739 #if __cplusplus >= 201103L
740 template<typename _Arg
, typename _NodeGen
>
742 _M_insert_(_Base_ptr __x
, _Base_ptr __y
, _Arg
&& __v
, _NodeGen
&);
745 _M_insert_node(_Base_ptr __x
, _Base_ptr __y
, _Link_type __z
);
747 template<typename _Arg
>
749 _M_insert_lower(_Base_ptr __y
, _Arg
&& __v
);
751 template<typename _Arg
>
753 _M_insert_equal_lower(_Arg
&& __x
);
756 _M_insert_lower_node(_Base_ptr __p
, _Link_type __z
);
759 _M_insert_equal_lower_node(_Link_type __z
);
761 template<typename _NodeGen
>
763 _M_insert_(_Base_ptr __x
, _Base_ptr __y
,
764 const value_type
& __v
, _NodeGen
&);
766 // _GLIBCXX_RESOLVE_LIB_DEFECTS
767 // 233. Insertion hints in associative containers.
769 _M_insert_lower(_Base_ptr __y
, const value_type
& __v
);
772 _M_insert_equal_lower(const value_type
& __x
);
775 template<typename _NodeGen
>
777 _M_copy(_Const_Link_type __x
, _Base_ptr __p
, _NodeGen
&);
780 _M_copy(_Const_Link_type __x
, _Base_ptr __p
)
782 _Alloc_node
__an(*this);
783 return _M_copy(__x
, __p
, __an
);
787 _M_erase(_Link_type __x
);
790 _M_lower_bound(_Link_type __x
, _Base_ptr __y
,
794 _M_lower_bound(_Const_Link_type __x
, _Const_Base_ptr __y
,
795 const _Key
& __k
) const;
798 _M_upper_bound(_Link_type __x
, _Base_ptr __y
,
802 _M_upper_bound(_Const_Link_type __x
, _Const_Base_ptr __y
,
803 const _Key
& __k
) const;
806 // allocation/deallocation
809 _Rb_tree(const _Compare
& __comp
,
810 const allocator_type
& __a
= allocator_type())
811 : _M_impl(__comp
, _Node_allocator(__a
)) { }
813 _Rb_tree(const _Rb_tree
& __x
)
814 : _M_impl(__x
._M_impl
._M_key_compare
,
815 _Alloc_traits::_S_select_on_copy(__x
._M_get_Node_allocator()))
817 if (__x
._M_root() != 0)
819 _M_root() = _M_copy(__x
._M_begin(), _M_end());
820 _M_leftmost() = _S_minimum(_M_root());
821 _M_rightmost() = _S_maximum(_M_root());
822 _M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
826 #if __cplusplus >= 201103L
827 _Rb_tree(const allocator_type
& __a
)
828 : _M_impl(_Compare(), _Node_allocator(__a
))
831 _Rb_tree(const _Rb_tree
& __x
, const allocator_type
& __a
)
832 : _M_impl(__x
._M_impl
._M_key_compare
, _Node_allocator(__a
))
834 if (__x
._M_root() != nullptr)
836 _M_root() = _M_copy(__x
._M_begin(), _M_end());
837 _M_leftmost() = _S_minimum(_M_root());
838 _M_rightmost() = _S_maximum(_M_root());
839 _M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
843 _Rb_tree(_Rb_tree
&& __x
)
844 : _M_impl(__x
._M_impl
._M_key_compare
, __x
._M_get_Node_allocator())
846 if (__x
._M_root() != 0)
847 _M_move_data(__x
, std::true_type());
850 _Rb_tree(_Rb_tree
&& __x
, const allocator_type
& __a
)
851 : _Rb_tree(std::move(__x
), _Node_allocator(__a
))
854 _Rb_tree(_Rb_tree
&& __x
, _Node_allocator
&& __a
);
857 ~_Rb_tree() _GLIBCXX_NOEXCEPT
858 { _M_erase(_M_begin()); }
861 operator=(const _Rb_tree
& __x
);
866 { return _M_impl
._M_key_compare
; }
869 begin() _GLIBCXX_NOEXCEPT
870 { return iterator(this->_M_impl
._M_header
._M_left
); }
873 begin() const _GLIBCXX_NOEXCEPT
874 { return const_iterator(this->_M_impl
._M_header
._M_left
); }
877 end() _GLIBCXX_NOEXCEPT
878 { return iterator(&this->_M_impl
._M_header
); }
881 end() const _GLIBCXX_NOEXCEPT
882 { return const_iterator(&this->_M_impl
._M_header
); }
885 rbegin() _GLIBCXX_NOEXCEPT
886 { return reverse_iterator(end()); }
888 const_reverse_iterator
889 rbegin() const _GLIBCXX_NOEXCEPT
890 { return const_reverse_iterator(end()); }
893 rend() _GLIBCXX_NOEXCEPT
894 { return reverse_iterator(begin()); }
896 const_reverse_iterator
897 rend() const _GLIBCXX_NOEXCEPT
898 { return const_reverse_iterator(begin()); }
901 empty() const _GLIBCXX_NOEXCEPT
902 { return _M_impl
._M_node_count
== 0; }
905 size() const _GLIBCXX_NOEXCEPT
906 { return _M_impl
._M_node_count
; }
909 max_size() const _GLIBCXX_NOEXCEPT
910 { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
913 #if __cplusplus >= 201103L
914 swap(_Rb_tree
& __t
) noexcept(_Alloc_traits::_S_nothrow_swap());
920 #if __cplusplus >= 201103L
921 template<typename _Arg
>
923 _M_insert_unique(_Arg
&& __x
);
925 template<typename _Arg
>
927 _M_insert_equal(_Arg
&& __x
);
929 template<typename _Arg
, typename _NodeGen
>
931 _M_insert_unique_(const_iterator __pos
, _Arg
&& __x
, _NodeGen
&);
933 template<typename _Arg
>
935 _M_insert_unique_(const_iterator __pos
, _Arg
&& __x
)
937 _Alloc_node
__an(*this);
938 return _M_insert_unique_(__pos
, std::forward
<_Arg
>(__x
), __an
);
941 template<typename _Arg
, typename _NodeGen
>
943 _M_insert_equal_(const_iterator __pos
, _Arg
&& __x
, _NodeGen
&);
945 template<typename _Arg
>
947 _M_insert_equal_(const_iterator __pos
, _Arg
&& __x
)
949 _Alloc_node
__an(*this);
950 return _M_insert_equal_(__pos
, std::forward
<_Arg
>(__x
), __an
);
953 template<typename
... _Args
>
955 _M_emplace_unique(_Args
&&... __args
);
957 template<typename
... _Args
>
959 _M_emplace_equal(_Args
&&... __args
);
961 template<typename
... _Args
>
963 _M_emplace_hint_unique(const_iterator __pos
, _Args
&&... __args
);
965 template<typename
... _Args
>
967 _M_emplace_hint_equal(const_iterator __pos
, _Args
&&... __args
);
970 _M_insert_unique(const value_type
& __x
);
973 _M_insert_equal(const value_type
& __x
);
975 template<typename _NodeGen
>
977 _M_insert_unique_(const_iterator __pos
, const value_type
& __x
,
981 _M_insert_unique_(const_iterator __pos
, const value_type
& __x
)
983 _Alloc_node
__an(*this);
984 return _M_insert_unique_(__pos
, __x
, __an
);
987 template<typename _NodeGen
>
989 _M_insert_equal_(const_iterator __pos
, const value_type
& __x
,
992 _M_insert_equal_(const_iterator __pos
, const value_type
& __x
)
994 _Alloc_node
__an(*this);
995 return _M_insert_equal_(__pos
, __x
, __an
);
999 template<typename _InputIterator
>
1001 _M_insert_unique(_InputIterator __first
, _InputIterator __last
);
1003 template<typename _InputIterator
>
1005 _M_insert_equal(_InputIterator __first
, _InputIterator __last
);
1009 _M_erase_aux(const_iterator __position
);
1012 _M_erase_aux(const_iterator __first
, const_iterator __last
);
1015 #if __cplusplus >= 201103L
1016 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1017 // DR 130. Associative erase should return an iterator.
1018 _GLIBCXX_ABI_TAG_CXX11
1020 erase(const_iterator __position
)
1022 const_iterator __result
= __position
;
1024 _M_erase_aux(__position
);
1025 return __result
._M_const_cast();
1029 _GLIBCXX_ABI_TAG_CXX11
1031 erase(iterator __position
)
1033 iterator __result
= __position
;
1035 _M_erase_aux(__position
);
1040 erase(iterator __position
)
1041 { _M_erase_aux(__position
); }
1044 erase(const_iterator __position
)
1045 { _M_erase_aux(__position
); }
1048 erase(const key_type
& __x
);
1050 #if __cplusplus >= 201103L
1051 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1052 // DR 130. Associative erase should return an iterator.
1053 _GLIBCXX_ABI_TAG_CXX11
1055 erase(const_iterator __first
, const_iterator __last
)
1057 _M_erase_aux(__first
, __last
);
1058 return __last
._M_const_cast();
1062 erase(iterator __first
, iterator __last
)
1063 { _M_erase_aux(__first
, __last
); }
1066 erase(const_iterator __first
, const_iterator __last
)
1067 { _M_erase_aux(__first
, __last
); }
1070 erase(const key_type
* __first
, const key_type
* __last
);
1073 clear() _GLIBCXX_NOEXCEPT
1075 _M_erase(_M_begin());
1081 find(const key_type
& __k
);
1084 find(const key_type
& __k
) const;
1087 count(const key_type
& __k
) const;
1090 lower_bound(const key_type
& __k
)
1091 { return _M_lower_bound(_M_begin(), _M_end(), __k
); }
1094 lower_bound(const key_type
& __k
) const
1095 { return _M_lower_bound(_M_begin(), _M_end(), __k
); }
1098 upper_bound(const key_type
& __k
)
1099 { return _M_upper_bound(_M_begin(), _M_end(), __k
); }
1102 upper_bound(const key_type
& __k
) const
1103 { return _M_upper_bound(_M_begin(), _M_end(), __k
); }
1105 pair
<iterator
, iterator
>
1106 equal_range(const key_type
& __k
);
1108 pair
<const_iterator
, const_iterator
>
1109 equal_range(const key_type
& __k
) const;
1111 #if __cplusplus > 201103L
1112 template<typename _Cmp
, typename _Kt
, typename
= __void_t
<>>
1113 struct __is_transparent
{ };
1115 template<typename _Cmp
, typename _Kt
>
1117 __is_transparent
<_Cmp
, _Kt
, __void_t
<typename
_Cmp::is_transparent
>>
1118 { typedef void type
; };
1120 template<typename _Kt
,
1121 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1123 _M_find_tr(const _Kt
& __k
)
1125 const _Rb_tree
* __const_this
= this;
1126 return __const_this
->_M_find_tr(__k
)._M_const_cast();
1129 template<typename _Kt
,
1130 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1132 _M_find_tr(const _Kt
& __k
) const
1134 auto __j
= _M_lower_bound_tr(__k
);
1135 if (__j
!= end() && _M_impl
._M_key_compare(__k
, _S_key(__j
._M_node
)))
1140 template<typename _Kt
,
1141 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1143 _M_count_tr(const _Kt
& __k
) const
1145 auto __p
= _M_equal_range_tr(__k
);
1146 return std::distance(__p
.first
, __p
.second
);
1149 template<typename _Kt
,
1150 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1152 _M_lower_bound_tr(const _Kt
& __k
)
1154 const _Rb_tree
* __const_this
= this;
1155 return __const_this
->_M_lower_bound_tr(__k
)._M_const_cast();
1158 template<typename _Kt
,
1159 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1161 _M_lower_bound_tr(const _Kt
& __k
) const
1163 auto __x
= _M_begin();
1164 auto __y
= _M_end();
1166 if (!_M_impl
._M_key_compare(_S_key(__x
), __k
))
1172 __x
= _S_right(__x
);
1173 return const_iterator(__y
);
1176 template<typename _Kt
,
1177 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1179 _M_upper_bound_tr(const _Kt
& __k
)
1181 const _Rb_tree
* __const_this
= this;
1182 return __const_this
->_M_upper_bound_tr(__k
)._M_const_cast();
1185 template<typename _Kt
,
1186 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1188 _M_upper_bound_tr(const _Kt
& __k
) const
1190 auto __x
= _M_begin();
1191 auto __y
= _M_end();
1193 if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1199 __x
= _S_right(__x
);
1200 return const_iterator(__y
);
1203 template<typename _Kt
,
1204 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1205 pair
<iterator
, iterator
>
1206 _M_equal_range_tr(const _Kt
& __k
)
1208 const _Rb_tree
* __const_this
= this;
1209 auto __ret
= __const_this
->_M_equal_range_tr(__k
);
1210 return { __ret
.first
._M_const_cast(), __ret
.second
._M_const_cast() };
1213 template<typename _Kt
,
1214 typename _Req
= typename __is_transparent
<_Compare
, _Kt
>::type
>
1215 pair
<const_iterator
, const_iterator
>
1216 _M_equal_range_tr(const _Kt
& __k
) const
1218 auto __low
= _M_lower_bound_tr(__k
);
1219 auto __high
= __low
;
1220 auto& __cmp
= _M_impl
._M_key_compare
;
1221 while (__high
!= end() && !__cmp(__k
, _S_key(__high
._M_node
)))
1223 return { __low
, __high
};
1229 __rb_verify() const;
1231 #if __cplusplus >= 201103L
1233 operator=(_Rb_tree
&&) noexcept(_Alloc_traits::_S_nothrow_move());
1235 template<typename _Iterator
>
1237 _M_assign_unique(_Iterator
, _Iterator
);
1239 template<typename _Iterator
>
1241 _M_assign_equal(_Iterator
, _Iterator
);
1244 // Move elements from container with equal allocator.
1246 _M_move_data(_Rb_tree
&, std::true_type
);
1248 // Move elements from container with possibly non-equal allocator,
1249 // which might result in a copy not a move.
1251 _M_move_data(_Rb_tree
&, std::false_type
);
1255 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1256 typename _Compare
, typename _Alloc
>
1258 operator==(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
1259 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
1261 return __x
.size() == __y
.size()
1262 && std::equal(__x
.begin(), __x
.end(), __y
.begin());
1265 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1266 typename _Compare
, typename _Alloc
>
1268 operator<(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
1269 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
1271 return std::lexicographical_compare(__x
.begin(), __x
.end(),
1272 __y
.begin(), __y
.end());
1275 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1276 typename _Compare
, typename _Alloc
>
1278 operator!=(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
1279 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
1280 { return !(__x
== __y
); }
1282 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1283 typename _Compare
, typename _Alloc
>
1285 operator>(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
1286 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
1287 { return __y
< __x
; }
1289 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1290 typename _Compare
, typename _Alloc
>
1292 operator<=(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
1293 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
1294 { return !(__y
< __x
); }
1296 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1297 typename _Compare
, typename _Alloc
>
1299 operator>=(const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
1300 const _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
1301 { return !(__x
< __y
); }
1303 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1304 typename _Compare
, typename _Alloc
>
1306 swap(_Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __x
,
1307 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __y
)
1310 #if __cplusplus >= 201103L
1311 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1312 typename _Compare
, typename _Alloc
>
1313 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1314 _Rb_tree(_Rb_tree
&& __x
, _Node_allocator
&& __a
)
1315 : _M_impl(__x
._M_impl
._M_key_compare
, std::move(__a
))
1317 using __eq
= integral_constant
<bool, _Alloc_traits::_S_always_equal()>;
1318 if (__x
._M_root() != nullptr)
1319 _M_move_data(__x
, __eq());
1322 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1323 typename _Compare
, typename _Alloc
>
1325 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1326 _M_move_data(_Rb_tree
& __x
, std::true_type
)
1328 _M_root() = __x
._M_root();
1329 _M_leftmost() = __x
._M_leftmost();
1330 _M_rightmost() = __x
._M_rightmost();
1331 _M_root()->_M_parent
= _M_end();
1334 __x
._M_leftmost() = __x
._M_end();
1335 __x
._M_rightmost() = __x
._M_end();
1337 this->_M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
1338 __x
._M_impl
._M_node_count
= 0;
1341 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1342 typename _Compare
, typename _Alloc
>
1344 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1345 _M_move_data(_Rb_tree
& __x
, std::false_type
)
1347 if (_M_get_Node_allocator() == __x
._M_get_Node_allocator())
1348 _M_move_data(__x
, std::true_type());
1351 _Alloc_node
__an(*this);
1353 [&__an
](const value_type
& __cval
)
1355 auto& __val
= const_cast<value_type
&>(__cval
);
1356 return __an(std::move_if_noexcept(__val
));
1358 _M_root() = _M_copy(__x
._M_begin(), _M_end(), __lbd
);
1359 _M_leftmost() = _S_minimum(_M_root());
1360 _M_rightmost() = _S_maximum(_M_root());
1361 _M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
1365 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1366 typename _Compare
, typename _Alloc
>
1367 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>&
1368 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1369 operator=(_Rb_tree
&& __x
)
1370 noexcept(_Alloc_traits::_S_nothrow_move())
1372 _M_impl
._M_key_compare
= __x
._M_impl
._M_key_compare
;
1373 if (_Alloc_traits::_S_propagate_on_move_assign()
1374 || _Alloc_traits::_S_always_equal()
1375 || _M_get_Node_allocator() == __x
._M_get_Node_allocator())
1378 if (__x
._M_root() != nullptr)
1379 _M_move_data(__x
, std::true_type());
1380 std::__alloc_on_move(_M_get_Node_allocator(),
1381 __x
._M_get_Node_allocator());
1385 // Try to move each node reusing existing nodes and copying __x nodes
1387 _Reuse_or_alloc_node
__roan(*this);
1389 if (__x
._M_root() != nullptr)
1392 [&__roan
](const value_type
& __cval
)
1394 auto& __val
= const_cast<value_type
&>(__cval
);
1395 return __roan(std::move_if_noexcept(__val
));
1397 _M_root() = _M_copy(__x
._M_begin(), _M_end(), __lbd
);
1398 _M_leftmost() = _S_minimum(_M_root());
1399 _M_rightmost() = _S_maximum(_M_root());
1400 _M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
1406 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1407 typename _Compare
, typename _Alloc
>
1408 template<typename _Iterator
>
1410 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1411 _M_assign_unique(_Iterator __first
, _Iterator __last
)
1413 _Reuse_or_alloc_node
__roan(*this);
1415 for (; __first
!= __last
; ++__first
)
1416 _M_insert_unique_(end(), *__first
, __roan
);
1419 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1420 typename _Compare
, typename _Alloc
>
1421 template<typename _Iterator
>
1423 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1424 _M_assign_equal(_Iterator __first
, _Iterator __last
)
1426 _Reuse_or_alloc_node
__roan(*this);
1428 for (; __first
!= __last
; ++__first
)
1429 _M_insert_equal_(end(), *__first
, __roan
);
1433 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1434 typename _Compare
, typename _Alloc
>
1435 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>&
1436 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1437 operator=(const _Rb_tree
& __x
)
1441 // Note that _Key may be a constant type.
1442 #if __cplusplus >= 201103L
1443 if (_Alloc_traits::_S_propagate_on_copy_assign())
1445 auto& __this_alloc
= this->_M_get_Node_allocator();
1446 auto& __that_alloc
= __x
._M_get_Node_allocator();
1447 if (!_Alloc_traits::_S_always_equal()
1448 && __this_alloc
!= __that_alloc
)
1450 // Replacement allocator cannot free existing storage, we need
1451 // to erase nodes first.
1453 std::__alloc_on_copy(__this_alloc
, __that_alloc
);
1458 _Reuse_or_alloc_node
__roan(*this);
1460 _M_impl
._M_key_compare
= __x
._M_impl
._M_key_compare
;
1461 if (__x
._M_root() != 0)
1463 _M_root() = _M_copy(__x
._M_begin(), _M_end(), __roan
);
1464 _M_leftmost() = _S_minimum(_M_root());
1465 _M_rightmost() = _S_maximum(_M_root());
1466 _M_impl
._M_node_count
= __x
._M_impl
._M_node_count
;
1473 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1474 typename _Compare
, typename _Alloc
>
1475 #if __cplusplus >= 201103L
1476 template<typename _Arg
, typename _NodeGen
>
1478 template<typename _NodeGen
>
1480 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1481 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1482 _M_insert_(_Base_ptr __x
, _Base_ptr __p
,
1483 #if __cplusplus >= 201103L
1488 _NodeGen
& __node_gen
)
1490 bool __insert_left
= (__x
!= 0 || __p
== _M_end()
1491 || _M_impl
._M_key_compare(_KeyOfValue()(__v
),
1494 _Link_type __z
= __node_gen(_GLIBCXX_FORWARD(_Arg
, __v
));
1496 _Rb_tree_insert_and_rebalance(__insert_left
, __z
, __p
,
1497 this->_M_impl
._M_header
);
1498 ++_M_impl
._M_node_count
;
1499 return iterator(__z
);
1502 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1503 typename _Compare
, typename _Alloc
>
1504 #if __cplusplus >= 201103L
1505 template<typename _Arg
>
1507 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1508 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1509 #if __cplusplus >= 201103L
1510 _M_insert_lower(_Base_ptr __p
, _Arg
&& __v
)
1512 _M_insert_lower(_Base_ptr __p
, const _Val
& __v
)
1515 bool __insert_left
= (__p
== _M_end()
1516 || !_M_impl
._M_key_compare(_S_key(__p
),
1517 _KeyOfValue()(__v
)));
1519 _Link_type __z
= _M_create_node(_GLIBCXX_FORWARD(_Arg
, __v
));
1521 _Rb_tree_insert_and_rebalance(__insert_left
, __z
, __p
,
1522 this->_M_impl
._M_header
);
1523 ++_M_impl
._M_node_count
;
1524 return iterator(__z
);
1527 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1528 typename _Compare
, typename _Alloc
>
1529 #if __cplusplus >= 201103L
1530 template<typename _Arg
>
1532 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1533 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1534 #if __cplusplus >= 201103L
1535 _M_insert_equal_lower(_Arg
&& __v
)
1537 _M_insert_equal_lower(const _Val
& __v
)
1540 _Link_type __x
= _M_begin();
1541 _Base_ptr __y
= _M_end();
1545 __x
= !_M_impl
._M_key_compare(_S_key(__x
), _KeyOfValue()(__v
)) ?
1546 _S_left(__x
) : _S_right(__x
);
1548 return _M_insert_lower(__y
, _GLIBCXX_FORWARD(_Arg
, __v
));
1551 template<typename _Key
, typename _Val
, typename _KoV
,
1552 typename _Compare
, typename _Alloc
>
1553 template<typename _NodeGen
>
1554 typename _Rb_tree
<_Key
, _Val
, _KoV
, _Compare
, _Alloc
>::_Link_type
1555 _Rb_tree
<_Key
, _Val
, _KoV
, _Compare
, _Alloc
>::
1556 _M_copy(_Const_Link_type __x
, _Base_ptr __p
, _NodeGen
& __node_gen
)
1558 // Structural copy. __x and __p must be non-null.
1559 _Link_type __top
= _M_clone_node(__x
, __node_gen
);
1560 __top
->_M_parent
= __p
;
1565 __top
->_M_right
= _M_copy(_S_right(__x
), __top
, __node_gen
);
1571 _Link_type __y
= _M_clone_node(__x
, __node_gen
);
1573 __y
->_M_parent
= __p
;
1575 __y
->_M_right
= _M_copy(_S_right(__x
), __y
, __node_gen
);
1583 __throw_exception_again
;
1588 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1589 typename _Compare
, typename _Alloc
>
1591 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1592 _M_erase(_Link_type __x
)
1594 // Erase without rebalancing.
1597 _M_erase(_S_right(__x
));
1598 _Link_type __y
= _S_left(__x
);
1604 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1605 typename _Compare
, typename _Alloc
>
1606 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1607 _Compare
, _Alloc
>::iterator
1608 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1609 _M_lower_bound(_Link_type __x
, _Base_ptr __y
,
1613 if (!_M_impl
._M_key_compare(_S_key(__x
), __k
))
1614 __y
= __x
, __x
= _S_left(__x
);
1616 __x
= _S_right(__x
);
1617 return iterator(__y
);
1620 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1621 typename _Compare
, typename _Alloc
>
1622 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1623 _Compare
, _Alloc
>::const_iterator
1624 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1625 _M_lower_bound(_Const_Link_type __x
, _Const_Base_ptr __y
,
1626 const _Key
& __k
) const
1629 if (!_M_impl
._M_key_compare(_S_key(__x
), __k
))
1630 __y
= __x
, __x
= _S_left(__x
);
1632 __x
= _S_right(__x
);
1633 return const_iterator(__y
);
1636 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1637 typename _Compare
, typename _Alloc
>
1638 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1639 _Compare
, _Alloc
>::iterator
1640 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1641 _M_upper_bound(_Link_type __x
, _Base_ptr __y
,
1645 if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1646 __y
= __x
, __x
= _S_left(__x
);
1648 __x
= _S_right(__x
);
1649 return iterator(__y
);
1652 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1653 typename _Compare
, typename _Alloc
>
1654 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1655 _Compare
, _Alloc
>::const_iterator
1656 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1657 _M_upper_bound(_Const_Link_type __x
, _Const_Base_ptr __y
,
1658 const _Key
& __k
) const
1661 if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1662 __y
= __x
, __x
= _S_left(__x
);
1664 __x
= _S_right(__x
);
1665 return const_iterator(__y
);
1668 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1669 typename _Compare
, typename _Alloc
>
1670 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1671 _Compare
, _Alloc
>::iterator
,
1672 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1673 _Compare
, _Alloc
>::iterator
>
1674 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1675 equal_range(const _Key
& __k
)
1677 _Link_type __x
= _M_begin();
1678 _Base_ptr __y
= _M_end();
1681 if (_M_impl
._M_key_compare(_S_key(__x
), __k
))
1682 __x
= _S_right(__x
);
1683 else if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1684 __y
= __x
, __x
= _S_left(__x
);
1687 _Link_type
__xu(__x
);
1688 _Base_ptr
__yu(__y
);
1689 __y
= __x
, __x
= _S_left(__x
);
1690 __xu
= _S_right(__xu
);
1691 return pair
<iterator
,
1692 iterator
>(_M_lower_bound(__x
, __y
, __k
),
1693 _M_upper_bound(__xu
, __yu
, __k
));
1696 return pair
<iterator
, iterator
>(iterator(__y
),
1700 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1701 typename _Compare
, typename _Alloc
>
1702 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1703 _Compare
, _Alloc
>::const_iterator
,
1704 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1705 _Compare
, _Alloc
>::const_iterator
>
1706 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1707 equal_range(const _Key
& __k
) const
1709 _Const_Link_type __x
= _M_begin();
1710 _Const_Base_ptr __y
= _M_end();
1713 if (_M_impl
._M_key_compare(_S_key(__x
), __k
))
1714 __x
= _S_right(__x
);
1715 else if (_M_impl
._M_key_compare(__k
, _S_key(__x
)))
1716 __y
= __x
, __x
= _S_left(__x
);
1719 _Const_Link_type
__xu(__x
);
1720 _Const_Base_ptr
__yu(__y
);
1721 __y
= __x
, __x
= _S_left(__x
);
1722 __xu
= _S_right(__xu
);
1723 return pair
<const_iterator
,
1724 const_iterator
>(_M_lower_bound(__x
, __y
, __k
),
1725 _M_upper_bound(__xu
, __yu
, __k
));
1728 return pair
<const_iterator
, const_iterator
>(const_iterator(__y
),
1729 const_iterator(__y
));
1732 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1733 typename _Compare
, typename _Alloc
>
1735 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1736 swap(_Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>& __t
)
1737 #if __cplusplus >= 201103L
1738 noexcept(_Alloc_traits::_S_nothrow_swap())
1743 if (__t
._M_root() != 0)
1745 _M_root() = __t
._M_root();
1746 _M_leftmost() = __t
._M_leftmost();
1747 _M_rightmost() = __t
._M_rightmost();
1748 _M_root()->_M_parent
= _M_end();
1749 _M_impl
._M_node_count
= __t
._M_impl
._M_node_count
;
1751 __t
._M_impl
._M_reset();
1754 else if (__t
._M_root() == 0)
1756 __t
._M_root() = _M_root();
1757 __t
._M_leftmost() = _M_leftmost();
1758 __t
._M_rightmost() = _M_rightmost();
1759 __t
._M_root()->_M_parent
= __t
._M_end();
1760 __t
._M_impl
._M_node_count
= _M_impl
._M_node_count
;
1766 std::swap(_M_root(),__t
._M_root());
1767 std::swap(_M_leftmost(),__t
._M_leftmost());
1768 std::swap(_M_rightmost(),__t
._M_rightmost());
1770 _M_root()->_M_parent
= _M_end();
1771 __t
._M_root()->_M_parent
= __t
._M_end();
1772 std::swap(this->_M_impl
._M_node_count
, __t
._M_impl
._M_node_count
);
1774 // No need to swap header's color as it does not change.
1775 std::swap(this->_M_impl
._M_key_compare
, __t
._M_impl
._M_key_compare
);
1777 _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
1778 __t
._M_get_Node_allocator());
1781 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1782 typename _Compare
, typename _Alloc
>
1783 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1784 _Compare
, _Alloc
>::_Base_ptr
,
1785 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1786 _Compare
, _Alloc
>::_Base_ptr
>
1787 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1788 _M_get_insert_unique_pos(const key_type
& __k
)
1790 typedef pair
<_Base_ptr
, _Base_ptr
> _Res
;
1791 _Link_type __x
= _M_begin();
1792 _Base_ptr __y
= _M_end();
1797 __comp
= _M_impl
._M_key_compare(__k
, _S_key(__x
));
1798 __x
= __comp
? _S_left(__x
) : _S_right(__x
);
1800 iterator __j
= iterator(__y
);
1804 return _Res(__x
, __y
);
1808 if (_M_impl
._M_key_compare(_S_key(__j
._M_node
), __k
))
1809 return _Res(__x
, __y
);
1810 return _Res(__j
._M_node
, 0);
1813 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1814 typename _Compare
, typename _Alloc
>
1815 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1816 _Compare
, _Alloc
>::_Base_ptr
,
1817 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1818 _Compare
, _Alloc
>::_Base_ptr
>
1819 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1820 _M_get_insert_equal_pos(const key_type
& __k
)
1822 typedef pair
<_Base_ptr
, _Base_ptr
> _Res
;
1823 _Link_type __x
= _M_begin();
1824 _Base_ptr __y
= _M_end();
1828 __x
= _M_impl
._M_key_compare(__k
, _S_key(__x
)) ?
1829 _S_left(__x
) : _S_right(__x
);
1831 return _Res(__x
, __y
);
1834 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1835 typename _Compare
, typename _Alloc
>
1836 #if __cplusplus >= 201103L
1837 template<typename _Arg
>
1839 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1840 _Compare
, _Alloc
>::iterator
, bool>
1841 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1842 #if __cplusplus >= 201103L
1843 _M_insert_unique(_Arg
&& __v
)
1845 _M_insert_unique(const _Val
& __v
)
1848 typedef pair
<iterator
, bool> _Res
;
1849 pair
<_Base_ptr
, _Base_ptr
> __res
1850 = _M_get_insert_unique_pos(_KeyOfValue()(__v
));
1854 _Alloc_node
__an(*this);
1855 return _Res(_M_insert_(__res
.first
, __res
.second
,
1856 _GLIBCXX_FORWARD(_Arg
, __v
), __an
),
1860 return _Res(iterator(__res
.first
), false);
1863 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1864 typename _Compare
, typename _Alloc
>
1865 #if __cplusplus >= 201103L
1866 template<typename _Arg
>
1868 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1869 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1870 #if __cplusplus >= 201103L
1871 _M_insert_equal(_Arg
&& __v
)
1873 _M_insert_equal(const _Val
& __v
)
1876 pair
<_Base_ptr
, _Base_ptr
> __res
1877 = _M_get_insert_equal_pos(_KeyOfValue()(__v
));
1878 _Alloc_node
__an(*this);
1879 return _M_insert_(__res
.first
, __res
.second
,
1880 _GLIBCXX_FORWARD(_Arg
, __v
), __an
);
1883 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1884 typename _Compare
, typename _Alloc
>
1885 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1886 _Compare
, _Alloc
>::_Base_ptr
,
1887 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1888 _Compare
, _Alloc
>::_Base_ptr
>
1889 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1890 _M_get_insert_hint_unique_pos(const_iterator __position
,
1891 const key_type
& __k
)
1893 iterator __pos
= __position
._M_const_cast();
1894 typedef pair
<_Base_ptr
, _Base_ptr
> _Res
;
1897 if (__pos
._M_node
== _M_end())
1900 && _M_impl
._M_key_compare(_S_key(_M_rightmost()), __k
))
1901 return _Res(0, _M_rightmost());
1903 return _M_get_insert_unique_pos(__k
);
1905 else if (_M_impl
._M_key_compare(__k
, _S_key(__pos
._M_node
)))
1907 // First, try before...
1908 iterator __before
= __pos
;
1909 if (__pos
._M_node
== _M_leftmost()) // begin()
1910 return _Res(_M_leftmost(), _M_leftmost());
1911 else if (_M_impl
._M_key_compare(_S_key((--__before
)._M_node
), __k
))
1913 if (_S_right(__before
._M_node
) == 0)
1914 return _Res(0, __before
._M_node
);
1916 return _Res(__pos
._M_node
, __pos
._M_node
);
1919 return _M_get_insert_unique_pos(__k
);
1921 else if (_M_impl
._M_key_compare(_S_key(__pos
._M_node
), __k
))
1923 // ... then try after.
1924 iterator __after
= __pos
;
1925 if (__pos
._M_node
== _M_rightmost())
1926 return _Res(0, _M_rightmost());
1927 else if (_M_impl
._M_key_compare(__k
, _S_key((++__after
)._M_node
)))
1929 if (_S_right(__pos
._M_node
) == 0)
1930 return _Res(0, __pos
._M_node
);
1932 return _Res(__after
._M_node
, __after
._M_node
);
1935 return _M_get_insert_unique_pos(__k
);
1939 return _Res(__pos
._M_node
, 0);
1942 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1943 typename _Compare
, typename _Alloc
>
1944 #if __cplusplus >= 201103L
1945 template<typename _Arg
, typename _NodeGen
>
1947 template<typename _NodeGen
>
1949 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
1950 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1951 _M_insert_unique_(const_iterator __position
,
1952 #if __cplusplus >= 201103L
1957 _NodeGen
& __node_gen
)
1959 pair
<_Base_ptr
, _Base_ptr
> __res
1960 = _M_get_insert_hint_unique_pos(__position
, _KeyOfValue()(__v
));
1963 return _M_insert_(__res
.first
, __res
.second
,
1964 _GLIBCXX_FORWARD(_Arg
, __v
),
1966 return iterator(__res
.first
);
1969 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
1970 typename _Compare
, typename _Alloc
>
1971 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1972 _Compare
, _Alloc
>::_Base_ptr
,
1973 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
1974 _Compare
, _Alloc
>::_Base_ptr
>
1975 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
1976 _M_get_insert_hint_equal_pos(const_iterator __position
, const key_type
& __k
)
1978 iterator __pos
= __position
._M_const_cast();
1979 typedef pair
<_Base_ptr
, _Base_ptr
> _Res
;
1982 if (__pos
._M_node
== _M_end())
1985 && !_M_impl
._M_key_compare(__k
, _S_key(_M_rightmost())))
1986 return _Res(0, _M_rightmost());
1988 return _M_get_insert_equal_pos(__k
);
1990 else if (!_M_impl
._M_key_compare(_S_key(__pos
._M_node
), __k
))
1992 // First, try before...
1993 iterator __before
= __pos
;
1994 if (__pos
._M_node
== _M_leftmost()) // begin()
1995 return _Res(_M_leftmost(), _M_leftmost());
1996 else if (!_M_impl
._M_key_compare(__k
, _S_key((--__before
)._M_node
)))
1998 if (_S_right(__before
._M_node
) == 0)
1999 return _Res(0, __before
._M_node
);
2001 return _Res(__pos
._M_node
, __pos
._M_node
);
2004 return _M_get_insert_equal_pos(__k
);
2008 // ... then try after.
2009 iterator __after
= __pos
;
2010 if (__pos
._M_node
== _M_rightmost())
2011 return _Res(0, _M_rightmost());
2012 else if (!_M_impl
._M_key_compare(_S_key((++__after
)._M_node
), __k
))
2014 if (_S_right(__pos
._M_node
) == 0)
2015 return _Res(0, __pos
._M_node
);
2017 return _Res(__after
._M_node
, __after
._M_node
);
2024 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2025 typename _Compare
, typename _Alloc
>
2026 #if __cplusplus >= 201103L
2027 template<typename _Arg
, typename _NodeGen
>
2029 template<typename _NodeGen
>
2031 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
2032 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2033 _M_insert_equal_(const_iterator __position
,
2034 #if __cplusplus >= 201103L
2039 _NodeGen
& __node_gen
)
2041 pair
<_Base_ptr
, _Base_ptr
> __res
2042 = _M_get_insert_hint_equal_pos(__position
, _KeyOfValue()(__v
));
2045 return _M_insert_(__res
.first
, __res
.second
,
2046 _GLIBCXX_FORWARD(_Arg
, __v
),
2049 return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg
, __v
));
2052 #if __cplusplus >= 201103L
2053 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2054 typename _Compare
, typename _Alloc
>
2055 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
2056 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2057 _M_insert_node(_Base_ptr __x
, _Base_ptr __p
, _Link_type __z
)
2059 bool __insert_left
= (__x
!= 0 || __p
== _M_end()
2060 || _M_impl
._M_key_compare(_S_key(__z
),
2063 _Rb_tree_insert_and_rebalance(__insert_left
, __z
, __p
,
2064 this->_M_impl
._M_header
);
2065 ++_M_impl
._M_node_count
;
2066 return iterator(__z
);
2069 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2070 typename _Compare
, typename _Alloc
>
2071 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
2072 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2073 _M_insert_lower_node(_Base_ptr __p
, _Link_type __z
)
2075 bool __insert_left
= (__p
== _M_end()
2076 || !_M_impl
._M_key_compare(_S_key(__p
),
2079 _Rb_tree_insert_and_rebalance(__insert_left
, __z
, __p
,
2080 this->_M_impl
._M_header
);
2081 ++_M_impl
._M_node_count
;
2082 return iterator(__z
);
2085 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2086 typename _Compare
, typename _Alloc
>
2087 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
2088 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2089 _M_insert_equal_lower_node(_Link_type __z
)
2091 _Link_type __x
= _M_begin();
2092 _Base_ptr __y
= _M_end();
2096 __x
= !_M_impl
._M_key_compare(_S_key(__x
), _S_key(__z
)) ?
2097 _S_left(__x
) : _S_right(__x
);
2099 return _M_insert_lower_node(__y
, __z
);
2102 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2103 typename _Compare
, typename _Alloc
>
2104 template<typename
... _Args
>
2105 pair
<typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
2106 _Compare
, _Alloc
>::iterator
, bool>
2107 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2108 _M_emplace_unique(_Args
&&... __args
)
2110 _Link_type __z
= _M_create_node(std::forward
<_Args
>(__args
)...);
2114 typedef pair
<iterator
, bool> _Res
;
2115 auto __res
= _M_get_insert_unique_pos(_S_key(__z
));
2117 return _Res(_M_insert_node(__res
.first
, __res
.second
, __z
), true);
2120 return _Res(iterator(__res
.first
), false);
2125 __throw_exception_again
;
2129 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2130 typename _Compare
, typename _Alloc
>
2131 template<typename
... _Args
>
2132 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
2133 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2134 _M_emplace_equal(_Args
&&... __args
)
2136 _Link_type __z
= _M_create_node(std::forward
<_Args
>(__args
)...);
2140 auto __res
= _M_get_insert_equal_pos(_S_key(__z
));
2141 return _M_insert_node(__res
.first
, __res
.second
, __z
);
2146 __throw_exception_again
;
2150 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2151 typename _Compare
, typename _Alloc
>
2152 template<typename
... _Args
>
2153 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
2154 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2155 _M_emplace_hint_unique(const_iterator __pos
, _Args
&&... __args
)
2157 _Link_type __z
= _M_create_node(std::forward
<_Args
>(__args
)...);
2161 auto __res
= _M_get_insert_hint_unique_pos(__pos
, _S_key(__z
));
2164 return _M_insert_node(__res
.first
, __res
.second
, __z
);
2167 return iterator(__res
.first
);
2172 __throw_exception_again
;
2176 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2177 typename _Compare
, typename _Alloc
>
2178 template<typename
... _Args
>
2179 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::iterator
2180 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2181 _M_emplace_hint_equal(const_iterator __pos
, _Args
&&... __args
)
2183 _Link_type __z
= _M_create_node(std::forward
<_Args
>(__args
)...);
2187 auto __res
= _M_get_insert_hint_equal_pos(__pos
, _S_key(__z
));
2190 return _M_insert_node(__res
.first
, __res
.second
, __z
);
2192 return _M_insert_equal_lower_node(__z
);
2197 __throw_exception_again
;
2202 template<typename _Key
, typename _Val
, typename _KoV
,
2203 typename _Cmp
, typename _Alloc
>
2206 _Rb_tree
<_Key
, _Val
, _KoV
, _Cmp
, _Alloc
>::
2207 _M_insert_unique(_II __first
, _II __last
)
2209 _Alloc_node
__an(*this);
2210 for (; __first
!= __last
; ++__first
)
2211 _M_insert_unique_(end(), *__first
, __an
);
2214 template<typename _Key
, typename _Val
, typename _KoV
,
2215 typename _Cmp
, typename _Alloc
>
2218 _Rb_tree
<_Key
, _Val
, _KoV
, _Cmp
, _Alloc
>::
2219 _M_insert_equal(_II __first
, _II __last
)
2221 _Alloc_node
__an(*this);
2222 for (; __first
!= __last
; ++__first
)
2223 _M_insert_equal_(end(), *__first
, __an
);
2226 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2227 typename _Compare
, typename _Alloc
>
2229 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2230 _M_erase_aux(const_iterator __position
)
2233 static_cast<_Link_type
>(_Rb_tree_rebalance_for_erase
2234 (const_cast<_Base_ptr
>(__position
._M_node
),
2235 this->_M_impl
._M_header
));
2237 --_M_impl
._M_node_count
;
2240 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2241 typename _Compare
, typename _Alloc
>
2243 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2244 _M_erase_aux(const_iterator __first
, const_iterator __last
)
2246 if (__first
== begin() && __last
== end())
2249 while (__first
!= __last
)
2253 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2254 typename _Compare
, typename _Alloc
>
2255 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::size_type
2256 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2257 erase(const _Key
& __x
)
2259 pair
<iterator
, iterator
> __p
= equal_range(__x
);
2260 const size_type __old_size
= size();
2261 erase(__p
.first
, __p
.second
);
2262 return __old_size
- size();
2265 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2266 typename _Compare
, typename _Alloc
>
2268 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2269 erase(const _Key
* __first
, const _Key
* __last
)
2271 while (__first
!= __last
)
2275 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2276 typename _Compare
, typename _Alloc
>
2277 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
2278 _Compare
, _Alloc
>::iterator
2279 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2280 find(const _Key
& __k
)
2282 iterator __j
= _M_lower_bound(_M_begin(), _M_end(), __k
);
2283 return (__j
== end()
2284 || _M_impl
._M_key_compare(__k
,
2285 _S_key(__j
._M_node
))) ? end() : __j
;
2288 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2289 typename _Compare
, typename _Alloc
>
2290 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
,
2291 _Compare
, _Alloc
>::const_iterator
2292 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2293 find(const _Key
& __k
) const
2295 const_iterator __j
= _M_lower_bound(_M_begin(), _M_end(), __k
);
2296 return (__j
== end()
2297 || _M_impl
._M_key_compare(__k
,
2298 _S_key(__j
._M_node
))) ? end() : __j
;
2301 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2302 typename _Compare
, typename _Alloc
>
2303 typename _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::size_type
2304 _Rb_tree
<_Key
, _Val
, _KeyOfValue
, _Compare
, _Alloc
>::
2305 count(const _Key
& __k
) const
2307 pair
<const_iterator
, const_iterator
> __p
= equal_range(__k
);
2308 const size_type __n
= std::distance(__p
.first
, __p
.second
);
2312 _GLIBCXX_PURE
unsigned int
2313 _Rb_tree_black_count(const _Rb_tree_node_base
* __node
,
2314 const _Rb_tree_node_base
* __root
) throw ();
2316 template<typename _Key
, typename _Val
, typename _KeyOfValue
,
2317 typename _Compare
, typename _Alloc
>
2319 _Rb_tree
<_Key
,_Val
,_KeyOfValue
,_Compare
,_Alloc
>::__rb_verify() const
2321 if (_M_impl
._M_node_count
== 0 || begin() == end())
2322 return _M_impl
._M_node_count
== 0 && begin() == end()
2323 && this->_M_impl
._M_header
._M_left
== _M_end()
2324 && this->_M_impl
._M_header
._M_right
== _M_end();
2326 unsigned int __len
= _Rb_tree_black_count(_M_leftmost(), _M_root());
2327 for (const_iterator __it
= begin(); __it
!= end(); ++__it
)
2329 _Const_Link_type __x
= static_cast<_Const_Link_type
>(__it
._M_node
);
2330 _Const_Link_type __L
= _S_left(__x
);
2331 _Const_Link_type __R
= _S_right(__x
);
2333 if (__x
->_M_color
== _S_red
)
2334 if ((__L
&& __L
->_M_color
== _S_red
)
2335 || (__R
&& __R
->_M_color
== _S_red
))
2338 if (__L
&& _M_impl
._M_key_compare(_S_key(__x
), _S_key(__L
)))
2340 if (__R
&& _M_impl
._M_key_compare(_S_key(__R
), _S_key(__x
)))
2343 if (!__L
&& !__R
&& _Rb_tree_black_count(__x
, _M_root()) != __len
)
2347 if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
2349 if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
2354 _GLIBCXX_END_NAMESPACE_VERSION