libstdc++
stl_tree.h
Go to the documentation of this file.
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