xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/stl_tree.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // RB tree implementation -*- C++ -*-
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2001-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /*
261debfc3dSmrg  *
271debfc3dSmrg  * Copyright (c) 1996,1997
281debfc3dSmrg  * Silicon Graphics Computer Systems, Inc.
291debfc3dSmrg  *
301debfc3dSmrg  * Permission to use, copy, modify, distribute and sell this software
311debfc3dSmrg  * and its documentation for any purpose is hereby granted without fee,
321debfc3dSmrg  * provided that the above copyright notice appear in all copies and
331debfc3dSmrg  * that both that copyright notice and this permission notice appear
341debfc3dSmrg  * in supporting documentation.  Silicon Graphics makes no
351debfc3dSmrg  * representations about the suitability of this software for any
361debfc3dSmrg  * purpose.  It is provided "as is" without express or implied warranty.
371debfc3dSmrg  *
381debfc3dSmrg  *
391debfc3dSmrg  * Copyright (c) 1994
401debfc3dSmrg  * Hewlett-Packard Company
411debfc3dSmrg  *
421debfc3dSmrg  * Permission to use, copy, modify, distribute and sell this software
431debfc3dSmrg  * and its documentation for any purpose is hereby granted without fee,
441debfc3dSmrg  * provided that the above copyright notice appear in all copies and
451debfc3dSmrg  * that both that copyright notice and this permission notice appear
461debfc3dSmrg  * in supporting documentation.  Hewlett-Packard Company makes no
471debfc3dSmrg  * representations about the suitability of this software for any
481debfc3dSmrg  * purpose.  It is provided "as is" without express or implied warranty.
491debfc3dSmrg  *
501debfc3dSmrg  *
511debfc3dSmrg  */
521debfc3dSmrg 
531debfc3dSmrg /** @file bits/stl_tree.h
541debfc3dSmrg  *  This is an internal header file, included by other library headers.
551debfc3dSmrg  *  Do not attempt to use it directly. @headername{map,set}
561debfc3dSmrg  */
571debfc3dSmrg 
581debfc3dSmrg #ifndef _STL_TREE_H
591debfc3dSmrg #define _STL_TREE_H 1
601debfc3dSmrg 
611debfc3dSmrg #pragma GCC system_header
621debfc3dSmrg 
631debfc3dSmrg #include <bits/stl_algobase.h>
641debfc3dSmrg #include <bits/allocator.h>
651debfc3dSmrg #include <bits/stl_function.h>
661debfc3dSmrg #include <bits/cpp_type_traits.h>
671debfc3dSmrg #include <ext/alloc_traits.h>
681debfc3dSmrg #if __cplusplus >= 201103L
691debfc3dSmrg # include <ext/aligned_buffer.h>
701debfc3dSmrg #endif
711debfc3dSmrg #if __cplusplus > 201402L
721debfc3dSmrg # include <bits/node_handle.h>
731debfc3dSmrg #endif
741debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)751debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
761debfc3dSmrg {
771debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
781debfc3dSmrg 
791debfc3dSmrg #if __cplusplus > 201103L
801debfc3dSmrg # define __cpp_lib_generic_associative_lookup 201304
811debfc3dSmrg #endif
821debfc3dSmrg 
831debfc3dSmrg   // Red-black tree class, designed for use in implementing STL
841debfc3dSmrg   // associative containers (set, multiset, map, and multimap). The
851debfc3dSmrg   // insertion and deletion algorithms are based on those in Cormen,
861debfc3dSmrg   // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
871debfc3dSmrg   // 1990), except that
881debfc3dSmrg   //
891debfc3dSmrg   // (1) the header cell is maintained with links not only to the root
901debfc3dSmrg   // but also to the leftmost node of the tree, to enable constant
911debfc3dSmrg   // time begin(), and to the rightmost node of the tree, to enable
921debfc3dSmrg   // linear time performance when used with the generic set algorithms
931debfc3dSmrg   // (set_union, etc.)
941debfc3dSmrg   //
951debfc3dSmrg   // (2) when a node being deleted has two children its successor node
961debfc3dSmrg   // is relinked into its place, rather than copied, so that the only
971debfc3dSmrg   // iterators invalidated are those referring to the deleted node.
981debfc3dSmrg 
991debfc3dSmrg   enum _Rb_tree_color { _S_red = false, _S_black = true };
1001debfc3dSmrg 
1011debfc3dSmrg   struct _Rb_tree_node_base
1021debfc3dSmrg   {
1031debfc3dSmrg     typedef _Rb_tree_node_base* _Base_ptr;
1041debfc3dSmrg     typedef const _Rb_tree_node_base* _Const_Base_ptr;
1051debfc3dSmrg 
1061debfc3dSmrg     _Rb_tree_color	_M_color;
1071debfc3dSmrg     _Base_ptr		_M_parent;
1081debfc3dSmrg     _Base_ptr		_M_left;
1091debfc3dSmrg     _Base_ptr		_M_right;
1101debfc3dSmrg 
1111debfc3dSmrg     static _Base_ptr
1121debfc3dSmrg     _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
1131debfc3dSmrg     {
1141debfc3dSmrg       while (__x->_M_left != 0) __x = __x->_M_left;
1151debfc3dSmrg       return __x;
1161debfc3dSmrg     }
1171debfc3dSmrg 
1181debfc3dSmrg     static _Const_Base_ptr
1191debfc3dSmrg     _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
1201debfc3dSmrg     {
1211debfc3dSmrg       while (__x->_M_left != 0) __x = __x->_M_left;
1221debfc3dSmrg       return __x;
1231debfc3dSmrg     }
1241debfc3dSmrg 
1251debfc3dSmrg     static _Base_ptr
1261debfc3dSmrg     _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
1271debfc3dSmrg     {
1281debfc3dSmrg       while (__x->_M_right != 0) __x = __x->_M_right;
1291debfc3dSmrg       return __x;
1301debfc3dSmrg     }
1311debfc3dSmrg 
1321debfc3dSmrg     static _Const_Base_ptr
1331debfc3dSmrg     _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
1341debfc3dSmrg     {
1351debfc3dSmrg       while (__x->_M_right != 0) __x = __x->_M_right;
1361debfc3dSmrg       return __x;
1371debfc3dSmrg     }
1381debfc3dSmrg   };
1391debfc3dSmrg 
1401debfc3dSmrg   // Helper type offering value initialization guarantee on the compare functor.
1411debfc3dSmrg   template<typename _Key_compare>
1421debfc3dSmrg     struct _Rb_tree_key_compare
1431debfc3dSmrg     {
1441debfc3dSmrg       _Key_compare		_M_key_compare;
1451debfc3dSmrg 
1461debfc3dSmrg       _Rb_tree_key_compare()
1471debfc3dSmrg       _GLIBCXX_NOEXCEPT_IF(
1481debfc3dSmrg 	is_nothrow_default_constructible<_Key_compare>::value)
1491debfc3dSmrg       : _M_key_compare()
1501debfc3dSmrg       { }
1511debfc3dSmrg 
1521debfc3dSmrg       _Rb_tree_key_compare(const _Key_compare& __comp)
1531debfc3dSmrg       : _M_key_compare(__comp)
1541debfc3dSmrg       { }
1551debfc3dSmrg 
1561debfc3dSmrg #if __cplusplus >= 201103L
1571debfc3dSmrg       // Copy constructor added for consistency with C++98 mode.
1581debfc3dSmrg       _Rb_tree_key_compare(const _Rb_tree_key_compare&) = default;
1591debfc3dSmrg 
1601debfc3dSmrg       _Rb_tree_key_compare(_Rb_tree_key_compare&& __x)
1611debfc3dSmrg 	noexcept(is_nothrow_copy_constructible<_Key_compare>::value)
1621debfc3dSmrg       : _M_key_compare(__x._M_key_compare)
1631debfc3dSmrg       { }
1641debfc3dSmrg #endif
1651debfc3dSmrg     };
1661debfc3dSmrg 
1671debfc3dSmrg   // Helper type to manage default initialization of node count and header.
1681debfc3dSmrg   struct _Rb_tree_header
1691debfc3dSmrg   {
1701debfc3dSmrg     _Rb_tree_node_base	_M_header;
1711debfc3dSmrg     size_t		_M_node_count; // Keeps track of size of tree.
1721debfc3dSmrg 
1731debfc3dSmrg     _Rb_tree_header() _GLIBCXX_NOEXCEPT
1741debfc3dSmrg     {
1751debfc3dSmrg       _M_header._M_color = _S_red;
1761debfc3dSmrg       _M_reset();
1771debfc3dSmrg     }
1781debfc3dSmrg 
1791debfc3dSmrg #if __cplusplus >= 201103L
1801debfc3dSmrg     _Rb_tree_header(_Rb_tree_header&& __x) noexcept
1811debfc3dSmrg     {
1821debfc3dSmrg       if (__x._M_header._M_parent != nullptr)
1831debfc3dSmrg 	_M_move_data(__x);
1841debfc3dSmrg       else
1851debfc3dSmrg 	{
1861debfc3dSmrg 	  _M_header._M_color = _S_red;
1871debfc3dSmrg 	  _M_reset();
1881debfc3dSmrg 	}
1891debfc3dSmrg     }
1901debfc3dSmrg #endif
1911debfc3dSmrg 
1921debfc3dSmrg     void
1931debfc3dSmrg     _M_move_data(_Rb_tree_header& __from)
1941debfc3dSmrg     {
1951debfc3dSmrg       _M_header._M_color = __from._M_header._M_color;
1961debfc3dSmrg       _M_header._M_parent = __from._M_header._M_parent;
1971debfc3dSmrg       _M_header._M_left = __from._M_header._M_left;
1981debfc3dSmrg       _M_header._M_right = __from._M_header._M_right;
1991debfc3dSmrg       _M_header._M_parent->_M_parent = &_M_header;
2001debfc3dSmrg       _M_node_count = __from._M_node_count;
2011debfc3dSmrg 
2021debfc3dSmrg       __from._M_reset();
2031debfc3dSmrg     }
2041debfc3dSmrg 
2051debfc3dSmrg     void
2061debfc3dSmrg     _M_reset()
2071debfc3dSmrg     {
2081debfc3dSmrg       _M_header._M_parent = 0;
2091debfc3dSmrg       _M_header._M_left = &_M_header;
2101debfc3dSmrg       _M_header._M_right = &_M_header;
2111debfc3dSmrg       _M_node_count = 0;
2121debfc3dSmrg     }
2131debfc3dSmrg   };
2141debfc3dSmrg 
2151debfc3dSmrg   template<typename _Val>
2161debfc3dSmrg     struct _Rb_tree_node : public _Rb_tree_node_base
2171debfc3dSmrg     {
2181debfc3dSmrg       typedef _Rb_tree_node<_Val>* _Link_type;
2191debfc3dSmrg 
2201debfc3dSmrg #if __cplusplus < 201103L
2211debfc3dSmrg       _Val _M_value_field;
2221debfc3dSmrg 
2231debfc3dSmrg       _Val*
2241debfc3dSmrg       _M_valptr()
2251debfc3dSmrg       { return std::__addressof(_M_value_field); }
2261debfc3dSmrg 
2271debfc3dSmrg       const _Val*
2281debfc3dSmrg       _M_valptr() const
2291debfc3dSmrg       { return std::__addressof(_M_value_field); }
2301debfc3dSmrg #else
2311debfc3dSmrg       __gnu_cxx::__aligned_membuf<_Val> _M_storage;
2321debfc3dSmrg 
2331debfc3dSmrg       _Val*
2341debfc3dSmrg       _M_valptr()
2351debfc3dSmrg       { return _M_storage._M_ptr(); }
2361debfc3dSmrg 
2371debfc3dSmrg       const _Val*
2381debfc3dSmrg       _M_valptr() const
2391debfc3dSmrg       { return _M_storage._M_ptr(); }
2401debfc3dSmrg #endif
2411debfc3dSmrg     };
2421debfc3dSmrg 
2431debfc3dSmrg   _GLIBCXX_PURE _Rb_tree_node_base*
2441debfc3dSmrg   _Rb_tree_increment(_Rb_tree_node_base* __x) throw ();
2451debfc3dSmrg 
2461debfc3dSmrg   _GLIBCXX_PURE const _Rb_tree_node_base*
2471debfc3dSmrg   _Rb_tree_increment(const _Rb_tree_node_base* __x) throw ();
2481debfc3dSmrg 
2491debfc3dSmrg   _GLIBCXX_PURE _Rb_tree_node_base*
2501debfc3dSmrg   _Rb_tree_decrement(_Rb_tree_node_base* __x) throw ();
2511debfc3dSmrg 
2521debfc3dSmrg   _GLIBCXX_PURE const _Rb_tree_node_base*
2531debfc3dSmrg   _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw ();
2541debfc3dSmrg 
2551debfc3dSmrg   template<typename _Tp>
2561debfc3dSmrg     struct _Rb_tree_iterator
2571debfc3dSmrg     {
2581debfc3dSmrg       typedef _Tp  value_type;
2591debfc3dSmrg       typedef _Tp& reference;
2601debfc3dSmrg       typedef _Tp* pointer;
2611debfc3dSmrg 
2621debfc3dSmrg       typedef bidirectional_iterator_tag iterator_category;
2631debfc3dSmrg       typedef ptrdiff_t			 difference_type;
2641debfc3dSmrg 
2651debfc3dSmrg       typedef _Rb_tree_iterator<_Tp>		_Self;
2661debfc3dSmrg       typedef _Rb_tree_node_base::_Base_ptr	_Base_ptr;
2671debfc3dSmrg       typedef _Rb_tree_node<_Tp>*		_Link_type;
2681debfc3dSmrg 
2691debfc3dSmrg       _Rb_tree_iterator() _GLIBCXX_NOEXCEPT
2701debfc3dSmrg       : _M_node() { }
2711debfc3dSmrg 
2721debfc3dSmrg       explicit
2731debfc3dSmrg       _Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
2741debfc3dSmrg       : _M_node(__x) { }
2751debfc3dSmrg 
2761debfc3dSmrg       reference
2771debfc3dSmrg       operator*() const _GLIBCXX_NOEXCEPT
2781debfc3dSmrg       { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
2791debfc3dSmrg 
2801debfc3dSmrg       pointer
2811debfc3dSmrg       operator->() const _GLIBCXX_NOEXCEPT
2821debfc3dSmrg       { return static_cast<_Link_type> (_M_node)->_M_valptr(); }
2831debfc3dSmrg 
2841debfc3dSmrg       _Self&
2851debfc3dSmrg       operator++() _GLIBCXX_NOEXCEPT
2861debfc3dSmrg       {
2871debfc3dSmrg 	_M_node = _Rb_tree_increment(_M_node);
2881debfc3dSmrg 	return *this;
2891debfc3dSmrg       }
2901debfc3dSmrg 
2911debfc3dSmrg       _Self
2921debfc3dSmrg       operator++(int) _GLIBCXX_NOEXCEPT
2931debfc3dSmrg       {
2941debfc3dSmrg 	_Self __tmp = *this;
2951debfc3dSmrg 	_M_node = _Rb_tree_increment(_M_node);
2961debfc3dSmrg 	return __tmp;
2971debfc3dSmrg       }
2981debfc3dSmrg 
2991debfc3dSmrg       _Self&
3001debfc3dSmrg       operator--() _GLIBCXX_NOEXCEPT
3011debfc3dSmrg       {
3021debfc3dSmrg 	_M_node = _Rb_tree_decrement(_M_node);
3031debfc3dSmrg 	return *this;
3041debfc3dSmrg       }
3051debfc3dSmrg 
3061debfc3dSmrg       _Self
3071debfc3dSmrg       operator--(int) _GLIBCXX_NOEXCEPT
3081debfc3dSmrg       {
3091debfc3dSmrg 	_Self __tmp = *this;
3101debfc3dSmrg 	_M_node = _Rb_tree_decrement(_M_node);
3111debfc3dSmrg 	return __tmp;
3121debfc3dSmrg       }
3131debfc3dSmrg 
314c0a68be4Smrg       friend bool
315c0a68be4Smrg       operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
316c0a68be4Smrg       { return __x._M_node == __y._M_node; }
3171debfc3dSmrg 
318*8feb0f0bSmrg #if ! __cpp_lib_three_way_comparison
319c0a68be4Smrg       friend bool
320c0a68be4Smrg       operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
321c0a68be4Smrg       { return __x._M_node != __y._M_node; }
322*8feb0f0bSmrg #endif
3231debfc3dSmrg 
3241debfc3dSmrg       _Base_ptr _M_node;
3251debfc3dSmrg   };
3261debfc3dSmrg 
3271debfc3dSmrg   template<typename _Tp>
3281debfc3dSmrg     struct _Rb_tree_const_iterator
3291debfc3dSmrg     {
3301debfc3dSmrg       typedef _Tp	 value_type;
3311debfc3dSmrg       typedef const _Tp& reference;
3321debfc3dSmrg       typedef const _Tp* pointer;
3331debfc3dSmrg 
3341debfc3dSmrg       typedef _Rb_tree_iterator<_Tp> iterator;
3351debfc3dSmrg 
3361debfc3dSmrg       typedef bidirectional_iterator_tag iterator_category;
3371debfc3dSmrg       typedef ptrdiff_t			 difference_type;
3381debfc3dSmrg 
3391debfc3dSmrg       typedef _Rb_tree_const_iterator<_Tp>		_Self;
3401debfc3dSmrg       typedef _Rb_tree_node_base::_Const_Base_ptr	_Base_ptr;
3411debfc3dSmrg       typedef const _Rb_tree_node<_Tp>*			_Link_type;
3421debfc3dSmrg 
3431debfc3dSmrg       _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT
3441debfc3dSmrg       : _M_node() { }
3451debfc3dSmrg 
3461debfc3dSmrg       explicit
3471debfc3dSmrg       _Rb_tree_const_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
3481debfc3dSmrg       : _M_node(__x) { }
3491debfc3dSmrg 
3501debfc3dSmrg       _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT
3511debfc3dSmrg       : _M_node(__it._M_node) { }
3521debfc3dSmrg 
3531debfc3dSmrg       iterator
3541debfc3dSmrg       _M_const_cast() const _GLIBCXX_NOEXCEPT
3551debfc3dSmrg       { return iterator(const_cast<typename iterator::_Base_ptr>(_M_node)); }
3561debfc3dSmrg 
3571debfc3dSmrg       reference
3581debfc3dSmrg       operator*() const _GLIBCXX_NOEXCEPT
3591debfc3dSmrg       { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
3601debfc3dSmrg 
3611debfc3dSmrg       pointer
3621debfc3dSmrg       operator->() const _GLIBCXX_NOEXCEPT
3631debfc3dSmrg       { return static_cast<_Link_type>(_M_node)->_M_valptr(); }
3641debfc3dSmrg 
3651debfc3dSmrg       _Self&
3661debfc3dSmrg       operator++() _GLIBCXX_NOEXCEPT
3671debfc3dSmrg       {
3681debfc3dSmrg 	_M_node = _Rb_tree_increment(_M_node);
3691debfc3dSmrg 	return *this;
3701debfc3dSmrg       }
3711debfc3dSmrg 
3721debfc3dSmrg       _Self
3731debfc3dSmrg       operator++(int) _GLIBCXX_NOEXCEPT
3741debfc3dSmrg       {
3751debfc3dSmrg 	_Self __tmp = *this;
3761debfc3dSmrg 	_M_node = _Rb_tree_increment(_M_node);
3771debfc3dSmrg 	return __tmp;
3781debfc3dSmrg       }
3791debfc3dSmrg 
3801debfc3dSmrg       _Self&
3811debfc3dSmrg       operator--() _GLIBCXX_NOEXCEPT
3821debfc3dSmrg       {
3831debfc3dSmrg 	_M_node = _Rb_tree_decrement(_M_node);
3841debfc3dSmrg 	return *this;
3851debfc3dSmrg       }
3861debfc3dSmrg 
3871debfc3dSmrg       _Self
3881debfc3dSmrg       operator--(int) _GLIBCXX_NOEXCEPT
3891debfc3dSmrg       {
3901debfc3dSmrg 	_Self __tmp = *this;
3911debfc3dSmrg 	_M_node = _Rb_tree_decrement(_M_node);
3921debfc3dSmrg 	return __tmp;
3931debfc3dSmrg       }
3941debfc3dSmrg 
395c0a68be4Smrg       friend bool
396c0a68be4Smrg       operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
397c0a68be4Smrg       { return __x._M_node == __y._M_node; }
3981debfc3dSmrg 
399*8feb0f0bSmrg #if ! __cpp_lib_three_way_comparison
400c0a68be4Smrg       friend bool
401c0a68be4Smrg       operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
402c0a68be4Smrg       { return __x._M_node != __y._M_node; }
403*8feb0f0bSmrg #endif
4041debfc3dSmrg 
4051debfc3dSmrg       _Base_ptr _M_node;
4061debfc3dSmrg     };
4071debfc3dSmrg 
4081debfc3dSmrg   void
4091debfc3dSmrg   _Rb_tree_insert_and_rebalance(const bool __insert_left,
4101debfc3dSmrg 				_Rb_tree_node_base* __x,
4111debfc3dSmrg 				_Rb_tree_node_base* __p,
4121debfc3dSmrg 				_Rb_tree_node_base& __header) throw ();
4131debfc3dSmrg 
4141debfc3dSmrg   _Rb_tree_node_base*
4151debfc3dSmrg   _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
4161debfc3dSmrg 			       _Rb_tree_node_base& __header) throw ();
4171debfc3dSmrg 
418c0a68be4Smrg #if __cplusplus >= 201402L
4191debfc3dSmrg   template<typename _Cmp, typename _SfinaeType, typename = __void_t<>>
4201debfc3dSmrg     struct __has_is_transparent
4211debfc3dSmrg     { };
4221debfc3dSmrg 
4231debfc3dSmrg   template<typename _Cmp, typename _SfinaeType>
4241debfc3dSmrg     struct __has_is_transparent<_Cmp, _SfinaeType,
4251debfc3dSmrg 				__void_t<typename _Cmp::is_transparent>>
4261debfc3dSmrg     { typedef void type; };
427c0a68be4Smrg 
428c0a68be4Smrg   template<typename _Cmp, typename _SfinaeType>
429c0a68be4Smrg     using __has_is_transparent_t
430c0a68be4Smrg       = typename __has_is_transparent<_Cmp, _SfinaeType>::type;
4311debfc3dSmrg #endif
4321debfc3dSmrg 
4331debfc3dSmrg #if __cplusplus > 201402L
4341debfc3dSmrg   template<typename _Tree1, typename _Cmp2>
4351debfc3dSmrg     struct _Rb_tree_merge_helper { };
4361debfc3dSmrg #endif
4371debfc3dSmrg 
4381debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
4391debfc3dSmrg 	   typename _Compare, typename _Alloc = allocator<_Val> >
4401debfc3dSmrg     class _Rb_tree
4411debfc3dSmrg     {
4421debfc3dSmrg       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
4431debfc3dSmrg 	rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
4441debfc3dSmrg 
4451debfc3dSmrg       typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
4461debfc3dSmrg 
4471debfc3dSmrg     protected:
4481debfc3dSmrg       typedef _Rb_tree_node_base* 		_Base_ptr;
4491debfc3dSmrg       typedef const _Rb_tree_node_base* 	_Const_Base_ptr;
4501debfc3dSmrg       typedef _Rb_tree_node<_Val>* 		_Link_type;
4511debfc3dSmrg       typedef const _Rb_tree_node<_Val>*	_Const_Link_type;
4521debfc3dSmrg 
4531debfc3dSmrg     private:
4541debfc3dSmrg       // Functor recycling a pool of nodes and using allocation once the pool
4551debfc3dSmrg       // is empty.
4561debfc3dSmrg       struct _Reuse_or_alloc_node
4571debfc3dSmrg       {
4581debfc3dSmrg 	_Reuse_or_alloc_node(_Rb_tree& __t)
4591debfc3dSmrg 	: _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t)
4601debfc3dSmrg 	{
4611debfc3dSmrg 	  if (_M_root)
4621debfc3dSmrg 	    {
4631debfc3dSmrg 	      _M_root->_M_parent = 0;
4641debfc3dSmrg 
4651debfc3dSmrg 	      if (_M_nodes->_M_left)
4661debfc3dSmrg 		_M_nodes = _M_nodes->_M_left;
4671debfc3dSmrg 	    }
4681debfc3dSmrg 	  else
4691debfc3dSmrg 	    _M_nodes = 0;
4701debfc3dSmrg 	}
4711debfc3dSmrg 
4721debfc3dSmrg #if __cplusplus >= 201103L
4731debfc3dSmrg 	_Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete;
4741debfc3dSmrg #endif
4751debfc3dSmrg 
4761debfc3dSmrg 	~_Reuse_or_alloc_node()
4771debfc3dSmrg 	{ _M_t._M_erase(static_cast<_Link_type>(_M_root)); }
4781debfc3dSmrg 
4791debfc3dSmrg 	template<typename _Arg>
4801debfc3dSmrg 	  _Link_type
4811debfc3dSmrg #if __cplusplus < 201103L
4821debfc3dSmrg 	  operator()(const _Arg& __arg)
4831debfc3dSmrg #else
4841debfc3dSmrg 	  operator()(_Arg&& __arg)
4851debfc3dSmrg #endif
4861debfc3dSmrg 	  {
4871debfc3dSmrg 	    _Link_type __node = static_cast<_Link_type>(_M_extract());
4881debfc3dSmrg 	    if (__node)
4891debfc3dSmrg 	      {
4901debfc3dSmrg 		_M_t._M_destroy_node(__node);
4911debfc3dSmrg 		_M_t._M_construct_node(__node, _GLIBCXX_FORWARD(_Arg, __arg));
4921debfc3dSmrg 		return __node;
4931debfc3dSmrg 	      }
4941debfc3dSmrg 
4951debfc3dSmrg 	    return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg));
4961debfc3dSmrg 	  }
4971debfc3dSmrg 
4981debfc3dSmrg       private:
4991debfc3dSmrg 	_Base_ptr
5001debfc3dSmrg 	_M_extract()
5011debfc3dSmrg 	{
5021debfc3dSmrg 	  if (!_M_nodes)
5031debfc3dSmrg 	    return _M_nodes;
5041debfc3dSmrg 
5051debfc3dSmrg 	  _Base_ptr __node = _M_nodes;
5061debfc3dSmrg 	  _M_nodes = _M_nodes->_M_parent;
5071debfc3dSmrg 	  if (_M_nodes)
5081debfc3dSmrg 	    {
5091debfc3dSmrg 	      if (_M_nodes->_M_right == __node)
5101debfc3dSmrg 		{
5111debfc3dSmrg 		  _M_nodes->_M_right = 0;
5121debfc3dSmrg 
5131debfc3dSmrg 		  if (_M_nodes->_M_left)
5141debfc3dSmrg 		    {
5151debfc3dSmrg 		      _M_nodes = _M_nodes->_M_left;
5161debfc3dSmrg 
5171debfc3dSmrg 		      while (_M_nodes->_M_right)
5181debfc3dSmrg 			_M_nodes = _M_nodes->_M_right;
5191debfc3dSmrg 
5201debfc3dSmrg 		      if (_M_nodes->_M_left)
5211debfc3dSmrg 			_M_nodes = _M_nodes->_M_left;
5221debfc3dSmrg 		    }
5231debfc3dSmrg 		}
5241debfc3dSmrg 	      else // __node is on the left.
5251debfc3dSmrg 		_M_nodes->_M_left = 0;
5261debfc3dSmrg 	    }
5271debfc3dSmrg 	  else
5281debfc3dSmrg 	    _M_root = 0;
5291debfc3dSmrg 
5301debfc3dSmrg 	  return __node;
5311debfc3dSmrg 	}
5321debfc3dSmrg 
5331debfc3dSmrg 	_Base_ptr _M_root;
5341debfc3dSmrg 	_Base_ptr _M_nodes;
5351debfc3dSmrg 	_Rb_tree& _M_t;
5361debfc3dSmrg       };
5371debfc3dSmrg 
5381debfc3dSmrg       // Functor similar to the previous one but without any pool of nodes to
5391debfc3dSmrg       // recycle.
5401debfc3dSmrg       struct _Alloc_node
5411debfc3dSmrg       {
5421debfc3dSmrg 	_Alloc_node(_Rb_tree& __t)
5431debfc3dSmrg 	: _M_t(__t) { }
5441debfc3dSmrg 
5451debfc3dSmrg 	template<typename _Arg>
5461debfc3dSmrg 	  _Link_type
5471debfc3dSmrg #if __cplusplus < 201103L
5481debfc3dSmrg 	  operator()(const _Arg& __arg) const
5491debfc3dSmrg #else
5501debfc3dSmrg 	  operator()(_Arg&& __arg) const
5511debfc3dSmrg #endif
5521debfc3dSmrg 	  { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); }
5531debfc3dSmrg 
5541debfc3dSmrg       private:
5551debfc3dSmrg 	_Rb_tree& _M_t;
5561debfc3dSmrg       };
5571debfc3dSmrg 
5581debfc3dSmrg     public:
5591debfc3dSmrg       typedef _Key 				key_type;
5601debfc3dSmrg       typedef _Val 				value_type;
5611debfc3dSmrg       typedef value_type* 			pointer;
5621debfc3dSmrg       typedef const value_type* 		const_pointer;
5631debfc3dSmrg       typedef value_type& 			reference;
5641debfc3dSmrg       typedef const value_type& 		const_reference;
5651debfc3dSmrg       typedef size_t 				size_type;
5661debfc3dSmrg       typedef ptrdiff_t 			difference_type;
5671debfc3dSmrg       typedef _Alloc 				allocator_type;
5681debfc3dSmrg 
5691debfc3dSmrg       _Node_allocator&
5701debfc3dSmrg       _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
571a2dc1f3fSmrg       { return this->_M_impl; }
5721debfc3dSmrg 
5731debfc3dSmrg       const _Node_allocator&
5741debfc3dSmrg       _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
575a2dc1f3fSmrg       { return this->_M_impl; }
5761debfc3dSmrg 
5771debfc3dSmrg       allocator_type
5781debfc3dSmrg       get_allocator() const _GLIBCXX_NOEXCEPT
5791debfc3dSmrg       { return allocator_type(_M_get_Node_allocator()); }
5801debfc3dSmrg 
5811debfc3dSmrg     protected:
5821debfc3dSmrg       _Link_type
5831debfc3dSmrg       _M_get_node()
5841debfc3dSmrg       { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
5851debfc3dSmrg 
5861debfc3dSmrg       void
5871debfc3dSmrg       _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT
5881debfc3dSmrg       { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
5891debfc3dSmrg 
5901debfc3dSmrg #if __cplusplus < 201103L
5911debfc3dSmrg       void
5921debfc3dSmrg       _M_construct_node(_Link_type __node, const value_type& __x)
5931debfc3dSmrg       {
5941debfc3dSmrg 	__try
5951debfc3dSmrg 	  { get_allocator().construct(__node->_M_valptr(), __x); }
5961debfc3dSmrg 	__catch(...)
5971debfc3dSmrg 	  {
5981debfc3dSmrg 	    _M_put_node(__node);
5991debfc3dSmrg 	    __throw_exception_again;
6001debfc3dSmrg 	  }
6011debfc3dSmrg       }
6021debfc3dSmrg 
6031debfc3dSmrg       _Link_type
6041debfc3dSmrg       _M_create_node(const value_type& __x)
6051debfc3dSmrg       {
6061debfc3dSmrg 	_Link_type __tmp = _M_get_node();
6071debfc3dSmrg 	_M_construct_node(__tmp, __x);
6081debfc3dSmrg 	return __tmp;
6091debfc3dSmrg       }
6101debfc3dSmrg #else
6111debfc3dSmrg       template<typename... _Args>
6121debfc3dSmrg 	void
6131debfc3dSmrg 	_M_construct_node(_Link_type __node, _Args&&... __args)
6141debfc3dSmrg 	{
6151debfc3dSmrg 	  __try
6161debfc3dSmrg 	    {
6171debfc3dSmrg 	      ::new(__node) _Rb_tree_node<_Val>;
6181debfc3dSmrg 	      _Alloc_traits::construct(_M_get_Node_allocator(),
6191debfc3dSmrg 				       __node->_M_valptr(),
6201debfc3dSmrg 				       std::forward<_Args>(__args)...);
6211debfc3dSmrg 	    }
6221debfc3dSmrg 	  __catch(...)
6231debfc3dSmrg 	    {
6241debfc3dSmrg 	      __node->~_Rb_tree_node<_Val>();
6251debfc3dSmrg 	      _M_put_node(__node);
6261debfc3dSmrg 	      __throw_exception_again;
6271debfc3dSmrg 	    }
6281debfc3dSmrg 	}
6291debfc3dSmrg 
6301debfc3dSmrg       template<typename... _Args>
6311debfc3dSmrg 	_Link_type
6321debfc3dSmrg 	_M_create_node(_Args&&... __args)
6331debfc3dSmrg 	{
6341debfc3dSmrg 	  _Link_type __tmp = _M_get_node();
6351debfc3dSmrg 	  _M_construct_node(__tmp, std::forward<_Args>(__args)...);
6361debfc3dSmrg 	  return __tmp;
6371debfc3dSmrg 	}
638c0a68be4Smrg #endif
6391debfc3dSmrg 
6401debfc3dSmrg       void
641c0a68be4Smrg       _M_destroy_node(_Link_type __p) _GLIBCXX_NOEXCEPT
6421debfc3dSmrg       {
643c0a68be4Smrg #if __cplusplus < 201103L
644c0a68be4Smrg 	get_allocator().destroy(__p->_M_valptr());
645c0a68be4Smrg #else
6461debfc3dSmrg 	_Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
6471debfc3dSmrg 	__p->~_Rb_tree_node<_Val>();
6481debfc3dSmrg #endif
649c0a68be4Smrg       }
6501debfc3dSmrg 
6511debfc3dSmrg       void
6521debfc3dSmrg       _M_drop_node(_Link_type __p) _GLIBCXX_NOEXCEPT
6531debfc3dSmrg       {
6541debfc3dSmrg 	_M_destroy_node(__p);
6551debfc3dSmrg 	_M_put_node(__p);
6561debfc3dSmrg       }
6571debfc3dSmrg 
6581debfc3dSmrg       template<typename _NodeGen>
6591debfc3dSmrg 	_Link_type
6601debfc3dSmrg 	_M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen)
6611debfc3dSmrg 	{
6621debfc3dSmrg 	  _Link_type __tmp = __node_gen(*__x->_M_valptr());
6631debfc3dSmrg 	  __tmp->_M_color = __x->_M_color;
6641debfc3dSmrg 	  __tmp->_M_left = 0;
6651debfc3dSmrg 	  __tmp->_M_right = 0;
6661debfc3dSmrg 	  return __tmp;
6671debfc3dSmrg 	}
6681debfc3dSmrg 
6691debfc3dSmrg     protected:
670a2dc1f3fSmrg #if _GLIBCXX_INLINE_VERSION
671a2dc1f3fSmrg       template<typename _Key_compare>
672a2dc1f3fSmrg #else
6731debfc3dSmrg       // Unused _Is_pod_comparator is kept as it is part of mangled name.
6741debfc3dSmrg       template<typename _Key_compare,
6751debfc3dSmrg 	       bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
676a2dc1f3fSmrg #endif
6771debfc3dSmrg 	struct _Rb_tree_impl
6781debfc3dSmrg 	: public _Node_allocator
6791debfc3dSmrg 	, public _Rb_tree_key_compare<_Key_compare>
6801debfc3dSmrg 	, public _Rb_tree_header
6811debfc3dSmrg 	{
6821debfc3dSmrg 	  typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare;
6831debfc3dSmrg 
6841debfc3dSmrg 	  _Rb_tree_impl()
685a2dc1f3fSmrg 	    _GLIBCXX_NOEXCEPT_IF(
686a2dc1f3fSmrg 		is_nothrow_default_constructible<_Node_allocator>::value
687a2dc1f3fSmrg 		&& is_nothrow_default_constructible<_Base_key_compare>::value )
688a2dc1f3fSmrg 	  : _Node_allocator()
6891debfc3dSmrg 	  { }
6901debfc3dSmrg 
6911debfc3dSmrg 	  _Rb_tree_impl(const _Rb_tree_impl& __x)
6921debfc3dSmrg 	  : _Node_allocator(_Alloc_traits::_S_select_on_copy(__x))
6931debfc3dSmrg 	  , _Base_key_compare(__x._M_key_compare)
6941debfc3dSmrg 	  { }
6951debfc3dSmrg 
6961debfc3dSmrg #if __cplusplus < 201103L
6971debfc3dSmrg 	  _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
6981debfc3dSmrg 	  : _Node_allocator(__a), _Base_key_compare(__comp)
6991debfc3dSmrg 	  { }
7001debfc3dSmrg #else
701*8feb0f0bSmrg 	  _Rb_tree_impl(_Rb_tree_impl&&)
702*8feb0f0bSmrg 	    noexcept( is_nothrow_move_constructible<_Base_key_compare>::value )
703*8feb0f0bSmrg 	  = default;
704a2dc1f3fSmrg 
705c0a68be4Smrg 	  explicit
706c0a68be4Smrg 	  _Rb_tree_impl(_Node_allocator&& __a)
707c0a68be4Smrg 	  : _Node_allocator(std::move(__a))
708c0a68be4Smrg 	  { }
709c0a68be4Smrg 
710c0a68be4Smrg 	  _Rb_tree_impl(_Rb_tree_impl&& __x, _Node_allocator&& __a)
711c0a68be4Smrg 	  : _Node_allocator(std::move(__a)),
712c0a68be4Smrg 	    _Base_key_compare(std::move(__x)),
713c0a68be4Smrg 	    _Rb_tree_header(std::move(__x))
714c0a68be4Smrg 	  { }
715c0a68be4Smrg 
7161debfc3dSmrg 	  _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
7171debfc3dSmrg 	  : _Node_allocator(std::move(__a)), _Base_key_compare(__comp)
7181debfc3dSmrg 	  { }
7191debfc3dSmrg #endif
7201debfc3dSmrg 	};
7211debfc3dSmrg 
7221debfc3dSmrg       _Rb_tree_impl<_Compare> _M_impl;
7231debfc3dSmrg 
7241debfc3dSmrg     protected:
7251debfc3dSmrg       _Base_ptr&
7261debfc3dSmrg       _M_root() _GLIBCXX_NOEXCEPT
7271debfc3dSmrg       { return this->_M_impl._M_header._M_parent; }
7281debfc3dSmrg 
7291debfc3dSmrg       _Const_Base_ptr
7301debfc3dSmrg       _M_root() const _GLIBCXX_NOEXCEPT
7311debfc3dSmrg       { return this->_M_impl._M_header._M_parent; }
7321debfc3dSmrg 
7331debfc3dSmrg       _Base_ptr&
7341debfc3dSmrg       _M_leftmost() _GLIBCXX_NOEXCEPT
7351debfc3dSmrg       { return this->_M_impl._M_header._M_left; }
7361debfc3dSmrg 
7371debfc3dSmrg       _Const_Base_ptr
7381debfc3dSmrg       _M_leftmost() const _GLIBCXX_NOEXCEPT
7391debfc3dSmrg       { return this->_M_impl._M_header._M_left; }
7401debfc3dSmrg 
7411debfc3dSmrg       _Base_ptr&
7421debfc3dSmrg       _M_rightmost() _GLIBCXX_NOEXCEPT
7431debfc3dSmrg       { return this->_M_impl._M_header._M_right; }
7441debfc3dSmrg 
7451debfc3dSmrg       _Const_Base_ptr
7461debfc3dSmrg       _M_rightmost() const _GLIBCXX_NOEXCEPT
7471debfc3dSmrg       { return this->_M_impl._M_header._M_right; }
7481debfc3dSmrg 
7491debfc3dSmrg       _Link_type
7501debfc3dSmrg       _M_begin() _GLIBCXX_NOEXCEPT
7511debfc3dSmrg       { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
7521debfc3dSmrg 
7531debfc3dSmrg       _Const_Link_type
7541debfc3dSmrg       _M_begin() const _GLIBCXX_NOEXCEPT
7551debfc3dSmrg       {
7561debfc3dSmrg 	return static_cast<_Const_Link_type>
7571debfc3dSmrg 	  (this->_M_impl._M_header._M_parent);
7581debfc3dSmrg       }
7591debfc3dSmrg 
7601debfc3dSmrg       _Base_ptr
7611debfc3dSmrg       _M_end() _GLIBCXX_NOEXCEPT
7621debfc3dSmrg       { return &this->_M_impl._M_header; }
7631debfc3dSmrg 
7641debfc3dSmrg       _Const_Base_ptr
7651debfc3dSmrg       _M_end() const _GLIBCXX_NOEXCEPT
7661debfc3dSmrg       { return &this->_M_impl._M_header; }
7671debfc3dSmrg 
7681debfc3dSmrg       static const _Key&
7691debfc3dSmrg       _S_key(_Const_Link_type __x)
770a2dc1f3fSmrg       {
771a2dc1f3fSmrg #if __cplusplus >= 201103L
772a2dc1f3fSmrg 	// If we're asking for the key we're presumably using the comparison
773a2dc1f3fSmrg 	// object, and so this is a good place to sanity check it.
774a2dc1f3fSmrg 	static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
775a2dc1f3fSmrg 		      "comparison object must be invocable "
776a2dc1f3fSmrg 		      "with two arguments of key type");
777a2dc1f3fSmrg # if __cplusplus >= 201703L
778a2dc1f3fSmrg 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
779a2dc1f3fSmrg 	// 2542. Missing const requirements for associative containers
780a2dc1f3fSmrg 	if constexpr (__is_invocable<_Compare&, const _Key&, const _Key&>{})
781a2dc1f3fSmrg 	  static_assert(
782a2dc1f3fSmrg 	      is_invocable_v<const _Compare&, const _Key&, const _Key&>,
783a2dc1f3fSmrg 	      "comparison object must be invocable as const");
784a2dc1f3fSmrg # endif // C++17
785a2dc1f3fSmrg #endif // C++11
786a2dc1f3fSmrg 
787a2dc1f3fSmrg 	return _KeyOfValue()(*__x->_M_valptr());
788a2dc1f3fSmrg       }
7891debfc3dSmrg 
7901debfc3dSmrg       static _Link_type
7911debfc3dSmrg       _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT
7921debfc3dSmrg       { return static_cast<_Link_type>(__x->_M_left); }
7931debfc3dSmrg 
7941debfc3dSmrg       static _Const_Link_type
7951debfc3dSmrg       _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
7961debfc3dSmrg       { return static_cast<_Const_Link_type>(__x->_M_left); }
7971debfc3dSmrg 
7981debfc3dSmrg       static _Link_type
7991debfc3dSmrg       _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT
8001debfc3dSmrg       { return static_cast<_Link_type>(__x->_M_right); }
8011debfc3dSmrg 
8021debfc3dSmrg       static _Const_Link_type
8031debfc3dSmrg       _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
8041debfc3dSmrg       { return static_cast<_Const_Link_type>(__x->_M_right); }
8051debfc3dSmrg 
8061debfc3dSmrg       static const _Key&
8071debfc3dSmrg       _S_key(_Const_Base_ptr __x)
808a2dc1f3fSmrg       { return _S_key(static_cast<_Const_Link_type>(__x)); }
8091debfc3dSmrg 
8101debfc3dSmrg       static _Base_ptr
8111debfc3dSmrg       _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
8121debfc3dSmrg       { return _Rb_tree_node_base::_S_minimum(__x); }
8131debfc3dSmrg 
8141debfc3dSmrg       static _Const_Base_ptr
8151debfc3dSmrg       _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
8161debfc3dSmrg       { return _Rb_tree_node_base::_S_minimum(__x); }
8171debfc3dSmrg 
8181debfc3dSmrg       static _Base_ptr
8191debfc3dSmrg       _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
8201debfc3dSmrg       { return _Rb_tree_node_base::_S_maximum(__x); }
8211debfc3dSmrg 
8221debfc3dSmrg       static _Const_Base_ptr
8231debfc3dSmrg       _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
8241debfc3dSmrg       { return _Rb_tree_node_base::_S_maximum(__x); }
8251debfc3dSmrg 
8261debfc3dSmrg     public:
8271debfc3dSmrg       typedef _Rb_tree_iterator<value_type>       iterator;
8281debfc3dSmrg       typedef _Rb_tree_const_iterator<value_type> const_iterator;
8291debfc3dSmrg 
8301debfc3dSmrg       typedef std::reverse_iterator<iterator>       reverse_iterator;
8311debfc3dSmrg       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
8321debfc3dSmrg 
8331debfc3dSmrg #if __cplusplus > 201402L
8341debfc3dSmrg       using node_type = _Node_handle<_Key, _Val, _Node_allocator>;
8351debfc3dSmrg       using insert_return_type = _Node_insert_return<
8361debfc3dSmrg 	conditional_t<is_same_v<_Key, _Val>, const_iterator, iterator>,
8371debfc3dSmrg 	node_type>;
8381debfc3dSmrg #endif
8391debfc3dSmrg 
8401debfc3dSmrg       pair<_Base_ptr, _Base_ptr>
8411debfc3dSmrg       _M_get_insert_unique_pos(const key_type& __k);
8421debfc3dSmrg 
8431debfc3dSmrg       pair<_Base_ptr, _Base_ptr>
8441debfc3dSmrg       _M_get_insert_equal_pos(const key_type& __k);
8451debfc3dSmrg 
8461debfc3dSmrg       pair<_Base_ptr, _Base_ptr>
8471debfc3dSmrg       _M_get_insert_hint_unique_pos(const_iterator __pos,
8481debfc3dSmrg 				    const key_type& __k);
8491debfc3dSmrg 
8501debfc3dSmrg       pair<_Base_ptr, _Base_ptr>
8511debfc3dSmrg       _M_get_insert_hint_equal_pos(const_iterator __pos,
8521debfc3dSmrg 				   const key_type& __k);
8531debfc3dSmrg 
8541debfc3dSmrg     private:
8551debfc3dSmrg #if __cplusplus >= 201103L
8561debfc3dSmrg       template<typename _Arg, typename _NodeGen>
8571debfc3dSmrg 	iterator
8581debfc3dSmrg 	_M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v, _NodeGen&);
8591debfc3dSmrg 
8601debfc3dSmrg       iterator
8611debfc3dSmrg       _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
8621debfc3dSmrg 
8631debfc3dSmrg       template<typename _Arg>
8641debfc3dSmrg 	iterator
8651debfc3dSmrg 	_M_insert_lower(_Base_ptr __y, _Arg&& __v);
8661debfc3dSmrg 
8671debfc3dSmrg       template<typename _Arg>
8681debfc3dSmrg 	iterator
8691debfc3dSmrg 	_M_insert_equal_lower(_Arg&& __x);
8701debfc3dSmrg 
8711debfc3dSmrg       iterator
8721debfc3dSmrg       _M_insert_lower_node(_Base_ptr __p, _Link_type __z);
8731debfc3dSmrg 
8741debfc3dSmrg       iterator
8751debfc3dSmrg       _M_insert_equal_lower_node(_Link_type __z);
8761debfc3dSmrg #else
8771debfc3dSmrg       template<typename _NodeGen>
8781debfc3dSmrg 	iterator
8791debfc3dSmrg 	_M_insert_(_Base_ptr __x, _Base_ptr __y,
8801debfc3dSmrg 		   const value_type& __v, _NodeGen&);
8811debfc3dSmrg 
8821debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
8831debfc3dSmrg       // 233. Insertion hints in associative containers.
8841debfc3dSmrg       iterator
8851debfc3dSmrg       _M_insert_lower(_Base_ptr __y, const value_type& __v);
8861debfc3dSmrg 
8871debfc3dSmrg       iterator
8881debfc3dSmrg       _M_insert_equal_lower(const value_type& __x);
8891debfc3dSmrg #endif
8901debfc3dSmrg 
8911debfc3dSmrg       template<typename _NodeGen>
8921debfc3dSmrg 	_Link_type
8931debfc3dSmrg 	_M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&);
8941debfc3dSmrg 
8951debfc3dSmrg       template<typename _NodeGen>
8961debfc3dSmrg 	_Link_type
8971debfc3dSmrg 	_M_copy(const _Rb_tree& __x, _NodeGen& __gen)
8981debfc3dSmrg 	{
8991debfc3dSmrg 	  _Link_type __root = _M_copy(__x._M_begin(), _M_end(), __gen);
9001debfc3dSmrg 	  _M_leftmost() = _S_minimum(__root);
9011debfc3dSmrg 	  _M_rightmost() = _S_maximum(__root);
9021debfc3dSmrg 	  _M_impl._M_node_count = __x._M_impl._M_node_count;
9031debfc3dSmrg 	  return __root;
9041debfc3dSmrg 	}
9051debfc3dSmrg 
9061debfc3dSmrg       _Link_type
9071debfc3dSmrg       _M_copy(const _Rb_tree& __x)
9081debfc3dSmrg       {
9091debfc3dSmrg 	_Alloc_node __an(*this);
9101debfc3dSmrg 	return _M_copy(__x, __an);
9111debfc3dSmrg       }
9121debfc3dSmrg 
9131debfc3dSmrg       void
9141debfc3dSmrg       _M_erase(_Link_type __x);
9151debfc3dSmrg 
9161debfc3dSmrg       iterator
9171debfc3dSmrg       _M_lower_bound(_Link_type __x, _Base_ptr __y,
9181debfc3dSmrg 		     const _Key& __k);
9191debfc3dSmrg 
9201debfc3dSmrg       const_iterator
9211debfc3dSmrg       _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
9221debfc3dSmrg 		     const _Key& __k) const;
9231debfc3dSmrg 
9241debfc3dSmrg       iterator
9251debfc3dSmrg       _M_upper_bound(_Link_type __x, _Base_ptr __y,
9261debfc3dSmrg 		     const _Key& __k);
9271debfc3dSmrg 
9281debfc3dSmrg       const_iterator
9291debfc3dSmrg       _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
9301debfc3dSmrg 		     const _Key& __k) const;
9311debfc3dSmrg 
9321debfc3dSmrg     public:
9331debfc3dSmrg       // allocation/deallocation
9341debfc3dSmrg #if __cplusplus < 201103L
9351debfc3dSmrg       _Rb_tree() { }
9361debfc3dSmrg #else
9371debfc3dSmrg       _Rb_tree() = default;
9381debfc3dSmrg #endif
9391debfc3dSmrg 
9401debfc3dSmrg       _Rb_tree(const _Compare& __comp,
9411debfc3dSmrg 	       const allocator_type& __a = allocator_type())
9421debfc3dSmrg       : _M_impl(__comp, _Node_allocator(__a)) { }
9431debfc3dSmrg 
9441debfc3dSmrg       _Rb_tree(const _Rb_tree& __x)
9451debfc3dSmrg       : _M_impl(__x._M_impl)
9461debfc3dSmrg       {
9471debfc3dSmrg 	if (__x._M_root() != 0)
9481debfc3dSmrg 	  _M_root() = _M_copy(__x);
9491debfc3dSmrg       }
9501debfc3dSmrg 
9511debfc3dSmrg #if __cplusplus >= 201103L
9521debfc3dSmrg       _Rb_tree(const allocator_type& __a)
953c0a68be4Smrg       : _M_impl(_Node_allocator(__a))
9541debfc3dSmrg       { }
9551debfc3dSmrg 
9561debfc3dSmrg       _Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
9571debfc3dSmrg       : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
9581debfc3dSmrg       {
9591debfc3dSmrg 	if (__x._M_root() != nullptr)
9601debfc3dSmrg 	  _M_root() = _M_copy(__x);
9611debfc3dSmrg       }
9621debfc3dSmrg 
9631debfc3dSmrg       _Rb_tree(_Rb_tree&&) = default;
9641debfc3dSmrg 
9651debfc3dSmrg       _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
9661debfc3dSmrg       : _Rb_tree(std::move(__x), _Node_allocator(__a))
9671debfc3dSmrg       { }
9681debfc3dSmrg 
969c0a68be4Smrg     private:
970c0a68be4Smrg       _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, true_type)
971c0a68be4Smrg       noexcept(is_nothrow_default_constructible<_Compare>::value)
972c0a68be4Smrg       : _M_impl(std::move(__x._M_impl), std::move(__a))
973c0a68be4Smrg       { }
974c0a68be4Smrg 
975c0a68be4Smrg       _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, false_type)
976c0a68be4Smrg       : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
977c0a68be4Smrg       {
978c0a68be4Smrg 	if (__x._M_root() != nullptr)
979c0a68be4Smrg 	  _M_move_data(__x, false_type{});
980c0a68be4Smrg       }
981c0a68be4Smrg 
982c0a68be4Smrg     public:
983c0a68be4Smrg       _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
984c0a68be4Smrg       noexcept( noexcept(
985c0a68be4Smrg 	_Rb_tree(std::declval<_Rb_tree&&>(), std::declval<_Node_allocator&&>(),
986c0a68be4Smrg 		 std::declval<typename _Alloc_traits::is_always_equal>())) )
987c0a68be4Smrg       : _Rb_tree(std::move(__x), std::move(__a),
988c0a68be4Smrg 		 typename _Alloc_traits::is_always_equal{})
989c0a68be4Smrg       { }
9901debfc3dSmrg #endif
9911debfc3dSmrg 
9921debfc3dSmrg       ~_Rb_tree() _GLIBCXX_NOEXCEPT
9931debfc3dSmrg       { _M_erase(_M_begin()); }
9941debfc3dSmrg 
9951debfc3dSmrg       _Rb_tree&
9961debfc3dSmrg       operator=(const _Rb_tree& __x);
9971debfc3dSmrg 
9981debfc3dSmrg       // Accessors.
9991debfc3dSmrg       _Compare
10001debfc3dSmrg       key_comp() const
10011debfc3dSmrg       { return _M_impl._M_key_compare; }
10021debfc3dSmrg 
10031debfc3dSmrg       iterator
10041debfc3dSmrg       begin() _GLIBCXX_NOEXCEPT
10051debfc3dSmrg       { return iterator(this->_M_impl._M_header._M_left); }
10061debfc3dSmrg 
10071debfc3dSmrg       const_iterator
10081debfc3dSmrg       begin() const _GLIBCXX_NOEXCEPT
10091debfc3dSmrg       { return const_iterator(this->_M_impl._M_header._M_left); }
10101debfc3dSmrg 
10111debfc3dSmrg       iterator
10121debfc3dSmrg       end() _GLIBCXX_NOEXCEPT
10131debfc3dSmrg       { return iterator(&this->_M_impl._M_header); }
10141debfc3dSmrg 
10151debfc3dSmrg       const_iterator
10161debfc3dSmrg       end() const _GLIBCXX_NOEXCEPT
10171debfc3dSmrg       { return const_iterator(&this->_M_impl._M_header); }
10181debfc3dSmrg 
10191debfc3dSmrg       reverse_iterator
10201debfc3dSmrg       rbegin() _GLIBCXX_NOEXCEPT
10211debfc3dSmrg       { return reverse_iterator(end()); }
10221debfc3dSmrg 
10231debfc3dSmrg       const_reverse_iterator
10241debfc3dSmrg       rbegin() const _GLIBCXX_NOEXCEPT
10251debfc3dSmrg       { return const_reverse_iterator(end()); }
10261debfc3dSmrg 
10271debfc3dSmrg       reverse_iterator
10281debfc3dSmrg       rend() _GLIBCXX_NOEXCEPT
10291debfc3dSmrg       { return reverse_iterator(begin()); }
10301debfc3dSmrg 
10311debfc3dSmrg       const_reverse_iterator
10321debfc3dSmrg       rend() const _GLIBCXX_NOEXCEPT
10331debfc3dSmrg       { return const_reverse_iterator(begin()); }
10341debfc3dSmrg 
1035c0a68be4Smrg       _GLIBCXX_NODISCARD bool
10361debfc3dSmrg       empty() const _GLIBCXX_NOEXCEPT
10371debfc3dSmrg       { return _M_impl._M_node_count == 0; }
10381debfc3dSmrg 
10391debfc3dSmrg       size_type
10401debfc3dSmrg       size() const _GLIBCXX_NOEXCEPT
10411debfc3dSmrg       { return _M_impl._M_node_count; }
10421debfc3dSmrg 
10431debfc3dSmrg       size_type
10441debfc3dSmrg       max_size() const _GLIBCXX_NOEXCEPT
10451debfc3dSmrg       { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
10461debfc3dSmrg 
10471debfc3dSmrg       void
10481debfc3dSmrg       swap(_Rb_tree& __t)
10491debfc3dSmrg       _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value);
10501debfc3dSmrg 
10511debfc3dSmrg       // Insert/erase.
10521debfc3dSmrg #if __cplusplus >= 201103L
10531debfc3dSmrg       template<typename _Arg>
10541debfc3dSmrg 	pair<iterator, bool>
10551debfc3dSmrg 	_M_insert_unique(_Arg&& __x);
10561debfc3dSmrg 
10571debfc3dSmrg       template<typename _Arg>
10581debfc3dSmrg 	iterator
10591debfc3dSmrg 	_M_insert_equal(_Arg&& __x);
10601debfc3dSmrg 
10611debfc3dSmrg       template<typename _Arg, typename _NodeGen>
10621debfc3dSmrg 	iterator
10631debfc3dSmrg 	_M_insert_unique_(const_iterator __pos, _Arg&& __x, _NodeGen&);
10641debfc3dSmrg 
10651debfc3dSmrg       template<typename _Arg>
10661debfc3dSmrg 	iterator
10671debfc3dSmrg 	_M_insert_unique_(const_iterator __pos, _Arg&& __x)
10681debfc3dSmrg 	{
10691debfc3dSmrg 	  _Alloc_node __an(*this);
10701debfc3dSmrg 	  return _M_insert_unique_(__pos, std::forward<_Arg>(__x), __an);
10711debfc3dSmrg 	}
10721debfc3dSmrg 
10731debfc3dSmrg       template<typename _Arg, typename _NodeGen>
10741debfc3dSmrg 	iterator
10751debfc3dSmrg 	_M_insert_equal_(const_iterator __pos, _Arg&& __x, _NodeGen&);
10761debfc3dSmrg 
10771debfc3dSmrg       template<typename _Arg>
10781debfc3dSmrg 	iterator
10791debfc3dSmrg 	_M_insert_equal_(const_iterator __pos, _Arg&& __x)
10801debfc3dSmrg 	{
10811debfc3dSmrg 	  _Alloc_node __an(*this);
10821debfc3dSmrg 	  return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an);
10831debfc3dSmrg 	}
10841debfc3dSmrg 
10851debfc3dSmrg       template<typename... _Args>
10861debfc3dSmrg 	pair<iterator, bool>
10871debfc3dSmrg 	_M_emplace_unique(_Args&&... __args);
10881debfc3dSmrg 
10891debfc3dSmrg       template<typename... _Args>
10901debfc3dSmrg 	iterator
10911debfc3dSmrg 	_M_emplace_equal(_Args&&... __args);
10921debfc3dSmrg 
10931debfc3dSmrg       template<typename... _Args>
10941debfc3dSmrg 	iterator
10951debfc3dSmrg 	_M_emplace_hint_unique(const_iterator __pos, _Args&&... __args);
10961debfc3dSmrg 
10971debfc3dSmrg       template<typename... _Args>
10981debfc3dSmrg 	iterator
10991debfc3dSmrg 	_M_emplace_hint_equal(const_iterator __pos, _Args&&... __args);
1100c0a68be4Smrg 
1101c0a68be4Smrg       template<typename _Iter>
1102c0a68be4Smrg 	using __same_value_type
1103c0a68be4Smrg 	  = is_same<value_type, typename iterator_traits<_Iter>::value_type>;
1104c0a68be4Smrg 
1105c0a68be4Smrg       template<typename _InputIterator>
1106c0a68be4Smrg 	__enable_if_t<__same_value_type<_InputIterator>::value>
1107c0a68be4Smrg 	_M_insert_range_unique(_InputIterator __first, _InputIterator __last)
1108c0a68be4Smrg 	{
1109c0a68be4Smrg 	  _Alloc_node __an(*this);
1110c0a68be4Smrg 	  for (; __first != __last; ++__first)
1111c0a68be4Smrg 	    _M_insert_unique_(end(), *__first, __an);
1112c0a68be4Smrg 	}
1113c0a68be4Smrg 
1114c0a68be4Smrg       template<typename _InputIterator>
1115c0a68be4Smrg 	__enable_if_t<!__same_value_type<_InputIterator>::value>
1116c0a68be4Smrg 	_M_insert_range_unique(_InputIterator __first, _InputIterator __last)
1117c0a68be4Smrg 	{
1118c0a68be4Smrg 	  for (; __first != __last; ++__first)
1119c0a68be4Smrg 	    _M_emplace_unique(*__first);
1120c0a68be4Smrg 	}
1121c0a68be4Smrg 
1122c0a68be4Smrg       template<typename _InputIterator>
1123c0a68be4Smrg 	__enable_if_t<__same_value_type<_InputIterator>::value>
1124c0a68be4Smrg 	_M_insert_range_equal(_InputIterator __first, _InputIterator __last)
1125c0a68be4Smrg 	{
1126c0a68be4Smrg 	  _Alloc_node __an(*this);
1127c0a68be4Smrg 	  for (; __first != __last; ++__first)
1128c0a68be4Smrg 	    _M_insert_equal_(end(), *__first, __an);
1129c0a68be4Smrg 	}
1130c0a68be4Smrg 
1131c0a68be4Smrg       template<typename _InputIterator>
1132c0a68be4Smrg 	__enable_if_t<!__same_value_type<_InputIterator>::value>
1133c0a68be4Smrg 	_M_insert_range_equal(_InputIterator __first, _InputIterator __last)
1134c0a68be4Smrg 	{
1135c0a68be4Smrg 	  _Alloc_node __an(*this);
1136c0a68be4Smrg 	  for (; __first != __last; ++__first)
1137c0a68be4Smrg 	    _M_emplace_equal(*__first);
1138c0a68be4Smrg 	}
11391debfc3dSmrg #else
11401debfc3dSmrg       pair<iterator, bool>
11411debfc3dSmrg       _M_insert_unique(const value_type& __x);
11421debfc3dSmrg 
11431debfc3dSmrg       iterator
11441debfc3dSmrg       _M_insert_equal(const value_type& __x);
11451debfc3dSmrg 
11461debfc3dSmrg       template<typename _NodeGen>
11471debfc3dSmrg 	iterator
11481debfc3dSmrg 	_M_insert_unique_(const_iterator __pos, const value_type& __x,
11491debfc3dSmrg 			  _NodeGen&);
11501debfc3dSmrg 
11511debfc3dSmrg       iterator
11521debfc3dSmrg       _M_insert_unique_(const_iterator __pos, const value_type& __x)
11531debfc3dSmrg       {
11541debfc3dSmrg 	_Alloc_node __an(*this);
11551debfc3dSmrg 	return _M_insert_unique_(__pos, __x, __an);
11561debfc3dSmrg       }
11571debfc3dSmrg 
11581debfc3dSmrg       template<typename _NodeGen>
11591debfc3dSmrg 	iterator
11601debfc3dSmrg 	_M_insert_equal_(const_iterator __pos, const value_type& __x,
11611debfc3dSmrg 			 _NodeGen&);
11621debfc3dSmrg       iterator
11631debfc3dSmrg       _M_insert_equal_(const_iterator __pos, const value_type& __x)
11641debfc3dSmrg       {
11651debfc3dSmrg 	_Alloc_node __an(*this);
11661debfc3dSmrg 	return _M_insert_equal_(__pos, __x, __an);
11671debfc3dSmrg       }
1168c0a68be4Smrg 
1169c0a68be4Smrg       template<typename _InputIterator>
1170c0a68be4Smrg 	void
1171c0a68be4Smrg 	_M_insert_range_unique(_InputIterator __first, _InputIterator __last)
1172c0a68be4Smrg 	{
1173c0a68be4Smrg 	  _Alloc_node __an(*this);
1174c0a68be4Smrg 	  for (; __first != __last; ++__first)
1175c0a68be4Smrg 	    _M_insert_unique_(end(), *__first, __an);
1176c0a68be4Smrg 	}
1177c0a68be4Smrg 
1178c0a68be4Smrg       template<typename _InputIterator>
1179c0a68be4Smrg 	void
1180c0a68be4Smrg 	_M_insert_range_equal(_InputIterator __first, _InputIterator __last)
1181c0a68be4Smrg 	{
1182c0a68be4Smrg 	  _Alloc_node __an(*this);
1183c0a68be4Smrg 	  for (; __first != __last; ++__first)
1184c0a68be4Smrg 	    _M_insert_equal_(end(), *__first, __an);
1185c0a68be4Smrg 	}
11861debfc3dSmrg #endif
11871debfc3dSmrg 
11881debfc3dSmrg     private:
11891debfc3dSmrg       void
11901debfc3dSmrg       _M_erase_aux(const_iterator __position);
11911debfc3dSmrg 
11921debfc3dSmrg       void
11931debfc3dSmrg       _M_erase_aux(const_iterator __first, const_iterator __last);
11941debfc3dSmrg 
11951debfc3dSmrg     public:
11961debfc3dSmrg #if __cplusplus >= 201103L
11971debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
11981debfc3dSmrg       // DR 130. Associative erase should return an iterator.
11991debfc3dSmrg       _GLIBCXX_ABI_TAG_CXX11
12001debfc3dSmrg       iterator
12011debfc3dSmrg       erase(const_iterator __position)
12021debfc3dSmrg       {
12031debfc3dSmrg 	__glibcxx_assert(__position != end());
12041debfc3dSmrg 	const_iterator __result = __position;
12051debfc3dSmrg 	++__result;
12061debfc3dSmrg 	_M_erase_aux(__position);
12071debfc3dSmrg 	return __result._M_const_cast();
12081debfc3dSmrg       }
12091debfc3dSmrg 
12101debfc3dSmrg       // LWG 2059.
12111debfc3dSmrg       _GLIBCXX_ABI_TAG_CXX11
12121debfc3dSmrg       iterator
12131debfc3dSmrg       erase(iterator __position)
12141debfc3dSmrg       {
12151debfc3dSmrg 	__glibcxx_assert(__position != end());
12161debfc3dSmrg 	iterator __result = __position;
12171debfc3dSmrg 	++__result;
12181debfc3dSmrg 	_M_erase_aux(__position);
12191debfc3dSmrg 	return __result;
12201debfc3dSmrg       }
12211debfc3dSmrg #else
12221debfc3dSmrg       void
12231debfc3dSmrg       erase(iterator __position)
12241debfc3dSmrg       {
12251debfc3dSmrg 	__glibcxx_assert(__position != end());
12261debfc3dSmrg 	_M_erase_aux(__position);
12271debfc3dSmrg       }
12281debfc3dSmrg 
12291debfc3dSmrg       void
12301debfc3dSmrg       erase(const_iterator __position)
12311debfc3dSmrg       {
12321debfc3dSmrg 	__glibcxx_assert(__position != end());
12331debfc3dSmrg 	_M_erase_aux(__position);
12341debfc3dSmrg       }
12351debfc3dSmrg #endif
1236*8feb0f0bSmrg 
12371debfc3dSmrg       size_type
12381debfc3dSmrg       erase(const key_type& __x);
12391debfc3dSmrg 
12401debfc3dSmrg #if __cplusplus >= 201103L
12411debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
12421debfc3dSmrg       // DR 130. Associative erase should return an iterator.
12431debfc3dSmrg       _GLIBCXX_ABI_TAG_CXX11
12441debfc3dSmrg       iterator
12451debfc3dSmrg       erase(const_iterator __first, const_iterator __last)
12461debfc3dSmrg       {
12471debfc3dSmrg 	_M_erase_aux(__first, __last);
12481debfc3dSmrg 	return __last._M_const_cast();
12491debfc3dSmrg       }
12501debfc3dSmrg #else
12511debfc3dSmrg       void
12521debfc3dSmrg       erase(iterator __first, iterator __last)
12531debfc3dSmrg       { _M_erase_aux(__first, __last); }
12541debfc3dSmrg 
12551debfc3dSmrg       void
12561debfc3dSmrg       erase(const_iterator __first, const_iterator __last)
12571debfc3dSmrg       { _M_erase_aux(__first, __last); }
12581debfc3dSmrg #endif
12591debfc3dSmrg 
12601debfc3dSmrg       void
12611debfc3dSmrg       clear() _GLIBCXX_NOEXCEPT
12621debfc3dSmrg       {
12631debfc3dSmrg 	_M_erase(_M_begin());
12641debfc3dSmrg 	_M_impl._M_reset();
12651debfc3dSmrg       }
12661debfc3dSmrg 
12671debfc3dSmrg       // Set operations.
12681debfc3dSmrg       iterator
12691debfc3dSmrg       find(const key_type& __k);
12701debfc3dSmrg 
12711debfc3dSmrg       const_iterator
12721debfc3dSmrg       find(const key_type& __k) const;
12731debfc3dSmrg 
12741debfc3dSmrg       size_type
12751debfc3dSmrg       count(const key_type& __k) const;
12761debfc3dSmrg 
12771debfc3dSmrg       iterator
12781debfc3dSmrg       lower_bound(const key_type& __k)
12791debfc3dSmrg       { return _M_lower_bound(_M_begin(), _M_end(), __k); }
12801debfc3dSmrg 
12811debfc3dSmrg       const_iterator
12821debfc3dSmrg       lower_bound(const key_type& __k) const
12831debfc3dSmrg       { return _M_lower_bound(_M_begin(), _M_end(), __k); }
12841debfc3dSmrg 
12851debfc3dSmrg       iterator
12861debfc3dSmrg       upper_bound(const key_type& __k)
12871debfc3dSmrg       { return _M_upper_bound(_M_begin(), _M_end(), __k); }
12881debfc3dSmrg 
12891debfc3dSmrg       const_iterator
12901debfc3dSmrg       upper_bound(const key_type& __k) const
12911debfc3dSmrg       { return _M_upper_bound(_M_begin(), _M_end(), __k); }
12921debfc3dSmrg 
12931debfc3dSmrg       pair<iterator, iterator>
12941debfc3dSmrg       equal_range(const key_type& __k);
12951debfc3dSmrg 
12961debfc3dSmrg       pair<const_iterator, const_iterator>
12971debfc3dSmrg       equal_range(const key_type& __k) const;
12981debfc3dSmrg 
1299c0a68be4Smrg #if __cplusplus >= 201402L
13001debfc3dSmrg       template<typename _Kt,
1301c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13021debfc3dSmrg 	iterator
13031debfc3dSmrg 	_M_find_tr(const _Kt& __k)
13041debfc3dSmrg 	{
13051debfc3dSmrg 	  const _Rb_tree* __const_this = this;
13061debfc3dSmrg 	  return __const_this->_M_find_tr(__k)._M_const_cast();
13071debfc3dSmrg 	}
13081debfc3dSmrg 
13091debfc3dSmrg       template<typename _Kt,
1310c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13111debfc3dSmrg 	const_iterator
13121debfc3dSmrg 	_M_find_tr(const _Kt& __k) const
13131debfc3dSmrg 	{
13141debfc3dSmrg 	  auto __j = _M_lower_bound_tr(__k);
13151debfc3dSmrg 	  if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node)))
13161debfc3dSmrg 	    __j = end();
13171debfc3dSmrg 	  return __j;
13181debfc3dSmrg 	}
13191debfc3dSmrg 
13201debfc3dSmrg       template<typename _Kt,
1321c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13221debfc3dSmrg 	size_type
13231debfc3dSmrg 	_M_count_tr(const _Kt& __k) const
13241debfc3dSmrg 	{
13251debfc3dSmrg 	  auto __p = _M_equal_range_tr(__k);
13261debfc3dSmrg 	  return std::distance(__p.first, __p.second);
13271debfc3dSmrg 	}
13281debfc3dSmrg 
13291debfc3dSmrg       template<typename _Kt,
1330c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13311debfc3dSmrg 	iterator
13321debfc3dSmrg 	_M_lower_bound_tr(const _Kt& __k)
13331debfc3dSmrg 	{
13341debfc3dSmrg 	  const _Rb_tree* __const_this = this;
13351debfc3dSmrg 	  return __const_this->_M_lower_bound_tr(__k)._M_const_cast();
13361debfc3dSmrg 	}
13371debfc3dSmrg 
13381debfc3dSmrg       template<typename _Kt,
1339c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13401debfc3dSmrg 	const_iterator
13411debfc3dSmrg 	_M_lower_bound_tr(const _Kt& __k) const
13421debfc3dSmrg 	{
13431debfc3dSmrg 	  auto __x = _M_begin();
13441debfc3dSmrg 	  auto __y = _M_end();
13451debfc3dSmrg 	  while (__x != 0)
13461debfc3dSmrg 	    if (!_M_impl._M_key_compare(_S_key(__x), __k))
13471debfc3dSmrg 	      {
13481debfc3dSmrg 		__y = __x;
13491debfc3dSmrg 		__x = _S_left(__x);
13501debfc3dSmrg 	      }
13511debfc3dSmrg 	    else
13521debfc3dSmrg 	      __x = _S_right(__x);
13531debfc3dSmrg 	  return const_iterator(__y);
13541debfc3dSmrg 	}
13551debfc3dSmrg 
13561debfc3dSmrg       template<typename _Kt,
1357c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13581debfc3dSmrg 	iterator
13591debfc3dSmrg 	_M_upper_bound_tr(const _Kt& __k)
13601debfc3dSmrg 	{
13611debfc3dSmrg 	  const _Rb_tree* __const_this = this;
13621debfc3dSmrg 	  return __const_this->_M_upper_bound_tr(__k)._M_const_cast();
13631debfc3dSmrg 	}
13641debfc3dSmrg 
13651debfc3dSmrg       template<typename _Kt,
1366c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13671debfc3dSmrg 	const_iterator
13681debfc3dSmrg 	_M_upper_bound_tr(const _Kt& __k) const
13691debfc3dSmrg 	{
13701debfc3dSmrg 	  auto __x = _M_begin();
13711debfc3dSmrg 	  auto __y = _M_end();
13721debfc3dSmrg 	  while (__x != 0)
13731debfc3dSmrg 	    if (_M_impl._M_key_compare(__k, _S_key(__x)))
13741debfc3dSmrg 	      {
13751debfc3dSmrg 		__y = __x;
13761debfc3dSmrg 		__x = _S_left(__x);
13771debfc3dSmrg 	      }
13781debfc3dSmrg 	    else
13791debfc3dSmrg 	      __x = _S_right(__x);
13801debfc3dSmrg 	  return const_iterator(__y);
13811debfc3dSmrg 	}
13821debfc3dSmrg 
13831debfc3dSmrg       template<typename _Kt,
1384c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13851debfc3dSmrg 	pair<iterator, iterator>
13861debfc3dSmrg 	_M_equal_range_tr(const _Kt& __k)
13871debfc3dSmrg 	{
13881debfc3dSmrg 	  const _Rb_tree* __const_this = this;
13891debfc3dSmrg 	  auto __ret = __const_this->_M_equal_range_tr(__k);
13901debfc3dSmrg 	  return { __ret.first._M_const_cast(), __ret.second._M_const_cast() };
13911debfc3dSmrg 	}
13921debfc3dSmrg 
13931debfc3dSmrg       template<typename _Kt,
1394c0a68be4Smrg 	       typename _Req = __has_is_transparent_t<_Compare, _Kt>>
13951debfc3dSmrg 	pair<const_iterator, const_iterator>
13961debfc3dSmrg 	_M_equal_range_tr(const _Kt& __k) const
13971debfc3dSmrg 	{
13981debfc3dSmrg 	  auto __low = _M_lower_bound_tr(__k);
13991debfc3dSmrg 	  auto __high = __low;
14001debfc3dSmrg 	  auto& __cmp = _M_impl._M_key_compare;
14011debfc3dSmrg 	  while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
14021debfc3dSmrg 	    ++__high;
14031debfc3dSmrg 	  return { __low, __high };
14041debfc3dSmrg 	}
14051debfc3dSmrg #endif
14061debfc3dSmrg 
14071debfc3dSmrg       // Debugging.
14081debfc3dSmrg       bool
14091debfc3dSmrg       __rb_verify() const;
14101debfc3dSmrg 
14111debfc3dSmrg #if __cplusplus >= 201103L
14121debfc3dSmrg       _Rb_tree&
14131debfc3dSmrg       operator=(_Rb_tree&&)
14141debfc3dSmrg       noexcept(_Alloc_traits::_S_nothrow_move()
14151debfc3dSmrg 	       && is_nothrow_move_assignable<_Compare>::value);
14161debfc3dSmrg 
14171debfc3dSmrg       template<typename _Iterator>
14181debfc3dSmrg 	void
14191debfc3dSmrg 	_M_assign_unique(_Iterator, _Iterator);
14201debfc3dSmrg 
14211debfc3dSmrg       template<typename _Iterator>
14221debfc3dSmrg 	void
14231debfc3dSmrg 	_M_assign_equal(_Iterator, _Iterator);
14241debfc3dSmrg 
14251debfc3dSmrg     private:
14261debfc3dSmrg       // Move elements from container with equal allocator.
14271debfc3dSmrg       void
1428c0a68be4Smrg       _M_move_data(_Rb_tree& __x, true_type)
14291debfc3dSmrg       { _M_impl._M_move_data(__x._M_impl); }
14301debfc3dSmrg 
14311debfc3dSmrg       // Move elements from container with possibly non-equal allocator,
14321debfc3dSmrg       // which might result in a copy not a move.
14331debfc3dSmrg       void
1434c0a68be4Smrg       _M_move_data(_Rb_tree&, false_type);
14351debfc3dSmrg 
14361debfc3dSmrg       // Move assignment from container with equal allocator.
14371debfc3dSmrg       void
1438c0a68be4Smrg       _M_move_assign(_Rb_tree&, true_type);
14391debfc3dSmrg 
14401debfc3dSmrg       // Move assignment from container with possibly non-equal allocator,
14411debfc3dSmrg       // which might result in a copy not a move.
14421debfc3dSmrg       void
1443c0a68be4Smrg       _M_move_assign(_Rb_tree&, false_type);
14441debfc3dSmrg #endif
14451debfc3dSmrg 
14461debfc3dSmrg #if __cplusplus > 201402L
14471debfc3dSmrg     public:
14481debfc3dSmrg       /// Re-insert an extracted node.
14491debfc3dSmrg       insert_return_type
14501debfc3dSmrg       _M_reinsert_node_unique(node_type&& __nh)
14511debfc3dSmrg       {
14521debfc3dSmrg 	insert_return_type __ret;
14531debfc3dSmrg 	if (__nh.empty())
14541debfc3dSmrg 	  __ret.position = end();
14551debfc3dSmrg 	else
14561debfc3dSmrg 	  {
14571debfc3dSmrg 	    __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
14581debfc3dSmrg 
14591debfc3dSmrg 	    auto __res = _M_get_insert_unique_pos(__nh._M_key());
14601debfc3dSmrg 	    if (__res.second)
14611debfc3dSmrg 	      {
14621debfc3dSmrg 		__ret.position
14631debfc3dSmrg 		  = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
14641debfc3dSmrg 		__nh._M_ptr = nullptr;
14651debfc3dSmrg 		__ret.inserted = true;
14661debfc3dSmrg 	      }
14671debfc3dSmrg 	    else
14681debfc3dSmrg 	      {
14691debfc3dSmrg 		__ret.node = std::move(__nh);
14701debfc3dSmrg 		__ret.position = iterator(__res.first);
14711debfc3dSmrg 		__ret.inserted = false;
14721debfc3dSmrg 	      }
14731debfc3dSmrg 	  }
14741debfc3dSmrg 	return __ret;
14751debfc3dSmrg       }
14761debfc3dSmrg 
14771debfc3dSmrg       /// Re-insert an extracted node.
14781debfc3dSmrg       iterator
14791debfc3dSmrg       _M_reinsert_node_equal(node_type&& __nh)
14801debfc3dSmrg       {
14811debfc3dSmrg 	iterator __ret;
14821debfc3dSmrg 	if (__nh.empty())
14831debfc3dSmrg 	  __ret = end();
14841debfc3dSmrg 	else
14851debfc3dSmrg 	  {
14861debfc3dSmrg 	    __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
14871debfc3dSmrg 	    auto __res = _M_get_insert_equal_pos(__nh._M_key());
14881debfc3dSmrg 	    if (__res.second)
14891debfc3dSmrg 	      __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
14901debfc3dSmrg 	    else
14911debfc3dSmrg 	      __ret = _M_insert_equal_lower_node(__nh._M_ptr);
14921debfc3dSmrg 	    __nh._M_ptr = nullptr;
14931debfc3dSmrg 	  }
14941debfc3dSmrg 	return __ret;
14951debfc3dSmrg       }
14961debfc3dSmrg 
14971debfc3dSmrg       /// Re-insert an extracted node.
14981debfc3dSmrg       iterator
14991debfc3dSmrg       _M_reinsert_node_hint_unique(const_iterator __hint, node_type&& __nh)
15001debfc3dSmrg       {
15011debfc3dSmrg 	iterator __ret;
15021debfc3dSmrg 	if (__nh.empty())
15031debfc3dSmrg 	  __ret = end();
15041debfc3dSmrg 	else
15051debfc3dSmrg 	  {
15061debfc3dSmrg 	    __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
15071debfc3dSmrg 	    auto __res = _M_get_insert_hint_unique_pos(__hint, __nh._M_key());
15081debfc3dSmrg 	    if (__res.second)
15091debfc3dSmrg 	      {
15101debfc3dSmrg 		__ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
15111debfc3dSmrg 		__nh._M_ptr = nullptr;
15121debfc3dSmrg 	      }
15131debfc3dSmrg 	    else
15141debfc3dSmrg 	      __ret = iterator(__res.first);
15151debfc3dSmrg 	  }
15161debfc3dSmrg 	return __ret;
15171debfc3dSmrg       }
15181debfc3dSmrg 
15191debfc3dSmrg       /// Re-insert an extracted node.
15201debfc3dSmrg       iterator
15211debfc3dSmrg       _M_reinsert_node_hint_equal(const_iterator __hint, node_type&& __nh)
15221debfc3dSmrg       {
15231debfc3dSmrg 	iterator __ret;
15241debfc3dSmrg 	if (__nh.empty())
15251debfc3dSmrg 	  __ret = end();
15261debfc3dSmrg 	else
15271debfc3dSmrg 	  {
15281debfc3dSmrg 	    __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
15291debfc3dSmrg 	    auto __res = _M_get_insert_hint_equal_pos(__hint, __nh._M_key());
15301debfc3dSmrg 	    if (__res.second)
15311debfc3dSmrg 	      __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
15321debfc3dSmrg 	    else
15331debfc3dSmrg 	      __ret = _M_insert_equal_lower_node(__nh._M_ptr);
15341debfc3dSmrg 	    __nh._M_ptr = nullptr;
15351debfc3dSmrg 	  }
15361debfc3dSmrg 	return __ret;
15371debfc3dSmrg       }
15381debfc3dSmrg 
15391debfc3dSmrg       /// Extract a node.
15401debfc3dSmrg       node_type
15411debfc3dSmrg       extract(const_iterator __pos)
15421debfc3dSmrg       {
15431debfc3dSmrg 	auto __ptr = _Rb_tree_rebalance_for_erase(
15441debfc3dSmrg 	    __pos._M_const_cast()._M_node, _M_impl._M_header);
15451debfc3dSmrg 	--_M_impl._M_node_count;
15461debfc3dSmrg 	return { static_cast<_Link_type>(__ptr), _M_get_Node_allocator() };
15471debfc3dSmrg       }
15481debfc3dSmrg 
15491debfc3dSmrg       /// Extract a node.
15501debfc3dSmrg       node_type
15511debfc3dSmrg       extract(const key_type& __k)
15521debfc3dSmrg       {
15531debfc3dSmrg 	node_type __nh;
15541debfc3dSmrg 	auto __pos = find(__k);
15551debfc3dSmrg 	if (__pos != end())
15561debfc3dSmrg 	  __nh = extract(const_iterator(__pos));
15571debfc3dSmrg 	return __nh;
15581debfc3dSmrg       }
15591debfc3dSmrg 
15601debfc3dSmrg       template<typename _Compare2>
15611debfc3dSmrg 	using _Compatible_tree
15621debfc3dSmrg 	  = _Rb_tree<_Key, _Val, _KeyOfValue, _Compare2, _Alloc>;
15631debfc3dSmrg 
15641debfc3dSmrg       template<typename, typename>
15651debfc3dSmrg 	friend class _Rb_tree_merge_helper;
15661debfc3dSmrg 
15671debfc3dSmrg       /// Merge from a compatible container into one with unique keys.
15681debfc3dSmrg       template<typename _Compare2>
15691debfc3dSmrg 	void
15701debfc3dSmrg 	_M_merge_unique(_Compatible_tree<_Compare2>& __src) noexcept
15711debfc3dSmrg 	{
15721debfc3dSmrg 	  using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
15731debfc3dSmrg 	  for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
15741debfc3dSmrg 	    {
15751debfc3dSmrg 	      auto __pos = __i++;
15761debfc3dSmrg 	      auto __res = _M_get_insert_unique_pos(_KeyOfValue()(*__pos));
15771debfc3dSmrg 	      if (__res.second)
15781debfc3dSmrg 		{
15791debfc3dSmrg 		  auto& __src_impl = _Merge_helper::_S_get_impl(__src);
15801debfc3dSmrg 		  auto __ptr = _Rb_tree_rebalance_for_erase(
15811debfc3dSmrg 		      __pos._M_node, __src_impl._M_header);
15821debfc3dSmrg 		  --__src_impl._M_node_count;
15831debfc3dSmrg 		  _M_insert_node(__res.first, __res.second,
15841debfc3dSmrg 				 static_cast<_Link_type>(__ptr));
15851debfc3dSmrg 		}
15861debfc3dSmrg 	    }
15871debfc3dSmrg 	}
15881debfc3dSmrg 
15891debfc3dSmrg       /// Merge from a compatible container into one with equivalent keys.
15901debfc3dSmrg       template<typename _Compare2>
15911debfc3dSmrg 	void
15921debfc3dSmrg 	_M_merge_equal(_Compatible_tree<_Compare2>& __src) noexcept
15931debfc3dSmrg 	{
15941debfc3dSmrg 	  using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
15951debfc3dSmrg 	  for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
15961debfc3dSmrg 	    {
15971debfc3dSmrg 	      auto __pos = __i++;
15981debfc3dSmrg 	      auto __res = _M_get_insert_equal_pos(_KeyOfValue()(*__pos));
15991debfc3dSmrg 	      if (__res.second)
16001debfc3dSmrg 		{
16011debfc3dSmrg 		  auto& __src_impl = _Merge_helper::_S_get_impl(__src);
16021debfc3dSmrg 		  auto __ptr = _Rb_tree_rebalance_for_erase(
16031debfc3dSmrg 		      __pos._M_node, __src_impl._M_header);
16041debfc3dSmrg 		  --__src_impl._M_node_count;
16051debfc3dSmrg 		  _M_insert_node(__res.first, __res.second,
16061debfc3dSmrg 				 static_cast<_Link_type>(__ptr));
16071debfc3dSmrg 		}
16081debfc3dSmrg 	    }
16091debfc3dSmrg 	}
16101debfc3dSmrg #endif // C++17
16111debfc3dSmrg 
1612c0a68be4Smrg       friend bool
1613c0a68be4Smrg       operator==(const _Rb_tree& __x, const _Rb_tree& __y)
16141debfc3dSmrg       {
16151debfc3dSmrg 	return __x.size() == __y.size()
16161debfc3dSmrg 	  && std::equal(__x.begin(), __x.end(), __y.begin());
16171debfc3dSmrg       }
16181debfc3dSmrg 
1619*8feb0f0bSmrg #if __cpp_lib_three_way_comparison
1620*8feb0f0bSmrg       friend auto
1621*8feb0f0bSmrg       operator<=>(const _Rb_tree& __x, const _Rb_tree& __y)
1622*8feb0f0bSmrg       {
1623*8feb0f0bSmrg 	if constexpr (requires { typename __detail::__synth3way_t<_Val>; })
1624*8feb0f0bSmrg 	  return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
1625*8feb0f0bSmrg 							__y.begin(), __y.end(),
1626*8feb0f0bSmrg 							__detail::__synth3way);
1627*8feb0f0bSmrg       }
1628*8feb0f0bSmrg #else
1629c0a68be4Smrg       friend bool
1630c0a68be4Smrg       operator<(const _Rb_tree& __x, const _Rb_tree& __y)
16311debfc3dSmrg       {
16321debfc3dSmrg 	return std::lexicographical_compare(__x.begin(), __x.end(),
16331debfc3dSmrg 					    __y.begin(), __y.end());
16341debfc3dSmrg       }
16351debfc3dSmrg 
1636c0a68be4Smrg       friend bool _GLIBCXX_DEPRECATED
1637c0a68be4Smrg       operator!=(const _Rb_tree& __x, const _Rb_tree& __y)
16381debfc3dSmrg       { return !(__x == __y); }
16391debfc3dSmrg 
1640c0a68be4Smrg       friend bool _GLIBCXX_DEPRECATED
1641c0a68be4Smrg       operator>(const _Rb_tree& __x, const _Rb_tree& __y)
16421debfc3dSmrg       { return __y < __x; }
16431debfc3dSmrg 
1644c0a68be4Smrg       friend bool _GLIBCXX_DEPRECATED
1645c0a68be4Smrg       operator<=(const _Rb_tree& __x, const _Rb_tree& __y)
16461debfc3dSmrg       { return !(__y < __x); }
16471debfc3dSmrg 
1648c0a68be4Smrg       friend bool _GLIBCXX_DEPRECATED
1649c0a68be4Smrg       operator>=(const _Rb_tree& __x, const _Rb_tree& __y)
16501debfc3dSmrg       { return !(__x < __y); }
1651*8feb0f0bSmrg #endif
1652c0a68be4Smrg     };
16531debfc3dSmrg 
16541debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
16551debfc3dSmrg 	   typename _Compare, typename _Alloc>
16561debfc3dSmrg     inline void
16571debfc3dSmrg     swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
16581debfc3dSmrg 	 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
16591debfc3dSmrg     { __x.swap(__y); }
16601debfc3dSmrg 
16611debfc3dSmrg #if __cplusplus >= 201103L
16621debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
16631debfc3dSmrg 	   typename _Compare, typename _Alloc>
16641debfc3dSmrg     void
16651debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1666c0a68be4Smrg     _M_move_data(_Rb_tree& __x, false_type)
16671debfc3dSmrg     {
16681debfc3dSmrg       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
1669c0a68be4Smrg 	_M_move_data(__x, true_type());
16701debfc3dSmrg       else
16711debfc3dSmrg 	{
1672*8feb0f0bSmrg 	  constexpr bool __move = !__move_if_noexcept_cond<value_type>::value;
16731debfc3dSmrg 	  _Alloc_node __an(*this);
16741debfc3dSmrg 	  auto __lbd =
16751debfc3dSmrg 	    [&__an](const value_type& __cval)
16761debfc3dSmrg 	    {
16771debfc3dSmrg 	      auto& __val = const_cast<value_type&>(__cval);
16781debfc3dSmrg 	      return __an(std::move_if_noexcept(__val));
16791debfc3dSmrg 	    };
16801debfc3dSmrg 	  _M_root() = _M_copy(__x, __lbd);
1681*8feb0f0bSmrg 	  if _GLIBCXX17_CONSTEXPR (__move)
1682*8feb0f0bSmrg 	    __x.clear();
16831debfc3dSmrg 	}
16841debfc3dSmrg     }
16851debfc3dSmrg 
16861debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
16871debfc3dSmrg 	   typename _Compare, typename _Alloc>
16881debfc3dSmrg     inline void
16891debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
16901debfc3dSmrg     _M_move_assign(_Rb_tree& __x, true_type)
16911debfc3dSmrg     {
16921debfc3dSmrg       clear();
16931debfc3dSmrg       if (__x._M_root() != nullptr)
1694c0a68be4Smrg 	_M_move_data(__x, true_type());
16951debfc3dSmrg       std::__alloc_on_move(_M_get_Node_allocator(),
16961debfc3dSmrg 			   __x._M_get_Node_allocator());
16971debfc3dSmrg     }
16981debfc3dSmrg 
16991debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
17001debfc3dSmrg 	   typename _Compare, typename _Alloc>
17011debfc3dSmrg     void
17021debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
17031debfc3dSmrg     _M_move_assign(_Rb_tree& __x, false_type)
17041debfc3dSmrg     {
17051debfc3dSmrg       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
17061debfc3dSmrg 	return _M_move_assign(__x, true_type{});
17071debfc3dSmrg 
17081debfc3dSmrg       // Try to move each node reusing existing nodes and copying __x nodes
17091debfc3dSmrg       // structure.
17101debfc3dSmrg       _Reuse_or_alloc_node __roan(*this);
17111debfc3dSmrg       _M_impl._M_reset();
17121debfc3dSmrg       if (__x._M_root() != nullptr)
17131debfc3dSmrg 	{
17141debfc3dSmrg 	  auto __lbd =
17151debfc3dSmrg 	    [&__roan](const value_type& __cval)
17161debfc3dSmrg 	    {
17171debfc3dSmrg 	      auto& __val = const_cast<value_type&>(__cval);
1718*8feb0f0bSmrg 	      return __roan(std::move(__val));
17191debfc3dSmrg 	    };
17201debfc3dSmrg 	  _M_root() = _M_copy(__x, __lbd);
17211debfc3dSmrg 	  __x.clear();
17221debfc3dSmrg 	}
17231debfc3dSmrg     }
17241debfc3dSmrg 
17251debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
17261debfc3dSmrg 	   typename _Compare, typename _Alloc>
17271debfc3dSmrg     inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
17281debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
17291debfc3dSmrg     operator=(_Rb_tree&& __x)
17301debfc3dSmrg     noexcept(_Alloc_traits::_S_nothrow_move()
17311debfc3dSmrg 	     && is_nothrow_move_assignable<_Compare>::value)
17321debfc3dSmrg     {
17331debfc3dSmrg       _M_impl._M_key_compare = std::move(__x._M_impl._M_key_compare);
17341debfc3dSmrg       _M_move_assign(__x, __bool_constant<_Alloc_traits::_S_nothrow_move()>());
17351debfc3dSmrg       return *this;
17361debfc3dSmrg     }
17371debfc3dSmrg 
17381debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
17391debfc3dSmrg 	   typename _Compare, typename _Alloc>
17401debfc3dSmrg     template<typename _Iterator>
17411debfc3dSmrg       void
17421debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
17431debfc3dSmrg       _M_assign_unique(_Iterator __first, _Iterator __last)
17441debfc3dSmrg       {
17451debfc3dSmrg 	_Reuse_or_alloc_node __roan(*this);
17461debfc3dSmrg 	_M_impl._M_reset();
17471debfc3dSmrg 	for (; __first != __last; ++__first)
17481debfc3dSmrg 	  _M_insert_unique_(end(), *__first, __roan);
17491debfc3dSmrg       }
17501debfc3dSmrg 
17511debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
17521debfc3dSmrg 	   typename _Compare, typename _Alloc>
17531debfc3dSmrg     template<typename _Iterator>
17541debfc3dSmrg       void
17551debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
17561debfc3dSmrg       _M_assign_equal(_Iterator __first, _Iterator __last)
17571debfc3dSmrg       {
17581debfc3dSmrg 	_Reuse_or_alloc_node __roan(*this);
17591debfc3dSmrg 	_M_impl._M_reset();
17601debfc3dSmrg 	for (; __first != __last; ++__first)
17611debfc3dSmrg 	  _M_insert_equal_(end(), *__first, __roan);
17621debfc3dSmrg       }
17631debfc3dSmrg #endif
17641debfc3dSmrg 
17651debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
17661debfc3dSmrg 	   typename _Compare, typename _Alloc>
17671debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
17681debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
17691debfc3dSmrg     operator=(const _Rb_tree& __x)
17701debfc3dSmrg     {
17711debfc3dSmrg       if (this != &__x)
17721debfc3dSmrg 	{
17731debfc3dSmrg 	  // Note that _Key may be a constant type.
17741debfc3dSmrg #if __cplusplus >= 201103L
17751debfc3dSmrg 	  if (_Alloc_traits::_S_propagate_on_copy_assign())
17761debfc3dSmrg 	    {
17771debfc3dSmrg 	      auto& __this_alloc = this->_M_get_Node_allocator();
17781debfc3dSmrg 	      auto& __that_alloc = __x._M_get_Node_allocator();
17791debfc3dSmrg 	      if (!_Alloc_traits::_S_always_equal()
17801debfc3dSmrg 		  && __this_alloc != __that_alloc)
17811debfc3dSmrg 		{
17821debfc3dSmrg 		  // Replacement allocator cannot free existing storage, we need
17831debfc3dSmrg 		  // to erase nodes first.
17841debfc3dSmrg 		  clear();
17851debfc3dSmrg 		  std::__alloc_on_copy(__this_alloc, __that_alloc);
17861debfc3dSmrg 		}
17871debfc3dSmrg 	    }
17881debfc3dSmrg #endif
17891debfc3dSmrg 
17901debfc3dSmrg 	  _Reuse_or_alloc_node __roan(*this);
17911debfc3dSmrg 	  _M_impl._M_reset();
17921debfc3dSmrg 	  _M_impl._M_key_compare = __x._M_impl._M_key_compare;
17931debfc3dSmrg 	  if (__x._M_root() != 0)
17941debfc3dSmrg 	    _M_root() = _M_copy(__x, __roan);
17951debfc3dSmrg 	}
17961debfc3dSmrg 
17971debfc3dSmrg       return *this;
17981debfc3dSmrg     }
17991debfc3dSmrg 
18001debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
18011debfc3dSmrg 	   typename _Compare, typename _Alloc>
18021debfc3dSmrg #if __cplusplus >= 201103L
18031debfc3dSmrg     template<typename _Arg, typename _NodeGen>
18041debfc3dSmrg #else
18051debfc3dSmrg     template<typename _NodeGen>
18061debfc3dSmrg #endif
18071debfc3dSmrg       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
18081debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
18091debfc3dSmrg       _M_insert_(_Base_ptr __x, _Base_ptr __p,
18101debfc3dSmrg #if __cplusplus >= 201103L
18111debfc3dSmrg 		 _Arg&& __v,
18121debfc3dSmrg #else
18131debfc3dSmrg 		 const _Val& __v,
18141debfc3dSmrg #endif
18151debfc3dSmrg 		 _NodeGen& __node_gen)
18161debfc3dSmrg       {
18171debfc3dSmrg 	bool __insert_left = (__x != 0 || __p == _M_end()
18181debfc3dSmrg 			      || _M_impl._M_key_compare(_KeyOfValue()(__v),
18191debfc3dSmrg 							_S_key(__p)));
18201debfc3dSmrg 
18211debfc3dSmrg 	_Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v));
18221debfc3dSmrg 
18231debfc3dSmrg 	_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
18241debfc3dSmrg 				      this->_M_impl._M_header);
18251debfc3dSmrg 	++_M_impl._M_node_count;
18261debfc3dSmrg 	return iterator(__z);
18271debfc3dSmrg       }
18281debfc3dSmrg 
18291debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
18301debfc3dSmrg 	   typename _Compare, typename _Alloc>
18311debfc3dSmrg #if __cplusplus >= 201103L
18321debfc3dSmrg     template<typename _Arg>
18331debfc3dSmrg #endif
18341debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
18351debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
18361debfc3dSmrg #if __cplusplus >= 201103L
18371debfc3dSmrg     _M_insert_lower(_Base_ptr __p, _Arg&& __v)
18381debfc3dSmrg #else
18391debfc3dSmrg     _M_insert_lower(_Base_ptr __p, const _Val& __v)
18401debfc3dSmrg #endif
18411debfc3dSmrg     {
18421debfc3dSmrg       bool __insert_left = (__p == _M_end()
18431debfc3dSmrg 			    || !_M_impl._M_key_compare(_S_key(__p),
18441debfc3dSmrg 						       _KeyOfValue()(__v)));
18451debfc3dSmrg 
18461debfc3dSmrg       _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
18471debfc3dSmrg 
18481debfc3dSmrg       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
18491debfc3dSmrg 				    this->_M_impl._M_header);
18501debfc3dSmrg       ++_M_impl._M_node_count;
18511debfc3dSmrg       return iterator(__z);
18521debfc3dSmrg     }
18531debfc3dSmrg 
18541debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
18551debfc3dSmrg 	   typename _Compare, typename _Alloc>
18561debfc3dSmrg #if __cplusplus >= 201103L
18571debfc3dSmrg     template<typename _Arg>
18581debfc3dSmrg #endif
18591debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
18601debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
18611debfc3dSmrg #if __cplusplus >= 201103L
18621debfc3dSmrg     _M_insert_equal_lower(_Arg&& __v)
18631debfc3dSmrg #else
18641debfc3dSmrg     _M_insert_equal_lower(const _Val& __v)
18651debfc3dSmrg #endif
18661debfc3dSmrg     {
18671debfc3dSmrg       _Link_type __x = _M_begin();
18681debfc3dSmrg       _Base_ptr __y = _M_end();
18691debfc3dSmrg       while (__x != 0)
18701debfc3dSmrg 	{
18711debfc3dSmrg 	  __y = __x;
18721debfc3dSmrg 	  __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
18731debfc3dSmrg 		_S_left(__x) : _S_right(__x);
18741debfc3dSmrg 	}
18751debfc3dSmrg       return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v));
18761debfc3dSmrg     }
18771debfc3dSmrg 
18781debfc3dSmrg   template<typename _Key, typename _Val, typename _KoV,
18791debfc3dSmrg 	   typename _Compare, typename _Alloc>
18801debfc3dSmrg     template<typename _NodeGen>
18811debfc3dSmrg       typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
18821debfc3dSmrg       _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
18831debfc3dSmrg       _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
18841debfc3dSmrg       {
18851debfc3dSmrg 	// Structural copy. __x and __p must be non-null.
18861debfc3dSmrg 	_Link_type __top = _M_clone_node(__x, __node_gen);
18871debfc3dSmrg 	__top->_M_parent = __p;
18881debfc3dSmrg 
18891debfc3dSmrg 	__try
18901debfc3dSmrg 	  {
18911debfc3dSmrg 	    if (__x->_M_right)
18921debfc3dSmrg 	      __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen);
18931debfc3dSmrg 	    __p = __top;
18941debfc3dSmrg 	    __x = _S_left(__x);
18951debfc3dSmrg 
18961debfc3dSmrg 	    while (__x != 0)
18971debfc3dSmrg 	      {
18981debfc3dSmrg 		_Link_type __y = _M_clone_node(__x, __node_gen);
18991debfc3dSmrg 		__p->_M_left = __y;
19001debfc3dSmrg 		__y->_M_parent = __p;
19011debfc3dSmrg 		if (__x->_M_right)
19021debfc3dSmrg 		  __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen);
19031debfc3dSmrg 		__p = __y;
19041debfc3dSmrg 		__x = _S_left(__x);
19051debfc3dSmrg 	      }
19061debfc3dSmrg 	  }
19071debfc3dSmrg 	__catch(...)
19081debfc3dSmrg 	  {
19091debfc3dSmrg 	    _M_erase(__top);
19101debfc3dSmrg 	    __throw_exception_again;
19111debfc3dSmrg 	  }
19121debfc3dSmrg 	return __top;
19131debfc3dSmrg       }
19141debfc3dSmrg 
19151debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
19161debfc3dSmrg 	   typename _Compare, typename _Alloc>
19171debfc3dSmrg     void
19181debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
19191debfc3dSmrg     _M_erase(_Link_type __x)
19201debfc3dSmrg     {
19211debfc3dSmrg       // Erase without rebalancing.
19221debfc3dSmrg       while (__x != 0)
19231debfc3dSmrg 	{
19241debfc3dSmrg 	  _M_erase(_S_right(__x));
19251debfc3dSmrg 	  _Link_type __y = _S_left(__x);
19261debfc3dSmrg 	  _M_drop_node(__x);
19271debfc3dSmrg 	  __x = __y;
19281debfc3dSmrg 	}
19291debfc3dSmrg     }
19301debfc3dSmrg 
19311debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
19321debfc3dSmrg 	   typename _Compare, typename _Alloc>
19331debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue,
19341debfc3dSmrg 		      _Compare, _Alloc>::iterator
19351debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
19361debfc3dSmrg     _M_lower_bound(_Link_type __x, _Base_ptr __y,
19371debfc3dSmrg 		   const _Key& __k)
19381debfc3dSmrg     {
19391debfc3dSmrg       while (__x != 0)
19401debfc3dSmrg 	if (!_M_impl._M_key_compare(_S_key(__x), __k))
19411debfc3dSmrg 	  __y = __x, __x = _S_left(__x);
19421debfc3dSmrg 	else
19431debfc3dSmrg 	  __x = _S_right(__x);
19441debfc3dSmrg       return iterator(__y);
19451debfc3dSmrg     }
19461debfc3dSmrg 
19471debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
19481debfc3dSmrg 	   typename _Compare, typename _Alloc>
19491debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue,
19501debfc3dSmrg 		      _Compare, _Alloc>::const_iterator
19511debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
19521debfc3dSmrg     _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
19531debfc3dSmrg 		   const _Key& __k) const
19541debfc3dSmrg     {
19551debfc3dSmrg       while (__x != 0)
19561debfc3dSmrg 	if (!_M_impl._M_key_compare(_S_key(__x), __k))
19571debfc3dSmrg 	  __y = __x, __x = _S_left(__x);
19581debfc3dSmrg 	else
19591debfc3dSmrg 	  __x = _S_right(__x);
19601debfc3dSmrg       return const_iterator(__y);
19611debfc3dSmrg     }
19621debfc3dSmrg 
19631debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
19641debfc3dSmrg 	   typename _Compare, typename _Alloc>
19651debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue,
19661debfc3dSmrg 		      _Compare, _Alloc>::iterator
19671debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
19681debfc3dSmrg     _M_upper_bound(_Link_type __x, _Base_ptr __y,
19691debfc3dSmrg 		   const _Key& __k)
19701debfc3dSmrg     {
19711debfc3dSmrg       while (__x != 0)
19721debfc3dSmrg 	if (_M_impl._M_key_compare(__k, _S_key(__x)))
19731debfc3dSmrg 	  __y = __x, __x = _S_left(__x);
19741debfc3dSmrg 	else
19751debfc3dSmrg 	  __x = _S_right(__x);
19761debfc3dSmrg       return iterator(__y);
19771debfc3dSmrg     }
19781debfc3dSmrg 
19791debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
19801debfc3dSmrg 	   typename _Compare, typename _Alloc>
19811debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue,
19821debfc3dSmrg 		      _Compare, _Alloc>::const_iterator
19831debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
19841debfc3dSmrg     _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
19851debfc3dSmrg 		   const _Key& __k) const
19861debfc3dSmrg     {
19871debfc3dSmrg       while (__x != 0)
19881debfc3dSmrg 	if (_M_impl._M_key_compare(__k, _S_key(__x)))
19891debfc3dSmrg 	  __y = __x, __x = _S_left(__x);
19901debfc3dSmrg 	else
19911debfc3dSmrg 	  __x = _S_right(__x);
19921debfc3dSmrg       return const_iterator(__y);
19931debfc3dSmrg     }
19941debfc3dSmrg 
19951debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
19961debfc3dSmrg 	   typename _Compare, typename _Alloc>
19971debfc3dSmrg     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
19981debfc3dSmrg 			   _Compare, _Alloc>::iterator,
19991debfc3dSmrg 	 typename _Rb_tree<_Key, _Val, _KeyOfValue,
20001debfc3dSmrg 			   _Compare, _Alloc>::iterator>
20011debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
20021debfc3dSmrg     equal_range(const _Key& __k)
20031debfc3dSmrg     {
20041debfc3dSmrg       _Link_type __x = _M_begin();
20051debfc3dSmrg       _Base_ptr __y = _M_end();
20061debfc3dSmrg       while (__x != 0)
20071debfc3dSmrg 	{
20081debfc3dSmrg 	  if (_M_impl._M_key_compare(_S_key(__x), __k))
20091debfc3dSmrg 	    __x = _S_right(__x);
20101debfc3dSmrg 	  else if (_M_impl._M_key_compare(__k, _S_key(__x)))
20111debfc3dSmrg 	    __y = __x, __x = _S_left(__x);
20121debfc3dSmrg 	  else
20131debfc3dSmrg 	    {
20141debfc3dSmrg 	      _Link_type __xu(__x);
20151debfc3dSmrg 	      _Base_ptr __yu(__y);
20161debfc3dSmrg 	      __y = __x, __x = _S_left(__x);
20171debfc3dSmrg 	      __xu = _S_right(__xu);
20181debfc3dSmrg 	      return pair<iterator,
20191debfc3dSmrg 			  iterator>(_M_lower_bound(__x, __y, __k),
20201debfc3dSmrg 				    _M_upper_bound(__xu, __yu, __k));
20211debfc3dSmrg 	    }
20221debfc3dSmrg 	}
20231debfc3dSmrg       return pair<iterator, iterator>(iterator(__y),
20241debfc3dSmrg 				      iterator(__y));
20251debfc3dSmrg     }
20261debfc3dSmrg 
20271debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
20281debfc3dSmrg 	   typename _Compare, typename _Alloc>
20291debfc3dSmrg     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
20301debfc3dSmrg 			   _Compare, _Alloc>::const_iterator,
20311debfc3dSmrg 	 typename _Rb_tree<_Key, _Val, _KeyOfValue,
20321debfc3dSmrg 			   _Compare, _Alloc>::const_iterator>
20331debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
20341debfc3dSmrg     equal_range(const _Key& __k) const
20351debfc3dSmrg     {
20361debfc3dSmrg       _Const_Link_type __x = _M_begin();
20371debfc3dSmrg       _Const_Base_ptr __y = _M_end();
20381debfc3dSmrg       while (__x != 0)
20391debfc3dSmrg 	{
20401debfc3dSmrg 	  if (_M_impl._M_key_compare(_S_key(__x), __k))
20411debfc3dSmrg 	    __x = _S_right(__x);
20421debfc3dSmrg 	  else if (_M_impl._M_key_compare(__k, _S_key(__x)))
20431debfc3dSmrg 	    __y = __x, __x = _S_left(__x);
20441debfc3dSmrg 	  else
20451debfc3dSmrg 	    {
20461debfc3dSmrg 	      _Const_Link_type __xu(__x);
20471debfc3dSmrg 	      _Const_Base_ptr __yu(__y);
20481debfc3dSmrg 	      __y = __x, __x = _S_left(__x);
20491debfc3dSmrg 	      __xu = _S_right(__xu);
20501debfc3dSmrg 	      return pair<const_iterator,
20511debfc3dSmrg 			  const_iterator>(_M_lower_bound(__x, __y, __k),
20521debfc3dSmrg 					  _M_upper_bound(__xu, __yu, __k));
20531debfc3dSmrg 	    }
20541debfc3dSmrg 	}
20551debfc3dSmrg       return pair<const_iterator, const_iterator>(const_iterator(__y),
20561debfc3dSmrg 						  const_iterator(__y));
20571debfc3dSmrg     }
20581debfc3dSmrg 
20591debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
20601debfc3dSmrg 	   typename _Compare, typename _Alloc>
20611debfc3dSmrg     void
20621debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
20631debfc3dSmrg     swap(_Rb_tree& __t)
20641debfc3dSmrg     _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value)
20651debfc3dSmrg     {
20661debfc3dSmrg       if (_M_root() == 0)
20671debfc3dSmrg 	{
20681debfc3dSmrg 	  if (__t._M_root() != 0)
20691debfc3dSmrg 	    _M_impl._M_move_data(__t._M_impl);
20701debfc3dSmrg 	}
20711debfc3dSmrg       else if (__t._M_root() == 0)
20721debfc3dSmrg 	__t._M_impl._M_move_data(_M_impl);
20731debfc3dSmrg       else
20741debfc3dSmrg 	{
20751debfc3dSmrg 	  std::swap(_M_root(),__t._M_root());
20761debfc3dSmrg 	  std::swap(_M_leftmost(),__t._M_leftmost());
20771debfc3dSmrg 	  std::swap(_M_rightmost(),__t._M_rightmost());
20781debfc3dSmrg 
20791debfc3dSmrg 	  _M_root()->_M_parent = _M_end();
20801debfc3dSmrg 	  __t._M_root()->_M_parent = __t._M_end();
20811debfc3dSmrg 	  std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
20821debfc3dSmrg 	}
20831debfc3dSmrg       // No need to swap header's color as it does not change.
20841debfc3dSmrg       std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
20851debfc3dSmrg 
20861debfc3dSmrg       _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
20871debfc3dSmrg 				__t._M_get_Node_allocator());
20881debfc3dSmrg     }
20891debfc3dSmrg 
20901debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
20911debfc3dSmrg 	   typename _Compare, typename _Alloc>
20921debfc3dSmrg     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
20931debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr,
20941debfc3dSmrg 	 typename _Rb_tree<_Key, _Val, _KeyOfValue,
20951debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr>
20961debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
20971debfc3dSmrg     _M_get_insert_unique_pos(const key_type& __k)
20981debfc3dSmrg     {
20991debfc3dSmrg       typedef pair<_Base_ptr, _Base_ptr> _Res;
21001debfc3dSmrg       _Link_type __x = _M_begin();
21011debfc3dSmrg       _Base_ptr __y = _M_end();
21021debfc3dSmrg       bool __comp = true;
21031debfc3dSmrg       while (__x != 0)
21041debfc3dSmrg 	{
21051debfc3dSmrg 	  __y = __x;
21061debfc3dSmrg 	  __comp = _M_impl._M_key_compare(__k, _S_key(__x));
21071debfc3dSmrg 	  __x = __comp ? _S_left(__x) : _S_right(__x);
21081debfc3dSmrg 	}
21091debfc3dSmrg       iterator __j = iterator(__y);
21101debfc3dSmrg       if (__comp)
21111debfc3dSmrg 	{
21121debfc3dSmrg 	  if (__j == begin())
21131debfc3dSmrg 	    return _Res(__x, __y);
21141debfc3dSmrg 	  else
21151debfc3dSmrg 	    --__j;
21161debfc3dSmrg 	}
21171debfc3dSmrg       if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
21181debfc3dSmrg 	return _Res(__x, __y);
21191debfc3dSmrg       return _Res(__j._M_node, 0);
21201debfc3dSmrg     }
21211debfc3dSmrg 
21221debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
21231debfc3dSmrg 	   typename _Compare, typename _Alloc>
21241debfc3dSmrg     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
21251debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr,
21261debfc3dSmrg 	 typename _Rb_tree<_Key, _Val, _KeyOfValue,
21271debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr>
21281debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
21291debfc3dSmrg     _M_get_insert_equal_pos(const key_type& __k)
21301debfc3dSmrg     {
21311debfc3dSmrg       typedef pair<_Base_ptr, _Base_ptr> _Res;
21321debfc3dSmrg       _Link_type __x = _M_begin();
21331debfc3dSmrg       _Base_ptr __y = _M_end();
21341debfc3dSmrg       while (__x != 0)
21351debfc3dSmrg 	{
21361debfc3dSmrg 	  __y = __x;
21371debfc3dSmrg 	  __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
21381debfc3dSmrg 		_S_left(__x) : _S_right(__x);
21391debfc3dSmrg 	}
21401debfc3dSmrg       return _Res(__x, __y);
21411debfc3dSmrg     }
21421debfc3dSmrg 
21431debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
21441debfc3dSmrg 	   typename _Compare, typename _Alloc>
21451debfc3dSmrg #if __cplusplus >= 201103L
21461debfc3dSmrg     template<typename _Arg>
21471debfc3dSmrg #endif
21481debfc3dSmrg     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
21491debfc3dSmrg 			   _Compare, _Alloc>::iterator, bool>
21501debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
21511debfc3dSmrg #if __cplusplus >= 201103L
21521debfc3dSmrg     _M_insert_unique(_Arg&& __v)
21531debfc3dSmrg #else
21541debfc3dSmrg     _M_insert_unique(const _Val& __v)
21551debfc3dSmrg #endif
21561debfc3dSmrg     {
21571debfc3dSmrg       typedef pair<iterator, bool> _Res;
21581debfc3dSmrg       pair<_Base_ptr, _Base_ptr> __res
21591debfc3dSmrg 	= _M_get_insert_unique_pos(_KeyOfValue()(__v));
21601debfc3dSmrg 
21611debfc3dSmrg       if (__res.second)
21621debfc3dSmrg 	{
21631debfc3dSmrg 	  _Alloc_node __an(*this);
21641debfc3dSmrg 	  return _Res(_M_insert_(__res.first, __res.second,
21651debfc3dSmrg 				 _GLIBCXX_FORWARD(_Arg, __v), __an),
21661debfc3dSmrg 		      true);
21671debfc3dSmrg 	}
21681debfc3dSmrg 
21691debfc3dSmrg       return _Res(iterator(__res.first), false);
21701debfc3dSmrg     }
21711debfc3dSmrg 
21721debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
21731debfc3dSmrg 	   typename _Compare, typename _Alloc>
21741debfc3dSmrg #if __cplusplus >= 201103L
21751debfc3dSmrg     template<typename _Arg>
21761debfc3dSmrg #endif
21771debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
21781debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
21791debfc3dSmrg #if __cplusplus >= 201103L
21801debfc3dSmrg     _M_insert_equal(_Arg&& __v)
21811debfc3dSmrg #else
21821debfc3dSmrg     _M_insert_equal(const _Val& __v)
21831debfc3dSmrg #endif
21841debfc3dSmrg     {
21851debfc3dSmrg       pair<_Base_ptr, _Base_ptr> __res
21861debfc3dSmrg 	= _M_get_insert_equal_pos(_KeyOfValue()(__v));
21871debfc3dSmrg       _Alloc_node __an(*this);
21881debfc3dSmrg       return _M_insert_(__res.first, __res.second,
21891debfc3dSmrg 			_GLIBCXX_FORWARD(_Arg, __v), __an);
21901debfc3dSmrg     }
21911debfc3dSmrg 
21921debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
21931debfc3dSmrg 	   typename _Compare, typename _Alloc>
21941debfc3dSmrg     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
21951debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr,
21961debfc3dSmrg 	 typename _Rb_tree<_Key, _Val, _KeyOfValue,
21971debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr>
21981debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
21991debfc3dSmrg     _M_get_insert_hint_unique_pos(const_iterator __position,
22001debfc3dSmrg 				  const key_type& __k)
22011debfc3dSmrg     {
22021debfc3dSmrg       iterator __pos = __position._M_const_cast();
22031debfc3dSmrg       typedef pair<_Base_ptr, _Base_ptr> _Res;
22041debfc3dSmrg 
22051debfc3dSmrg       // end()
22061debfc3dSmrg       if (__pos._M_node == _M_end())
22071debfc3dSmrg 	{
22081debfc3dSmrg 	  if (size() > 0
22091debfc3dSmrg 	      && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k))
22101debfc3dSmrg 	    return _Res(0, _M_rightmost());
22111debfc3dSmrg 	  else
22121debfc3dSmrg 	    return _M_get_insert_unique_pos(__k);
22131debfc3dSmrg 	}
22141debfc3dSmrg       else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node)))
22151debfc3dSmrg 	{
22161debfc3dSmrg 	  // First, try before...
22171debfc3dSmrg 	  iterator __before = __pos;
22181debfc3dSmrg 	  if (__pos._M_node == _M_leftmost()) // begin()
22191debfc3dSmrg 	    return _Res(_M_leftmost(), _M_leftmost());
22201debfc3dSmrg 	  else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k))
22211debfc3dSmrg 	    {
22221debfc3dSmrg 	      if (_S_right(__before._M_node) == 0)
22231debfc3dSmrg 		return _Res(0, __before._M_node);
22241debfc3dSmrg 	      else
22251debfc3dSmrg 		return _Res(__pos._M_node, __pos._M_node);
22261debfc3dSmrg 	    }
22271debfc3dSmrg 	  else
22281debfc3dSmrg 	    return _M_get_insert_unique_pos(__k);
22291debfc3dSmrg 	}
22301debfc3dSmrg       else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
22311debfc3dSmrg 	{
22321debfc3dSmrg 	  // ... then try after.
22331debfc3dSmrg 	  iterator __after = __pos;
22341debfc3dSmrg 	  if (__pos._M_node == _M_rightmost())
22351debfc3dSmrg 	    return _Res(0, _M_rightmost());
22361debfc3dSmrg 	  else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node)))
22371debfc3dSmrg 	    {
22381debfc3dSmrg 	      if (_S_right(__pos._M_node) == 0)
22391debfc3dSmrg 		return _Res(0, __pos._M_node);
22401debfc3dSmrg 	      else
22411debfc3dSmrg 		return _Res(__after._M_node, __after._M_node);
22421debfc3dSmrg 	    }
22431debfc3dSmrg 	  else
22441debfc3dSmrg 	    return _M_get_insert_unique_pos(__k);
22451debfc3dSmrg 	}
22461debfc3dSmrg       else
22471debfc3dSmrg 	// Equivalent keys.
22481debfc3dSmrg 	return _Res(__pos._M_node, 0);
22491debfc3dSmrg     }
22501debfc3dSmrg 
22511debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
22521debfc3dSmrg 	   typename _Compare, typename _Alloc>
22531debfc3dSmrg #if __cplusplus >= 201103L
22541debfc3dSmrg     template<typename _Arg, typename _NodeGen>
22551debfc3dSmrg #else
22561debfc3dSmrg     template<typename _NodeGen>
22571debfc3dSmrg #endif
22581debfc3dSmrg       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
22591debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
22601debfc3dSmrg       _M_insert_unique_(const_iterator __position,
22611debfc3dSmrg #if __cplusplus >= 201103L
22621debfc3dSmrg 			_Arg&& __v,
22631debfc3dSmrg #else
22641debfc3dSmrg 			const _Val& __v,
22651debfc3dSmrg #endif
22661debfc3dSmrg 			_NodeGen& __node_gen)
22671debfc3dSmrg     {
22681debfc3dSmrg       pair<_Base_ptr, _Base_ptr> __res
22691debfc3dSmrg 	= _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
22701debfc3dSmrg 
22711debfc3dSmrg       if (__res.second)
22721debfc3dSmrg 	return _M_insert_(__res.first, __res.second,
22731debfc3dSmrg 			  _GLIBCXX_FORWARD(_Arg, __v),
22741debfc3dSmrg 			  __node_gen);
22751debfc3dSmrg       return iterator(__res.first);
22761debfc3dSmrg     }
22771debfc3dSmrg 
22781debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
22791debfc3dSmrg 	   typename _Compare, typename _Alloc>
22801debfc3dSmrg     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
22811debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr,
22821debfc3dSmrg 	 typename _Rb_tree<_Key, _Val, _KeyOfValue,
22831debfc3dSmrg 			   _Compare, _Alloc>::_Base_ptr>
22841debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
22851debfc3dSmrg     _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k)
22861debfc3dSmrg     {
22871debfc3dSmrg       iterator __pos = __position._M_const_cast();
22881debfc3dSmrg       typedef pair<_Base_ptr, _Base_ptr> _Res;
22891debfc3dSmrg 
22901debfc3dSmrg       // end()
22911debfc3dSmrg       if (__pos._M_node == _M_end())
22921debfc3dSmrg 	{
22931debfc3dSmrg 	  if (size() > 0
22941debfc3dSmrg 	      && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost())))
22951debfc3dSmrg 	    return _Res(0, _M_rightmost());
22961debfc3dSmrg 	  else
22971debfc3dSmrg 	    return _M_get_insert_equal_pos(__k);
22981debfc3dSmrg 	}
22991debfc3dSmrg       else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
23001debfc3dSmrg 	{
23011debfc3dSmrg 	  // First, try before...
23021debfc3dSmrg 	  iterator __before = __pos;
23031debfc3dSmrg 	  if (__pos._M_node == _M_leftmost()) // begin()
23041debfc3dSmrg 	    return _Res(_M_leftmost(), _M_leftmost());
23051debfc3dSmrg 	  else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node)))
23061debfc3dSmrg 	    {
23071debfc3dSmrg 	      if (_S_right(__before._M_node) == 0)
23081debfc3dSmrg 		return _Res(0, __before._M_node);
23091debfc3dSmrg 	      else
23101debfc3dSmrg 		return _Res(__pos._M_node, __pos._M_node);
23111debfc3dSmrg 	    }
23121debfc3dSmrg 	  else
23131debfc3dSmrg 	    return _M_get_insert_equal_pos(__k);
23141debfc3dSmrg 	}
23151debfc3dSmrg       else
23161debfc3dSmrg 	{
23171debfc3dSmrg 	  // ... then try after.
23181debfc3dSmrg 	  iterator __after = __pos;
23191debfc3dSmrg 	  if (__pos._M_node == _M_rightmost())
23201debfc3dSmrg 	    return _Res(0, _M_rightmost());
23211debfc3dSmrg 	  else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k))
23221debfc3dSmrg 	    {
23231debfc3dSmrg 	      if (_S_right(__pos._M_node) == 0)
23241debfc3dSmrg 		return _Res(0, __pos._M_node);
23251debfc3dSmrg 	      else
23261debfc3dSmrg 		return _Res(__after._M_node, __after._M_node);
23271debfc3dSmrg 	    }
23281debfc3dSmrg 	  else
23291debfc3dSmrg 	    return _Res(0, 0);
23301debfc3dSmrg 	}
23311debfc3dSmrg     }
23321debfc3dSmrg 
23331debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
23341debfc3dSmrg 	   typename _Compare, typename _Alloc>
23351debfc3dSmrg #if __cplusplus >= 201103L
23361debfc3dSmrg     template<typename _Arg, typename _NodeGen>
23371debfc3dSmrg #else
23381debfc3dSmrg     template<typename _NodeGen>
23391debfc3dSmrg #endif
23401debfc3dSmrg       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
23411debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
23421debfc3dSmrg       _M_insert_equal_(const_iterator __position,
23431debfc3dSmrg #if __cplusplus >= 201103L
23441debfc3dSmrg 		       _Arg&& __v,
23451debfc3dSmrg #else
23461debfc3dSmrg 		       const _Val& __v,
23471debfc3dSmrg #endif
23481debfc3dSmrg 		       _NodeGen& __node_gen)
23491debfc3dSmrg       {
23501debfc3dSmrg 	pair<_Base_ptr, _Base_ptr> __res
23511debfc3dSmrg 	  = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
23521debfc3dSmrg 
23531debfc3dSmrg 	if (__res.second)
23541debfc3dSmrg 	  return _M_insert_(__res.first, __res.second,
23551debfc3dSmrg 			    _GLIBCXX_FORWARD(_Arg, __v),
23561debfc3dSmrg 			    __node_gen);
23571debfc3dSmrg 
23581debfc3dSmrg 	return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
23591debfc3dSmrg       }
23601debfc3dSmrg 
23611debfc3dSmrg #if __cplusplus >= 201103L
23621debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
23631debfc3dSmrg 	   typename _Compare, typename _Alloc>
23641debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
23651debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
23661debfc3dSmrg     _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
23671debfc3dSmrg     {
23681debfc3dSmrg       bool __insert_left = (__x != 0 || __p == _M_end()
23691debfc3dSmrg 			    || _M_impl._M_key_compare(_S_key(__z),
23701debfc3dSmrg 						      _S_key(__p)));
23711debfc3dSmrg 
23721debfc3dSmrg       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
23731debfc3dSmrg 				    this->_M_impl._M_header);
23741debfc3dSmrg       ++_M_impl._M_node_count;
23751debfc3dSmrg       return iterator(__z);
23761debfc3dSmrg     }
23771debfc3dSmrg 
23781debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
23791debfc3dSmrg 	   typename _Compare, typename _Alloc>
23801debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
23811debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
23821debfc3dSmrg     _M_insert_lower_node(_Base_ptr __p, _Link_type __z)
23831debfc3dSmrg     {
23841debfc3dSmrg       bool __insert_left = (__p == _M_end()
23851debfc3dSmrg 			    || !_M_impl._M_key_compare(_S_key(__p),
23861debfc3dSmrg 						       _S_key(__z)));
23871debfc3dSmrg 
23881debfc3dSmrg       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
23891debfc3dSmrg 				    this->_M_impl._M_header);
23901debfc3dSmrg       ++_M_impl._M_node_count;
23911debfc3dSmrg       return iterator(__z);
23921debfc3dSmrg     }
23931debfc3dSmrg 
23941debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
23951debfc3dSmrg 	   typename _Compare, typename _Alloc>
23961debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
23971debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
23981debfc3dSmrg     _M_insert_equal_lower_node(_Link_type __z)
23991debfc3dSmrg     {
24001debfc3dSmrg       _Link_type __x = _M_begin();
24011debfc3dSmrg       _Base_ptr __y = _M_end();
24021debfc3dSmrg       while (__x != 0)
24031debfc3dSmrg 	{
24041debfc3dSmrg 	  __y = __x;
24051debfc3dSmrg 	  __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ?
24061debfc3dSmrg 		_S_left(__x) : _S_right(__x);
24071debfc3dSmrg 	}
24081debfc3dSmrg       return _M_insert_lower_node(__y, __z);
24091debfc3dSmrg     }
24101debfc3dSmrg 
24111debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
24121debfc3dSmrg 	   typename _Compare, typename _Alloc>
24131debfc3dSmrg     template<typename... _Args>
24141debfc3dSmrg       pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
24151debfc3dSmrg 			     _Compare, _Alloc>::iterator, bool>
24161debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
24171debfc3dSmrg       _M_emplace_unique(_Args&&... __args)
24181debfc3dSmrg       {
24191debfc3dSmrg 	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
24201debfc3dSmrg 
24211debfc3dSmrg 	__try
24221debfc3dSmrg 	  {
24231debfc3dSmrg 	    typedef pair<iterator, bool> _Res;
24241debfc3dSmrg 	    auto __res = _M_get_insert_unique_pos(_S_key(__z));
24251debfc3dSmrg 	    if (__res.second)
24261debfc3dSmrg 	      return _Res(_M_insert_node(__res.first, __res.second, __z), true);
24271debfc3dSmrg 
24281debfc3dSmrg 	    _M_drop_node(__z);
24291debfc3dSmrg 	    return _Res(iterator(__res.first), false);
24301debfc3dSmrg 	  }
24311debfc3dSmrg 	__catch(...)
24321debfc3dSmrg 	  {
24331debfc3dSmrg 	    _M_drop_node(__z);
24341debfc3dSmrg 	    __throw_exception_again;
24351debfc3dSmrg 	  }
24361debfc3dSmrg       }
24371debfc3dSmrg 
24381debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
24391debfc3dSmrg 	   typename _Compare, typename _Alloc>
24401debfc3dSmrg     template<typename... _Args>
24411debfc3dSmrg       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
24421debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
24431debfc3dSmrg       _M_emplace_equal(_Args&&... __args)
24441debfc3dSmrg       {
24451debfc3dSmrg 	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
24461debfc3dSmrg 
24471debfc3dSmrg 	__try
24481debfc3dSmrg 	  {
24491debfc3dSmrg 	    auto __res = _M_get_insert_equal_pos(_S_key(__z));
24501debfc3dSmrg 	    return _M_insert_node(__res.first, __res.second, __z);
24511debfc3dSmrg 	  }
24521debfc3dSmrg 	__catch(...)
24531debfc3dSmrg 	  {
24541debfc3dSmrg 	    _M_drop_node(__z);
24551debfc3dSmrg 	    __throw_exception_again;
24561debfc3dSmrg 	  }
24571debfc3dSmrg       }
24581debfc3dSmrg 
24591debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
24601debfc3dSmrg 	   typename _Compare, typename _Alloc>
24611debfc3dSmrg     template<typename... _Args>
24621debfc3dSmrg       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
24631debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
24641debfc3dSmrg       _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
24651debfc3dSmrg       {
24661debfc3dSmrg 	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
24671debfc3dSmrg 
24681debfc3dSmrg 	__try
24691debfc3dSmrg 	  {
24701debfc3dSmrg 	    auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z));
24711debfc3dSmrg 
24721debfc3dSmrg 	    if (__res.second)
24731debfc3dSmrg 	      return _M_insert_node(__res.first, __res.second, __z);
24741debfc3dSmrg 
24751debfc3dSmrg 	    _M_drop_node(__z);
24761debfc3dSmrg 	    return iterator(__res.first);
24771debfc3dSmrg 	  }
24781debfc3dSmrg 	__catch(...)
24791debfc3dSmrg 	  {
24801debfc3dSmrg 	    _M_drop_node(__z);
24811debfc3dSmrg 	    __throw_exception_again;
24821debfc3dSmrg 	  }
24831debfc3dSmrg       }
24841debfc3dSmrg 
24851debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
24861debfc3dSmrg 	   typename _Compare, typename _Alloc>
24871debfc3dSmrg     template<typename... _Args>
24881debfc3dSmrg       typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
24891debfc3dSmrg       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
24901debfc3dSmrg       _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
24911debfc3dSmrg       {
24921debfc3dSmrg 	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
24931debfc3dSmrg 
24941debfc3dSmrg 	__try
24951debfc3dSmrg 	  {
24961debfc3dSmrg 	    auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z));
24971debfc3dSmrg 
24981debfc3dSmrg 	    if (__res.second)
24991debfc3dSmrg 	      return _M_insert_node(__res.first, __res.second, __z);
25001debfc3dSmrg 
25011debfc3dSmrg 	    return _M_insert_equal_lower_node(__z);
25021debfc3dSmrg 	  }
25031debfc3dSmrg 	__catch(...)
25041debfc3dSmrg 	  {
25051debfc3dSmrg 	    _M_drop_node(__z);
25061debfc3dSmrg 	    __throw_exception_again;
25071debfc3dSmrg 	  }
25081debfc3dSmrg       }
25091debfc3dSmrg #endif
25101debfc3dSmrg 
25111debfc3dSmrg 
25121debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
25131debfc3dSmrg 	   typename _Compare, typename _Alloc>
25141debfc3dSmrg     void
25151debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
25161debfc3dSmrg     _M_erase_aux(const_iterator __position)
25171debfc3dSmrg     {
25181debfc3dSmrg       _Link_type __y =
25191debfc3dSmrg 	static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
25201debfc3dSmrg 				(const_cast<_Base_ptr>(__position._M_node),
25211debfc3dSmrg 				 this->_M_impl._M_header));
25221debfc3dSmrg       _M_drop_node(__y);
25231debfc3dSmrg       --_M_impl._M_node_count;
25241debfc3dSmrg     }
25251debfc3dSmrg 
25261debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
25271debfc3dSmrg 	   typename _Compare, typename _Alloc>
25281debfc3dSmrg     void
25291debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
25301debfc3dSmrg     _M_erase_aux(const_iterator __first, const_iterator __last)
25311debfc3dSmrg     {
25321debfc3dSmrg       if (__first == begin() && __last == end())
25331debfc3dSmrg 	clear();
25341debfc3dSmrg       else
25351debfc3dSmrg 	while (__first != __last)
25361debfc3dSmrg 	  _M_erase_aux(__first++);
25371debfc3dSmrg     }
25381debfc3dSmrg 
25391debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
25401debfc3dSmrg 	   typename _Compare, typename _Alloc>
25411debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
25421debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
25431debfc3dSmrg     erase(const _Key& __x)
25441debfc3dSmrg     {
25451debfc3dSmrg       pair<iterator, iterator> __p = equal_range(__x);
25461debfc3dSmrg       const size_type __old_size = size();
25471debfc3dSmrg       _M_erase_aux(__p.first, __p.second);
25481debfc3dSmrg       return __old_size - size();
25491debfc3dSmrg     }
25501debfc3dSmrg 
25511debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
25521debfc3dSmrg 	   typename _Compare, typename _Alloc>
25531debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue,
25541debfc3dSmrg 		      _Compare, _Alloc>::iterator
25551debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
25561debfc3dSmrg     find(const _Key& __k)
25571debfc3dSmrg     {
25581debfc3dSmrg       iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
25591debfc3dSmrg       return (__j == end()
25601debfc3dSmrg 	      || _M_impl._M_key_compare(__k,
25611debfc3dSmrg 					_S_key(__j._M_node))) ? end() : __j;
25621debfc3dSmrg     }
25631debfc3dSmrg 
25641debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
25651debfc3dSmrg 	   typename _Compare, typename _Alloc>
25661debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue,
25671debfc3dSmrg 		      _Compare, _Alloc>::const_iterator
25681debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
25691debfc3dSmrg     find(const _Key& __k) const
25701debfc3dSmrg     {
25711debfc3dSmrg       const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
25721debfc3dSmrg       return (__j == end()
25731debfc3dSmrg 	      || _M_impl._M_key_compare(__k,
25741debfc3dSmrg 					_S_key(__j._M_node))) ? end() : __j;
25751debfc3dSmrg     }
25761debfc3dSmrg 
25771debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
25781debfc3dSmrg 	   typename _Compare, typename _Alloc>
25791debfc3dSmrg     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
25801debfc3dSmrg     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
25811debfc3dSmrg     count(const _Key& __k) const
25821debfc3dSmrg     {
25831debfc3dSmrg       pair<const_iterator, const_iterator> __p = equal_range(__k);
25841debfc3dSmrg       const size_type __n = std::distance(__p.first, __p.second);
25851debfc3dSmrg       return __n;
25861debfc3dSmrg     }
25871debfc3dSmrg 
25881debfc3dSmrg   _GLIBCXX_PURE unsigned int
25891debfc3dSmrg   _Rb_tree_black_count(const _Rb_tree_node_base* __node,
25901debfc3dSmrg 		       const _Rb_tree_node_base* __root) throw ();
25911debfc3dSmrg 
25921debfc3dSmrg   template<typename _Key, typename _Val, typename _KeyOfValue,
25931debfc3dSmrg 	   typename _Compare, typename _Alloc>
25941debfc3dSmrg     bool
25951debfc3dSmrg     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
25961debfc3dSmrg     {
25971debfc3dSmrg       if (_M_impl._M_node_count == 0 || begin() == end())
25981debfc3dSmrg 	return _M_impl._M_node_count == 0 && begin() == end()
25991debfc3dSmrg 	       && this->_M_impl._M_header._M_left == _M_end()
26001debfc3dSmrg 	       && this->_M_impl._M_header._M_right == _M_end();
26011debfc3dSmrg 
26021debfc3dSmrg       unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
26031debfc3dSmrg       for (const_iterator __it = begin(); __it != end(); ++__it)
26041debfc3dSmrg 	{
26051debfc3dSmrg 	  _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
26061debfc3dSmrg 	  _Const_Link_type __L = _S_left(__x);
26071debfc3dSmrg 	  _Const_Link_type __R = _S_right(__x);
26081debfc3dSmrg 
26091debfc3dSmrg 	  if (__x->_M_color == _S_red)
26101debfc3dSmrg 	    if ((__L && __L->_M_color == _S_red)
26111debfc3dSmrg 		|| (__R && __R->_M_color == _S_red))
26121debfc3dSmrg 	      return false;
26131debfc3dSmrg 
26141debfc3dSmrg 	  if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
26151debfc3dSmrg 	    return false;
26161debfc3dSmrg 	  if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
26171debfc3dSmrg 	    return false;
26181debfc3dSmrg 
26191debfc3dSmrg 	  if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
26201debfc3dSmrg 	    return false;
26211debfc3dSmrg 	}
26221debfc3dSmrg 
26231debfc3dSmrg       if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
26241debfc3dSmrg 	return false;
26251debfc3dSmrg       if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
26261debfc3dSmrg 	return false;
26271debfc3dSmrg       return true;
26281debfc3dSmrg     }
26291debfc3dSmrg 
26301debfc3dSmrg #if __cplusplus > 201402L
26311debfc3dSmrg   // Allow access to internals of compatible _Rb_tree specializations.
26321debfc3dSmrg   template<typename _Key, typename _Val, typename _Sel, typename _Cmp1,
26331debfc3dSmrg 	   typename _Alloc, typename _Cmp2>
26341debfc3dSmrg     struct _Rb_tree_merge_helper<_Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>,
26351debfc3dSmrg 				 _Cmp2>
26361debfc3dSmrg     {
26371debfc3dSmrg     private:
26381debfc3dSmrg       friend class _Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>;
26391debfc3dSmrg 
26401debfc3dSmrg       static auto&
26411debfc3dSmrg       _S_get_impl(_Rb_tree<_Key, _Val, _Sel, _Cmp2, _Alloc>& __tree)
26421debfc3dSmrg       { return __tree._M_impl; }
26431debfc3dSmrg     };
26441debfc3dSmrg #endif // C++17
26451debfc3dSmrg 
26461debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
26471debfc3dSmrg } // namespace
26481debfc3dSmrg 
26491debfc3dSmrg #endif
2650