LCOV - code coverage report
Current view: top level - /usr/include/c++/14/bits - stl_tree.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 51.6 % 64 33
Test Date: 2026-02-27 05:14:50 Functions: 14.4 % 90 13
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // RB tree implementation -*- C++ -*-
       2              : 
       3              : // Copyright (C) 2001-2024 Free Software Foundation, Inc.
       4              : //
       5              : // This file is part of the GNU ISO C++ Library.  This library is free
       6              : // software; you can redistribute it and/or modify it under the
       7              : // terms of the GNU General Public License as published by the
       8              : // Free Software Foundation; either version 3, or (at your option)
       9              : // any later version.
      10              : 
      11              : // This library is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : 
      16              : // Under Section 7 of GPL version 3, you are granted additional
      17              : // permissions described in the GCC Runtime Library Exception, version
      18              : // 3.1, as published by the Free Software Foundation.
      19              : 
      20              : // You should have received a copy of the GNU General Public License and
      21              : // a copy of the GCC Runtime Library Exception along with this program;
      22              : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23              : // <http://www.gnu.org/licenses/>.
      24              : 
      25              : /*
      26              :  *
      27              :  * Copyright (c) 1996,1997
      28              :  * Silicon Graphics Computer Systems, Inc.
      29              :  *
      30              :  * Permission to use, copy, modify, distribute and sell this software
      31              :  * and its documentation for any purpose is hereby granted without fee,
      32              :  * provided that the above copyright notice appear in all copies and
      33              :  * that both that copyright notice and this permission notice appear
      34              :  * in supporting documentation.  Silicon Graphics makes no
      35              :  * representations about the suitability of this software for any
      36              :  * purpose.  It is provided "as is" without express or implied warranty.
      37              :  *
      38              :  *
      39              :  * Copyright (c) 1994
      40              :  * Hewlett-Packard Company
      41              :  *
      42              :  * Permission to use, copy, modify, distribute and sell this software
      43              :  * and its documentation for any purpose is hereby granted without fee,
      44              :  * provided that the above copyright notice appear in all copies and
      45              :  * that both that copyright notice and this permission notice appear
      46              :  * in supporting documentation.  Hewlett-Packard Company makes no
      47              :  * representations about the suitability of this software for any
      48              :  * purpose.  It is provided "as is" without express or implied warranty.
      49              :  *
      50              :  *
      51              :  */
      52              : 
      53              : /** @file bits/stl_tree.h
      54              :  *  This is an internal header file, included by other library headers.
      55              :  *  Do not attempt to use it directly. @headername{map,set}
      56              :  */
      57              : 
      58              : #ifndef _STL_TREE_H
      59              : #define _STL_TREE_H 1
      60              : 
      61              : #pragma GCC system_header
      62              : 
      63              : #include <bits/stl_algobase.h>
      64              : #include <bits/allocator.h>
      65              : #include <bits/stl_function.h>
      66              : #include <bits/cpp_type_traits.h>
      67              : #include <ext/alloc_traits.h>
      68              : #if __cplusplus >= 201103L
      69              : # include <ext/aligned_buffer.h>
      70              : #endif
      71              : #if __cplusplus > 201402L
      72              : # include <bits/node_handle.h>
      73              : #endif
      74              : 
      75              : namespace std _GLIBCXX_VISIBILITY(default)
      76              : {
      77              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      78              : 
      79              :   // Red-black tree class, designed for use in implementing STL
      80              :   // associative containers (set, multiset, map, and multimap). The
      81              :   // insertion and deletion algorithms are based on those in Cormen,
      82              :   // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
      83              :   // 1990), except that
      84              :   //
      85              :   // (1) the header cell is maintained with links not only to the root
      86              :   // but also to the leftmost node of the tree, to enable constant
      87              :   // time begin(), and to the rightmost node of the tree, to enable
      88              :   // linear time performance when used with the generic set algorithms
      89              :   // (set_union, etc.)
      90              :   //
      91              :   // (2) when a node being deleted has two children its successor node
      92              :   // is relinked into its place, rather than copied, so that the only
      93              :   // iterators invalidated are those referring to the deleted node.
      94              : 
      95              :   enum _Rb_tree_color { _S_red = false, _S_black = true };
      96              : 
      97              :   struct _Rb_tree_node_base
      98              :   {
      99              :     typedef _Rb_tree_node_base* _Base_ptr;
     100              :     typedef const _Rb_tree_node_base* _Const_Base_ptr;
     101              : 
     102              :     _Rb_tree_color  _M_color;
     103              :     _Base_ptr       _M_parent;
     104              :     _Base_ptr       _M_left;
     105              :     _Base_ptr       _M_right;
     106              : 
     107              :     static _Base_ptr
     108              :     _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     109              :     {
     110              :       while (__x->_M_left != 0) __x = __x->_M_left;
     111              :       return __x;
     112              :     }
     113              : 
     114              :     static _Const_Base_ptr
     115              :     _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     116              :     {
     117              :       while (__x->_M_left != 0) __x = __x->_M_left;
     118              :       return __x;
     119              :     }
     120              : 
     121              :     static _Base_ptr
     122              :     _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     123              :     {
     124              :       while (__x->_M_right != 0) __x = __x->_M_right;
     125              :       return __x;
     126              :     }
     127              : 
     128              :     static _Const_Base_ptr
     129              :     _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     130              :     {
     131              :       while (__x->_M_right != 0) __x = __x->_M_right;
     132              :       return __x;
     133              :     }
     134              :   };
     135              : 
     136              :   // Helper type offering value initialization guarantee on the compare functor.
     137              :   template<typename _Key_compare>
     138              :     struct _Rb_tree_key_compare
     139              :     {
     140              :       _Key_compare      _M_key_compare;
     141              : 
     142              :       _Rb_tree_key_compare()
     143              :       _GLIBCXX_NOEXCEPT_IF(
     144              :     is_nothrow_default_constructible<_Key_compare>::value)
     145              :       : _M_key_compare()
     146              :       { }
     147              : 
     148              :       _Rb_tree_key_compare(const _Key_compare& __comp)
     149              :       : _M_key_compare(__comp)
     150              :       { }
     151              : 
     152              : #if __cplusplus >= 201103L
     153              :       // Copy constructor added for consistency with C++98 mode.
     154              :       _Rb_tree_key_compare(const _Rb_tree_key_compare&) = default;
     155              : 
     156              :       _Rb_tree_key_compare(_Rb_tree_key_compare&& __x)
     157              :     noexcept(is_nothrow_copy_constructible<_Key_compare>::value)
     158              :       : _M_key_compare(__x._M_key_compare)
     159              :       { }
     160              : #endif
     161              :     };
     162              : 
     163              :   // Helper type to manage default initialization of node count and header.
     164              :   struct _Rb_tree_header
     165              :   {
     166              :     _Rb_tree_node_base  _M_header;
     167              :     size_t      _M_node_count; // Keeps track of size of tree.
     168              : 
     169              :     _Rb_tree_header() _GLIBCXX_NOEXCEPT
     170              :     {
     171              :       _M_header._M_color = _S_red;
     172              :       _M_reset();
     173              :     }
     174              : 
     175              : #if __cplusplus >= 201103L
     176              :     _Rb_tree_header(_Rb_tree_header&& __x) noexcept
     177              :     {
     178              :       if (__x._M_header._M_parent != nullptr)
     179              :     _M_move_data(__x);
     180              :       else
     181              :     {
     182              :       _M_header._M_color = _S_red;
     183              :       _M_reset();
     184              :     }
     185              :     }
     186              : #endif
     187              : 
     188              :     void
     189              :     _M_move_data(_Rb_tree_header& __from)
     190              :     {
     191              :       _M_header._M_color = __from._M_header._M_color;
     192              :       _M_header._M_parent = __from._M_header._M_parent;
     193              :       _M_header._M_left = __from._M_header._M_left;
     194              :       _M_header._M_right = __from._M_header._M_right;
     195              :       _M_header._M_parent->_M_parent = &_M_header;
     196              :       _M_node_count = __from._M_node_count;
     197              : 
     198              :       __from._M_reset();
     199              :     }
     200              : 
     201              :     void
     202              :     _M_reset()
     203              :     {
     204              :       _M_header._M_parent = 0;
     205              :       _M_header._M_left = &_M_header;
     206              :       _M_header._M_right = &_M_header;
     207              :       _M_node_count = 0;
     208              :     }
     209              :   };
     210              : 
     211              :   template<typename _Val>
     212              :     struct _Rb_tree_node : public _Rb_tree_node_base
     213              :     {
     214              :       typedef _Rb_tree_node<_Val>* _Link_type;
     215              : 
     216              : #if __cplusplus < 201103L
     217              :       _Val _M_value_field;
     218              : 
     219              :       _Val*
     220              :       _M_valptr()
     221              :       { return std::__addressof(_M_value_field); }
     222              : 
     223              :       const _Val*
     224              :       _M_valptr() const
     225              :       { return std::__addressof(_M_value_field); }
     226              : #else
     227              :       __gnu_cxx::__aligned_membuf<_Val> _M_storage;
     228              : 
     229              :       _Val*
     230            0 :       _M_valptr()
     231            0 :       { return _M_storage._M_ptr(); }
     232              : 
     233              :       const _Val*
     234        82046 :       _M_valptr() const
     235        82046 :       { return _M_storage._M_ptr(); }
     236              : #endif
     237              :     };
     238              : 
     239              :   _GLIBCXX_PURE _Rb_tree_node_base*
     240              :   _Rb_tree_increment(_Rb_tree_node_base* __x) throw ();
     241              : 
     242              :   _GLIBCXX_PURE const _Rb_tree_node_base*
     243              :   _Rb_tree_increment(const _Rb_tree_node_base* __x) throw ();
     244              : 
     245              :   _GLIBCXX_PURE _Rb_tree_node_base*
     246              :   _Rb_tree_decrement(_Rb_tree_node_base* __x) throw ();
     247              : 
     248              :   _GLIBCXX_PURE const _Rb_tree_node_base*
     249              :   _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw ();
     250              : 
     251              :   template<typename _Tp>
     252              :     struct _Rb_tree_iterator
     253              :     {
     254              :       typedef _Tp  value_type;
     255              :       typedef _Tp& reference;
     256              :       typedef _Tp* pointer;
     257              : 
     258              :       typedef bidirectional_iterator_tag iterator_category;
     259              :       typedef ptrdiff_t          difference_type;
     260              : 
     261              :       typedef _Rb_tree_iterator<_Tp>      _Self;
     262              :       typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
     263              :       typedef _Rb_tree_node<_Tp>*     _Link_type;
     264              : 
     265              :       _Rb_tree_iterator() _GLIBCXX_NOEXCEPT
     266              :       : _M_node() { }
     267              : 
     268              :       explicit
     269              :       _Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     270              :       : _M_node(__x) { }
     271              : 
     272              :       reference
     273              :       operator*() const _GLIBCXX_NOEXCEPT
     274              :       { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
     275              : 
     276              :       pointer
     277              :       operator->() const _GLIBCXX_NOEXCEPT
     278              :       { return static_cast<_Link_type> (_M_node)->_M_valptr(); }
     279              : 
     280              :       _Self&
     281              :       operator++() _GLIBCXX_NOEXCEPT
     282              :       {
     283              :     _M_node = _Rb_tree_increment(_M_node);
     284              :     return *this;
     285              :       }
     286              : 
     287              :       _Self
     288              :       operator++(int) _GLIBCXX_NOEXCEPT
     289              :       {
     290              :     _Self __tmp = *this;
     291              :     _M_node = _Rb_tree_increment(_M_node);
     292              :     return __tmp;
     293              :       }
     294              : 
     295              :       _Self&
     296              :       operator--() _GLIBCXX_NOEXCEPT
     297              :       {
     298              :     _M_node = _Rb_tree_decrement(_M_node);
     299              :     return *this;
     300              :       }
     301              : 
     302              :       _Self
     303              :       operator--(int) _GLIBCXX_NOEXCEPT
     304              :       {
     305              :     _Self __tmp = *this;
     306              :     _M_node = _Rb_tree_decrement(_M_node);
     307              :     return __tmp;
     308              :       }
     309              : 
     310              :       friend bool
     311              :       operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
     312              :       { return __x._M_node == __y._M_node; }
     313              : 
     314              : #if ! __cpp_lib_three_way_comparison
     315              :       friend bool
     316              :       operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
     317              :       { return __x._M_node != __y._M_node; }
     318              : #endif
     319              : 
     320              :       _Base_ptr _M_node;
     321              :     };
     322              : 
     323              :   template<typename _Tp>
     324              :     struct _Rb_tree_const_iterator
     325              :     {
     326              :       typedef _Tp    value_type;
     327              :       typedef const _Tp& reference;
     328              :       typedef const _Tp* pointer;
     329              : 
     330              :       typedef _Rb_tree_iterator<_Tp> iterator;
     331              : 
     332              :       typedef bidirectional_iterator_tag iterator_category;
     333              :       typedef ptrdiff_t          difference_type;
     334              : 
     335              :       typedef _Rb_tree_const_iterator<_Tp>        _Self;
     336              :       typedef _Rb_tree_node_base::_Const_Base_ptr   _Base_ptr;
     337              :       typedef const _Rb_tree_node<_Tp>*           _Link_type;
     338              : 
     339              :       _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT
     340              :       : _M_node() { }
     341              : 
     342              :       explicit
     343        14123 :       _Rb_tree_const_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     344        14123 :       : _M_node(__x) { }
     345              : 
     346              :       _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT
     347              :       : _M_node(__it._M_node) { }
     348              : 
     349              :       iterator
     350              :       _M_const_cast() const _GLIBCXX_NOEXCEPT
     351              :       { return iterator(const_cast<typename iterator::_Base_ptr>(_M_node)); }
     352              : 
     353              :       reference
     354         4377 :       operator*() const _GLIBCXX_NOEXCEPT
     355         4377 :       { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
     356              : 
     357              :       pointer
     358              :       operator->() const _GLIBCXX_NOEXCEPT
     359              :       { return static_cast<_Link_type>(_M_node)->_M_valptr(); }
     360              : 
     361              :       _Self&
     362              :       operator++() _GLIBCXX_NOEXCEPT
     363              :       {
     364              :     _M_node = _Rb_tree_increment(_M_node);
     365              :     return *this;
     366              :       }
     367              : 
     368              :       _Self
     369              :       operator++(int) _GLIBCXX_NOEXCEPT
     370              :       {
     371              :     _Self __tmp = *this;
     372              :     _M_node = _Rb_tree_increment(_M_node);
     373              :     return __tmp;
     374              :       }
     375              : 
     376              :       _Self&
     377              :       operator--() _GLIBCXX_NOEXCEPT
     378              :       {
     379              :     _M_node = _Rb_tree_decrement(_M_node);
     380              :     return *this;
     381              :       }
     382              : 
     383              :       _Self
     384              :       operator--(int) _GLIBCXX_NOEXCEPT
     385              :       {
     386              :     _Self __tmp = *this;
     387              :     _M_node = _Rb_tree_decrement(_M_node);
     388              :     return __tmp;
     389              :       }
     390              : 
     391              :       friend bool
     392         9250 :       operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
     393         9250 :       { return __x._M_node == __y._M_node; }
     394              : 
     395              : #if ! __cpp_lib_three_way_comparison
     396              :       friend bool
     397              :       operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
     398              :       { return __x._M_node != __y._M_node; }
     399              : #endif
     400              : 
     401              :       _Base_ptr _M_node;
     402              :     };
     403              : 
     404              :   __attribute__((__nonnull__))
     405              :   void
     406              :   _Rb_tree_insert_and_rebalance(const bool __insert_left,
     407              :                 _Rb_tree_node_base* __x,
     408              :                 _Rb_tree_node_base* __p,
     409              :                 _Rb_tree_node_base& __header) throw ();
     410              : 
     411              :   __attribute__((__nonnull__,__returns_nonnull__))
     412              :   _Rb_tree_node_base*
     413              :   _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
     414              :                    _Rb_tree_node_base& __header) throw ();
     415              : 
     416              : #if __cplusplus > 201402L
     417              :   template<typename _Tree1, typename _Cmp2>
     418              :     struct _Rb_tree_merge_helper { };
     419              : #endif
     420              : 
     421              :   template<typename _Key, typename _Val, typename _KeyOfValue,
     422              :        typename _Compare, typename _Alloc = allocator<_Val> >
     423              :     class _Rb_tree
     424              :     {
     425              :       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
     426              :     rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
     427              : 
     428              :       typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
     429              : 
     430              :     protected:
     431              :       typedef _Rb_tree_node_base*       _Base_ptr;
     432              :       typedef const _Rb_tree_node_base*     _Const_Base_ptr;
     433              :       typedef _Rb_tree_node<_Val>*        _Link_type;
     434              :       typedef const _Rb_tree_node<_Val>*  _Const_Link_type;
     435              : 
     436              :     private:
     437              :       // Functor recycling a pool of nodes and using allocation once the pool
     438              :       // is empty.
     439              :       struct _Reuse_or_alloc_node
     440              :       {
     441              :     _Reuse_or_alloc_node(_Rb_tree& __t)
     442              :     : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t)
     443              :     {
     444              :       if (_M_root)
     445              :         {
     446              :           _M_root->_M_parent = 0;
     447              : 
     448              :           if (_M_nodes->_M_left)
     449              :         _M_nodes = _M_nodes->_M_left;
     450              :         }
     451              :       else
     452              :         _M_nodes = 0;
     453              :     }
     454              : 
     455              : #if __cplusplus >= 201103L
     456              :     _Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete;
     457              : #endif
     458              : 
     459              :     ~_Reuse_or_alloc_node()
     460              :     { _M_t._M_erase(static_cast<_Link_type>(_M_root)); }
     461              : 
     462              :     template<typename _Arg>
     463              :       _Link_type
     464              :       operator()(_GLIBCXX_FWDREF(_Arg) __arg)
     465              :       {
     466              :         _Link_type __node = static_cast<_Link_type>(_M_extract());
     467              :         if (__node)
     468              :           {
     469              :         _M_t._M_destroy_node(__node);
     470              :         _M_t._M_construct_node(__node, _GLIBCXX_FORWARD(_Arg, __arg));
     471              :         return __node;
     472              :           }
     473              : 
     474              :         return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg));
     475              :       }
     476              : 
     477              :       private:
     478              :     _Base_ptr
     479              :     _M_extract()
     480              :     {
     481              :       if (!_M_nodes)
     482              :         return _M_nodes;
     483              : 
     484              :       _Base_ptr __node = _M_nodes;
     485              :       _M_nodes = _M_nodes->_M_parent;
     486              :       if (_M_nodes)
     487              :         {
     488              :           if (_M_nodes->_M_right == __node)
     489              :         {
     490              :           _M_nodes->_M_right = 0;
     491              : 
     492              :           if (_M_nodes->_M_left)
     493              :             {
     494              :               _M_nodes = _M_nodes->_M_left;
     495              : 
     496              :               while (_M_nodes->_M_right)
     497              :             _M_nodes = _M_nodes->_M_right;
     498              : 
     499              :               if (_M_nodes->_M_left)
     500              :             _M_nodes = _M_nodes->_M_left;
     501              :             }
     502              :         }
     503              :           else // __node is on the left.
     504              :         _M_nodes->_M_left = 0;
     505              :         }
     506              :       else
     507              :         _M_root = 0;
     508              : 
     509              :       return __node;
     510              :     }
     511              : 
     512              :     _Base_ptr _M_root;
     513              :     _Base_ptr _M_nodes;
     514              :     _Rb_tree& _M_t;
     515              :       };
     516              : 
     517              :       // Functor similar to the previous one but without any pool of nodes to
     518              :       // recycle.
     519              :       struct _Alloc_node
     520              :       {
     521              :     _Alloc_node(_Rb_tree& __t)
     522              :     : _M_t(__t) { }
     523              : 
     524              :     template<typename _Arg>
     525              :       _Link_type
     526              :       operator()(_GLIBCXX_FWDREF(_Arg) __arg) const
     527              :       { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); }
     528              : 
     529              :       private:
     530              :     _Rb_tree& _M_t;
     531              :       };
     532              : 
     533              :     public:
     534              :       typedef _Key              key_type;
     535              :       typedef _Val              value_type;
     536              :       typedef value_type*           pointer;
     537              :       typedef const value_type*         const_pointer;
     538              :       typedef value_type&           reference;
     539              :       typedef const value_type&         const_reference;
     540              :       typedef size_t                size_type;
     541              :       typedef ptrdiff_t             difference_type;
     542              :       typedef _Alloc                allocator_type;
     543              : 
     544              :       _Node_allocator&
     545            0 :       _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
     546            0 :       { return this->_M_impl; }
     547              : 
     548              :       const _Node_allocator&
     549              :       _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
     550              :       { return this->_M_impl; }
     551              : 
     552              :       allocator_type
     553              :       get_allocator() const _GLIBCXX_NOEXCEPT
     554              :       { return allocator_type(_M_get_Node_allocator()); }
     555              : 
     556              :     protected:
     557              :       _Link_type
     558              :       _M_get_node()
     559              :       { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
     560              : 
     561              :       void
     562            0 :       _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT
     563            0 :       { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
     564              : 
     565              : #if __cplusplus < 201103L
     566              :       void
     567              :       _M_construct_node(_Link_type __node, const value_type& __x)
     568              :       {
     569              :     __try
     570              :       { get_allocator().construct(__node->_M_valptr(), __x); }
     571              :     __catch(...)
     572              :       {
     573              :         _M_put_node(__node);
     574              :         __throw_exception_again;
     575              :       }
     576              :       }
     577              : 
     578              :       _Link_type
     579              :       _M_create_node(const value_type& __x)
     580              :       {
     581              :     _Link_type __tmp = _M_get_node();
     582              :     _M_construct_node(__tmp, __x);
     583              :     return __tmp;
     584              :       }
     585              : #else
     586              :       template<typename... _Args>
     587              :     void
     588              :     _M_construct_node(_Link_type __node, _Args&&... __args)
     589              :     {
     590              :       __try
     591              :         {
     592              :           ::new(__node) _Rb_tree_node<_Val>;
     593              :           _Alloc_traits::construct(_M_get_Node_allocator(),
     594              :                        __node->_M_valptr(),
     595              :                        std::forward<_Args>(__args)...);
     596              :         }
     597              :       __catch(...)
     598              :         {
     599              :           __node->~_Rb_tree_node<_Val>();
     600              :           _M_put_node(__node);
     601              :           __throw_exception_again;
     602              :         }
     603              :     }
     604              : 
     605              :       template<typename... _Args>
     606              :     _Link_type
     607              :     _M_create_node(_Args&&... __args)
     608              :     {
     609              :       _Link_type __tmp = _M_get_node();
     610              :       _M_construct_node(__tmp, std::forward<_Args>(__args)...);
     611              :       return __tmp;
     612              :     }
     613              : #endif
     614              : 
     615              :       void
     616            0 :       _M_destroy_node(_Link_type __p) _GLIBCXX_NOEXCEPT
     617              :       {
     618              : #if __cplusplus < 201103L
     619              :     get_allocator().destroy(__p->_M_valptr());
     620              : #else
     621            0 :     _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
     622            0 :     __p->~_Rb_tree_node<_Val>();
     623              : #endif
     624            0 :       }
     625              : 
     626              :       void
     627            0 :       _M_drop_node(_Link_type __p) _GLIBCXX_NOEXCEPT
     628              :       {
     629            0 :     _M_destroy_node(__p);
     630            0 :     _M_put_node(__p);
     631            0 :       }
     632              : 
     633              :       template<bool _MoveValue, typename _NodeGen>
     634              :     _Link_type
     635              :     _M_clone_node(_Link_type __x, _NodeGen& __node_gen)
     636              :     {
     637              : #if __cplusplus >= 201103L
     638              :       using _Vp = __conditional_t<_MoveValue,
     639              :                       value_type&&,
     640              :                       const value_type&>;
     641              : #endif
     642              :       _Link_type __tmp
     643              :         = __node_gen(_GLIBCXX_FORWARD(_Vp, *__x->_M_valptr()));
     644              :       __tmp->_M_color = __x->_M_color;
     645              :       __tmp->_M_left = 0;
     646              :       __tmp->_M_right = 0;
     647              :       return __tmp;
     648              :     }
     649              : 
     650              :     protected:
     651              : #if _GLIBCXX_INLINE_VERSION
     652              :       template<typename _Key_compare>
     653              : #else
     654              :       // Unused _Is_pod_comparator is kept as it is part of mangled name.
     655              :       template<typename _Key_compare,
     656              :            bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
     657              : #endif
     658              :     struct _Rb_tree_impl
     659              :     : public _Node_allocator
     660              :     , public _Rb_tree_key_compare<_Key_compare>
     661              :     , public _Rb_tree_header
     662              :     {
     663              :       typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare;
     664              : 
     665              :       _Rb_tree_impl()
     666              :         _GLIBCXX_NOEXCEPT_IF(
     667              :         is_nothrow_default_constructible<_Node_allocator>::value
     668              :         && is_nothrow_default_constructible<_Base_key_compare>::value )
     669              :       : _Node_allocator()
     670              :       { }
     671              : 
     672              :       _Rb_tree_impl(const _Rb_tree_impl& __x)
     673              :       : _Node_allocator(_Alloc_traits::_S_select_on_copy(__x))
     674              :       , _Base_key_compare(__x._M_key_compare)
     675              :       , _Rb_tree_header()
     676              :       { }
     677              : 
     678              : #if __cplusplus < 201103L
     679              :       _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
     680              :       : _Node_allocator(__a), _Base_key_compare(__comp)
     681              :       { }
     682              : #else
     683              :       _Rb_tree_impl(_Rb_tree_impl&&)
     684              :         noexcept( is_nothrow_move_constructible<_Base_key_compare>::value )
     685              :       = default;
     686              : 
     687              :       explicit
     688              :       _Rb_tree_impl(_Node_allocator&& __a)
     689              :       : _Node_allocator(std::move(__a))
     690              :       { }
     691              : 
     692              :       _Rb_tree_impl(_Rb_tree_impl&& __x, _Node_allocator&& __a)
     693              :       : _Node_allocator(std::move(__a)),
     694              :         _Base_key_compare(std::move(__x)),
     695              :         _Rb_tree_header(std::move(__x))
     696              :       { }
     697              : 
     698              :       _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
     699              :       : _Node_allocator(std::move(__a)), _Base_key_compare(__comp)
     700              :       { }
     701              : #endif
     702              :     };
     703              : 
     704              :       _Rb_tree_impl<_Compare> _M_impl;
     705              : 
     706              :     protected:
     707              :       _Base_ptr&
     708              :       _M_root() _GLIBCXX_NOEXCEPT
     709              :       { return this->_M_impl._M_header._M_parent; }
     710              : 
     711              :       _Const_Base_ptr
     712              :       _M_root() const _GLIBCXX_NOEXCEPT
     713              :       { return this->_M_impl._M_header._M_parent; }
     714              : 
     715              :       _Base_ptr&
     716              :       _M_leftmost() _GLIBCXX_NOEXCEPT
     717              :       { return this->_M_impl._M_header._M_left; }
     718              : 
     719              :       _Const_Base_ptr
     720              :       _M_leftmost() const _GLIBCXX_NOEXCEPT
     721              :       { return this->_M_impl._M_header._M_left; }
     722              : 
     723              :       _Base_ptr&
     724              :       _M_rightmost() _GLIBCXX_NOEXCEPT
     725              :       { return this->_M_impl._M_header._M_right; }
     726              : 
     727              :       _Const_Base_ptr
     728              :       _M_rightmost() const _GLIBCXX_NOEXCEPT
     729              :       { return this->_M_impl._M_header._M_right; }
     730              : 
     731              :       _Link_type
     732            0 :       _M_mbegin() const _GLIBCXX_NOEXCEPT
     733            0 :       { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
     734              : 
     735              :       _Link_type
     736            0 :       _M_begin() _GLIBCXX_NOEXCEPT
     737            0 :       { return _M_mbegin(); }
     738              : 
     739              :       _Const_Link_type
     740         4625 :       _M_begin() const _GLIBCXX_NOEXCEPT
     741              :       {
     742              :     return static_cast<_Const_Link_type>
     743         4625 :       (this->_M_impl._M_header._M_parent);
     744              :       }
     745              : 
     746              :       _Base_ptr
     747              :       _M_end() _GLIBCXX_NOEXCEPT
     748              :       { return &this->_M_impl._M_header; }
     749              : 
     750              :       _Const_Base_ptr
     751         4625 :       _M_end() const _GLIBCXX_NOEXCEPT
     752         4625 :       { return &this->_M_impl._M_header; }
     753              : 
     754              :       static const _Key&
     755        77669 :       _S_key(_Const_Link_type __x)
     756              :       {
     757              : #if __cplusplus >= 201103L
     758              :     // If we're asking for the key we're presumably using the comparison
     759              :     // object, and so this is a good place to sanity check it.
     760              :     static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
     761              :               "comparison object must be invocable "
     762              :               "with two arguments of key type");
     763              : # if __cplusplus >= 201703L
     764              :     // _GLIBCXX_RESOLVE_LIB_DEFECTS
     765              :     // 2542. Missing const requirements for associative containers
     766              :     if constexpr (__is_invocable<_Compare&, const _Key&, const _Key&>{})
     767              :       static_assert(
     768              :           is_invocable_v<const _Compare&, const _Key&, const _Key&>,
     769              :           "comparison object must be invocable as const");
     770              : # endif // C++17
     771              : #endif // C++11
     772              : 
     773        77669 :     return _KeyOfValue()(*__x->_M_valptr());
     774              :       }
     775              : 
     776              :       static _Link_type
     777            0 :       _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     778            0 :       { return static_cast<_Link_type>(__x->_M_left); }
     779              : 
     780              :       static _Const_Link_type
     781        33108 :       _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     782        33108 :       { return static_cast<_Const_Link_type>(__x->_M_left); }
     783              : 
     784              :       static _Link_type
     785            0 :       _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     786            0 :       { return static_cast<_Link_type>(__x->_M_right); }
     787              : 
     788              :       static _Const_Link_type
     789        39936 :       _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     790        39936 :       { return static_cast<_Const_Link_type>(__x->_M_right); }
     791              : 
     792              :       static const _Key&
     793         4625 :       _S_key(_Const_Base_ptr __x)
     794         4625 :       { return _S_key(static_cast<_Const_Link_type>(__x)); }
     795              : 
     796              :       static _Base_ptr
     797              :       _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     798              :       { return _Rb_tree_node_base::_S_minimum(__x); }
     799              : 
     800              :       static _Const_Base_ptr
     801              :       _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     802              :       { return _Rb_tree_node_base::_S_minimum(__x); }
     803              : 
     804              :       static _Base_ptr
     805              :       _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     806              :       { return _Rb_tree_node_base::_S_maximum(__x); }
     807              : 
     808              :       static _Const_Base_ptr
     809              :       _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     810              :       { return _Rb_tree_node_base::_S_maximum(__x); }
     811              : 
     812              :     public:
     813              :       typedef _Rb_tree_iterator<value_type>       iterator;
     814              :       typedef _Rb_tree_const_iterator<value_type> const_iterator;
     815              : 
     816              :       typedef std::reverse_iterator<iterator>       reverse_iterator;
     817              :       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     818              : 
     819              : #if __cplusplus > 201402L
     820              :       using node_type = _Node_handle<_Key, _Val, _Node_allocator>;
     821              :       using insert_return_type = _Node_insert_return<
     822              :     __conditional_t<is_same_v<_Key, _Val>, const_iterator, iterator>,
     823              :     node_type>;
     824              : #endif
     825              : 
     826              :       pair<_Base_ptr, _Base_ptr>
     827              :       _M_get_insert_unique_pos(const key_type& __k);
     828              : 
     829              :       pair<_Base_ptr, _Base_ptr>
     830              :       _M_get_insert_equal_pos(const key_type& __k);
     831              : 
     832              :       pair<_Base_ptr, _Base_ptr>
     833              :       _M_get_insert_hint_unique_pos(const_iterator __pos,
     834              :                     const key_type& __k);
     835              : 
     836              :       pair<_Base_ptr, _Base_ptr>
     837              :       _M_get_insert_hint_equal_pos(const_iterator __pos,
     838              :                    const key_type& __k);
     839              : 
     840              :     private:
     841              : #if __cplusplus >= 201103L
     842              :       template<typename _Arg, typename _NodeGen>
     843              :     iterator
     844              :     _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v, _NodeGen&);
     845              : 
     846              :       iterator
     847              :       _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
     848              : 
     849              :       template<typename _Arg>
     850              :     iterator
     851              :     _M_insert_lower(_Base_ptr __y, _Arg&& __v);
     852              : 
     853              :       template<typename _Arg>
     854              :     iterator
     855              :     _M_insert_equal_lower(_Arg&& __x);
     856              : 
     857              :       iterator
     858              :       _M_insert_lower_node(_Base_ptr __p, _Link_type __z);
     859              : 
     860              :       iterator
     861              :       _M_insert_equal_lower_node(_Link_type __z);
     862              : #else
     863              :       template<typename _NodeGen>
     864              :     iterator
     865              :     _M_insert_(_Base_ptr __x, _Base_ptr __y,
     866              :            const value_type& __v, _NodeGen&);
     867              : 
     868              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     869              :       // 233. Insertion hints in associative containers.
     870              :       iterator
     871              :       _M_insert_lower(_Base_ptr __y, const value_type& __v);
     872              : 
     873              :       iterator
     874              :       _M_insert_equal_lower(const value_type& __x);
     875              : #endif
     876              : 
     877              :       enum { __as_lvalue, __as_rvalue };
     878              : 
     879              :       template<bool _MoveValues, typename _NodeGen>
     880              :     _Link_type
     881              :     _M_copy(_Link_type, _Base_ptr, _NodeGen&);
     882              : 
     883              :       template<bool _MoveValues, typename _NodeGen>
     884              :     _Link_type
     885              :     _M_copy(const _Rb_tree& __x, _NodeGen& __gen)
     886              :     {
     887              :       _Link_type __root =
     888              :         _M_copy<_MoveValues>(__x._M_mbegin(), _M_end(), __gen);
     889              :       _M_leftmost() = _S_minimum(__root);
     890              :       _M_rightmost() = _S_maximum(__root);
     891              :       _M_impl._M_node_count = __x._M_impl._M_node_count;
     892              :       return __root;
     893              :     }
     894              : 
     895              :       _Link_type
     896              :       _M_copy(const _Rb_tree& __x)
     897              :       {
     898              :     _Alloc_node __an(*this);
     899              :     return _M_copy<__as_lvalue>(__x, __an);
     900              :       }
     901              : 
     902              :       void
     903              :       _M_erase(_Link_type __x);
     904              : 
     905              :       iterator
     906              :       _M_lower_bound(_Link_type __x, _Base_ptr __y,
     907              :              const _Key& __k);
     908              : 
     909              :       const_iterator
     910              :       _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
     911              :              const _Key& __k) const;
     912              : 
     913              :       iterator
     914              :       _M_upper_bound(_Link_type __x, _Base_ptr __y,
     915              :              const _Key& __k);
     916              : 
     917              :       const_iterator
     918              :       _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
     919              :              const _Key& __k) const;
     920              : 
     921              :     public:
     922              :       // allocation/deallocation
     923              : #if __cplusplus < 201103L
     924              :       _Rb_tree() { }
     925              : #else
     926              :       _Rb_tree() = default;
     927              : #endif
     928              : 
     929              :       _Rb_tree(const _Compare& __comp,
     930              :            const allocator_type& __a = allocator_type())
     931              :       : _M_impl(__comp, _Node_allocator(__a)) { }
     932              : 
     933              :       _Rb_tree(const _Rb_tree& __x)
     934              :       : _M_impl(__x._M_impl)
     935              :       {
     936              :     if (__x._M_root() != 0)
     937              :       _M_root() = _M_copy(__x);
     938              :       }
     939              : 
     940              : #if __cplusplus >= 201103L
     941              :       _Rb_tree(const allocator_type& __a)
     942              :       : _M_impl(_Node_allocator(__a))
     943              :       { }
     944              : 
     945              :       _Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
     946              :       : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
     947              :       {
     948              :     if (__x._M_root() != nullptr)
     949              :       _M_root() = _M_copy(__x);
     950              :       }
     951              : 
     952              :       _Rb_tree(_Rb_tree&&) = default;
     953              : 
     954              :       _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
     955              :       : _Rb_tree(std::move(__x), _Node_allocator(__a))
     956              :       { }
     957              : 
     958              :     private:
     959              :       _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, true_type)
     960              :       noexcept(is_nothrow_default_constructible<_Compare>::value)
     961              :       : _M_impl(std::move(__x._M_impl), std::move(__a))
     962              :       { }
     963              : 
     964              :       _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, false_type)
     965              :       : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
     966              :       {
     967              :     if (__x._M_root() != nullptr)
     968              :       _M_move_data(__x, false_type{});
     969              :       }
     970              : 
     971              :     public:
     972              :       _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
     973              :       noexcept( noexcept(
     974              :     _Rb_tree(std::declval<_Rb_tree&&>(), std::declval<_Node_allocator&&>(),
     975              :          std::declval<typename _Alloc_traits::is_always_equal>())) )
     976              :       : _Rb_tree(std::move(__x), std::move(__a),
     977              :          typename _Alloc_traits::is_always_equal{})
     978              :       { }
     979              : #endif
     980              : 
     981            0 :       ~_Rb_tree() _GLIBCXX_NOEXCEPT
     982            0 :       { _M_erase(_M_begin()); }
     983              : 
     984              :       _Rb_tree&
     985              :       operator=(const _Rb_tree& __x);
     986              : 
     987              :       // Accessors.
     988              :       _Compare
     989              :       key_comp() const
     990              :       { return _M_impl._M_key_compare; }
     991              : 
     992              :       iterator
     993              :       begin() _GLIBCXX_NOEXCEPT
     994              :       { return iterator(this->_M_impl._M_header._M_left); }
     995              : 
     996              :       const_iterator
     997              :       begin() const _GLIBCXX_NOEXCEPT
     998              :       { return const_iterator(this->_M_impl._M_header._M_left); }
     999              : 
    1000              :       iterator
    1001              :       end() _GLIBCXX_NOEXCEPT
    1002              :       { return iterator(&this->_M_impl._M_header); }
    1003              : 
    1004              :       const_iterator
    1005         9498 :       end() const _GLIBCXX_NOEXCEPT
    1006         9498 :       { return const_iterator(&this->_M_impl._M_header); }
    1007              : 
    1008              :       reverse_iterator
    1009              :       rbegin() _GLIBCXX_NOEXCEPT
    1010              :       { return reverse_iterator(end()); }
    1011              : 
    1012              :       const_reverse_iterator
    1013              :       rbegin() const _GLIBCXX_NOEXCEPT
    1014              :       { return const_reverse_iterator(end()); }
    1015              : 
    1016              :       reverse_iterator
    1017              :       rend() _GLIBCXX_NOEXCEPT
    1018              :       { return reverse_iterator(begin()); }
    1019              : 
    1020              :       const_reverse_iterator
    1021              :       rend() const _GLIBCXX_NOEXCEPT
    1022              :       { return const_reverse_iterator(begin()); }
    1023              : 
    1024              :       _GLIBCXX_NODISCARD bool
    1025              :       empty() const _GLIBCXX_NOEXCEPT
    1026              :       { return _M_impl._M_node_count == 0; }
    1027              : 
    1028              :       size_type
    1029              :       size() const _GLIBCXX_NOEXCEPT
    1030              :       { return _M_impl._M_node_count; }
    1031              : 
    1032              :       size_type
    1033              :       max_size() const _GLIBCXX_NOEXCEPT
    1034              :       { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
    1035              : 
    1036              :       void
    1037              :       swap(_Rb_tree& __t)
    1038              :       _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value);
    1039              : 
    1040              :       // Insert/erase.
    1041              : #if __cplusplus >= 201103L
    1042              :       template<typename _Arg>
    1043              :     pair<iterator, bool>
    1044              :     _M_insert_unique(_Arg&& __x);
    1045              : 
    1046              :       template<typename _Arg>
    1047              :     iterator
    1048              :     _M_insert_equal(_Arg&& __x);
    1049              : 
    1050              :       template<typename _Arg, typename _NodeGen>
    1051              :     iterator
    1052              :     _M_insert_unique_(const_iterator __pos, _Arg&& __x, _NodeGen&);
    1053              : 
    1054              :       template<typename _Arg>
    1055              :     iterator
    1056              :     _M_insert_unique_(const_iterator __pos, _Arg&& __x)
    1057              :     {
    1058              :       _Alloc_node __an(*this);
    1059              :       return _M_insert_unique_(__pos, std::forward<_Arg>(__x), __an);
    1060              :     }
    1061              : 
    1062              :       template<typename _Arg, typename _NodeGen>
    1063              :     iterator
    1064              :     _M_insert_equal_(const_iterator __pos, _Arg&& __x, _NodeGen&);
    1065              : 
    1066              :       template<typename _Arg>
    1067              :     iterator
    1068              :     _M_insert_equal_(const_iterator __pos, _Arg&& __x)
    1069              :     {
    1070              :       _Alloc_node __an(*this);
    1071              :       return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an);
    1072              :     }
    1073              : 
    1074              :       template<typename... _Args>
    1075              :     pair<iterator, bool>
    1076              :     _M_emplace_unique(_Args&&... __args);
    1077              : 
    1078              :       template<typename... _Args>
    1079              :     iterator
    1080              :     _M_emplace_equal(_Args&&... __args);
    1081              : 
    1082              :       template<typename... _Args>
    1083              :     iterator
    1084              :     _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args);
    1085              : 
    1086              :       template<typename... _Args>
    1087              :     iterator
    1088              :     _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args);
    1089              : 
    1090              :       template<typename _Iter>
    1091              :     using __same_value_type
    1092              :       = is_same<value_type, typename iterator_traits<_Iter>::value_type>;
    1093              : 
    1094              :       template<typename _InputIterator>
    1095              :     __enable_if_t<__same_value_type<_InputIterator>::value>
    1096              :     _M_insert_range_unique(_InputIterator __first, _InputIterator __last)
    1097              :     {
    1098              :       _Alloc_node __an(*this);
    1099              :       for (; __first != __last; ++__first)
    1100              :         _M_insert_unique_(end(), *__first, __an);
    1101              :     }
    1102              : 
    1103              :       template<typename _InputIterator>
    1104              :     __enable_if_t<!__same_value_type<_InputIterator>::value>
    1105              :     _M_insert_range_unique(_InputIterator __first, _InputIterator __last)
    1106              :     {
    1107              :       for (; __first != __last; ++__first)
    1108              :         _M_emplace_unique(*__first);
    1109              :     }
    1110              : 
    1111              :       template<typename _InputIterator>
    1112              :     __enable_if_t<__same_value_type<_InputIterator>::value>
    1113              :     _M_insert_range_equal(_InputIterator __first, _InputIterator __last)
    1114              :     {
    1115              :       _Alloc_node __an(*this);
    1116              :       for (; __first != __last; ++__first)
    1117              :         _M_insert_equal_(end(), *__first, __an);
    1118              :     }
    1119              : 
    1120              :       template<typename _InputIterator>
    1121              :     __enable_if_t<!__same_value_type<_InputIterator>::value>
    1122              :     _M_insert_range_equal(_InputIterator __first, _InputIterator __last)
    1123              :     {
    1124              :       for (; __first != __last; ++__first)
    1125              :         _M_emplace_equal(*__first);
    1126              :     }
    1127              : #else
    1128              :       pair<iterator, bool>
    1129              :       _M_insert_unique(const value_type& __x);
    1130              : 
    1131              :       iterator
    1132              :       _M_insert_equal(const value_type& __x);
    1133              : 
    1134              :       template<typename _NodeGen>
    1135              :     iterator
    1136              :     _M_insert_unique_(const_iterator __pos, const value_type& __x,
    1137              :               _NodeGen&);
    1138              : 
    1139              :       iterator
    1140              :       _M_insert_unique_(const_iterator __pos, const value_type& __x)
    1141              :       {
    1142              :     _Alloc_node __an(*this);
    1143              :     return _M_insert_unique_(__pos, __x, __an);
    1144              :       }
    1145              : 
    1146              :       template<typename _NodeGen>
    1147              :     iterator
    1148              :     _M_insert_equal_(const_iterator __pos, const value_type& __x,
    1149              :              _NodeGen&);
    1150              :       iterator
    1151              :       _M_insert_equal_(const_iterator __pos, const value_type& __x)
    1152              :       {
    1153              :     _Alloc_node __an(*this);
    1154              :     return _M_insert_equal_(__pos, __x, __an);
    1155              :       }
    1156              : 
    1157              :       template<typename _InputIterator>
    1158              :     void
    1159              :     _M_insert_range_unique(_InputIterator __first, _InputIterator __last)
    1160              :     {
    1161              :       _Alloc_node __an(*this);
    1162              :       for (; __first != __last; ++__first)
    1163              :         _M_insert_unique_(end(), *__first, __an);
    1164              :     }
    1165              : 
    1166              :       template<typename _InputIterator>
    1167              :     void
    1168              :     _M_insert_range_equal(_InputIterator __first, _InputIterator __last)
    1169              :     {
    1170              :       _Alloc_node __an(*this);
    1171              :       for (; __first != __last; ++__first)
    1172              :         _M_insert_equal_(end(), *__first, __an);
    1173              :     }
    1174              : #endif
    1175              : 
    1176              :     private:
    1177              :       void
    1178              :       _M_erase_aux(const_iterator __position);
    1179              : 
    1180              :       void
    1181              :       _M_erase_aux(const_iterator __first, const_iterator __last);
    1182              : 
    1183              :     public:
    1184              : #if __cplusplus >= 201103L
    1185              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    1186              :       // DR 130. Associative erase should return an iterator.
    1187              :       _GLIBCXX_ABI_TAG_CXX11
    1188              :       iterator
    1189              :       erase(const_iterator __position)
    1190              :       {
    1191              :     __glibcxx_assert(__position != end());
    1192              :     const_iterator __result = __position;
    1193              :     ++__result;
    1194              :     _M_erase_aux(__position);
    1195              :     return __result._M_const_cast();
    1196              :       }
    1197              : 
    1198              :       // LWG 2059.
    1199              :       _GLIBCXX_ABI_TAG_CXX11
    1200              :       iterator
    1201              :       erase(iterator __position)
    1202              :       {
    1203              :     __glibcxx_assert(__position != end());
    1204              :     iterator __result = __position;
    1205              :     ++__result;
    1206              :     _M_erase_aux(__position);
    1207              :     return __result;
    1208              :       }
    1209              : #else
    1210              :       void
    1211              :       erase(iterator __position)
    1212              :       {
    1213              :     __glibcxx_assert(__position != end());
    1214              :     _M_erase_aux(__position);
    1215              :       }
    1216              : 
    1217              :       void
    1218              :       erase(const_iterator __position)
    1219              :       {
    1220              :     __glibcxx_assert(__position != end());
    1221              :     _M_erase_aux(__position);
    1222              :       }
    1223              : #endif
    1224              : 
    1225              :       size_type
    1226              :       erase(const key_type& __x);
    1227              : 
    1228              : #if __cplusplus >= 201103L
    1229              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    1230              :       // DR 130. Associative erase should return an iterator.
    1231              :       _GLIBCXX_ABI_TAG_CXX11
    1232              :       iterator
    1233              :       erase(const_iterator __first, const_iterator __last)
    1234              :       {
    1235              :     _M_erase_aux(__first, __last);
    1236              :     return __last._M_const_cast();
    1237              :       }
    1238              : #else
    1239              :       void
    1240              :       erase(iterator __first, iterator __last)
    1241              :       { _M_erase_aux(__first, __last); }
    1242              : 
    1243              :       void
    1244              :       erase(const_iterator __first, const_iterator __last)
    1245              :       { _M_erase_aux(__first, __last); }
    1246              : #endif
    1247              : 
    1248              :       void
    1249              :       clear() _GLIBCXX_NOEXCEPT
    1250              :       {
    1251              :     _M_erase(_M_begin());
    1252              :     _M_impl._M_reset();
    1253              :       }
    1254              : 
    1255              :       // Set operations.
    1256              :       iterator
    1257              :       find(const key_type& __k);
    1258              : 
    1259              :       const_iterator
    1260              :       find(const key_type& __k) const;
    1261              : 
    1262              :       size_type
    1263              :       count(const key_type& __k) const;
    1264              : 
    1265              :       iterator
    1266              :       lower_bound(const key_type& __k)
    1267              :       { return _M_lower_bound(_M_begin(), _M_end(), __k); }
    1268              : 
    1269              :       const_iterator
    1270              :       lower_bound(const key_type& __k) const
    1271              :       { return _M_lower_bound(_M_begin(), _M_end(), __k); }
    1272              : 
    1273              :       iterator
    1274              :       upper_bound(const key_type& __k)
    1275              :       { return _M_upper_bound(_M_begin(), _M_end(), __k); }
    1276              : 
    1277              :       const_iterator
    1278              :       upper_bound(const key_type& __k) const
    1279              :       { return _M_upper_bound(_M_begin(), _M_end(), __k); }
    1280              : 
    1281              :       pair<iterator, iterator>
    1282              :       equal_range(const key_type& __k);
    1283              : 
    1284              :       pair<const_iterator, const_iterator>
    1285              :       equal_range(const key_type& __k) const;
    1286              : 
    1287              : #if __cplusplus >= 201402L
    1288              :       template<typename _Kt,
    1289              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1290              :     iterator
    1291              :     _M_find_tr(const _Kt& __k)
    1292              :     {
    1293              :       const _Rb_tree* __const_this = this;
    1294              :       return __const_this->_M_find_tr(__k)._M_const_cast();
    1295              :     }
    1296              : 
    1297              :       template<typename _Kt,
    1298              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1299              :     const_iterator
    1300              :     _M_find_tr(const _Kt& __k) const
    1301              :     {
    1302              :       auto __j = _M_lower_bound_tr(__k);
    1303              :       if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node)))
    1304              :         __j = end();
    1305              :       return __j;
    1306              :     }
    1307              : 
    1308              :       template<typename _Kt,
    1309              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1310              :     size_type
    1311              :     _M_count_tr(const _Kt& __k) const
    1312              :     {
    1313              :       auto __p = _M_equal_range_tr(__k);
    1314              :       return std::distance(__p.first, __p.second);
    1315              :     }
    1316              : 
    1317              :       template<typename _Kt,
    1318              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1319              :     iterator
    1320              :     _M_lower_bound_tr(const _Kt& __k)
    1321              :     {
    1322              :       const _Rb_tree* __const_this = this;
    1323              :       return __const_this->_M_lower_bound_tr(__k)._M_const_cast();
    1324              :     }
    1325              : 
    1326              :       template<typename _Kt,
    1327              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1328              :     const_iterator
    1329              :     _M_lower_bound_tr(const _Kt& __k) const
    1330              :     {
    1331              :       auto __x = _M_begin();
    1332              :       auto __y = _M_end();
    1333              :       while (__x != 0)
    1334              :         if (!_M_impl._M_key_compare(_S_key(__x), __k))
    1335              :           {
    1336              :         __y = __x;
    1337              :         __x = _S_left(__x);
    1338              :           }
    1339              :         else
    1340              :           __x = _S_right(__x);
    1341              :       return const_iterator(__y);
    1342              :     }
    1343              : 
    1344              :       template<typename _Kt,
    1345              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1346              :     iterator
    1347              :     _M_upper_bound_tr(const _Kt& __k)
    1348              :     {
    1349              :       const _Rb_tree* __const_this = this;
    1350              :       return __const_this->_M_upper_bound_tr(__k)._M_const_cast();
    1351              :     }
    1352              : 
    1353              :       template<typename _Kt,
    1354              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1355              :     const_iterator
    1356              :     _M_upper_bound_tr(const _Kt& __k) const
    1357              :     {
    1358              :       auto __x = _M_begin();
    1359              :       auto __y = _M_end();
    1360              :       while (__x != 0)
    1361              :         if (_M_impl._M_key_compare(__k, _S_key(__x)))
    1362              :           {
    1363              :         __y = __x;
    1364              :         __x = _S_left(__x);
    1365              :           }
    1366              :         else
    1367              :           __x = _S_right(__x);
    1368              :       return const_iterator(__y);
    1369              :     }
    1370              : 
    1371              :       template<typename _Kt,
    1372              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1373              :     pair<iterator, iterator>
    1374              :     _M_equal_range_tr(const _Kt& __k)
    1375              :     {
    1376              :       const _Rb_tree* __const_this = this;
    1377              :       auto __ret = __const_this->_M_equal_range_tr(__k);
    1378              :       return { __ret.first._M_const_cast(), __ret.second._M_const_cast() };
    1379              :     }
    1380              : 
    1381              :       template<typename _Kt,
    1382              :            typename _Req = __has_is_transparent_t<_Compare, _Kt>>
    1383              :     pair<const_iterator, const_iterator>
    1384              :     _M_equal_range_tr(const _Kt& __k) const
    1385              :     {
    1386              :       auto __low = _M_lower_bound_tr(__k);
    1387              :       auto __high = __low;
    1388              :       auto& __cmp = _M_impl._M_key_compare;
    1389              :       while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
    1390              :         ++__high;
    1391              :       return { __low, __high };
    1392              :     }
    1393              : #endif
    1394              : 
    1395              :       // Debugging.
    1396              :       bool
    1397              :       __rb_verify() const;
    1398              : 
    1399              : #if __cplusplus >= 201103L
    1400              :       _Rb_tree&
    1401              :       operator=(_Rb_tree&&)
    1402              :       noexcept(_Alloc_traits::_S_nothrow_move()
    1403              :            && is_nothrow_move_assignable<_Compare>::value);
    1404              : 
    1405              :       template<typename _Iterator>
    1406              :     void
    1407              :     _M_assign_unique(_Iterator, _Iterator);
    1408              : 
    1409              :       template<typename _Iterator>
    1410              :     void
    1411              :     _M_assign_equal(_Iterator, _Iterator);
    1412              : 
    1413              :     private:
    1414              :       // Move elements from container with equal allocator.
    1415              :       void
    1416              :       _M_move_data(_Rb_tree& __x, true_type)
    1417              :       { _M_impl._M_move_data(__x._M_impl); }
    1418              : 
    1419              :       // Move elements from container with possibly non-equal allocator,
    1420              :       // which might result in a copy not a move.
    1421              :       void
    1422              :       _M_move_data(_Rb_tree&, false_type);
    1423              : 
    1424              :       // Move assignment from container with equal allocator.
    1425              :       void
    1426              :       _M_move_assign(_Rb_tree&, true_type);
    1427              : 
    1428              :       // Move assignment from container with possibly non-equal allocator,
    1429              :       // which might result in a copy not a move.
    1430              :       void
    1431              :       _M_move_assign(_Rb_tree&, false_type);
    1432              : #endif
    1433              : 
    1434              : #if __glibcxx_node_extract // >= C++17
    1435              :     public:
    1436              :       /// Re-insert an extracted node.
    1437              :       insert_return_type
    1438              :       _M_reinsert_node_unique(node_type&& __nh)
    1439              :       {
    1440              :     insert_return_type __ret;
    1441              :     if (__nh.empty())
    1442              :       __ret.position = end();
    1443              :     else
    1444              :       {
    1445              :         __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
    1446              : 
    1447              :         auto __res = _M_get_insert_unique_pos(__nh._M_key());
    1448              :         if (__res.second)
    1449              :           {
    1450              :         __ret.position
    1451              :           = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
    1452              :         __nh.release();
    1453              :         __ret.inserted = true;
    1454              :           }
    1455              :         else
    1456              :           {
    1457              :         __ret.node = std::move(__nh);
    1458              :         __ret.position = iterator(__res.first);
    1459              :         __ret.inserted = false;
    1460              :           }
    1461              :       }
    1462              :     return __ret;
    1463              :       }
    1464              : 
    1465              :       /// Re-insert an extracted node.
    1466              :       iterator
    1467              :       _M_reinsert_node_equal(node_type&& __nh)
    1468              :       {
    1469              :     iterator __ret;
    1470              :     if (__nh.empty())
    1471              :       __ret = end();
    1472              :     else
    1473              :       {
    1474              :         __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
    1475              :         auto __res = _M_get_insert_equal_pos(__nh._M_key());
    1476              :         if (__res.second)
    1477              :           __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
    1478              :         else
    1479              :           __ret = _M_insert_equal_lower_node(__nh._M_ptr);
    1480              :         __nh.release();
    1481              :       }
    1482              :     return __ret;
    1483              :       }
    1484              : 
    1485              :       /// Re-insert an extracted node.
    1486              :       iterator
    1487              :       _M_reinsert_node_hint_unique(const_iterator __hint, node_type&& __nh)
    1488              :       {
    1489              :     iterator __ret;
    1490              :     if (__nh.empty())
    1491              :       __ret = end();
    1492              :     else
    1493              :       {
    1494              :         __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
    1495              :         auto __res = _M_get_insert_hint_unique_pos(__hint, __nh._M_key());
    1496              :         if (__res.second)
    1497              :           {
    1498              :         __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
    1499              :         __nh.release();
    1500              :           }
    1501              :         else
    1502              :           __ret = iterator(__res.first);
    1503              :       }
    1504              :     return __ret;
    1505              :       }
    1506              : 
    1507              :       /// Re-insert an extracted node.
    1508              :       iterator
    1509              :       _M_reinsert_node_hint_equal(const_iterator __hint, node_type&& __nh)
    1510              :       {
    1511              :     iterator __ret;
    1512              :     if (__nh.empty())
    1513              :       __ret = end();
    1514              :     else
    1515              :       {
    1516              :         __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
    1517              :         auto __res = _M_get_insert_hint_equal_pos(__hint, __nh._M_key());
    1518              :         if (__res.second)
    1519              :           __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
    1520              :         else
    1521              :           __ret = _M_insert_equal_lower_node(__nh._M_ptr);
    1522              :         __nh.release();
    1523              :       }
    1524              :     return __ret;
    1525              :       }
    1526              : 
    1527              :       /// Extract a node.
    1528              :       node_type
    1529              :       extract(const_iterator __pos)
    1530              :       {
    1531              :     auto __ptr = _Rb_tree_rebalance_for_erase(
    1532              :         __pos._M_const_cast()._M_node, _M_impl._M_header);
    1533              :     --_M_impl._M_node_count;
    1534              :     return { static_cast<_Link_type>(__ptr), _M_get_Node_allocator() };
    1535              :       }
    1536              : 
    1537              :       /// Extract a node.
    1538              :       node_type
    1539              :       extract(const key_type& __k)
    1540              :       {
    1541              :     node_type __nh;
    1542              :     auto __pos = find(__k);
    1543              :     if (__pos != end())
    1544              :       __nh = extract(const_iterator(__pos));
    1545              :     return __nh;
    1546              :       }
    1547              : 
    1548              :       template<typename _Compare2>
    1549              :     using _Compatible_tree
    1550              :       = _Rb_tree<_Key, _Val, _KeyOfValue, _Compare2, _Alloc>;
    1551              : 
    1552              :       template<typename, typename>
    1553              :     friend struct _Rb_tree_merge_helper;
    1554              : 
    1555              :       /// Merge from a compatible container into one with unique keys.
    1556              :       template<typename _Compare2>
    1557              :     void
    1558              :     _M_merge_unique(_Compatible_tree<_Compare2>& __src) noexcept
    1559              :     {
    1560              :       using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
    1561              :       for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
    1562              :         {
    1563              :           auto __pos = __i++;
    1564              :           auto __res = _M_get_insert_unique_pos(_KeyOfValue()(*__pos));
    1565              :           if (__res.second)
    1566              :         {
    1567              :           auto& __src_impl = _Merge_helper::_S_get_impl(__src);
    1568              :           auto __ptr = _Rb_tree_rebalance_for_erase(
    1569              :               __pos._M_node, __src_impl._M_header);
    1570              :           --__src_impl._M_node_count;
    1571              :           _M_insert_node(__res.first, __res.second,
    1572              :                  static_cast<_Link_type>(__ptr));
    1573              :         }
    1574              :         }
    1575              :     }
    1576              : 
    1577              :       /// Merge from a compatible container into one with equivalent keys.
    1578              :       template<typename _Compare2>
    1579              :     void
    1580              :     _M_merge_equal(_Compatible_tree<_Compare2>& __src) noexcept
    1581              :     {
    1582              :       using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
    1583              :       for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
    1584              :         {
    1585              :           auto __pos = __i++;
    1586              :           auto __res = _M_get_insert_equal_pos(_KeyOfValue()(*__pos));
    1587              :           if (__res.second)
    1588              :         {
    1589              :           auto& __src_impl = _Merge_helper::_S_get_impl(__src);
    1590              :           auto __ptr = _Rb_tree_rebalance_for_erase(
    1591              :               __pos._M_node, __src_impl._M_header);
    1592              :           --__src_impl._M_node_count;
    1593              :           _M_insert_node(__res.first, __res.second,
    1594              :                  static_cast<_Link_type>(__ptr));
    1595              :         }
    1596              :         }
    1597              :     }
    1598              : #endif // C++17 node_extract
    1599              : 
    1600              :       friend bool
    1601              :       operator==(const _Rb_tree& __x, const _Rb_tree& __y)
    1602              :       {
    1603              :     return __x.size() == __y.size()
    1604              :       && std::equal(__x.begin(), __x.end(), __y.begin());
    1605              :       }
    1606              : 
    1607              : #if __cpp_lib_three_way_comparison
    1608              :       friend auto
    1609              :       operator<=>(const _Rb_tree& __x, const _Rb_tree& __y)
    1610              :       {
    1611              :     if constexpr (requires { typename __detail::__synth3way_t<_Val>; })
    1612              :       return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
    1613              :                             __y.begin(), __y.end(),
    1614              :                             __detail::__synth3way);
    1615              :       }
    1616              : #else
    1617              :       friend bool
    1618              :       operator<(const _Rb_tree& __x, const _Rb_tree& __y)
    1619              :       {
    1620              :     return std::lexicographical_compare(__x.begin(), __x.end(),
    1621              :                         __y.begin(), __y.end());
    1622              :       }
    1623              : #endif
    1624              : 
    1625              :     private:
    1626              : #if __cplusplus >= 201103L
    1627              :       // An RAII _Node handle
    1628              :       struct _Auto_node
    1629              :       {
    1630              :     template<typename... _Args>
    1631              :       _Auto_node(_Rb_tree& __t, _Args&&... __args)
    1632              :       : _M_t(__t),
    1633              :         _M_node(__t._M_create_node(std::forward<_Args>(__args)...))
    1634              :       { }
    1635              : 
    1636              :     ~_Auto_node()
    1637              :     {
    1638              :       if (_M_node)
    1639              :         _M_t._M_drop_node(_M_node);
    1640              :     }
    1641              : 
    1642              :     _Auto_node(_Auto_node&& __n)
    1643              :     : _M_t(__n._M_t), _M_node(__n._M_node)
    1644              :     { __n._M_node = nullptr; }
    1645              : 
    1646              :     const _Key&
    1647              :     _M_key() const
    1648              :     { return _S_key(_M_node); }
    1649              : 
    1650              :     iterator
    1651              :     _M_insert(pair<_Base_ptr, _Base_ptr> __p)
    1652              :     {
    1653              :       auto __it = _M_t._M_insert_node(__p.first, __p.second, _M_node);
    1654              :       _M_node = nullptr;
    1655              :       return __it;
    1656              :     }
    1657              : 
    1658              :     iterator
    1659              :     _M_insert_equal_lower()
    1660              :     {
    1661              :       auto __it = _M_t._M_insert_equal_lower_node(_M_node);
    1662              :       _M_node = nullptr;
    1663              :       return __it;
    1664              :     }
    1665              : 
    1666              :     _Rb_tree& _M_t;
    1667              :     _Link_type _M_node;
    1668              :       };
    1669              : #endif // C++11
    1670              :     };
    1671              : 
    1672              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1673              :        typename _Compare, typename _Alloc>
    1674              :     inline void
    1675              :     swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
    1676              :      _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
    1677              :     { __x.swap(__y); }
    1678              : 
    1679              : #if __cplusplus >= 201103L
    1680              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1681              :        typename _Compare, typename _Alloc>
    1682              :     void
    1683              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1684              :     _M_move_data(_Rb_tree& __x, false_type)
    1685              :     {
    1686              :       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
    1687              :     _M_move_data(__x, true_type());
    1688              :       else
    1689              :     {
    1690              :       constexpr bool __move = !__move_if_noexcept_cond<value_type>::value;
    1691              :       _Alloc_node __an(*this);
    1692              :       _M_root() = _M_copy<__move>(__x, __an);
    1693              :       if _GLIBCXX17_CONSTEXPR (__move)
    1694              :         __x.clear();
    1695              :     }
    1696              :     }
    1697              : 
    1698              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1699              :        typename _Compare, typename _Alloc>
    1700              :     inline void
    1701              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1702              :     _M_move_assign(_Rb_tree& __x, true_type)
    1703              :     {
    1704              :       clear();
    1705              :       if (__x._M_root() != nullptr)
    1706              :     _M_move_data(__x, true_type());
    1707              :       std::__alloc_on_move(_M_get_Node_allocator(),
    1708              :                __x._M_get_Node_allocator());
    1709              :     }
    1710              : 
    1711              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1712              :        typename _Compare, typename _Alloc>
    1713              :     void
    1714              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1715              :     _M_move_assign(_Rb_tree& __x, false_type)
    1716              :     {
    1717              :       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
    1718              :     return _M_move_assign(__x, true_type{});
    1719              : 
    1720              :       // Try to move each node reusing existing nodes and copying __x nodes
    1721              :       // structure.
    1722              :       _Reuse_or_alloc_node __roan(*this);
    1723              :       _M_impl._M_reset();
    1724              :       if (__x._M_root() != nullptr)
    1725              :     {
    1726              :       _M_root() = _M_copy<__as_rvalue>(__x, __roan);
    1727              :       __x.clear();
    1728              :     }
    1729              :     }
    1730              : 
    1731              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1732              :        typename _Compare, typename _Alloc>
    1733              :     inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
    1734              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1735              :     operator=(_Rb_tree&& __x)
    1736              :     noexcept(_Alloc_traits::_S_nothrow_move()
    1737              :          && is_nothrow_move_assignable<_Compare>::value)
    1738              :     {
    1739              :       _M_impl._M_key_compare = std::move(__x._M_impl._M_key_compare);
    1740              :       _M_move_assign(__x, __bool_constant<_Alloc_traits::_S_nothrow_move()>());
    1741              :       return *this;
    1742              :     }
    1743              : 
    1744              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1745              :        typename _Compare, typename _Alloc>
    1746              :     template<typename _Iterator>
    1747              :       void
    1748              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1749              :       _M_assign_unique(_Iterator __first, _Iterator __last)
    1750              :       {
    1751              :     _Reuse_or_alloc_node __roan(*this);
    1752              :     _M_impl._M_reset();
    1753              :     for (; __first != __last; ++__first)
    1754              :       _M_insert_unique_(end(), *__first, __roan);
    1755              :       }
    1756              : 
    1757              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1758              :        typename _Compare, typename _Alloc>
    1759              :     template<typename _Iterator>
    1760              :       void
    1761              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1762              :       _M_assign_equal(_Iterator __first, _Iterator __last)
    1763              :       {
    1764              :     _Reuse_or_alloc_node __roan(*this);
    1765              :     _M_impl._M_reset();
    1766              :     for (; __first != __last; ++__first)
    1767              :       _M_insert_equal_(end(), *__first, __roan);
    1768              :       }
    1769              : #endif
    1770              : 
    1771              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1772              :        typename _Compare, typename _Alloc>
    1773              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
    1774              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1775              :     operator=(const _Rb_tree& __x)
    1776              :     {
    1777              :       if (this != std::__addressof(__x))
    1778              :     {
    1779              :       // Note that _Key may be a constant type.
    1780              : #if __cplusplus >= 201103L
    1781              :       if (_Alloc_traits::_S_propagate_on_copy_assign())
    1782              :         {
    1783              :           auto& __this_alloc = this->_M_get_Node_allocator();
    1784              :           auto& __that_alloc = __x._M_get_Node_allocator();
    1785              :           if (!_Alloc_traits::_S_always_equal()
    1786              :           && __this_alloc != __that_alloc)
    1787              :         {
    1788              :           // Replacement allocator cannot free existing storage, we need
    1789              :           // to erase nodes first.
    1790              :           clear();
    1791              :           std::__alloc_on_copy(__this_alloc, __that_alloc);
    1792              :         }
    1793              :         }
    1794              : #endif
    1795              : 
    1796              :       _Reuse_or_alloc_node __roan(*this);
    1797              :       _M_impl._M_reset();
    1798              :       _M_impl._M_key_compare = __x._M_impl._M_key_compare;
    1799              :       if (__x._M_root() != 0)
    1800              :         _M_root() = _M_copy<__as_lvalue>(__x, __roan);
    1801              :     }
    1802              : 
    1803              :       return *this;
    1804              :     }
    1805              : 
    1806              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1807              :        typename _Compare, typename _Alloc>
    1808              : #if __cplusplus >= 201103L
    1809              :     template<typename _Arg, typename _NodeGen>
    1810              : #else
    1811              :     template<typename _NodeGen>
    1812              : #endif
    1813              :       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
    1814              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1815              :       _M_insert_(_Base_ptr __x, _Base_ptr __p,
    1816              : #if __cplusplus >= 201103L
    1817              :          _Arg&& __v,
    1818              : #else
    1819              :          const _Val& __v,
    1820              : #endif
    1821              :          _NodeGen& __node_gen)
    1822              :       {
    1823              :     bool __insert_left = (__x != 0 || __p == _M_end()
    1824              :                   || _M_impl._M_key_compare(_KeyOfValue()(__v),
    1825              :                             _S_key(__p)));
    1826              : 
    1827              :     _Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v));
    1828              : 
    1829              :     _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
    1830              :                       this->_M_impl._M_header);
    1831              :     ++_M_impl._M_node_count;
    1832              :     return iterator(__z);
    1833              :       }
    1834              : 
    1835              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1836              :        typename _Compare, typename _Alloc>
    1837              : #if __cplusplus >= 201103L
    1838              :     template<typename _Arg>
    1839              : #endif
    1840              :     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
    1841              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1842              : #if __cplusplus >= 201103L
    1843              :     _M_insert_lower(_Base_ptr __p, _Arg&& __v)
    1844              : #else
    1845              :     _M_insert_lower(_Base_ptr __p, const _Val& __v)
    1846              : #endif
    1847              :     {
    1848              :       bool __insert_left = (__p == _M_end()
    1849              :                 || !_M_impl._M_key_compare(_S_key(__p),
    1850              :                                _KeyOfValue()(__v)));
    1851              : 
    1852              :       _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
    1853              : 
    1854              :       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
    1855              :                     this->_M_impl._M_header);
    1856              :       ++_M_impl._M_node_count;
    1857              :       return iterator(__z);
    1858              :     }
    1859              : 
    1860              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1861              :        typename _Compare, typename _Alloc>
    1862              : #if __cplusplus >= 201103L
    1863              :     template<typename _Arg>
    1864              : #endif
    1865              :     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
    1866              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1867              : #if __cplusplus >= 201103L
    1868              :     _M_insert_equal_lower(_Arg&& __v)
    1869              : #else
    1870              :     _M_insert_equal_lower(const _Val& __v)
    1871              : #endif
    1872              :     {
    1873              :       _Link_type __x = _M_begin();
    1874              :       _Base_ptr __y = _M_end();
    1875              :       while (__x != 0)
    1876              :     {
    1877              :       __y = __x;
    1878              :       __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
    1879              :         _S_left(__x) : _S_right(__x);
    1880              :     }
    1881              :       return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v));
    1882              :     }
    1883              : 
    1884              :   template<typename _Key, typename _Val, typename _KoV,
    1885              :        typename _Compare, typename _Alloc>
    1886              :     template<bool _MoveValues, typename _NodeGen>
    1887              :       typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
    1888              :       _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
    1889              :       _M_copy(_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
    1890              :       {
    1891              :     // Structural copy. __x and __p must be non-null.
    1892              :     _Link_type __top = _M_clone_node<_MoveValues>(__x, __node_gen);
    1893              :     __top->_M_parent = __p;
    1894              : 
    1895              :     __try
    1896              :       {
    1897              :         if (__x->_M_right)
    1898              :           __top->_M_right =
    1899              :         _M_copy<_MoveValues>(_S_right(__x), __top, __node_gen);
    1900              :         __p = __top;
    1901              :         __x = _S_left(__x);
    1902              : 
    1903              :         while (__x != 0)
    1904              :           {
    1905              :         _Link_type __y = _M_clone_node<_MoveValues>(__x, __node_gen);
    1906              :         __p->_M_left = __y;
    1907              :         __y->_M_parent = __p;
    1908              :         if (__x->_M_right)
    1909              :           __y->_M_right = _M_copy<_MoveValues>(_S_right(__x),
    1910              :                                __y, __node_gen);
    1911              :         __p = __y;
    1912              :         __x = _S_left(__x);
    1913              :           }
    1914              :       }
    1915              :     __catch(...)
    1916              :       {
    1917              :         _M_erase(__top);
    1918              :         __throw_exception_again;
    1919              :       }
    1920              :     return __top;
    1921              :       }
    1922              : 
    1923              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1924              :        typename _Compare, typename _Alloc>
    1925              :     void
    1926            0 :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1927              :     _M_erase(_Link_type __x)
    1928              :     {
    1929              :       // Erase without rebalancing.
    1930            0 :       while (__x != 0)
    1931              :     {
    1932            0 :       _M_erase(_S_right(__x));
    1933            0 :       _Link_type __y = _S_left(__x);
    1934            0 :       _M_drop_node(__x);
    1935            0 :       __x = __y;
    1936              :     }
    1937            0 :     }
    1938              : 
    1939              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1940              :        typename _Compare, typename _Alloc>
    1941              :     typename _Rb_tree<_Key, _Val, _KeyOfValue,
    1942              :               _Compare, _Alloc>::iterator
    1943              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1944              :     _M_lower_bound(_Link_type __x, _Base_ptr __y,
    1945              :            const _Key& __k)
    1946              :     {
    1947              :       while (__x != 0)
    1948              :     if (!_M_impl._M_key_compare(_S_key(__x), __k))
    1949              :       __y = __x, __x = _S_left(__x);
    1950              :     else
    1951              :       __x = _S_right(__x);
    1952              :       return iterator(__y);
    1953              :     }
    1954              : 
    1955              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1956              :        typename _Compare, typename _Alloc>
    1957              :     typename _Rb_tree<_Key, _Val, _KeyOfValue,
    1958              :               _Compare, _Alloc>::const_iterator
    1959         4625 :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1960              :     _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
    1961              :            const _Key& __k) const
    1962              :     {
    1963        77669 :       while (__x != 0)
    1964        73044 :     if (!_M_impl._M_key_compare(_S_key(__x), __k))
    1965        33108 :       __y = __x, __x = _S_left(__x);
    1966              :     else
    1967        39936 :       __x = _S_right(__x);
    1968         4625 :       return const_iterator(__y);
    1969              :     }
    1970              : 
    1971              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1972              :        typename _Compare, typename _Alloc>
    1973              :     typename _Rb_tree<_Key, _Val, _KeyOfValue,
    1974              :               _Compare, _Alloc>::iterator
    1975              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1976              :     _M_upper_bound(_Link_type __x, _Base_ptr __y,
    1977              :            const _Key& __k)
    1978              :     {
    1979              :       while (__x != 0)
    1980              :     if (_M_impl._M_key_compare(__k, _S_key(__x)))
    1981              :       __y = __x, __x = _S_left(__x);
    1982              :     else
    1983              :       __x = _S_right(__x);
    1984              :       return iterator(__y);
    1985              :     }
    1986              : 
    1987              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    1988              :        typename _Compare, typename _Alloc>
    1989              :     typename _Rb_tree<_Key, _Val, _KeyOfValue,
    1990              :               _Compare, _Alloc>::const_iterator
    1991              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    1992              :     _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
    1993              :            const _Key& __k) const
    1994              :     {
    1995              :       while (__x != 0)
    1996              :     if (_M_impl._M_key_compare(__k, _S_key(__x)))
    1997              :       __y = __x, __x = _S_left(__x);
    1998              :     else
    1999              :       __x = _S_right(__x);
    2000              :       return const_iterator(__y);
    2001              :     }
    2002              : 
    2003              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2004              :        typename _Compare, typename _Alloc>
    2005              :     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2006              :                _Compare, _Alloc>::iterator,
    2007              :      typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2008              :                _Compare, _Alloc>::iterator>
    2009              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2010              :     equal_range(const _Key& __k)
    2011              :     {
    2012              :       _Link_type __x = _M_begin();
    2013              :       _Base_ptr __y = _M_end();
    2014              :       while (__x != 0)
    2015              :     {
    2016              :       if (_M_impl._M_key_compare(_S_key(__x), __k))
    2017              :         __x = _S_right(__x);
    2018              :       else if (_M_impl._M_key_compare(__k, _S_key(__x)))
    2019              :         __y = __x, __x = _S_left(__x);
    2020              :       else
    2021              :         {
    2022              :           _Link_type __xu(__x);
    2023              :           _Base_ptr __yu(__y);
    2024              :           __y = __x, __x = _S_left(__x);
    2025              :           __xu = _S_right(__xu);
    2026              :           return pair<iterator,
    2027              :               iterator>(_M_lower_bound(__x, __y, __k),
    2028              :                     _M_upper_bound(__xu, __yu, __k));
    2029              :         }
    2030              :     }
    2031              :       return pair<iterator, iterator>(iterator(__y),
    2032              :                       iterator(__y));
    2033              :     }
    2034              : 
    2035              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2036              :        typename _Compare, typename _Alloc>
    2037              :     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2038              :                _Compare, _Alloc>::const_iterator,
    2039              :      typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2040              :                _Compare, _Alloc>::const_iterator>
    2041              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2042              :     equal_range(const _Key& __k) const
    2043              :     {
    2044              :       _Const_Link_type __x = _M_begin();
    2045              :       _Const_Base_ptr __y = _M_end();
    2046              :       while (__x != 0)
    2047              :     {
    2048              :       if (_M_impl._M_key_compare(_S_key(__x), __k))
    2049              :         __x = _S_right(__x);
    2050              :       else if (_M_impl._M_key_compare(__k, _S_key(__x)))
    2051              :         __y = __x, __x = _S_left(__x);
    2052              :       else
    2053              :         {
    2054              :           _Const_Link_type __xu(__x);
    2055              :           _Const_Base_ptr __yu(__y);
    2056              :           __y = __x, __x = _S_left(__x);
    2057              :           __xu = _S_right(__xu);
    2058              :           return pair<const_iterator,
    2059              :               const_iterator>(_M_lower_bound(__x, __y, __k),
    2060              :                       _M_upper_bound(__xu, __yu, __k));
    2061              :         }
    2062              :     }
    2063              :       return pair<const_iterator, const_iterator>(const_iterator(__y),
    2064              :                           const_iterator(__y));
    2065              :     }
    2066              : 
    2067              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2068              :        typename _Compare, typename _Alloc>
    2069              :     void
    2070              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2071              :     swap(_Rb_tree& __t)
    2072              :     _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value)
    2073              :     {
    2074              :       if (_M_root() == 0)
    2075              :     {
    2076              :       if (__t._M_root() != 0)
    2077              :         _M_impl._M_move_data(__t._M_impl);
    2078              :     }
    2079              :       else if (__t._M_root() == 0)
    2080              :     __t._M_impl._M_move_data(_M_impl);
    2081              :       else
    2082              :     {
    2083              :       std::swap(_M_root(),__t._M_root());
    2084              :       std::swap(_M_leftmost(),__t._M_leftmost());
    2085              :       std::swap(_M_rightmost(),__t._M_rightmost());
    2086              : 
    2087              :       _M_root()->_M_parent = _M_end();
    2088              :       __t._M_root()->_M_parent = __t._M_end();
    2089              :       std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
    2090              :     }
    2091              :       // No need to swap header's color as it does not change.
    2092              : 
    2093              :       using std::swap;
    2094              :       swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
    2095              : 
    2096              :       _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
    2097              :                 __t._M_get_Node_allocator());
    2098              :     }
    2099              : 
    2100              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2101              :        typename _Compare, typename _Alloc>
    2102              :     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2103              :                _Compare, _Alloc>::_Base_ptr,
    2104              :      typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2105              :                _Compare, _Alloc>::_Base_ptr>
    2106              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2107              :     _M_get_insert_unique_pos(const key_type& __k)
    2108              :     {
    2109              :       typedef pair<_Base_ptr, _Base_ptr> _Res;
    2110              :       _Link_type __x = _M_begin();
    2111              :       _Base_ptr __y = _M_end();
    2112              :       bool __comp = true;
    2113              :       while (__x != 0)
    2114              :     {
    2115              :       __y = __x;
    2116              :       __comp = _M_impl._M_key_compare(__k, _S_key(__x));
    2117              :       __x = __comp ? _S_left(__x) : _S_right(__x);
    2118              :     }
    2119              :       iterator __j = iterator(__y);
    2120              :       if (__comp)
    2121              :     {
    2122              :       if (__j == begin())
    2123              :         return _Res(__x, __y);
    2124              :       else
    2125              :         --__j;
    2126              :     }
    2127              :       if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
    2128              :     return _Res(__x, __y);
    2129              :       return _Res(__j._M_node, 0);
    2130              :     }
    2131              : 
    2132              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2133              :        typename _Compare, typename _Alloc>
    2134              :     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2135              :                _Compare, _Alloc>::_Base_ptr,
    2136              :      typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2137              :                _Compare, _Alloc>::_Base_ptr>
    2138              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2139              :     _M_get_insert_equal_pos(const key_type& __k)
    2140              :     {
    2141              :       typedef pair<_Base_ptr, _Base_ptr> _Res;
    2142              :       _Link_type __x = _M_begin();
    2143              :       _Base_ptr __y = _M_end();
    2144              :       while (__x != 0)
    2145              :     {
    2146              :       __y = __x;
    2147              :       __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
    2148              :         _S_left(__x) : _S_right(__x);
    2149              :     }
    2150              :       return _Res(__x, __y);
    2151              :     }
    2152              : 
    2153              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2154              :        typename _Compare, typename _Alloc>
    2155              : #if __cplusplus >= 201103L
    2156              :     template<typename _Arg>
    2157              : #endif
    2158              :     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2159              :                _Compare, _Alloc>::iterator, bool>
    2160              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2161              : #if __cplusplus >= 201103L
    2162              :     _M_insert_unique(_Arg&& __v)
    2163              : #else
    2164              :     _M_insert_unique(const _Val& __v)
    2165              : #endif
    2166              :     {
    2167              :       typedef pair<iterator, bool> _Res;
    2168              :       pair<_Base_ptr, _Base_ptr> __res
    2169              :     = _M_get_insert_unique_pos(_KeyOfValue()(__v));
    2170              : 
    2171              :       if (__res.second)
    2172              :     {
    2173              :       _Alloc_node __an(*this);
    2174              :       return _Res(_M_insert_(__res.first, __res.second,
    2175              :                  _GLIBCXX_FORWARD(_Arg, __v), __an),
    2176              :               true);
    2177              :     }
    2178              : 
    2179              :       return _Res(iterator(__res.first), false);
    2180              :     }
    2181              : 
    2182              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2183              :        typename _Compare, typename _Alloc>
    2184              : #if __cplusplus >= 201103L
    2185              :     template<typename _Arg>
    2186              : #endif
    2187              :     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
    2188              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2189              : #if __cplusplus >= 201103L
    2190              :     _M_insert_equal(_Arg&& __v)
    2191              : #else
    2192              :     _M_insert_equal(const _Val& __v)
    2193              : #endif
    2194              :     {
    2195              :       pair<_Base_ptr, _Base_ptr> __res
    2196              :     = _M_get_insert_equal_pos(_KeyOfValue()(__v));
    2197              :       _Alloc_node __an(*this);
    2198              :       return _M_insert_(__res.first, __res.second,
    2199              :             _GLIBCXX_FORWARD(_Arg, __v), __an);
    2200              :     }
    2201              : 
    2202              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2203              :        typename _Compare, typename _Alloc>
    2204              :     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2205              :                _Compare, _Alloc>::_Base_ptr,
    2206              :      typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2207              :                _Compare, _Alloc>::_Base_ptr>
    2208              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2209              :     _M_get_insert_hint_unique_pos(const_iterator __position,
    2210              :                   const key_type& __k)
    2211              :     {
    2212              :       iterator __pos = __position._M_const_cast();
    2213              :       typedef pair<_Base_ptr, _Base_ptr> _Res;
    2214              : 
    2215              :       // end()
    2216              :       if (__pos._M_node == _M_end())
    2217              :     {
    2218              :       if (size() > 0
    2219              :           && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k))
    2220              :         return _Res(0, _M_rightmost());
    2221              :       else
    2222              :         return _M_get_insert_unique_pos(__k);
    2223              :     }
    2224              :       else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node)))
    2225              :     {
    2226              :       // First, try before...
    2227              :       iterator __before = __pos;
    2228              :       if (__pos._M_node == _M_leftmost()) // begin()
    2229              :         return _Res(_M_leftmost(), _M_leftmost());
    2230              :       else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k))
    2231              :         {
    2232              :           if (_S_right(__before._M_node) == 0)
    2233              :         return _Res(0, __before._M_node);
    2234              :           else
    2235              :         return _Res(__pos._M_node, __pos._M_node);
    2236              :         }
    2237              :       else
    2238              :         return _M_get_insert_unique_pos(__k);
    2239              :     }
    2240              :       else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
    2241              :     {
    2242              :       // ... then try after.
    2243              :       iterator __after = __pos;
    2244              :       if (__pos._M_node == _M_rightmost())
    2245              :         return _Res(0, _M_rightmost());
    2246              :       else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node)))
    2247              :         {
    2248              :           if (_S_right(__pos._M_node) == 0)
    2249              :         return _Res(0, __pos._M_node);
    2250              :           else
    2251              :         return _Res(__after._M_node, __after._M_node);
    2252              :         }
    2253              :       else
    2254              :         return _M_get_insert_unique_pos(__k);
    2255              :     }
    2256              :       else
    2257              :     // Equivalent keys.
    2258              :     return _Res(__pos._M_node, 0);
    2259              :     }
    2260              : 
    2261              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2262              :        typename _Compare, typename _Alloc>
    2263              : #if __cplusplus >= 201103L
    2264              :     template<typename _Arg, typename _NodeGen>
    2265              : #else
    2266              :     template<typename _NodeGen>
    2267              : #endif
    2268              :       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
    2269              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2270              :       _M_insert_unique_(const_iterator __position,
    2271              : #if __cplusplus >= 201103L
    2272              :             _Arg&& __v,
    2273              : #else
    2274              :             const _Val& __v,
    2275              : #endif
    2276              :             _NodeGen& __node_gen)
    2277              :     {
    2278              :       pair<_Base_ptr, _Base_ptr> __res
    2279              :     = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
    2280              : 
    2281              :       if (__res.second)
    2282              :     return _M_insert_(__res.first, __res.second,
    2283              :               _GLIBCXX_FORWARD(_Arg, __v),
    2284              :               __node_gen);
    2285              :       return iterator(__res.first);
    2286              :     }
    2287              : 
    2288              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2289              :        typename _Compare, typename _Alloc>
    2290              :     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2291              :                _Compare, _Alloc>::_Base_ptr,
    2292              :      typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2293              :                _Compare, _Alloc>::_Base_ptr>
    2294              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2295              :     _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k)
    2296              :     {
    2297              :       iterator __pos = __position._M_const_cast();
    2298              :       typedef pair<_Base_ptr, _Base_ptr> _Res;
    2299              : 
    2300              :       // end()
    2301              :       if (__pos._M_node == _M_end())
    2302              :     {
    2303              :       if (size() > 0
    2304              :           && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost())))
    2305              :         return _Res(0, _M_rightmost());
    2306              :       else
    2307              :         return _M_get_insert_equal_pos(__k);
    2308              :     }
    2309              :       else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
    2310              :     {
    2311              :       // First, try before...
    2312              :       iterator __before = __pos;
    2313              :       if (__pos._M_node == _M_leftmost()) // begin()
    2314              :         return _Res(_M_leftmost(), _M_leftmost());
    2315              :       else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node)))
    2316              :         {
    2317              :           if (_S_right(__before._M_node) == 0)
    2318              :         return _Res(0, __before._M_node);
    2319              :           else
    2320              :         return _Res(__pos._M_node, __pos._M_node);
    2321              :         }
    2322              :       else
    2323              :         return _M_get_insert_equal_pos(__k);
    2324              :     }
    2325              :       else
    2326              :     {
    2327              :       // ... then try after.
    2328              :       iterator __after = __pos;
    2329              :       if (__pos._M_node == _M_rightmost())
    2330              :         return _Res(0, _M_rightmost());
    2331              :       else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k))
    2332              :         {
    2333              :           if (_S_right(__pos._M_node) == 0)
    2334              :         return _Res(0, __pos._M_node);
    2335              :           else
    2336              :         return _Res(__after._M_node, __after._M_node);
    2337              :         }
    2338              :       else
    2339              :         return _Res(0, 0);
    2340              :     }
    2341              :     }
    2342              : 
    2343              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2344              :        typename _Compare, typename _Alloc>
    2345              : #if __cplusplus >= 201103L
    2346              :     template<typename _Arg, typename _NodeGen>
    2347              : #else
    2348              :     template<typename _NodeGen>
    2349              : #endif
    2350              :       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
    2351              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2352              :       _M_insert_equal_(const_iterator __position,
    2353              : #if __cplusplus >= 201103L
    2354              :                _Arg&& __v,
    2355              : #else
    2356              :                const _Val& __v,
    2357              : #endif
    2358              :                _NodeGen& __node_gen)
    2359              :       {
    2360              :     pair<_Base_ptr, _Base_ptr> __res
    2361              :       = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
    2362              : 
    2363              :     if (__res.second)
    2364              :       return _M_insert_(__res.first, __res.second,
    2365              :                 _GLIBCXX_FORWARD(_Arg, __v),
    2366              :                 __node_gen);
    2367              : 
    2368              :     return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
    2369              :       }
    2370              : 
    2371              : #if __cplusplus >= 201103L
    2372              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2373              :        typename _Compare, typename _Alloc>
    2374              :     auto
    2375              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2376              :     _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
    2377              :     -> iterator
    2378              :     {
    2379              :       bool __insert_left = (__x != 0 || __p == _M_end()
    2380              :                 || _M_impl._M_key_compare(_S_key(__z),
    2381              :                               _S_key(__p)));
    2382              : 
    2383              :       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
    2384              :                     this->_M_impl._M_header);
    2385              :       ++_M_impl._M_node_count;
    2386              :       return iterator(__z);
    2387              :     }
    2388              : 
    2389              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2390              :        typename _Compare, typename _Alloc>
    2391              :     auto
    2392              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2393              :     _M_insert_lower_node(_Base_ptr __p, _Link_type __z)
    2394              :     -> iterator
    2395              :     {
    2396              :       bool __insert_left = (__p == _M_end()
    2397              :                 || !_M_impl._M_key_compare(_S_key(__p),
    2398              :                                _S_key(__z)));
    2399              : 
    2400              :       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
    2401              :                     this->_M_impl._M_header);
    2402              :       ++_M_impl._M_node_count;
    2403              :       return iterator(__z);
    2404              :     }
    2405              : 
    2406              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2407              :        typename _Compare, typename _Alloc>
    2408              :     auto
    2409              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2410              :     _M_insert_equal_lower_node(_Link_type __z)
    2411              :     -> iterator
    2412              :     {
    2413              :       _Link_type __x = _M_begin();
    2414              :       _Base_ptr __y = _M_end();
    2415              :       while (__x != 0)
    2416              :     {
    2417              :       __y = __x;
    2418              :       __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ?
    2419              :         _S_left(__x) : _S_right(__x);
    2420              :     }
    2421              :       return _M_insert_lower_node(__y, __z);
    2422              :     }
    2423              : 
    2424              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2425              :        typename _Compare, typename _Alloc>
    2426              :     template<typename... _Args>
    2427              :       auto
    2428              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2429              :       _M_emplace_unique(_Args&&... __args)
    2430              :       -> pair<iterator, bool>
    2431              :       {
    2432              :     _Auto_node __z(*this, std::forward<_Args>(__args)...);
    2433              :     auto __res = _M_get_insert_unique_pos(__z._M_key());
    2434              :     if (__res.second)
    2435              :       return {__z._M_insert(__res), true};
    2436              :     return {iterator(__res.first), false};
    2437              :       }
    2438              : 
    2439              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2440              :        typename _Compare, typename _Alloc>
    2441              :     template<typename... _Args>
    2442              :       auto
    2443              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2444              :       _M_emplace_equal(_Args&&... __args)
    2445              :       -> iterator
    2446              :       {
    2447              :     _Auto_node __z(*this, std::forward<_Args>(__args)...);
    2448              :     auto __res = _M_get_insert_equal_pos(__z._M_key());
    2449              :     return __z._M_insert(__res);
    2450              :       }
    2451              : 
    2452              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2453              :        typename _Compare, typename _Alloc>
    2454              :     template<typename... _Args>
    2455              :       auto
    2456              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2457              :       _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
    2458              :       -> iterator
    2459              :       {
    2460              :     _Auto_node __z(*this, std::forward<_Args>(__args)...);
    2461              :     auto __res = _M_get_insert_hint_unique_pos(__pos, __z._M_key());
    2462              :     if (__res.second)
    2463              :       return __z._M_insert(__res);
    2464              :     return iterator(__res.first);
    2465              :       }
    2466              : 
    2467              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2468              :        typename _Compare, typename _Alloc>
    2469              :     template<typename... _Args>
    2470              :       auto
    2471              :       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2472              :       _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
    2473              :       -> iterator
    2474              :       {
    2475              :     _Auto_node __z(*this, std::forward<_Args>(__args)...);
    2476              :     auto __res = _M_get_insert_hint_equal_pos(__pos, __z._M_key());
    2477              :     if (__res.second)
    2478              :       return __z._M_insert(__res);
    2479              :     return __z._M_insert_equal_lower();
    2480              :       }
    2481              : #endif
    2482              : 
    2483              : 
    2484              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2485              :        typename _Compare, typename _Alloc>
    2486              :     void
    2487              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2488              :     _M_erase_aux(const_iterator __position)
    2489              :     {
    2490              :       _Link_type __y =
    2491              :     static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
    2492              :                 (const_cast<_Base_ptr>(__position._M_node),
    2493              :                  this->_M_impl._M_header));
    2494              :       _M_drop_node(__y);
    2495              :       --_M_impl._M_node_count;
    2496              :     }
    2497              : 
    2498              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2499              :        typename _Compare, typename _Alloc>
    2500              :     void
    2501              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2502              :     _M_erase_aux(const_iterator __first, const_iterator __last)
    2503              :     {
    2504              :       if (__first == begin() && __last == end())
    2505              :     clear();
    2506              :       else
    2507              :     while (__first != __last)
    2508              :       _M_erase_aux(__first++);
    2509              :     }
    2510              : 
    2511              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2512              :        typename _Compare, typename _Alloc>
    2513              :     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
    2514              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2515              :     erase(const _Key& __x)
    2516              :     {
    2517              :       pair<iterator, iterator> __p = equal_range(__x);
    2518              :       const size_type __old_size = size();
    2519              :       _M_erase_aux(__p.first, __p.second);
    2520              :       return __old_size - size();
    2521              :     }
    2522              : 
    2523              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2524              :        typename _Compare, typename _Alloc>
    2525              :     typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2526              :               _Compare, _Alloc>::iterator
    2527              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2528              :     find(const _Key& __k)
    2529              :     {
    2530              :       iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
    2531              :       return (__j == end()
    2532              :           || _M_impl._M_key_compare(__k,
    2533              :                     _S_key(__j._M_node))) ? end() : __j;
    2534              :     }
    2535              : 
    2536              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2537              :        typename _Compare, typename _Alloc>
    2538              :     typename _Rb_tree<_Key, _Val, _KeyOfValue,
    2539              :               _Compare, _Alloc>::const_iterator
    2540         4625 :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2541              :     find(const _Key& __k) const
    2542              :     {
    2543         4625 :       const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
    2544         9250 :       return (__j == end()
    2545         4625 :           || _M_impl._M_key_compare(__k,
    2546        13875 :                     _S_key(__j._M_node))) ? end() : __j;
    2547              :     }
    2548              : 
    2549              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2550              :        typename _Compare, typename _Alloc>
    2551              :     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
    2552              :     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
    2553              :     count(const _Key& __k) const
    2554              :     {
    2555              :       pair<const_iterator, const_iterator> __p = equal_range(__k);
    2556              :       const size_type __n = std::distance(__p.first, __p.second);
    2557              :       return __n;
    2558              :     }
    2559              : 
    2560              :   _GLIBCXX_PURE unsigned int
    2561              :   _Rb_tree_black_count(const _Rb_tree_node_base* __node,
    2562              :                const _Rb_tree_node_base* __root) throw ();
    2563              : 
    2564              :   template<typename _Key, typename _Val, typename _KeyOfValue,
    2565              :        typename _Compare, typename _Alloc>
    2566              :     bool
    2567              :     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
    2568              :     {
    2569              :       if (_M_impl._M_node_count == 0 || begin() == end())
    2570              :     return _M_impl._M_node_count == 0 && begin() == end()
    2571              :            && this->_M_impl._M_header._M_left == _M_end()
    2572              :            && this->_M_impl._M_header._M_right == _M_end();
    2573              : 
    2574              :       unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
    2575              :       for (const_iterator __it = begin(); __it != end(); ++__it)
    2576              :     {
    2577              :       _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
    2578              :       _Const_Link_type __L = _S_left(__x);
    2579              :       _Const_Link_type __R = _S_right(__x);
    2580              : 
    2581              :       if (__x->_M_color == _S_red)
    2582              :         if ((__L && __L->_M_color == _S_red)
    2583              :         || (__R && __R->_M_color == _S_red))
    2584              :           return false;
    2585              : 
    2586              :       if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
    2587              :         return false;
    2588              :       if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
    2589              :         return false;
    2590              : 
    2591              :       if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
    2592              :         return false;
    2593              :     }
    2594              : 
    2595              :       if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
    2596              :     return false;
    2597              :       if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
    2598              :     return false;
    2599              :       return true;
    2600              :     }
    2601              : 
    2602              : #if __cplusplus > 201402L
    2603              :   // Allow access to internals of compatible _Rb_tree specializations.
    2604              :   template<typename _Key, typename _Val, typename _Sel, typename _Cmp1,
    2605              :        typename _Alloc, typename _Cmp2>
    2606              :     struct _Rb_tree_merge_helper<_Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>,
    2607              :                  _Cmp2>
    2608              :     {
    2609              :     private:
    2610              :       friend class _Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>;
    2611              : 
    2612              :       static auto&
    2613              :       _S_get_impl(_Rb_tree<_Key, _Val, _Sel, _Cmp2, _Alloc>& __tree)
    2614              :       { return __tree._M_impl; }
    2615              :     };
    2616              : #endif // C++17
    2617              : 
    2618              : _GLIBCXX_END_NAMESPACE_VERSION
    2619              : } // namespace
    2620              : 
    2621              : #endif
        

Generated by: LCOV version 2.0-1