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