|
libstdc++
|
00001 // RB tree implementation -*- C++ -*- 00002 00003 // Copyright (C) 2001-2018 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /* 00026 * 00027 * Copyright (c) 1996,1997 00028 * Silicon Graphics Computer Systems, Inc. 00029 * 00030 * Permission to use, copy, modify, distribute and sell this software 00031 * and its documentation for any purpose is hereby granted without fee, 00032 * provided that the above copyright notice appear in all copies and 00033 * that both that copyright notice and this permission notice appear 00034 * in supporting documentation. Silicon Graphics makes no 00035 * representations about the suitability of this software for any 00036 * purpose. It is provided "as is" without express or implied warranty. 00037 * 00038 * 00039 * Copyright (c) 1994 00040 * Hewlett-Packard Company 00041 * 00042 * Permission to use, copy, modify, distribute and sell this software 00043 * and its documentation for any purpose is hereby granted without fee, 00044 * provided that the above copyright notice appear in all copies and 00045 * that both that copyright notice and this permission notice appear 00046 * in supporting documentation. Hewlett-Packard Company makes no 00047 * representations about the suitability of this software for any 00048 * purpose. It is provided "as is" without express or implied warranty. 00049 * 00050 * 00051 */ 00052 00053 /** @file bits/stl_tree.h 00054 * This is an internal header file, included by other library headers. 00055 * Do not attempt to use it directly. @headername{map,set} 00056 */ 00057 00058 #ifndef _STL_TREE_H 00059 #define _STL_TREE_H 1 00060 00061 #pragma GCC system_header 00062 00063 #include <bits/stl_algobase.h> 00064 #include <bits/allocator.h> 00065 #include <bits/stl_function.h> 00066 #include <bits/cpp_type_traits.h> 00067 #include <ext/alloc_traits.h> 00068 #if __cplusplus >= 201103L 00069 # include <ext/aligned_buffer.h> 00070 #endif 00071 #if __cplusplus > 201402L 00072 # include <bits/node_handle.h> 00073 #endif 00074 00075 namespace std _GLIBCXX_VISIBILITY(default) 00076 { 00077 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00078 00079 #if __cplusplus > 201103L 00080 # define __cpp_lib_generic_associative_lookup 201304 00081 #endif 00082 00083 // Red-black tree class, designed for use in implementing STL 00084 // associative containers (set, multiset, map, and multimap). The 00085 // insertion and deletion algorithms are based on those in Cormen, 00086 // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 00087 // 1990), except that 00088 // 00089 // (1) the header cell is maintained with links not only to the root 00090 // but also to the leftmost node of the tree, to enable constant 00091 // time begin(), and to the rightmost node of the tree, to enable 00092 // linear time performance when used with the generic set algorithms 00093 // (set_union, etc.) 00094 // 00095 // (2) when a node being deleted has two children its successor node 00096 // is relinked into its place, rather than copied, so that the only 00097 // iterators invalidated are those referring to the deleted node. 00098 00099 enum _Rb_tree_color { _S_red = false, _S_black = true }; 00100 00101 struct _Rb_tree_node_base 00102 { 00103 typedef _Rb_tree_node_base* _Base_ptr; 00104 typedef const _Rb_tree_node_base* _Const_Base_ptr; 00105 00106 _Rb_tree_color _M_color; 00107 _Base_ptr _M_parent; 00108 _Base_ptr _M_left; 00109 _Base_ptr _M_right; 00110 00111 static _Base_ptr 00112 _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00113 { 00114 while (__x->_M_left != 0) __x = __x->_M_left; 00115 return __x; 00116 } 00117 00118 static _Const_Base_ptr 00119 _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT 00120 { 00121 while (__x->_M_left != 0) __x = __x->_M_left; 00122 return __x; 00123 } 00124 00125 static _Base_ptr 00126 _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00127 { 00128 while (__x->_M_right != 0) __x = __x->_M_right; 00129 return __x; 00130 } 00131 00132 static _Const_Base_ptr 00133 _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT 00134 { 00135 while (__x->_M_right != 0) __x = __x->_M_right; 00136 return __x; 00137 } 00138 }; 00139 00140 // Helper type offering value initialization guarantee on the compare functor. 00141 template<typename _Key_compare> 00142 struct _Rb_tree_key_compare 00143 { 00144 _Key_compare _M_key_compare; 00145 00146 _Rb_tree_key_compare() 00147 _GLIBCXX_NOEXCEPT_IF( 00148 is_nothrow_default_constructible<_Key_compare>::value) 00149 : _M_key_compare() 00150 { } 00151 00152 _Rb_tree_key_compare(const _Key_compare& __comp) 00153 : _M_key_compare(__comp) 00154 { } 00155 00156 #if __cplusplus >= 201103L 00157 // Copy constructor added for consistency with C++98 mode. 00158 _Rb_tree_key_compare(const _Rb_tree_key_compare&) = default; 00159 00160 _Rb_tree_key_compare(_Rb_tree_key_compare&& __x) 00161 noexcept(is_nothrow_copy_constructible<_Key_compare>::value) 00162 : _M_key_compare(__x._M_key_compare) 00163 { } 00164 #endif 00165 }; 00166 00167 // Helper type to manage default initialization of node count and header. 00168 struct _Rb_tree_header 00169 { 00170 _Rb_tree_node_base _M_header; 00171 size_t _M_node_count; // Keeps track of size of tree. 00172 00173 _Rb_tree_header() _GLIBCXX_NOEXCEPT 00174 { 00175 _M_header._M_color = _S_red; 00176 _M_reset(); 00177 } 00178 00179 #if __cplusplus >= 201103L 00180 _Rb_tree_header(_Rb_tree_header&& __x) noexcept 00181 { 00182 if (__x._M_header._M_parent != nullptr) 00183 _M_move_data(__x); 00184 else 00185 { 00186 _M_header._M_color = _S_red; 00187 _M_reset(); 00188 } 00189 } 00190 #endif 00191 00192 void 00193 _M_move_data(_Rb_tree_header& __from) 00194 { 00195 _M_header._M_color = __from._M_header._M_color; 00196 _M_header._M_parent = __from._M_header._M_parent; 00197 _M_header._M_left = __from._M_header._M_left; 00198 _M_header._M_right = __from._M_header._M_right; 00199 _M_header._M_parent->_M_parent = &_M_header; 00200 _M_node_count = __from._M_node_count; 00201 00202 __from._M_reset(); 00203 } 00204 00205 void 00206 _M_reset() 00207 { 00208 _M_header._M_parent = 0; 00209 _M_header._M_left = &_M_header; 00210 _M_header._M_right = &_M_header; 00211 _M_node_count = 0; 00212 } 00213 }; 00214 00215 template<typename _Val> 00216 struct _Rb_tree_node : public _Rb_tree_node_base 00217 { 00218 typedef _Rb_tree_node<_Val>* _Link_type; 00219 00220 #if __cplusplus < 201103L 00221 _Val _M_value_field; 00222 00223 _Val* 00224 _M_valptr() 00225 { return std::__addressof(_M_value_field); } 00226 00227 const _Val* 00228 _M_valptr() const 00229 { return std::__addressof(_M_value_field); } 00230 #else 00231 __gnu_cxx::__aligned_membuf<_Val> _M_storage; 00232 00233 _Val* 00234 _M_valptr() 00235 { return _M_storage._M_ptr(); } 00236 00237 const _Val* 00238 _M_valptr() const 00239 { return _M_storage._M_ptr(); } 00240 #endif 00241 }; 00242 00243 _GLIBCXX_PURE _Rb_tree_node_base* 00244 _Rb_tree_increment(_Rb_tree_node_base* __x) throw (); 00245 00246 _GLIBCXX_PURE const _Rb_tree_node_base* 00247 _Rb_tree_increment(const _Rb_tree_node_base* __x) throw (); 00248 00249 _GLIBCXX_PURE _Rb_tree_node_base* 00250 _Rb_tree_decrement(_Rb_tree_node_base* __x) throw (); 00251 00252 _GLIBCXX_PURE const _Rb_tree_node_base* 00253 _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw (); 00254 00255 template<typename _Tp> 00256 struct _Rb_tree_iterator 00257 { 00258 typedef _Tp value_type; 00259 typedef _Tp& reference; 00260 typedef _Tp* pointer; 00261 00262 typedef bidirectional_iterator_tag iterator_category; 00263 typedef ptrdiff_t difference_type; 00264 00265 typedef _Rb_tree_iterator<_Tp> _Self; 00266 typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; 00267 typedef _Rb_tree_node<_Tp>* _Link_type; 00268 00269 _Rb_tree_iterator() _GLIBCXX_NOEXCEPT 00270 : _M_node() { } 00271 00272 explicit 00273 _Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00274 : _M_node(__x) { } 00275 00276 reference 00277 operator*() const _GLIBCXX_NOEXCEPT 00278 { return *static_cast<_Link_type>(_M_node)->_M_valptr(); } 00279 00280 pointer 00281 operator->() const _GLIBCXX_NOEXCEPT 00282 { return static_cast<_Link_type> (_M_node)->_M_valptr(); } 00283 00284 _Self& 00285 operator++() _GLIBCXX_NOEXCEPT 00286 { 00287 _M_node = _Rb_tree_increment(_M_node); 00288 return *this; 00289 } 00290 00291 _Self 00292 operator++(int) _GLIBCXX_NOEXCEPT 00293 { 00294 _Self __tmp = *this; 00295 _M_node = _Rb_tree_increment(_M_node); 00296 return __tmp; 00297 } 00298 00299 _Self& 00300 operator--() _GLIBCXX_NOEXCEPT 00301 { 00302 _M_node = _Rb_tree_decrement(_M_node); 00303 return *this; 00304 } 00305 00306 _Self 00307 operator--(int) _GLIBCXX_NOEXCEPT 00308 { 00309 _Self __tmp = *this; 00310 _M_node = _Rb_tree_decrement(_M_node); 00311 return __tmp; 00312 } 00313 00314 bool 00315 operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT 00316 { return _M_node == __x._M_node; } 00317 00318 bool 00319 operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT 00320 { return _M_node != __x._M_node; } 00321 00322 _Base_ptr _M_node; 00323 }; 00324 00325 template<typename _Tp> 00326 struct _Rb_tree_const_iterator 00327 { 00328 typedef _Tp value_type; 00329 typedef const _Tp& reference; 00330 typedef const _Tp* pointer; 00331 00332 typedef _Rb_tree_iterator<_Tp> iterator; 00333 00334 typedef bidirectional_iterator_tag iterator_category; 00335 typedef ptrdiff_t difference_type; 00336 00337 typedef _Rb_tree_const_iterator<_Tp> _Self; 00338 typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; 00339 typedef const _Rb_tree_node<_Tp>* _Link_type; 00340 00341 _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT 00342 : _M_node() { } 00343 00344 explicit 00345 _Rb_tree_const_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00346 : _M_node(__x) { } 00347 00348 _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT 00349 : _M_node(__it._M_node) { } 00350 00351 iterator 00352 _M_const_cast() const _GLIBCXX_NOEXCEPT 00353 { return iterator(const_cast<typename iterator::_Base_ptr>(_M_node)); } 00354 00355 reference 00356 operator*() const _GLIBCXX_NOEXCEPT 00357 { return *static_cast<_Link_type>(_M_node)->_M_valptr(); } 00358 00359 pointer 00360 operator->() const _GLIBCXX_NOEXCEPT 00361 { return static_cast<_Link_type>(_M_node)->_M_valptr(); } 00362 00363 _Self& 00364 operator++() _GLIBCXX_NOEXCEPT 00365 { 00366 _M_node = _Rb_tree_increment(_M_node); 00367 return *this; 00368 } 00369 00370 _Self 00371 operator++(int) _GLIBCXX_NOEXCEPT 00372 { 00373 _Self __tmp = *this; 00374 _M_node = _Rb_tree_increment(_M_node); 00375 return __tmp; 00376 } 00377 00378 _Self& 00379 operator--() _GLIBCXX_NOEXCEPT 00380 { 00381 _M_node = _Rb_tree_decrement(_M_node); 00382 return *this; 00383 } 00384 00385 _Self 00386 operator--(int) _GLIBCXX_NOEXCEPT 00387 { 00388 _Self __tmp = *this; 00389 _M_node = _Rb_tree_decrement(_M_node); 00390 return __tmp; 00391 } 00392 00393 bool 00394 operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT 00395 { return _M_node == __x._M_node; } 00396 00397 bool 00398 operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT 00399 { return _M_node != __x._M_node; } 00400 00401 _Base_ptr _M_node; 00402 }; 00403 00404 template<typename _Val> 00405 inline bool 00406 operator==(const _Rb_tree_iterator<_Val>& __x, 00407 const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT 00408 { return __x._M_node == __y._M_node; } 00409 00410 template<typename _Val> 00411 inline bool 00412 operator!=(const _Rb_tree_iterator<_Val>& __x, 00413 const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT 00414 { return __x._M_node != __y._M_node; } 00415 00416 void 00417 _Rb_tree_insert_and_rebalance(const bool __insert_left, 00418 _Rb_tree_node_base* __x, 00419 _Rb_tree_node_base* __p, 00420 _Rb_tree_node_base& __header) throw (); 00421 00422 _Rb_tree_node_base* 00423 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, 00424 _Rb_tree_node_base& __header) throw (); 00425 00426 #if __cplusplus > 201103L 00427 template<typename _Cmp, typename _SfinaeType, typename = __void_t<>> 00428 struct __has_is_transparent 00429 { }; 00430 00431 template<typename _Cmp, typename _SfinaeType> 00432 struct __has_is_transparent<_Cmp, _SfinaeType, 00433 __void_t<typename _Cmp::is_transparent>> 00434 { typedef void type; }; 00435 #endif 00436 00437 #if __cplusplus > 201402L 00438 template<typename _Tree1, typename _Cmp2> 00439 struct _Rb_tree_merge_helper { }; 00440 #endif 00441 00442 template<typename _Key, typename _Val, typename _KeyOfValue, 00443 typename _Compare, typename _Alloc = allocator<_Val> > 00444 class _Rb_tree 00445 { 00446 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 00447 rebind<_Rb_tree_node<_Val> >::other _Node_allocator; 00448 00449 typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits; 00450 00451 protected: 00452 typedef _Rb_tree_node_base* _Base_ptr; 00453 typedef const _Rb_tree_node_base* _Const_Base_ptr; 00454 typedef _Rb_tree_node<_Val>* _Link_type; 00455 typedef const _Rb_tree_node<_Val>* _Const_Link_type; 00456 00457 private: 00458 // Functor recycling a pool of nodes and using allocation once the pool 00459 // is empty. 00460 struct _Reuse_or_alloc_node 00461 { 00462 _Reuse_or_alloc_node(_Rb_tree& __t) 00463 : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t) 00464 { 00465 if (_M_root) 00466 { 00467 _M_root->_M_parent = 0; 00468 00469 if (_M_nodes->_M_left) 00470 _M_nodes = _M_nodes->_M_left; 00471 } 00472 else 00473 _M_nodes = 0; 00474 } 00475 00476 #if __cplusplus >= 201103L 00477 _Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete; 00478 #endif 00479 00480 ~_Reuse_or_alloc_node() 00481 { _M_t._M_erase(static_cast<_Link_type>(_M_root)); } 00482 00483 template<typename _Arg> 00484 _Link_type 00485 #if __cplusplus < 201103L 00486 operator()(const _Arg& __arg) 00487 #else 00488 operator()(_Arg&& __arg) 00489 #endif 00490 { 00491 _Link_type __node = static_cast<_Link_type>(_M_extract()); 00492 if (__node) 00493 { 00494 _M_t._M_destroy_node(__node); 00495 _M_t._M_construct_node(__node, _GLIBCXX_FORWARD(_Arg, __arg)); 00496 return __node; 00497 } 00498 00499 return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); 00500 } 00501 00502 private: 00503 _Base_ptr 00504 _M_extract() 00505 { 00506 if (!_M_nodes) 00507 return _M_nodes; 00508 00509 _Base_ptr __node = _M_nodes; 00510 _M_nodes = _M_nodes->_M_parent; 00511 if (_M_nodes) 00512 { 00513 if (_M_nodes->_M_right == __node) 00514 { 00515 _M_nodes->_M_right = 0; 00516 00517 if (_M_nodes->_M_left) 00518 { 00519 _M_nodes = _M_nodes->_M_left; 00520 00521 while (_M_nodes->_M_right) 00522 _M_nodes = _M_nodes->_M_right; 00523 00524 if (_M_nodes->_M_left) 00525 _M_nodes = _M_nodes->_M_left; 00526 } 00527 } 00528 else // __node is on the left. 00529 _M_nodes->_M_left = 0; 00530 } 00531 else 00532 _M_root = 0; 00533 00534 return __node; 00535 } 00536 00537 _Base_ptr _M_root; 00538 _Base_ptr _M_nodes; 00539 _Rb_tree& _M_t; 00540 }; 00541 00542 // Functor similar to the previous one but without any pool of nodes to 00543 // recycle. 00544 struct _Alloc_node 00545 { 00546 _Alloc_node(_Rb_tree& __t) 00547 : _M_t(__t) { } 00548 00549 template<typename _Arg> 00550 _Link_type 00551 #if __cplusplus < 201103L 00552 operator()(const _Arg& __arg) const 00553 #else 00554 operator()(_Arg&& __arg) const 00555 #endif 00556 { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); } 00557 00558 private: 00559 _Rb_tree& _M_t; 00560 }; 00561 00562 public: 00563 typedef _Key key_type; 00564 typedef _Val value_type; 00565 typedef value_type* pointer; 00566 typedef const value_type* const_pointer; 00567 typedef value_type& reference; 00568 typedef const value_type& const_reference; 00569 typedef size_t size_type; 00570 typedef ptrdiff_t difference_type; 00571 typedef _Alloc allocator_type; 00572 00573 _Node_allocator& 00574 _M_get_Node_allocator() _GLIBCXX_NOEXCEPT 00575 { return this->_M_impl; } 00576 00577 const _Node_allocator& 00578 _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT 00579 { return this->_M_impl; } 00580 00581 allocator_type 00582 get_allocator() const _GLIBCXX_NOEXCEPT 00583 { return allocator_type(_M_get_Node_allocator()); } 00584 00585 protected: 00586 _Link_type 00587 _M_get_node() 00588 { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); } 00589 00590 void 00591 _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT 00592 { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); } 00593 00594 #if __cplusplus < 201103L 00595 void 00596 _M_construct_node(_Link_type __node, const value_type& __x) 00597 { 00598 __try 00599 { get_allocator().construct(__node->_M_valptr(), __x); } 00600 __catch(...) 00601 { 00602 _M_put_node(__node); 00603 __throw_exception_again; 00604 } 00605 } 00606 00607 _Link_type 00608 _M_create_node(const value_type& __x) 00609 { 00610 _Link_type __tmp = _M_get_node(); 00611 _M_construct_node(__tmp, __x); 00612 return __tmp; 00613 } 00614 00615 void 00616 _M_destroy_node(_Link_type __p) 00617 { get_allocator().destroy(__p->_M_valptr()); } 00618 #else 00619 template<typename... _Args> 00620 void 00621 _M_construct_node(_Link_type __node, _Args&&... __args) 00622 { 00623 __try 00624 { 00625 ::new(__node) _Rb_tree_node<_Val>; 00626 _Alloc_traits::construct(_M_get_Node_allocator(), 00627 __node->_M_valptr(), 00628 std::forward<_Args>(__args)...); 00629 } 00630 __catch(...) 00631 { 00632 __node->~_Rb_tree_node<_Val>(); 00633 _M_put_node(__node); 00634 __throw_exception_again; 00635 } 00636 } 00637 00638 template<typename... _Args> 00639 _Link_type 00640 _M_create_node(_Args&&... __args) 00641 { 00642 _Link_type __tmp = _M_get_node(); 00643 _M_construct_node(__tmp, std::forward<_Args>(__args)...); 00644 return __tmp; 00645 } 00646 00647 void 00648 _M_destroy_node(_Link_type __p) noexcept 00649 { 00650 _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr()); 00651 __p->~_Rb_tree_node<_Val>(); 00652 } 00653 #endif 00654 00655 void 00656 _M_drop_node(_Link_type __p) _GLIBCXX_NOEXCEPT 00657 { 00658 _M_destroy_node(__p); 00659 _M_put_node(__p); 00660 } 00661 00662 template<typename _NodeGen> 00663 _Link_type 00664 _M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen) 00665 { 00666 _Link_type __tmp = __node_gen(*__x->_M_valptr()); 00667 __tmp->_M_color = __x->_M_color; 00668 __tmp->_M_left = 0; 00669 __tmp->_M_right = 0; 00670 return __tmp; 00671 } 00672 00673 protected: 00674 #if _GLIBCXX_INLINE_VERSION 00675 template<typename _Key_compare> 00676 #else 00677 // Unused _Is_pod_comparator is kept as it is part of mangled name. 00678 template<typename _Key_compare, 00679 bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)> 00680 #endif 00681 struct _Rb_tree_impl 00682 : public _Node_allocator 00683 , public _Rb_tree_key_compare<_Key_compare> 00684 , public _Rb_tree_header 00685 { 00686 typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare; 00687 00688 _Rb_tree_impl() 00689 _GLIBCXX_NOEXCEPT_IF( 00690 is_nothrow_default_constructible<_Node_allocator>::value 00691 && is_nothrow_default_constructible<_Base_key_compare>::value ) 00692 : _Node_allocator() 00693 { } 00694 00695 _Rb_tree_impl(const _Rb_tree_impl& __x) 00696 : _Node_allocator(_Alloc_traits::_S_select_on_copy(__x)) 00697 , _Base_key_compare(__x._M_key_compare) 00698 { } 00699 00700 #if __cplusplus < 201103L 00701 _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a) 00702 : _Node_allocator(__a), _Base_key_compare(__comp) 00703 { } 00704 #else 00705 _Rb_tree_impl(_Rb_tree_impl&&) = default; 00706 00707 _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a) 00708 : _Node_allocator(std::move(__a)), _Base_key_compare(__comp) 00709 { } 00710 #endif 00711 }; 00712 00713 _Rb_tree_impl<_Compare> _M_impl; 00714 00715 protected: 00716 _Base_ptr& 00717 _M_root() _GLIBCXX_NOEXCEPT 00718 { return this->_M_impl._M_header._M_parent; } 00719 00720 _Const_Base_ptr 00721 _M_root() const _GLIBCXX_NOEXCEPT 00722 { return this->_M_impl._M_header._M_parent; } 00723 00724 _Base_ptr& 00725 _M_leftmost() _GLIBCXX_NOEXCEPT 00726 { return this->_M_impl._M_header._M_left; } 00727 00728 _Const_Base_ptr 00729 _M_leftmost() const _GLIBCXX_NOEXCEPT 00730 { return this->_M_impl._M_header._M_left; } 00731 00732 _Base_ptr& 00733 _M_rightmost() _GLIBCXX_NOEXCEPT 00734 { return this->_M_impl._M_header._M_right; } 00735 00736 _Const_Base_ptr 00737 _M_rightmost() const _GLIBCXX_NOEXCEPT 00738 { return this->_M_impl._M_header._M_right; } 00739 00740 _Link_type 00741 _M_begin() _GLIBCXX_NOEXCEPT 00742 { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } 00743 00744 _Const_Link_type 00745 _M_begin() const _GLIBCXX_NOEXCEPT 00746 { 00747 return static_cast<_Const_Link_type> 00748 (this->_M_impl._M_header._M_parent); 00749 } 00750 00751 _Base_ptr 00752 _M_end() _GLIBCXX_NOEXCEPT 00753 { return &this->_M_impl._M_header; } 00754 00755 _Const_Base_ptr 00756 _M_end() const _GLIBCXX_NOEXCEPT 00757 { return &this->_M_impl._M_header; } 00758 00759 static const_reference 00760 _S_value(_Const_Link_type __x) 00761 { return *__x->_M_valptr(); } 00762 00763 static const _Key& 00764 _S_key(_Const_Link_type __x) 00765 { 00766 #if __cplusplus >= 201103L 00767 // If we're asking for the key we're presumably using the comparison 00768 // object, and so this is a good place to sanity check it. 00769 static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{}, 00770 "comparison object must be invocable " 00771 "with two arguments of key type"); 00772 # if __cplusplus >= 201703L 00773 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00774 // 2542. Missing const requirements for associative containers 00775 if constexpr (__is_invocable<_Compare&, const _Key&, const _Key&>{}) 00776 static_assert( 00777 is_invocable_v<const _Compare&, const _Key&, const _Key&>, 00778 "comparison object must be invocable as const"); 00779 # endif // C++17 00780 #endif // C++11 00781 00782 return _KeyOfValue()(*__x->_M_valptr()); 00783 } 00784 00785 static _Link_type 00786 _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00787 { return static_cast<_Link_type>(__x->_M_left); } 00788 00789 static _Const_Link_type 00790 _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT 00791 { return static_cast<_Const_Link_type>(__x->_M_left); } 00792 00793 static _Link_type 00794 _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00795 { return static_cast<_Link_type>(__x->_M_right); } 00796 00797 static _Const_Link_type 00798 _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT 00799 { return static_cast<_Const_Link_type>(__x->_M_right); } 00800 00801 static const_reference 00802 _S_value(_Const_Base_ptr __x) 00803 { return *static_cast<_Const_Link_type>(__x)->_M_valptr(); } 00804 00805 static const _Key& 00806 _S_key(_Const_Base_ptr __x) 00807 { return _S_key(static_cast<_Const_Link_type>(__x)); } 00808 00809 static _Base_ptr 00810 _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00811 { return _Rb_tree_node_base::_S_minimum(__x); } 00812 00813 static _Const_Base_ptr 00814 _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT 00815 { return _Rb_tree_node_base::_S_minimum(__x); } 00816 00817 static _Base_ptr 00818 _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT 00819 { return _Rb_tree_node_base::_S_maximum(__x); } 00820 00821 static _Const_Base_ptr 00822 _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT 00823 { return _Rb_tree_node_base::_S_maximum(__x); } 00824 00825 public: 00826 typedef _Rb_tree_iterator<value_type> iterator; 00827 typedef _Rb_tree_const_iterator<value_type> const_iterator; 00828 00829 typedef std::reverse_iterator<iterator> reverse_iterator; 00830 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00831 00832 #if __cplusplus > 201402L 00833 using node_type = _Node_handle<_Key, _Val, _Node_allocator>; 00834 using insert_return_type = _Node_insert_return< 00835 conditional_t<is_same_v<_Key, _Val>, const_iterator, iterator>, 00836 node_type>; 00837 #endif 00838 00839 pair<_Base_ptr, _Base_ptr> 00840 _M_get_insert_unique_pos(const key_type& __k); 00841 00842 pair<_Base_ptr, _Base_ptr> 00843 _M_get_insert_equal_pos(const key_type& __k); 00844 00845 pair<_Base_ptr, _Base_ptr> 00846 _M_get_insert_hint_unique_pos(const_iterator __pos, 00847 const key_type& __k); 00848 00849 pair<_Base_ptr, _Base_ptr> 00850 _M_get_insert_hint_equal_pos(const_iterator __pos, 00851 const key_type& __k); 00852 00853 private: 00854 #if __cplusplus >= 201103L 00855 template<typename _Arg, typename _NodeGen> 00856 iterator 00857 _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v, _NodeGen&); 00858 00859 iterator 00860 _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z); 00861 00862 template<typename _Arg> 00863 iterator 00864 _M_insert_lower(_Base_ptr __y, _Arg&& __v); 00865 00866 template<typename _Arg> 00867 iterator 00868 _M_insert_equal_lower(_Arg&& __x); 00869 00870 iterator 00871 _M_insert_lower_node(_Base_ptr __p, _Link_type __z); 00872 00873 iterator 00874 _M_insert_equal_lower_node(_Link_type __z); 00875 #else 00876 template<typename _NodeGen> 00877 iterator 00878 _M_insert_(_Base_ptr __x, _Base_ptr __y, 00879 const value_type& __v, _NodeGen&); 00880 00881 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00882 // 233. Insertion hints in associative containers. 00883 iterator 00884 _M_insert_lower(_Base_ptr __y, const value_type& __v); 00885 00886 iterator 00887 _M_insert_equal_lower(const value_type& __x); 00888 #endif 00889 00890 template<typename _NodeGen> 00891 _Link_type 00892 _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&); 00893 00894 template<typename _NodeGen> 00895 _Link_type 00896 _M_copy(const _Rb_tree& __x, _NodeGen& __gen) 00897 { 00898 _Link_type __root = _M_copy(__x._M_begin(), _M_end(), __gen); 00899 _M_leftmost() = _S_minimum(__root); 00900 _M_rightmost() = _S_maximum(__root); 00901 _M_impl._M_node_count = __x._M_impl._M_node_count; 00902 return __root; 00903 } 00904 00905 _Link_type 00906 _M_copy(const _Rb_tree& __x) 00907 { 00908 _Alloc_node __an(*this); 00909 return _M_copy(__x, __an); 00910 } 00911 00912 void 00913 _M_erase(_Link_type __x); 00914 00915 iterator 00916 _M_lower_bound(_Link_type __x, _Base_ptr __y, 00917 const _Key& __k); 00918 00919 const_iterator 00920 _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y, 00921 const _Key& __k) const; 00922 00923 iterator 00924 _M_upper_bound(_Link_type __x, _Base_ptr __y, 00925 const _Key& __k); 00926 00927 const_iterator 00928 _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y, 00929 const _Key& __k) const; 00930 00931 public: 00932 // allocation/deallocation 00933 #if __cplusplus < 201103L 00934 _Rb_tree() { } 00935 #else 00936 _Rb_tree() = default; 00937 #endif 00938 00939 _Rb_tree(const _Compare& __comp, 00940 const allocator_type& __a = allocator_type()) 00941 : _M_impl(__comp, _Node_allocator(__a)) { } 00942 00943 _Rb_tree(const _Rb_tree& __x) 00944 : _M_impl(__x._M_impl) 00945 { 00946 if (__x._M_root() != 0) 00947 _M_root() = _M_copy(__x); 00948 } 00949 00950 #if __cplusplus >= 201103L 00951 _Rb_tree(const allocator_type& __a) 00952 : _M_impl(_Compare(), _Node_allocator(__a)) 00953 { } 00954 00955 _Rb_tree(const _Rb_tree& __x, const allocator_type& __a) 00956 : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a)) 00957 { 00958 if (__x._M_root() != nullptr) 00959 _M_root() = _M_copy(__x); 00960 } 00961 00962 _Rb_tree(_Rb_tree&&) = default; 00963 00964 _Rb_tree(_Rb_tree&& __x, const allocator_type& __a) 00965 : _Rb_tree(std::move(__x), _Node_allocator(__a)) 00966 { } 00967 00968 _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a); 00969 #endif 00970 00971 ~_Rb_tree() _GLIBCXX_NOEXCEPT 00972 { _M_erase(_M_begin()); } 00973 00974 _Rb_tree& 00975 operator=(const _Rb_tree& __x); 00976 00977 // Accessors. 00978 _Compare 00979 key_comp() const 00980 { return _M_impl._M_key_compare; } 00981 00982 iterator 00983 begin() _GLIBCXX_NOEXCEPT 00984 { return iterator(this->_M_impl._M_header._M_left); } 00985 00986 const_iterator 00987 begin() const _GLIBCXX_NOEXCEPT 00988 { return const_iterator(this->_M_impl._M_header._M_left); } 00989 00990 iterator 00991 end() _GLIBCXX_NOEXCEPT 00992 { return iterator(&this->_M_impl._M_header); } 00993 00994 const_iterator 00995 end() const _GLIBCXX_NOEXCEPT 00996 { return const_iterator(&this->_M_impl._M_header); } 00997 00998 reverse_iterator 00999 rbegin() _GLIBCXX_NOEXCEPT 01000 { return reverse_iterator(end()); } 01001 01002 const_reverse_iterator 01003 rbegin() const _GLIBCXX_NOEXCEPT 01004 { return const_reverse_iterator(end()); } 01005 01006 reverse_iterator 01007 rend() _GLIBCXX_NOEXCEPT 01008 { return reverse_iterator(begin()); } 01009 01010 const_reverse_iterator 01011 rend() const _GLIBCXX_NOEXCEPT 01012 { return const_reverse_iterator(begin()); } 01013 01014 bool 01015 empty() const _GLIBCXX_NOEXCEPT 01016 { return _M_impl._M_node_count == 0; } 01017 01018 size_type 01019 size() const _GLIBCXX_NOEXCEPT 01020 { return _M_impl._M_node_count; } 01021 01022 size_type 01023 max_size() const _GLIBCXX_NOEXCEPT 01024 { return _Alloc_traits::max_size(_M_get_Node_allocator()); } 01025 01026 void 01027 swap(_Rb_tree& __t) 01028 _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value); 01029 01030 // Insert/erase. 01031 #if __cplusplus >= 201103L 01032 template<typename _Arg> 01033 pair<iterator, bool> 01034 _M_insert_unique(_Arg&& __x); 01035 01036 template<typename _Arg> 01037 iterator 01038 _M_insert_equal(_Arg&& __x); 01039 01040 template<typename _Arg, typename _NodeGen> 01041 iterator 01042 _M_insert_unique_(const_iterator __pos, _Arg&& __x, _NodeGen&); 01043 01044 template<typename _Arg> 01045 iterator 01046 _M_insert_unique_(const_iterator __pos, _Arg&& __x) 01047 { 01048 _Alloc_node __an(*this); 01049 return _M_insert_unique_(__pos, std::forward<_Arg>(__x), __an); 01050 } 01051 01052 template<typename _Arg, typename _NodeGen> 01053 iterator 01054 _M_insert_equal_(const_iterator __pos, _Arg&& __x, _NodeGen&); 01055 01056 template<typename _Arg> 01057 iterator 01058 _M_insert_equal_(const_iterator __pos, _Arg&& __x) 01059 { 01060 _Alloc_node __an(*this); 01061 return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an); 01062 } 01063 01064 template<typename... _Args> 01065 pair<iterator, bool> 01066 _M_emplace_unique(_Args&&... __args); 01067 01068 template<typename... _Args> 01069 iterator 01070 _M_emplace_equal(_Args&&... __args); 01071 01072 template<typename... _Args> 01073 iterator 01074 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args); 01075 01076 template<typename... _Args> 01077 iterator 01078 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args); 01079 #else 01080 pair<iterator, bool> 01081 _M_insert_unique(const value_type& __x); 01082 01083 iterator 01084 _M_insert_equal(const value_type& __x); 01085 01086 template<typename _NodeGen> 01087 iterator 01088 _M_insert_unique_(const_iterator __pos, const value_type& __x, 01089 _NodeGen&); 01090 01091 iterator 01092 _M_insert_unique_(const_iterator __pos, const value_type& __x) 01093 { 01094 _Alloc_node __an(*this); 01095 return _M_insert_unique_(__pos, __x, __an); 01096 } 01097 01098 template<typename _NodeGen> 01099 iterator 01100 _M_insert_equal_(const_iterator __pos, const value_type& __x, 01101 _NodeGen&); 01102 iterator 01103 _M_insert_equal_(const_iterator __pos, const value_type& __x) 01104 { 01105 _Alloc_node __an(*this); 01106 return _M_insert_equal_(__pos, __x, __an); 01107 } 01108 #endif 01109 01110 template<typename _InputIterator> 01111 void 01112 _M_insert_unique(_InputIterator __first, _InputIterator __last); 01113 01114 template<typename _InputIterator> 01115 void 01116 _M_insert_equal(_InputIterator __first, _InputIterator __last); 01117 01118 private: 01119 void 01120 _M_erase_aux(const_iterator __position); 01121 01122 void 01123 _M_erase_aux(const_iterator __first, const_iterator __last); 01124 01125 public: 01126 #if __cplusplus >= 201103L 01127 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01128 // DR 130. Associative erase should return an iterator. 01129 _GLIBCXX_ABI_TAG_CXX11 01130 iterator 01131 erase(const_iterator __position) 01132 { 01133 __glibcxx_assert(__position != end()); 01134 const_iterator __result = __position; 01135 ++__result; 01136 _M_erase_aux(__position); 01137 return __result._M_const_cast(); 01138 } 01139 01140 // LWG 2059. 01141 _GLIBCXX_ABI_TAG_CXX11 01142 iterator 01143 erase(iterator __position) 01144 { 01145 __glibcxx_assert(__position != end()); 01146 iterator __result = __position; 01147 ++__result; 01148 _M_erase_aux(__position); 01149 return __result; 01150 } 01151 #else 01152 void 01153 erase(iterator __position) 01154 { 01155 __glibcxx_assert(__position != end()); 01156 _M_erase_aux(__position); 01157 } 01158 01159 void 01160 erase(const_iterator __position) 01161 { 01162 __glibcxx_assert(__position != end()); 01163 _M_erase_aux(__position); 01164 } 01165 #endif 01166 size_type 01167 erase(const key_type& __x); 01168 01169 #if __cplusplus >= 201103L 01170 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01171 // DR 130. Associative erase should return an iterator. 01172 _GLIBCXX_ABI_TAG_CXX11 01173 iterator 01174 erase(const_iterator __first, const_iterator __last) 01175 { 01176 _M_erase_aux(__first, __last); 01177 return __last._M_const_cast(); 01178 } 01179 #else 01180 void 01181 erase(iterator __first, iterator __last) 01182 { _M_erase_aux(__first, __last); } 01183 01184 void 01185 erase(const_iterator __first, const_iterator __last) 01186 { _M_erase_aux(__first, __last); } 01187 #endif 01188 void 01189 erase(const key_type* __first, const key_type* __last); 01190 01191 void 01192 clear() _GLIBCXX_NOEXCEPT 01193 { 01194 _M_erase(_M_begin()); 01195 _M_impl._M_reset(); 01196 } 01197 01198 // Set operations. 01199 iterator 01200 find(const key_type& __k); 01201 01202 const_iterator 01203 find(const key_type& __k) const; 01204 01205 size_type 01206 count(const key_type& __k) const; 01207 01208 iterator 01209 lower_bound(const key_type& __k) 01210 { return _M_lower_bound(_M_begin(), _M_end(), __k); } 01211 01212 const_iterator 01213 lower_bound(const key_type& __k) const 01214 { return _M_lower_bound(_M_begin(), _M_end(), __k); } 01215 01216 iterator 01217 upper_bound(const key_type& __k) 01218 { return _M_upper_bound(_M_begin(), _M_end(), __k); } 01219 01220 const_iterator 01221 upper_bound(const key_type& __k) const 01222 { return _M_upper_bound(_M_begin(), _M_end(), __k); } 01223 01224 pair<iterator, iterator> 01225 equal_range(const key_type& __k); 01226 01227 pair<const_iterator, const_iterator> 01228 equal_range(const key_type& __k) const; 01229 01230 #if __cplusplus > 201103L 01231 template<typename _Kt, 01232 typename _Req = 01233 typename __has_is_transparent<_Compare, _Kt>::type> 01234 iterator 01235 _M_find_tr(const _Kt& __k) 01236 { 01237 const _Rb_tree* __const_this = this; 01238 return __const_this->_M_find_tr(__k)._M_const_cast(); 01239 } 01240 01241 template<typename _Kt, 01242 typename _Req = 01243 typename __has_is_transparent<_Compare, _Kt>::type> 01244 const_iterator 01245 _M_find_tr(const _Kt& __k) const 01246 { 01247 auto __j = _M_lower_bound_tr(__k); 01248 if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node))) 01249 __j = end(); 01250 return __j; 01251 } 01252 01253 template<typename _Kt, 01254 typename _Req = 01255 typename __has_is_transparent<_Compare, _Kt>::type> 01256 size_type 01257 _M_count_tr(const _Kt& __k) const 01258 { 01259 auto __p = _M_equal_range_tr(__k); 01260 return std::distance(__p.first, __p.second); 01261 } 01262 01263 template<typename _Kt, 01264 typename _Req = 01265 typename __has_is_transparent<_Compare, _Kt>::type> 01266 iterator 01267 _M_lower_bound_tr(const _Kt& __k) 01268 { 01269 const _Rb_tree* __const_this = this; 01270 return __const_this->_M_lower_bound_tr(__k)._M_const_cast(); 01271 } 01272 01273 template<typename _Kt, 01274 typename _Req = 01275 typename __has_is_transparent<_Compare, _Kt>::type> 01276 const_iterator 01277 _M_lower_bound_tr(const _Kt& __k) const 01278 { 01279 auto __x = _M_begin(); 01280 auto __y = _M_end(); 01281 while (__x != 0) 01282 if (!_M_impl._M_key_compare(_S_key(__x), __k)) 01283 { 01284 __y = __x; 01285 __x = _S_left(__x); 01286 } 01287 else 01288 __x = _S_right(__x); 01289 return const_iterator(__y); 01290 } 01291 01292 template<typename _Kt, 01293 typename _Req = 01294 typename __has_is_transparent<_Compare, _Kt>::type> 01295 iterator 01296 _M_upper_bound_tr(const _Kt& __k) 01297 { 01298 const _Rb_tree* __const_this = this; 01299 return __const_this->_M_upper_bound_tr(__k)._M_const_cast(); 01300 } 01301 01302 template<typename _Kt, 01303 typename _Req = 01304 typename __has_is_transparent<_Compare, _Kt>::type> 01305 const_iterator 01306 _M_upper_bound_tr(const _Kt& __k) const 01307 { 01308 auto __x = _M_begin(); 01309 auto __y = _M_end(); 01310 while (__x != 0) 01311 if (_M_impl._M_key_compare(__k, _S_key(__x))) 01312 { 01313 __y = __x; 01314 __x = _S_left(__x); 01315 } 01316 else 01317 __x = _S_right(__x); 01318 return const_iterator(__y); 01319 } 01320 01321 template<typename _Kt, 01322 typename _Req = 01323 typename __has_is_transparent<_Compare, _Kt>::type> 01324 pair<iterator, iterator> 01325 _M_equal_range_tr(const _Kt& __k) 01326 { 01327 const _Rb_tree* __const_this = this; 01328 auto __ret = __const_this->_M_equal_range_tr(__k); 01329 return { __ret.first._M_const_cast(), __ret.second._M_const_cast() }; 01330 } 01331 01332 template<typename _Kt, 01333 typename _Req = 01334 typename __has_is_transparent<_Compare, _Kt>::type> 01335 pair<const_iterator, const_iterator> 01336 _M_equal_range_tr(const _Kt& __k) const 01337 { 01338 auto __low = _M_lower_bound_tr(__k); 01339 auto __high = __low; 01340 auto& __cmp = _M_impl._M_key_compare; 01341 while (__high != end() && !__cmp(__k, _S_key(__high._M_node))) 01342 ++__high; 01343 return { __low, __high }; 01344 } 01345 #endif 01346 01347 // Debugging. 01348 bool 01349 __rb_verify() const; 01350 01351 #if __cplusplus >= 201103L 01352 _Rb_tree& 01353 operator=(_Rb_tree&&) 01354 noexcept(_Alloc_traits::_S_nothrow_move() 01355 && is_nothrow_move_assignable<_Compare>::value); 01356 01357 template<typename _Iterator> 01358 void 01359 _M_assign_unique(_Iterator, _Iterator); 01360 01361 template<typename _Iterator> 01362 void 01363 _M_assign_equal(_Iterator, _Iterator); 01364 01365 private: 01366 // Move elements from container with equal allocator. 01367 void 01368 _M_move_data(_Rb_tree& __x, std::true_type) 01369 { _M_impl._M_move_data(__x._M_impl); } 01370 01371 // Move elements from container with possibly non-equal allocator, 01372 // which might result in a copy not a move. 01373 void 01374 _M_move_data(_Rb_tree&, std::false_type); 01375 01376 // Move assignment from container with equal allocator. 01377 void 01378 _M_move_assign(_Rb_tree&, std::true_type); 01379 01380 // Move assignment from container with possibly non-equal allocator, 01381 // which might result in a copy not a move. 01382 void 01383 _M_move_assign(_Rb_tree&, std::false_type); 01384 #endif 01385 01386 #if __cplusplus > 201402L 01387 public: 01388 /// Re-insert an extracted node. 01389 insert_return_type 01390 _M_reinsert_node_unique(node_type&& __nh) 01391 { 01392 insert_return_type __ret; 01393 if (__nh.empty()) 01394 __ret.position = end(); 01395 else 01396 { 01397 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); 01398 01399 auto __res = _M_get_insert_unique_pos(__nh._M_key()); 01400 if (__res.second) 01401 { 01402 __ret.position 01403 = _M_insert_node(__res.first, __res.second, __nh._M_ptr); 01404 __nh._M_ptr = nullptr; 01405 __ret.inserted = true; 01406 } 01407 else 01408 { 01409 __ret.node = std::move(__nh); 01410 __ret.position = iterator(__res.first); 01411 __ret.inserted = false; 01412 } 01413 } 01414 return __ret; 01415 } 01416 01417 /// Re-insert an extracted node. 01418 iterator 01419 _M_reinsert_node_equal(node_type&& __nh) 01420 { 01421 iterator __ret; 01422 if (__nh.empty()) 01423 __ret = end(); 01424 else 01425 { 01426 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); 01427 auto __res = _M_get_insert_equal_pos(__nh._M_key()); 01428 if (__res.second) 01429 __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr); 01430 else 01431 __ret = _M_insert_equal_lower_node(__nh._M_ptr); 01432 __nh._M_ptr = nullptr; 01433 } 01434 return __ret; 01435 } 01436 01437 /// Re-insert an extracted node. 01438 iterator 01439 _M_reinsert_node_hint_unique(const_iterator __hint, node_type&& __nh) 01440 { 01441 iterator __ret; 01442 if (__nh.empty()) 01443 __ret = end(); 01444 else 01445 { 01446 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); 01447 auto __res = _M_get_insert_hint_unique_pos(__hint, __nh._M_key()); 01448 if (__res.second) 01449 { 01450 __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr); 01451 __nh._M_ptr = nullptr; 01452 } 01453 else 01454 __ret = iterator(__res.first); 01455 } 01456 return __ret; 01457 } 01458 01459 /// Re-insert an extracted node. 01460 iterator 01461 _M_reinsert_node_hint_equal(const_iterator __hint, node_type&& __nh) 01462 { 01463 iterator __ret; 01464 if (__nh.empty()) 01465 __ret = end(); 01466 else 01467 { 01468 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); 01469 auto __res = _M_get_insert_hint_equal_pos(__hint, __nh._M_key()); 01470 if (__res.second) 01471 __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr); 01472 else 01473 __ret = _M_insert_equal_lower_node(__nh._M_ptr); 01474 __nh._M_ptr = nullptr; 01475 } 01476 return __ret; 01477 } 01478 01479 /// Extract a node. 01480 node_type 01481 extract(const_iterator __pos) 01482 { 01483 auto __ptr = _Rb_tree_rebalance_for_erase( 01484 __pos._M_const_cast()._M_node, _M_impl._M_header); 01485 --_M_impl._M_node_count; 01486 return { static_cast<_Link_type>(__ptr), _M_get_Node_allocator() }; 01487 } 01488 01489 /// Extract a node. 01490 node_type 01491 extract(const key_type& __k) 01492 { 01493 node_type __nh; 01494 auto __pos = find(__k); 01495 if (__pos != end()) 01496 __nh = extract(const_iterator(__pos)); 01497 return __nh; 01498 } 01499 01500 template<typename _Compare2> 01501 using _Compatible_tree 01502 = _Rb_tree<_Key, _Val, _KeyOfValue, _Compare2, _Alloc>; 01503 01504 template<typename, typename> 01505 friend class _Rb_tree_merge_helper; 01506 01507 /// Merge from a compatible container into one with unique keys. 01508 template<typename _Compare2> 01509 void 01510 _M_merge_unique(_Compatible_tree<_Compare2>& __src) noexcept 01511 { 01512 using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>; 01513 for (auto __i = __src.begin(), __end = __src.end(); __i != __end;) 01514 { 01515 auto __pos = __i++; 01516 auto __res = _M_get_insert_unique_pos(_KeyOfValue()(*__pos)); 01517 if (__res.second) 01518 { 01519 auto& __src_impl = _Merge_helper::_S_get_impl(__src); 01520 auto __ptr = _Rb_tree_rebalance_for_erase( 01521 __pos._M_node, __src_impl._M_header); 01522 --__src_impl._M_node_count; 01523 _M_insert_node(__res.first, __res.second, 01524 static_cast<_Link_type>(__ptr)); 01525 } 01526 } 01527 } 01528 01529 /// Merge from a compatible container into one with equivalent keys. 01530 template<typename _Compare2> 01531 void 01532 _M_merge_equal(_Compatible_tree<_Compare2>& __src) noexcept 01533 { 01534 using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>; 01535 for (auto __i = __src.begin(), __end = __src.end(); __i != __end;) 01536 { 01537 auto __pos = __i++; 01538 auto __res = _M_get_insert_equal_pos(_KeyOfValue()(*__pos)); 01539 if (__res.second) 01540 { 01541 auto& __src_impl = _Merge_helper::_S_get_impl(__src); 01542 auto __ptr = _Rb_tree_rebalance_for_erase( 01543 __pos._M_node, __src_impl._M_header); 01544 --__src_impl._M_node_count; 01545 _M_insert_node(__res.first, __res.second, 01546 static_cast<_Link_type>(__ptr)); 01547 } 01548 } 01549 } 01550 #endif // C++17 01551 }; 01552 01553 template<typename _Key, typename _Val, typename _KeyOfValue, 01554 typename _Compare, typename _Alloc> 01555 inline bool 01556 operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 01557 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 01558 { 01559 return __x.size() == __y.size() 01560 && std::equal(__x.begin(), __x.end(), __y.begin()); 01561 } 01562 01563 template<typename _Key, typename _Val, typename _KeyOfValue, 01564 typename _Compare, typename _Alloc> 01565 inline bool 01566 operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 01567 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 01568 { 01569 return std::lexicographical_compare(__x.begin(), __x.end(), 01570 __y.begin(), __y.end()); 01571 } 01572 01573 template<typename _Key, typename _Val, typename _KeyOfValue, 01574 typename _Compare, typename _Alloc> 01575 inline bool 01576 operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 01577 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 01578 { return !(__x == __y); } 01579 01580 template<typename _Key, typename _Val, typename _KeyOfValue, 01581 typename _Compare, typename _Alloc> 01582 inline bool 01583 operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 01584 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 01585 { return __y < __x; } 01586 01587 template<typename _Key, typename _Val, typename _KeyOfValue, 01588 typename _Compare, typename _Alloc> 01589 inline bool 01590 operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 01591 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 01592 { return !(__y < __x); } 01593 01594 template<typename _Key, typename _Val, typename _KeyOfValue, 01595 typename _Compare, typename _Alloc> 01596 inline bool 01597 operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 01598 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 01599 { return !(__x < __y); } 01600 01601 template<typename _Key, typename _Val, typename _KeyOfValue, 01602 typename _Compare, typename _Alloc> 01603 inline void 01604 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 01605 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 01606 { __x.swap(__y); } 01607 01608 #if __cplusplus >= 201103L 01609 template<typename _Key, typename _Val, typename _KeyOfValue, 01610 typename _Compare, typename _Alloc> 01611 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01612 _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a) 01613 : _M_impl(__x._M_impl._M_key_compare, std::move(__a)) 01614 { 01615 using __eq = typename _Alloc_traits::is_always_equal; 01616 if (__x._M_root() != nullptr) 01617 _M_move_data(__x, __eq()); 01618 } 01619 01620 template<typename _Key, typename _Val, typename _KeyOfValue, 01621 typename _Compare, typename _Alloc> 01622 void 01623 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01624 _M_move_data(_Rb_tree& __x, std::false_type) 01625 { 01626 if (_M_get_Node_allocator() == __x._M_get_Node_allocator()) 01627 _M_move_data(__x, std::true_type()); 01628 else 01629 { 01630 _Alloc_node __an(*this); 01631 auto __lbd = 01632 [&__an](const value_type& __cval) 01633 { 01634 auto& __val = const_cast<value_type&>(__cval); 01635 return __an(std::move_if_noexcept(__val)); 01636 }; 01637 _M_root() = _M_copy(__x, __lbd); 01638 } 01639 } 01640 01641 template<typename _Key, typename _Val, typename _KeyOfValue, 01642 typename _Compare, typename _Alloc> 01643 inline void 01644 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01645 _M_move_assign(_Rb_tree& __x, true_type) 01646 { 01647 clear(); 01648 if (__x._M_root() != nullptr) 01649 _M_move_data(__x, std::true_type()); 01650 std::__alloc_on_move(_M_get_Node_allocator(), 01651 __x._M_get_Node_allocator()); 01652 } 01653 01654 template<typename _Key, typename _Val, typename _KeyOfValue, 01655 typename _Compare, typename _Alloc> 01656 void 01657 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01658 _M_move_assign(_Rb_tree& __x, false_type) 01659 { 01660 if (_M_get_Node_allocator() == __x._M_get_Node_allocator()) 01661 return _M_move_assign(__x, true_type{}); 01662 01663 // Try to move each node reusing existing nodes and copying __x nodes 01664 // structure. 01665 _Reuse_or_alloc_node __roan(*this); 01666 _M_impl._M_reset(); 01667 if (__x._M_root() != nullptr) 01668 { 01669 auto __lbd = 01670 [&__roan](const value_type& __cval) 01671 { 01672 auto& __val = const_cast<value_type&>(__cval); 01673 return __roan(std::move_if_noexcept(__val)); 01674 }; 01675 _M_root() = _M_copy(__x, __lbd); 01676 __x.clear(); 01677 } 01678 } 01679 01680 template<typename _Key, typename _Val, typename _KeyOfValue, 01681 typename _Compare, typename _Alloc> 01682 inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& 01683 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01684 operator=(_Rb_tree&& __x) 01685 noexcept(_Alloc_traits::_S_nothrow_move() 01686 && is_nothrow_move_assignable<_Compare>::value) 01687 { 01688 _M_impl._M_key_compare = std::move(__x._M_impl._M_key_compare); 01689 _M_move_assign(__x, __bool_constant<_Alloc_traits::_S_nothrow_move()>()); 01690 return *this; 01691 } 01692 01693 template<typename _Key, typename _Val, typename _KeyOfValue, 01694 typename _Compare, typename _Alloc> 01695 template<typename _Iterator> 01696 void 01697 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01698 _M_assign_unique(_Iterator __first, _Iterator __last) 01699 { 01700 _Reuse_or_alloc_node __roan(*this); 01701 _M_impl._M_reset(); 01702 for (; __first != __last; ++__first) 01703 _M_insert_unique_(end(), *__first, __roan); 01704 } 01705 01706 template<typename _Key, typename _Val, typename _KeyOfValue, 01707 typename _Compare, typename _Alloc> 01708 template<typename _Iterator> 01709 void 01710 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01711 _M_assign_equal(_Iterator __first, _Iterator __last) 01712 { 01713 _Reuse_or_alloc_node __roan(*this); 01714 _M_impl._M_reset(); 01715 for (; __first != __last; ++__first) 01716 _M_insert_equal_(end(), *__first, __roan); 01717 } 01718 #endif 01719 01720 template<typename _Key, typename _Val, typename _KeyOfValue, 01721 typename _Compare, typename _Alloc> 01722 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& 01723 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01724 operator=(const _Rb_tree& __x) 01725 { 01726 if (this != &__x) 01727 { 01728 // Note that _Key may be a constant type. 01729 #if __cplusplus >= 201103L 01730 if (_Alloc_traits::_S_propagate_on_copy_assign()) 01731 { 01732 auto& __this_alloc = this->_M_get_Node_allocator(); 01733 auto& __that_alloc = __x._M_get_Node_allocator(); 01734 if (!_Alloc_traits::_S_always_equal() 01735 && __this_alloc != __that_alloc) 01736 { 01737 // Replacement allocator cannot free existing storage, we need 01738 // to erase nodes first. 01739 clear(); 01740 std::__alloc_on_copy(__this_alloc, __that_alloc); 01741 } 01742 } 01743 #endif 01744 01745 _Reuse_or_alloc_node __roan(*this); 01746 _M_impl._M_reset(); 01747 _M_impl._M_key_compare = __x._M_impl._M_key_compare; 01748 if (__x._M_root() != 0) 01749 _M_root() = _M_copy(__x, __roan); 01750 } 01751 01752 return *this; 01753 } 01754 01755 template<typename _Key, typename _Val, typename _KeyOfValue, 01756 typename _Compare, typename _Alloc> 01757 #if __cplusplus >= 201103L 01758 template<typename _Arg, typename _NodeGen> 01759 #else 01760 template<typename _NodeGen> 01761 #endif 01762 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 01763 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01764 _M_insert_(_Base_ptr __x, _Base_ptr __p, 01765 #if __cplusplus >= 201103L 01766 _Arg&& __v, 01767 #else 01768 const _Val& __v, 01769 #endif 01770 _NodeGen& __node_gen) 01771 { 01772 bool __insert_left = (__x != 0 || __p == _M_end() 01773 || _M_impl._M_key_compare(_KeyOfValue()(__v), 01774 _S_key(__p))); 01775 01776 _Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v)); 01777 01778 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, 01779 this->_M_impl._M_header); 01780 ++_M_impl._M_node_count; 01781 return iterator(__z); 01782 } 01783 01784 template<typename _Key, typename _Val, typename _KeyOfValue, 01785 typename _Compare, typename _Alloc> 01786 #if __cplusplus >= 201103L 01787 template<typename _Arg> 01788 #endif 01789 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 01790 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01791 #if __cplusplus >= 201103L 01792 _M_insert_lower(_Base_ptr __p, _Arg&& __v) 01793 #else 01794 _M_insert_lower(_Base_ptr __p, const _Val& __v) 01795 #endif 01796 { 01797 bool __insert_left = (__p == _M_end() 01798 || !_M_impl._M_key_compare(_S_key(__p), 01799 _KeyOfValue()(__v))); 01800 01801 _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v)); 01802 01803 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, 01804 this->_M_impl._M_header); 01805 ++_M_impl._M_node_count; 01806 return iterator(__z); 01807 } 01808 01809 template<typename _Key, typename _Val, typename _KeyOfValue, 01810 typename _Compare, typename _Alloc> 01811 #if __cplusplus >= 201103L 01812 template<typename _Arg> 01813 #endif 01814 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 01815 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01816 #if __cplusplus >= 201103L 01817 _M_insert_equal_lower(_Arg&& __v) 01818 #else 01819 _M_insert_equal_lower(const _Val& __v) 01820 #endif 01821 { 01822 _Link_type __x = _M_begin(); 01823 _Base_ptr __y = _M_end(); 01824 while (__x != 0) 01825 { 01826 __y = __x; 01827 __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? 01828 _S_left(__x) : _S_right(__x); 01829 } 01830 return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v)); 01831 } 01832 01833 template<typename _Key, typename _Val, typename _KoV, 01834 typename _Compare, typename _Alloc> 01835 template<typename _NodeGen> 01836 typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type 01837 _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: 01838 _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen) 01839 { 01840 // Structural copy. __x and __p must be non-null. 01841 _Link_type __top = _M_clone_node(__x, __node_gen); 01842 __top->_M_parent = __p; 01843 01844 __try 01845 { 01846 if (__x->_M_right) 01847 __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen); 01848 __p = __top; 01849 __x = _S_left(__x); 01850 01851 while (__x != 0) 01852 { 01853 _Link_type __y = _M_clone_node(__x, __node_gen); 01854 __p->_M_left = __y; 01855 __y->_M_parent = __p; 01856 if (__x->_M_right) 01857 __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen); 01858 __p = __y; 01859 __x = _S_left(__x); 01860 } 01861 } 01862 __catch(...) 01863 { 01864 _M_erase(__top); 01865 __throw_exception_again; 01866 } 01867 return __top; 01868 } 01869 01870 template<typename _Key, typename _Val, typename _KeyOfValue, 01871 typename _Compare, typename _Alloc> 01872 void 01873 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01874 _M_erase(_Link_type __x) 01875 { 01876 // Erase without rebalancing. 01877 while (__x != 0) 01878 { 01879 _M_erase(_S_right(__x)); 01880 _Link_type __y = _S_left(__x); 01881 _M_drop_node(__x); 01882 __x = __y; 01883 } 01884 } 01885 01886 template<typename _Key, typename _Val, typename _KeyOfValue, 01887 typename _Compare, typename _Alloc> 01888 typename _Rb_tree<_Key, _Val, _KeyOfValue, 01889 _Compare, _Alloc>::iterator 01890 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01891 _M_lower_bound(_Link_type __x, _Base_ptr __y, 01892 const _Key& __k) 01893 { 01894 while (__x != 0) 01895 if (!_M_impl._M_key_compare(_S_key(__x), __k)) 01896 __y = __x, __x = _S_left(__x); 01897 else 01898 __x = _S_right(__x); 01899 return iterator(__y); 01900 } 01901 01902 template<typename _Key, typename _Val, typename _KeyOfValue, 01903 typename _Compare, typename _Alloc> 01904 typename _Rb_tree<_Key, _Val, _KeyOfValue, 01905 _Compare, _Alloc>::const_iterator 01906 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01907 _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y, 01908 const _Key& __k) const 01909 { 01910 while (__x != 0) 01911 if (!_M_impl._M_key_compare(_S_key(__x), __k)) 01912 __y = __x, __x = _S_left(__x); 01913 else 01914 __x = _S_right(__x); 01915 return const_iterator(__y); 01916 } 01917 01918 template<typename _Key, typename _Val, typename _KeyOfValue, 01919 typename _Compare, typename _Alloc> 01920 typename _Rb_tree<_Key, _Val, _KeyOfValue, 01921 _Compare, _Alloc>::iterator 01922 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01923 _M_upper_bound(_Link_type __x, _Base_ptr __y, 01924 const _Key& __k) 01925 { 01926 while (__x != 0) 01927 if (_M_impl._M_key_compare(__k, _S_key(__x))) 01928 __y = __x, __x = _S_left(__x); 01929 else 01930 __x = _S_right(__x); 01931 return iterator(__y); 01932 } 01933 01934 template<typename _Key, typename _Val, typename _KeyOfValue, 01935 typename _Compare, typename _Alloc> 01936 typename _Rb_tree<_Key, _Val, _KeyOfValue, 01937 _Compare, _Alloc>::const_iterator 01938 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01939 _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y, 01940 const _Key& __k) const 01941 { 01942 while (__x != 0) 01943 if (_M_impl._M_key_compare(__k, _S_key(__x))) 01944 __y = __x, __x = _S_left(__x); 01945 else 01946 __x = _S_right(__x); 01947 return const_iterator(__y); 01948 } 01949 01950 template<typename _Key, typename _Val, typename _KeyOfValue, 01951 typename _Compare, typename _Alloc> 01952 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 01953 _Compare, _Alloc>::iterator, 01954 typename _Rb_tree<_Key, _Val, _KeyOfValue, 01955 _Compare, _Alloc>::iterator> 01956 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01957 equal_range(const _Key& __k) 01958 { 01959 _Link_type __x = _M_begin(); 01960 _Base_ptr __y = _M_end(); 01961 while (__x != 0) 01962 { 01963 if (_M_impl._M_key_compare(_S_key(__x), __k)) 01964 __x = _S_right(__x); 01965 else if (_M_impl._M_key_compare(__k, _S_key(__x))) 01966 __y = __x, __x = _S_left(__x); 01967 else 01968 { 01969 _Link_type __xu(__x); 01970 _Base_ptr __yu(__y); 01971 __y = __x, __x = _S_left(__x); 01972 __xu = _S_right(__xu); 01973 return pair<iterator, 01974 iterator>(_M_lower_bound(__x, __y, __k), 01975 _M_upper_bound(__xu, __yu, __k)); 01976 } 01977 } 01978 return pair<iterator, iterator>(iterator(__y), 01979 iterator(__y)); 01980 } 01981 01982 template<typename _Key, typename _Val, typename _KeyOfValue, 01983 typename _Compare, typename _Alloc> 01984 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 01985 _Compare, _Alloc>::const_iterator, 01986 typename _Rb_tree<_Key, _Val, _KeyOfValue, 01987 _Compare, _Alloc>::const_iterator> 01988 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 01989 equal_range(const _Key& __k) const 01990 { 01991 _Const_Link_type __x = _M_begin(); 01992 _Const_Base_ptr __y = _M_end(); 01993 while (__x != 0) 01994 { 01995 if (_M_impl._M_key_compare(_S_key(__x), __k)) 01996 __x = _S_right(__x); 01997 else if (_M_impl._M_key_compare(__k, _S_key(__x))) 01998 __y = __x, __x = _S_left(__x); 01999 else 02000 { 02001 _Const_Link_type __xu(__x); 02002 _Const_Base_ptr __yu(__y); 02003 __y = __x, __x = _S_left(__x); 02004 __xu = _S_right(__xu); 02005 return pair<const_iterator, 02006 const_iterator>(_M_lower_bound(__x, __y, __k), 02007 _M_upper_bound(__xu, __yu, __k)); 02008 } 02009 } 02010 return pair<const_iterator, const_iterator>(const_iterator(__y), 02011 const_iterator(__y)); 02012 } 02013 02014 template<typename _Key, typename _Val, typename _KeyOfValue, 02015 typename _Compare, typename _Alloc> 02016 void 02017 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02018 swap(_Rb_tree& __t) 02019 _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value) 02020 { 02021 if (_M_root() == 0) 02022 { 02023 if (__t._M_root() != 0) 02024 _M_impl._M_move_data(__t._M_impl); 02025 } 02026 else if (__t._M_root() == 0) 02027 __t._M_impl._M_move_data(_M_impl); 02028 else 02029 { 02030 std::swap(_M_root(),__t._M_root()); 02031 std::swap(_M_leftmost(),__t._M_leftmost()); 02032 std::swap(_M_rightmost(),__t._M_rightmost()); 02033 02034 _M_root()->_M_parent = _M_end(); 02035 __t._M_root()->_M_parent = __t._M_end(); 02036 std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); 02037 } 02038 // No need to swap header's color as it does not change. 02039 std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); 02040 02041 _Alloc_traits::_S_on_swap(_M_get_Node_allocator(), 02042 __t._M_get_Node_allocator()); 02043 } 02044 02045 template<typename _Key, typename _Val, typename _KeyOfValue, 02046 typename _Compare, typename _Alloc> 02047 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 02048 _Compare, _Alloc>::_Base_ptr, 02049 typename _Rb_tree<_Key, _Val, _KeyOfValue, 02050 _Compare, _Alloc>::_Base_ptr> 02051 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02052 _M_get_insert_unique_pos(const key_type& __k) 02053 { 02054 typedef pair<_Base_ptr, _Base_ptr> _Res; 02055 _Link_type __x = _M_begin(); 02056 _Base_ptr __y = _M_end(); 02057 bool __comp = true; 02058 while (__x != 0) 02059 { 02060 __y = __x; 02061 __comp = _M_impl._M_key_compare(__k, _S_key(__x)); 02062 __x = __comp ? _S_left(__x) : _S_right(__x); 02063 } 02064 iterator __j = iterator(__y); 02065 if (__comp) 02066 { 02067 if (__j == begin()) 02068 return _Res(__x, __y); 02069 else 02070 --__j; 02071 } 02072 if (_M_impl._M_key_compare(_S_key(__j._M_node), __k)) 02073 return _Res(__x, __y); 02074 return _Res(__j._M_node, 0); 02075 } 02076 02077 template<typename _Key, typename _Val, typename _KeyOfValue, 02078 typename _Compare, typename _Alloc> 02079 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 02080 _Compare, _Alloc>::_Base_ptr, 02081 typename _Rb_tree<_Key, _Val, _KeyOfValue, 02082 _Compare, _Alloc>::_Base_ptr> 02083 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02084 _M_get_insert_equal_pos(const key_type& __k) 02085 { 02086 typedef pair<_Base_ptr, _Base_ptr> _Res; 02087 _Link_type __x = _M_begin(); 02088 _Base_ptr __y = _M_end(); 02089 while (__x != 0) 02090 { 02091 __y = __x; 02092 __x = _M_impl._M_key_compare(__k, _S_key(__x)) ? 02093 _S_left(__x) : _S_right(__x); 02094 } 02095 return _Res(__x, __y); 02096 } 02097 02098 template<typename _Key, typename _Val, typename _KeyOfValue, 02099 typename _Compare, typename _Alloc> 02100 #if __cplusplus >= 201103L 02101 template<typename _Arg> 02102 #endif 02103 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 02104 _Compare, _Alloc>::iterator, bool> 02105 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02106 #if __cplusplus >= 201103L 02107 _M_insert_unique(_Arg&& __v) 02108 #else 02109 _M_insert_unique(const _Val& __v) 02110 #endif 02111 { 02112 typedef pair<iterator, bool> _Res; 02113 pair<_Base_ptr, _Base_ptr> __res 02114 = _M_get_insert_unique_pos(_KeyOfValue()(__v)); 02115 02116 if (__res.second) 02117 { 02118 _Alloc_node __an(*this); 02119 return _Res(_M_insert_(__res.first, __res.second, 02120 _GLIBCXX_FORWARD(_Arg, __v), __an), 02121 true); 02122 } 02123 02124 return _Res(iterator(__res.first), false); 02125 } 02126 02127 template<typename _Key, typename _Val, typename _KeyOfValue, 02128 typename _Compare, typename _Alloc> 02129 #if __cplusplus >= 201103L 02130 template<typename _Arg> 02131 #endif 02132 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02133 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02134 #if __cplusplus >= 201103L 02135 _M_insert_equal(_Arg&& __v) 02136 #else 02137 _M_insert_equal(const _Val& __v) 02138 #endif 02139 { 02140 pair<_Base_ptr, _Base_ptr> __res 02141 = _M_get_insert_equal_pos(_KeyOfValue()(__v)); 02142 _Alloc_node __an(*this); 02143 return _M_insert_(__res.first, __res.second, 02144 _GLIBCXX_FORWARD(_Arg, __v), __an); 02145 } 02146 02147 template<typename _Key, typename _Val, typename _KeyOfValue, 02148 typename _Compare, typename _Alloc> 02149 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 02150 _Compare, _Alloc>::_Base_ptr, 02151 typename _Rb_tree<_Key, _Val, _KeyOfValue, 02152 _Compare, _Alloc>::_Base_ptr> 02153 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02154 _M_get_insert_hint_unique_pos(const_iterator __position, 02155 const key_type& __k) 02156 { 02157 iterator __pos = __position._M_const_cast(); 02158 typedef pair<_Base_ptr, _Base_ptr> _Res; 02159 02160 // end() 02161 if (__pos._M_node == _M_end()) 02162 { 02163 if (size() > 0 02164 && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k)) 02165 return _Res(0, _M_rightmost()); 02166 else 02167 return _M_get_insert_unique_pos(__k); 02168 } 02169 else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node))) 02170 { 02171 // First, try before... 02172 iterator __before = __pos; 02173 if (__pos._M_node == _M_leftmost()) // begin() 02174 return _Res(_M_leftmost(), _M_leftmost()); 02175 else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k)) 02176 { 02177 if (_S_right(__before._M_node) == 0) 02178 return _Res(0, __before._M_node); 02179 else 02180 return _Res(__pos._M_node, __pos._M_node); 02181 } 02182 else 02183 return _M_get_insert_unique_pos(__k); 02184 } 02185 else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k)) 02186 { 02187 // ... then try after. 02188 iterator __after = __pos; 02189 if (__pos._M_node == _M_rightmost()) 02190 return _Res(0, _M_rightmost()); 02191 else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node))) 02192 { 02193 if (_S_right(__pos._M_node) == 0) 02194 return _Res(0, __pos._M_node); 02195 else 02196 return _Res(__after._M_node, __after._M_node); 02197 } 02198 else 02199 return _M_get_insert_unique_pos(__k); 02200 } 02201 else 02202 // Equivalent keys. 02203 return _Res(__pos._M_node, 0); 02204 } 02205 02206 template<typename _Key, typename _Val, typename _KeyOfValue, 02207 typename _Compare, typename _Alloc> 02208 #if __cplusplus >= 201103L 02209 template<typename _Arg, typename _NodeGen> 02210 #else 02211 template<typename _NodeGen> 02212 #endif 02213 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02214 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02215 _M_insert_unique_(const_iterator __position, 02216 #if __cplusplus >= 201103L 02217 _Arg&& __v, 02218 #else 02219 const _Val& __v, 02220 #endif 02221 _NodeGen& __node_gen) 02222 { 02223 pair<_Base_ptr, _Base_ptr> __res 02224 = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v)); 02225 02226 if (__res.second) 02227 return _M_insert_(__res.first, __res.second, 02228 _GLIBCXX_FORWARD(_Arg, __v), 02229 __node_gen); 02230 return iterator(__res.first); 02231 } 02232 02233 template<typename _Key, typename _Val, typename _KeyOfValue, 02234 typename _Compare, typename _Alloc> 02235 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 02236 _Compare, _Alloc>::_Base_ptr, 02237 typename _Rb_tree<_Key, _Val, _KeyOfValue, 02238 _Compare, _Alloc>::_Base_ptr> 02239 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02240 _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k) 02241 { 02242 iterator __pos = __position._M_const_cast(); 02243 typedef pair<_Base_ptr, _Base_ptr> _Res; 02244 02245 // end() 02246 if (__pos._M_node == _M_end()) 02247 { 02248 if (size() > 0 02249 && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost()))) 02250 return _Res(0, _M_rightmost()); 02251 else 02252 return _M_get_insert_equal_pos(__k); 02253 } 02254 else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k)) 02255 { 02256 // First, try before... 02257 iterator __before = __pos; 02258 if (__pos._M_node == _M_leftmost()) // begin() 02259 return _Res(_M_leftmost(), _M_leftmost()); 02260 else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node))) 02261 { 02262 if (_S_right(__before._M_node) == 0) 02263 return _Res(0, __before._M_node); 02264 else 02265 return _Res(__pos._M_node, __pos._M_node); 02266 } 02267 else 02268 return _M_get_insert_equal_pos(__k); 02269 } 02270 else 02271 { 02272 // ... then try after. 02273 iterator __after = __pos; 02274 if (__pos._M_node == _M_rightmost()) 02275 return _Res(0, _M_rightmost()); 02276 else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k)) 02277 { 02278 if (_S_right(__pos._M_node) == 0) 02279 return _Res(0, __pos._M_node); 02280 else 02281 return _Res(__after._M_node, __after._M_node); 02282 } 02283 else 02284 return _Res(0, 0); 02285 } 02286 } 02287 02288 template<typename _Key, typename _Val, typename _KeyOfValue, 02289 typename _Compare, typename _Alloc> 02290 #if __cplusplus >= 201103L 02291 template<typename _Arg, typename _NodeGen> 02292 #else 02293 template<typename _NodeGen> 02294 #endif 02295 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02296 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02297 _M_insert_equal_(const_iterator __position, 02298 #if __cplusplus >= 201103L 02299 _Arg&& __v, 02300 #else 02301 const _Val& __v, 02302 #endif 02303 _NodeGen& __node_gen) 02304 { 02305 pair<_Base_ptr, _Base_ptr> __res 02306 = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v)); 02307 02308 if (__res.second) 02309 return _M_insert_(__res.first, __res.second, 02310 _GLIBCXX_FORWARD(_Arg, __v), 02311 __node_gen); 02312 02313 return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v)); 02314 } 02315 02316 #if __cplusplus >= 201103L 02317 template<typename _Key, typename _Val, typename _KeyOfValue, 02318 typename _Compare, typename _Alloc> 02319 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02320 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02321 _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z) 02322 { 02323 bool __insert_left = (__x != 0 || __p == _M_end() 02324 || _M_impl._M_key_compare(_S_key(__z), 02325 _S_key(__p))); 02326 02327 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, 02328 this->_M_impl._M_header); 02329 ++_M_impl._M_node_count; 02330 return iterator(__z); 02331 } 02332 02333 template<typename _Key, typename _Val, typename _KeyOfValue, 02334 typename _Compare, typename _Alloc> 02335 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02336 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02337 _M_insert_lower_node(_Base_ptr __p, _Link_type __z) 02338 { 02339 bool __insert_left = (__p == _M_end() 02340 || !_M_impl._M_key_compare(_S_key(__p), 02341 _S_key(__z))); 02342 02343 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, 02344 this->_M_impl._M_header); 02345 ++_M_impl._M_node_count; 02346 return iterator(__z); 02347 } 02348 02349 template<typename _Key, typename _Val, typename _KeyOfValue, 02350 typename _Compare, typename _Alloc> 02351 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02352 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02353 _M_insert_equal_lower_node(_Link_type __z) 02354 { 02355 _Link_type __x = _M_begin(); 02356 _Base_ptr __y = _M_end(); 02357 while (__x != 0) 02358 { 02359 __y = __x; 02360 __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ? 02361 _S_left(__x) : _S_right(__x); 02362 } 02363 return _M_insert_lower_node(__y, __z); 02364 } 02365 02366 template<typename _Key, typename _Val, typename _KeyOfValue, 02367 typename _Compare, typename _Alloc> 02368 template<typename... _Args> 02369 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 02370 _Compare, _Alloc>::iterator, bool> 02371 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02372 _M_emplace_unique(_Args&&... __args) 02373 { 02374 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); 02375 02376 __try 02377 { 02378 typedef pair<iterator, bool> _Res; 02379 auto __res = _M_get_insert_unique_pos(_S_key(__z)); 02380 if (__res.second) 02381 return _Res(_M_insert_node(__res.first, __res.second, __z), true); 02382 02383 _M_drop_node(__z); 02384 return _Res(iterator(__res.first), false); 02385 } 02386 __catch(...) 02387 { 02388 _M_drop_node(__z); 02389 __throw_exception_again; 02390 } 02391 } 02392 02393 template<typename _Key, typename _Val, typename _KeyOfValue, 02394 typename _Compare, typename _Alloc> 02395 template<typename... _Args> 02396 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02397 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02398 _M_emplace_equal(_Args&&... __args) 02399 { 02400 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); 02401 02402 __try 02403 { 02404 auto __res = _M_get_insert_equal_pos(_S_key(__z)); 02405 return _M_insert_node(__res.first, __res.second, __z); 02406 } 02407 __catch(...) 02408 { 02409 _M_drop_node(__z); 02410 __throw_exception_again; 02411 } 02412 } 02413 02414 template<typename _Key, typename _Val, typename _KeyOfValue, 02415 typename _Compare, typename _Alloc> 02416 template<typename... _Args> 02417 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02418 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02419 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args) 02420 { 02421 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); 02422 02423 __try 02424 { 02425 auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z)); 02426 02427 if (__res.second) 02428 return _M_insert_node(__res.first, __res.second, __z); 02429 02430 _M_drop_node(__z); 02431 return iterator(__res.first); 02432 } 02433 __catch(...) 02434 { 02435 _M_drop_node(__z); 02436 __throw_exception_again; 02437 } 02438 } 02439 02440 template<typename _Key, typename _Val, typename _KeyOfValue, 02441 typename _Compare, typename _Alloc> 02442 template<typename... _Args> 02443 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 02444 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02445 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args) 02446 { 02447 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); 02448 02449 __try 02450 { 02451 auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z)); 02452 02453 if (__res.second) 02454 return _M_insert_node(__res.first, __res.second, __z); 02455 02456 return _M_insert_equal_lower_node(__z); 02457 } 02458 __catch(...) 02459 { 02460 _M_drop_node(__z); 02461 __throw_exception_again; 02462 } 02463 } 02464 #endif 02465 02466 template<typename _Key, typename _Val, typename _KoV, 02467 typename _Cmp, typename _Alloc> 02468 template<class _II> 02469 void 02470 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: 02471 _M_insert_unique(_II __first, _II __last) 02472 { 02473 _Alloc_node __an(*this); 02474 for (; __first != __last; ++__first) 02475 _M_insert_unique_(end(), *__first, __an); 02476 } 02477 02478 template<typename _Key, typename _Val, typename _KoV, 02479 typename _Cmp, typename _Alloc> 02480 template<class _II> 02481 void 02482 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: 02483 _M_insert_equal(_II __first, _II __last) 02484 { 02485 _Alloc_node __an(*this); 02486 for (; __first != __last; ++__first) 02487 _M_insert_equal_(end(), *__first, __an); 02488 } 02489 02490 template<typename _Key, typename _Val, typename _KeyOfValue, 02491 typename _Compare, typename _Alloc> 02492 void 02493 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02494 _M_erase_aux(const_iterator __position) 02495 { 02496 _Link_type __y = 02497 static_cast<_Link_type>(_Rb_tree_rebalance_for_erase 02498 (const_cast<_Base_ptr>(__position._M_node), 02499 this->_M_impl._M_header)); 02500 _M_drop_node(__y); 02501 --_M_impl._M_node_count; 02502 } 02503 02504 template<typename _Key, typename _Val, typename _KeyOfValue, 02505 typename _Compare, typename _Alloc> 02506 void 02507 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02508 _M_erase_aux(const_iterator __first, const_iterator __last) 02509 { 02510 if (__first == begin() && __last == end()) 02511 clear(); 02512 else 02513 while (__first != __last) 02514 _M_erase_aux(__first++); 02515 } 02516 02517 template<typename _Key, typename _Val, typename _KeyOfValue, 02518 typename _Compare, typename _Alloc> 02519 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type 02520 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02521 erase(const _Key& __x) 02522 { 02523 pair<iterator, iterator> __p = equal_range(__x); 02524 const size_type __old_size = size(); 02525 _M_erase_aux(__p.first, __p.second); 02526 return __old_size - size(); 02527 } 02528 02529 template<typename _Key, typename _Val, typename _KeyOfValue, 02530 typename _Compare, typename _Alloc> 02531 void 02532 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02533 erase(const _Key* __first, const _Key* __last) 02534 { 02535 while (__first != __last) 02536 erase(*__first++); 02537 } 02538 02539 template<typename _Key, typename _Val, typename _KeyOfValue, 02540 typename _Compare, typename _Alloc> 02541 typename _Rb_tree<_Key, _Val, _KeyOfValue, 02542 _Compare, _Alloc>::iterator 02543 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02544 find(const _Key& __k) 02545 { 02546 iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); 02547 return (__j == end() 02548 || _M_impl._M_key_compare(__k, 02549 _S_key(__j._M_node))) ? end() : __j; 02550 } 02551 02552 template<typename _Key, typename _Val, typename _KeyOfValue, 02553 typename _Compare, typename _Alloc> 02554 typename _Rb_tree<_Key, _Val, _KeyOfValue, 02555 _Compare, _Alloc>::const_iterator 02556 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02557 find(const _Key& __k) const 02558 { 02559 const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); 02560 return (__j == end() 02561 || _M_impl._M_key_compare(__k, 02562 _S_key(__j._M_node))) ? end() : __j; 02563 } 02564 02565 template<typename _Key, typename _Val, typename _KeyOfValue, 02566 typename _Compare, typename _Alloc> 02567 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type 02568 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 02569 count(const _Key& __k) const 02570 { 02571 pair<const_iterator, const_iterator> __p = equal_range(__k); 02572 const size_type __n = std::distance(__p.first, __p.second); 02573 return __n; 02574 } 02575 02576 _GLIBCXX_PURE unsigned int 02577 _Rb_tree_black_count(const _Rb_tree_node_base* __node, 02578 const _Rb_tree_node_base* __root) throw (); 02579 02580 template<typename _Key, typename _Val, typename _KeyOfValue, 02581 typename _Compare, typename _Alloc> 02582 bool 02583 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const 02584 { 02585 if (_M_impl._M_node_count == 0 || begin() == end()) 02586 return _M_impl._M_node_count == 0 && begin() == end() 02587 && this->_M_impl._M_header._M_left == _M_end() 02588 && this->_M_impl._M_header._M_right == _M_end(); 02589 02590 unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); 02591 for (const_iterator __it = begin(); __it != end(); ++__it) 02592 { 02593 _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); 02594 _Const_Link_type __L = _S_left(__x); 02595 _Const_Link_type __R = _S_right(__x); 02596 02597 if (__x->_M_color == _S_red) 02598 if ((__L && __L->_M_color == _S_red) 02599 || (__R && __R->_M_color == _S_red)) 02600 return false; 02601 02602 if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) 02603 return false; 02604 if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) 02605 return false; 02606 02607 if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) 02608 return false; 02609 } 02610 02611 if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) 02612 return false; 02613 if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) 02614 return false; 02615 return true; 02616 } 02617 02618 #if __cplusplus > 201402L 02619 // Allow access to internals of compatible _Rb_tree specializations. 02620 template<typename _Key, typename _Val, typename _Sel, typename _Cmp1, 02621 typename _Alloc, typename _Cmp2> 02622 struct _Rb_tree_merge_helper<_Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>, 02623 _Cmp2> 02624 { 02625 private: 02626 friend class _Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>; 02627 02628 static auto& 02629 _S_get_impl(_Rb_tree<_Key, _Val, _Sel, _Cmp2, _Alloc>& __tree) 02630 { return __tree._M_impl; } 02631 }; 02632 #endif // C++17 02633 02634 _GLIBCXX_END_NAMESPACE_VERSION 02635 } // namespace 02636 02637 #endif