LCOV - code coverage report
Current view: top level - usr/include/c++/8/bits - stl_tree.h (source / functions) Hit Total Coverage
Test: Coverage example Lines: 128 133 96.2 %
Date: 2021-12-02 17:21:05 Functions: 115 159 72.3 %

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

Generated by: LCOV version 1.14