LCOV - code coverage report
Current view: top level - usr/include/c++/12/bits - stl_tree.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 138 162 85.2 %
Date: 2023-07-19 08:18:47 Functions: 13 13 100.0 %

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

Generated by: LCOV version 1.16