xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/__tree (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1*4d6fc14bSjoerg// -*- C++ -*-
2*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
3*4d6fc14bSjoerg//
4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information.
6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4d6fc14bSjoerg//
8*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
9*4d6fc14bSjoerg
10*4d6fc14bSjoerg#ifndef _LIBCPP___TREE
11*4d6fc14bSjoerg#define _LIBCPP___TREE
12*4d6fc14bSjoerg
13*4d6fc14bSjoerg#include <__config>
14*4d6fc14bSjoerg#include <iterator>
15*4d6fc14bSjoerg#include <memory>
16*4d6fc14bSjoerg#include <stdexcept>
17*4d6fc14bSjoerg#include <algorithm>
18*4d6fc14bSjoerg
19*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20*4d6fc14bSjoerg#pragma GCC system_header
21*4d6fc14bSjoerg#endif
22*4d6fc14bSjoerg
23*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS
24*4d6fc14bSjoerg#include <__undef_macros>
25*4d6fc14bSjoerg
26*4d6fc14bSjoerg
27*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD
28*4d6fc14bSjoerg
29*4d6fc14bSjoerg#if defined(__GNUC__) && !defined(__clang__) // gcc.gnu.org/PR37804
30*4d6fc14bSjoergtemplate <class, class, class, class> class _LIBCPP_TEMPLATE_VIS map;
31*4d6fc14bSjoergtemplate <class, class, class, class> class _LIBCPP_TEMPLATE_VIS multimap;
32*4d6fc14bSjoergtemplate <class, class, class> class _LIBCPP_TEMPLATE_VIS set;
33*4d6fc14bSjoergtemplate <class, class, class> class _LIBCPP_TEMPLATE_VIS multiset;
34*4d6fc14bSjoerg#endif
35*4d6fc14bSjoerg
36*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator> class __tree;
37*4d6fc14bSjoergtemplate <class _Tp, class _NodePtr, class _DiffType>
38*4d6fc14bSjoerg    class _LIBCPP_TEMPLATE_VIS __tree_iterator;
39*4d6fc14bSjoergtemplate <class _Tp, class _ConstNodePtr, class _DiffType>
40*4d6fc14bSjoerg    class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
41*4d6fc14bSjoerg
42*4d6fc14bSjoergtemplate <class _Pointer> class __tree_end_node;
43*4d6fc14bSjoergtemplate <class _VoidPtr> class __tree_node_base;
44*4d6fc14bSjoergtemplate <class _Tp, class _VoidPtr> class __tree_node;
45*4d6fc14bSjoerg
46*4d6fc14bSjoergtemplate <class _Key, class _Value>
47*4d6fc14bSjoergstruct __value_type;
48*4d6fc14bSjoerg
49*4d6fc14bSjoergtemplate <class _Allocator> class __map_node_destructor;
50*4d6fc14bSjoergtemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
51*4d6fc14bSjoergtemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
52*4d6fc14bSjoerg
53*4d6fc14bSjoerg/*
54*4d6fc14bSjoerg
55*4d6fc14bSjoerg_NodePtr algorithms
56*4d6fc14bSjoerg
57*4d6fc14bSjoergThe algorithms taking _NodePtr are red black tree algorithms.  Those
58*4d6fc14bSjoergalgorithms taking a parameter named __root should assume that __root
59*4d6fc14bSjoergpoints to a proper red black tree (unless otherwise specified).
60*4d6fc14bSjoerg
61*4d6fc14bSjoergEach algorithm herein assumes that __root->__parent_ points to a non-null
62*4d6fc14bSjoergstructure which has a member __left_ which points back to __root.  No other
63*4d6fc14bSjoergmember is read or written to at __root->__parent_.
64*4d6fc14bSjoerg
65*4d6fc14bSjoerg__root->__parent_ will be referred to below (in comments only) as end_node.
66*4d6fc14bSjoergend_node->__left_ is an externably accessible lvalue for __root, and can be
67*4d6fc14bSjoergchanged by node insertion and removal (without explicit reference to end_node).
68*4d6fc14bSjoerg
69*4d6fc14bSjoergAll nodes (with the exception of end_node), even the node referred to as
70*4d6fc14bSjoerg__root, have a non-null __parent_ field.
71*4d6fc14bSjoerg
72*4d6fc14bSjoerg*/
73*4d6fc14bSjoerg
74*4d6fc14bSjoerg// Returns:  true if __x is a left child of its parent, else false
75*4d6fc14bSjoerg// Precondition:  __x != nullptr.
76*4d6fc14bSjoergtemplate <class _NodePtr>
77*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
78*4d6fc14bSjoergbool
79*4d6fc14bSjoerg__tree_is_left_child(_NodePtr __x) _NOEXCEPT
80*4d6fc14bSjoerg{
81*4d6fc14bSjoerg    return __x == __x->__parent_->__left_;
82*4d6fc14bSjoerg}
83*4d6fc14bSjoerg
84*4d6fc14bSjoerg// Determines if the subtree rooted at __x is a proper red black subtree.  If
85*4d6fc14bSjoerg//    __x is a proper subtree, returns the black height (null counts as 1).  If
86*4d6fc14bSjoerg//    __x is an improper subtree, returns 0.
87*4d6fc14bSjoergtemplate <class _NodePtr>
88*4d6fc14bSjoergunsigned
89*4d6fc14bSjoerg__tree_sub_invariant(_NodePtr __x)
90*4d6fc14bSjoerg{
91*4d6fc14bSjoerg    if (__x == nullptr)
92*4d6fc14bSjoerg        return 1;
93*4d6fc14bSjoerg    // parent consistency checked by caller
94*4d6fc14bSjoerg    // check __x->__left_ consistency
95*4d6fc14bSjoerg    if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
96*4d6fc14bSjoerg        return 0;
97*4d6fc14bSjoerg    // check __x->__right_ consistency
98*4d6fc14bSjoerg    if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
99*4d6fc14bSjoerg        return 0;
100*4d6fc14bSjoerg    // check __x->__left_ != __x->__right_ unless both are nullptr
101*4d6fc14bSjoerg    if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
102*4d6fc14bSjoerg        return 0;
103*4d6fc14bSjoerg    // If this is red, neither child can be red
104*4d6fc14bSjoerg    if (!__x->__is_black_)
105*4d6fc14bSjoerg    {
106*4d6fc14bSjoerg        if (__x->__left_ && !__x->__left_->__is_black_)
107*4d6fc14bSjoerg            return 0;
108*4d6fc14bSjoerg        if (__x->__right_ && !__x->__right_->__is_black_)
109*4d6fc14bSjoerg            return 0;
110*4d6fc14bSjoerg    }
111*4d6fc14bSjoerg    unsigned __h = _VSTD::__tree_sub_invariant(__x->__left_);
112*4d6fc14bSjoerg    if (__h == 0)
113*4d6fc14bSjoerg        return 0;  // invalid left subtree
114*4d6fc14bSjoerg    if (__h != _VSTD::__tree_sub_invariant(__x->__right_))
115*4d6fc14bSjoerg        return 0;  // invalid or different height right subtree
116*4d6fc14bSjoerg    return __h + __x->__is_black_;  // return black height of this node
117*4d6fc14bSjoerg}
118*4d6fc14bSjoerg
119*4d6fc14bSjoerg// Determines if the red black tree rooted at __root is a proper red black tree.
120*4d6fc14bSjoerg//    __root == nullptr is a proper tree.  Returns true is __root is a proper
121*4d6fc14bSjoerg//    red black tree, else returns false.
122*4d6fc14bSjoergtemplate <class _NodePtr>
123*4d6fc14bSjoergbool
124*4d6fc14bSjoerg__tree_invariant(_NodePtr __root)
125*4d6fc14bSjoerg{
126*4d6fc14bSjoerg    if (__root == nullptr)
127*4d6fc14bSjoerg        return true;
128*4d6fc14bSjoerg    // check __x->__parent_ consistency
129*4d6fc14bSjoerg    if (__root->__parent_ == nullptr)
130*4d6fc14bSjoerg        return false;
131*4d6fc14bSjoerg    if (!_VSTD::__tree_is_left_child(__root))
132*4d6fc14bSjoerg        return false;
133*4d6fc14bSjoerg    // root must be black
134*4d6fc14bSjoerg    if (!__root->__is_black_)
135*4d6fc14bSjoerg        return false;
136*4d6fc14bSjoerg    // do normal node checks
137*4d6fc14bSjoerg    return _VSTD::__tree_sub_invariant(__root) != 0;
138*4d6fc14bSjoerg}
139*4d6fc14bSjoerg
140*4d6fc14bSjoerg// Returns:  pointer to the left-most node under __x.
141*4d6fc14bSjoerg// Precondition:  __x != nullptr.
142*4d6fc14bSjoergtemplate <class _NodePtr>
143*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
144*4d6fc14bSjoerg_NodePtr
145*4d6fc14bSjoerg__tree_min(_NodePtr __x) _NOEXCEPT
146*4d6fc14bSjoerg{
147*4d6fc14bSjoerg    while (__x->__left_ != nullptr)
148*4d6fc14bSjoerg        __x = __x->__left_;
149*4d6fc14bSjoerg    return __x;
150*4d6fc14bSjoerg}
151*4d6fc14bSjoerg
152*4d6fc14bSjoerg// Returns:  pointer to the right-most node under __x.
153*4d6fc14bSjoerg// Precondition:  __x != nullptr.
154*4d6fc14bSjoergtemplate <class _NodePtr>
155*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
156*4d6fc14bSjoerg_NodePtr
157*4d6fc14bSjoerg__tree_max(_NodePtr __x) _NOEXCEPT
158*4d6fc14bSjoerg{
159*4d6fc14bSjoerg    while (__x->__right_ != nullptr)
160*4d6fc14bSjoerg        __x = __x->__right_;
161*4d6fc14bSjoerg    return __x;
162*4d6fc14bSjoerg}
163*4d6fc14bSjoerg
164*4d6fc14bSjoerg// Returns:  pointer to the next in-order node after __x.
165*4d6fc14bSjoerg// Precondition:  __x != nullptr.
166*4d6fc14bSjoergtemplate <class _NodePtr>
167*4d6fc14bSjoerg_NodePtr
168*4d6fc14bSjoerg__tree_next(_NodePtr __x) _NOEXCEPT
169*4d6fc14bSjoerg{
170*4d6fc14bSjoerg    if (__x->__right_ != nullptr)
171*4d6fc14bSjoerg        return _VSTD::__tree_min(__x->__right_);
172*4d6fc14bSjoerg    while (!_VSTD::__tree_is_left_child(__x))
173*4d6fc14bSjoerg        __x = __x->__parent_unsafe();
174*4d6fc14bSjoerg    return __x->__parent_unsafe();
175*4d6fc14bSjoerg}
176*4d6fc14bSjoerg
177*4d6fc14bSjoergtemplate <class _EndNodePtr, class _NodePtr>
178*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
179*4d6fc14bSjoerg_EndNodePtr
180*4d6fc14bSjoerg__tree_next_iter(_NodePtr __x) _NOEXCEPT
181*4d6fc14bSjoerg{
182*4d6fc14bSjoerg    if (__x->__right_ != nullptr)
183*4d6fc14bSjoerg        return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_));
184*4d6fc14bSjoerg    while (!_VSTD::__tree_is_left_child(__x))
185*4d6fc14bSjoerg        __x = __x->__parent_unsafe();
186*4d6fc14bSjoerg    return static_cast<_EndNodePtr>(__x->__parent_);
187*4d6fc14bSjoerg}
188*4d6fc14bSjoerg
189*4d6fc14bSjoerg// Returns:  pointer to the previous in-order node before __x.
190*4d6fc14bSjoerg// Precondition:  __x != nullptr.
191*4d6fc14bSjoerg// Note: __x may be the end node.
192*4d6fc14bSjoergtemplate <class _NodePtr, class _EndNodePtr>
193*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
194*4d6fc14bSjoerg_NodePtr
195*4d6fc14bSjoerg__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
196*4d6fc14bSjoerg{
197*4d6fc14bSjoerg    if (__x->__left_ != nullptr)
198*4d6fc14bSjoerg        return _VSTD::__tree_max(__x->__left_);
199*4d6fc14bSjoerg    _NodePtr __xx = static_cast<_NodePtr>(__x);
200*4d6fc14bSjoerg    while (_VSTD::__tree_is_left_child(__xx))
201*4d6fc14bSjoerg        __xx = __xx->__parent_unsafe();
202*4d6fc14bSjoerg    return __xx->__parent_unsafe();
203*4d6fc14bSjoerg}
204*4d6fc14bSjoerg
205*4d6fc14bSjoerg// Returns:  pointer to a node which has no children
206*4d6fc14bSjoerg// Precondition:  __x != nullptr.
207*4d6fc14bSjoergtemplate <class _NodePtr>
208*4d6fc14bSjoerg_NodePtr
209*4d6fc14bSjoerg__tree_leaf(_NodePtr __x) _NOEXCEPT
210*4d6fc14bSjoerg{
211*4d6fc14bSjoerg    while (true)
212*4d6fc14bSjoerg    {
213*4d6fc14bSjoerg        if (__x->__left_ != nullptr)
214*4d6fc14bSjoerg        {
215*4d6fc14bSjoerg            __x = __x->__left_;
216*4d6fc14bSjoerg            continue;
217*4d6fc14bSjoerg        }
218*4d6fc14bSjoerg        if (__x->__right_ != nullptr)
219*4d6fc14bSjoerg        {
220*4d6fc14bSjoerg            __x = __x->__right_;
221*4d6fc14bSjoerg            continue;
222*4d6fc14bSjoerg        }
223*4d6fc14bSjoerg        break;
224*4d6fc14bSjoerg    }
225*4d6fc14bSjoerg    return __x;
226*4d6fc14bSjoerg}
227*4d6fc14bSjoerg
228*4d6fc14bSjoerg// Effects:  Makes __x->__right_ the subtree root with __x as its left child
229*4d6fc14bSjoerg//           while preserving in-order order.
230*4d6fc14bSjoerg// Precondition:  __x->__right_ != nullptr
231*4d6fc14bSjoergtemplate <class _NodePtr>
232*4d6fc14bSjoergvoid
233*4d6fc14bSjoerg__tree_left_rotate(_NodePtr __x) _NOEXCEPT
234*4d6fc14bSjoerg{
235*4d6fc14bSjoerg    _NodePtr __y = __x->__right_;
236*4d6fc14bSjoerg    __x->__right_ = __y->__left_;
237*4d6fc14bSjoerg    if (__x->__right_ != nullptr)
238*4d6fc14bSjoerg        __x->__right_->__set_parent(__x);
239*4d6fc14bSjoerg    __y->__parent_ = __x->__parent_;
240*4d6fc14bSjoerg    if (_VSTD::__tree_is_left_child(__x))
241*4d6fc14bSjoerg        __x->__parent_->__left_ = __y;
242*4d6fc14bSjoerg    else
243*4d6fc14bSjoerg        __x->__parent_unsafe()->__right_ = __y;
244*4d6fc14bSjoerg    __y->__left_ = __x;
245*4d6fc14bSjoerg    __x->__set_parent(__y);
246*4d6fc14bSjoerg}
247*4d6fc14bSjoerg
248*4d6fc14bSjoerg// Effects:  Makes __x->__left_ the subtree root with __x as its right child
249*4d6fc14bSjoerg//           while preserving in-order order.
250*4d6fc14bSjoerg// Precondition:  __x->__left_ != nullptr
251*4d6fc14bSjoergtemplate <class _NodePtr>
252*4d6fc14bSjoergvoid
253*4d6fc14bSjoerg__tree_right_rotate(_NodePtr __x) _NOEXCEPT
254*4d6fc14bSjoerg{
255*4d6fc14bSjoerg    _NodePtr __y = __x->__left_;
256*4d6fc14bSjoerg    __x->__left_ = __y->__right_;
257*4d6fc14bSjoerg    if (__x->__left_ != nullptr)
258*4d6fc14bSjoerg        __x->__left_->__set_parent(__x);
259*4d6fc14bSjoerg    __y->__parent_ = __x->__parent_;
260*4d6fc14bSjoerg    if (_VSTD::__tree_is_left_child(__x))
261*4d6fc14bSjoerg        __x->__parent_->__left_ = __y;
262*4d6fc14bSjoerg    else
263*4d6fc14bSjoerg        __x->__parent_unsafe()->__right_ = __y;
264*4d6fc14bSjoerg    __y->__right_ = __x;
265*4d6fc14bSjoerg    __x->__set_parent(__y);
266*4d6fc14bSjoerg}
267*4d6fc14bSjoerg
268*4d6fc14bSjoerg// Effects:  Rebalances __root after attaching __x to a leaf.
269*4d6fc14bSjoerg// Precondition:  __root != nulptr && __x != nullptr.
270*4d6fc14bSjoerg//                __x has no children.
271*4d6fc14bSjoerg//                __x == __root or == a direct or indirect child of __root.
272*4d6fc14bSjoerg//                If __x were to be unlinked from __root (setting __root to
273*4d6fc14bSjoerg//                  nullptr if __root == __x), __tree_invariant(__root) == true.
274*4d6fc14bSjoerg// Postcondition: __tree_invariant(end_node->__left_) == true.  end_node->__left_
275*4d6fc14bSjoerg//                may be different than the value passed in as __root.
276*4d6fc14bSjoergtemplate <class _NodePtr>
277*4d6fc14bSjoergvoid
278*4d6fc14bSjoerg__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
279*4d6fc14bSjoerg{
280*4d6fc14bSjoerg    __x->__is_black_ = __x == __root;
281*4d6fc14bSjoerg    while (__x != __root && !__x->__parent_unsafe()->__is_black_)
282*4d6fc14bSjoerg    {
283*4d6fc14bSjoerg        // __x->__parent_ != __root because __x->__parent_->__is_black == false
284*4d6fc14bSjoerg        if (_VSTD::__tree_is_left_child(__x->__parent_unsafe()))
285*4d6fc14bSjoerg        {
286*4d6fc14bSjoerg            _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
287*4d6fc14bSjoerg            if (__y != nullptr && !__y->__is_black_)
288*4d6fc14bSjoerg            {
289*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
290*4d6fc14bSjoerg                __x->__is_black_ = true;
291*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
292*4d6fc14bSjoerg                __x->__is_black_ = __x == __root;
293*4d6fc14bSjoerg                __y->__is_black_ = true;
294*4d6fc14bSjoerg            }
295*4d6fc14bSjoerg            else
296*4d6fc14bSjoerg            {
297*4d6fc14bSjoerg                if (!_VSTD::__tree_is_left_child(__x))
298*4d6fc14bSjoerg                {
299*4d6fc14bSjoerg                    __x = __x->__parent_unsafe();
300*4d6fc14bSjoerg                    _VSTD::__tree_left_rotate(__x);
301*4d6fc14bSjoerg                }
302*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
303*4d6fc14bSjoerg                __x->__is_black_ = true;
304*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
305*4d6fc14bSjoerg                __x->__is_black_ = false;
306*4d6fc14bSjoerg                _VSTD::__tree_right_rotate(__x);
307*4d6fc14bSjoerg                break;
308*4d6fc14bSjoerg            }
309*4d6fc14bSjoerg        }
310*4d6fc14bSjoerg        else
311*4d6fc14bSjoerg        {
312*4d6fc14bSjoerg            _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
313*4d6fc14bSjoerg            if (__y != nullptr && !__y->__is_black_)
314*4d6fc14bSjoerg            {
315*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
316*4d6fc14bSjoerg                __x->__is_black_ = true;
317*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
318*4d6fc14bSjoerg                __x->__is_black_ = __x == __root;
319*4d6fc14bSjoerg                __y->__is_black_ = true;
320*4d6fc14bSjoerg            }
321*4d6fc14bSjoerg            else
322*4d6fc14bSjoerg            {
323*4d6fc14bSjoerg                if (_VSTD::__tree_is_left_child(__x))
324*4d6fc14bSjoerg                {
325*4d6fc14bSjoerg                    __x = __x->__parent_unsafe();
326*4d6fc14bSjoerg                    _VSTD::__tree_right_rotate(__x);
327*4d6fc14bSjoerg                }
328*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
329*4d6fc14bSjoerg                __x->__is_black_ = true;
330*4d6fc14bSjoerg                __x = __x->__parent_unsafe();
331*4d6fc14bSjoerg                __x->__is_black_ = false;
332*4d6fc14bSjoerg                _VSTD::__tree_left_rotate(__x);
333*4d6fc14bSjoerg                break;
334*4d6fc14bSjoerg            }
335*4d6fc14bSjoerg        }
336*4d6fc14bSjoerg    }
337*4d6fc14bSjoerg}
338*4d6fc14bSjoerg
339*4d6fc14bSjoerg// Precondition:  __root != nullptr && __z != nullptr.
340*4d6fc14bSjoerg//                __tree_invariant(__root) == true.
341*4d6fc14bSjoerg//                __z == __root or == a direct or indirect child of __root.
342*4d6fc14bSjoerg// Effects:  unlinks __z from the tree rooted at __root, rebalancing as needed.
343*4d6fc14bSjoerg// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
344*4d6fc14bSjoerg//                nor any of its children refer to __z.  end_node->__left_
345*4d6fc14bSjoerg//                may be different than the value passed in as __root.
346*4d6fc14bSjoergtemplate <class _NodePtr>
347*4d6fc14bSjoergvoid
348*4d6fc14bSjoerg__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
349*4d6fc14bSjoerg{
350*4d6fc14bSjoerg    // __z will be removed from the tree.  Client still needs to destruct/deallocate it
351*4d6fc14bSjoerg    // __y is either __z, or if __z has two children, __tree_next(__z).
352*4d6fc14bSjoerg    // __y will have at most one child.
353*4d6fc14bSjoerg    // __y will be the initial hole in the tree (make the hole at a leaf)
354*4d6fc14bSjoerg    _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
355*4d6fc14bSjoerg                    __z : _VSTD::__tree_next(__z);
356*4d6fc14bSjoerg    // __x is __y's possibly null single child
357*4d6fc14bSjoerg    _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
358*4d6fc14bSjoerg    // __w is __x's possibly null uncle (will become __x's sibling)
359*4d6fc14bSjoerg    _NodePtr __w = nullptr;
360*4d6fc14bSjoerg    // link __x to __y's parent, and find __w
361*4d6fc14bSjoerg    if (__x != nullptr)
362*4d6fc14bSjoerg        __x->__parent_ = __y->__parent_;
363*4d6fc14bSjoerg    if (_VSTD::__tree_is_left_child(__y))
364*4d6fc14bSjoerg    {
365*4d6fc14bSjoerg        __y->__parent_->__left_ = __x;
366*4d6fc14bSjoerg        if (__y != __root)
367*4d6fc14bSjoerg            __w = __y->__parent_unsafe()->__right_;
368*4d6fc14bSjoerg        else
369*4d6fc14bSjoerg            __root = __x;  // __w == nullptr
370*4d6fc14bSjoerg    }
371*4d6fc14bSjoerg    else
372*4d6fc14bSjoerg    {
373*4d6fc14bSjoerg        __y->__parent_unsafe()->__right_ = __x;
374*4d6fc14bSjoerg        // __y can't be root if it is a right child
375*4d6fc14bSjoerg        __w = __y->__parent_->__left_;
376*4d6fc14bSjoerg    }
377*4d6fc14bSjoerg    bool __removed_black = __y->__is_black_;
378*4d6fc14bSjoerg    // If we didn't remove __z, do so now by splicing in __y for __z,
379*4d6fc14bSjoerg    //    but copy __z's color.  This does not impact __x or __w.
380*4d6fc14bSjoerg    if (__y != __z)
381*4d6fc14bSjoerg    {
382*4d6fc14bSjoerg        // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
383*4d6fc14bSjoerg        __y->__parent_ = __z->__parent_;
384*4d6fc14bSjoerg        if (_VSTD::__tree_is_left_child(__z))
385*4d6fc14bSjoerg            __y->__parent_->__left_ = __y;
386*4d6fc14bSjoerg        else
387*4d6fc14bSjoerg            __y->__parent_unsafe()->__right_ = __y;
388*4d6fc14bSjoerg        __y->__left_ = __z->__left_;
389*4d6fc14bSjoerg        __y->__left_->__set_parent(__y);
390*4d6fc14bSjoerg        __y->__right_ = __z->__right_;
391*4d6fc14bSjoerg        if (__y->__right_ != nullptr)
392*4d6fc14bSjoerg            __y->__right_->__set_parent(__y);
393*4d6fc14bSjoerg        __y->__is_black_ = __z->__is_black_;
394*4d6fc14bSjoerg        if (__root == __z)
395*4d6fc14bSjoerg            __root = __y;
396*4d6fc14bSjoerg    }
397*4d6fc14bSjoerg    // There is no need to rebalance if we removed a red, or if we removed
398*4d6fc14bSjoerg    //     the last node.
399*4d6fc14bSjoerg    if (__removed_black && __root != nullptr)
400*4d6fc14bSjoerg    {
401*4d6fc14bSjoerg        // Rebalance:
402*4d6fc14bSjoerg        // __x has an implicit black color (transferred from the removed __y)
403*4d6fc14bSjoerg        //    associated with it, no matter what its color is.
404*4d6fc14bSjoerg        // If __x is __root (in which case it can't be null), it is supposed
405*4d6fc14bSjoerg        //    to be black anyway, and if it is doubly black, then the double
406*4d6fc14bSjoerg        //    can just be ignored.
407*4d6fc14bSjoerg        // If __x is red (in which case it can't be null), then it can absorb
408*4d6fc14bSjoerg        //    the implicit black just by setting its color to black.
409*4d6fc14bSjoerg        // Since __y was black and only had one child (which __x points to), __x
410*4d6fc14bSjoerg        //   is either red with no children, else null, otherwise __y would have
411*4d6fc14bSjoerg        //   different black heights under left and right pointers.
412*4d6fc14bSjoerg        // if (__x == __root || __x != nullptr && !__x->__is_black_)
413*4d6fc14bSjoerg        if (__x != nullptr)
414*4d6fc14bSjoerg            __x->__is_black_ = true;
415*4d6fc14bSjoerg        else
416*4d6fc14bSjoerg        {
417*4d6fc14bSjoerg            //  Else __x isn't root, and is "doubly black", even though it may
418*4d6fc14bSjoerg            //     be null.  __w can not be null here, else the parent would
419*4d6fc14bSjoerg            //     see a black height >= 2 on the __x side and a black height
420*4d6fc14bSjoerg            //     of 1 on the __w side (__w must be a non-null black or a red
421*4d6fc14bSjoerg            //     with a non-null black child).
422*4d6fc14bSjoerg            while (true)
423*4d6fc14bSjoerg            {
424*4d6fc14bSjoerg                if (!_VSTD::__tree_is_left_child(__w))  // if x is left child
425*4d6fc14bSjoerg                {
426*4d6fc14bSjoerg                    if (!__w->__is_black_)
427*4d6fc14bSjoerg                    {
428*4d6fc14bSjoerg                        __w->__is_black_ = true;
429*4d6fc14bSjoerg                        __w->__parent_unsafe()->__is_black_ = false;
430*4d6fc14bSjoerg                        _VSTD::__tree_left_rotate(__w->__parent_unsafe());
431*4d6fc14bSjoerg                        // __x is still valid
432*4d6fc14bSjoerg                        // reset __root only if necessary
433*4d6fc14bSjoerg                        if (__root == __w->__left_)
434*4d6fc14bSjoerg                            __root = __w;
435*4d6fc14bSjoerg                        // reset sibling, and it still can't be null
436*4d6fc14bSjoerg                        __w = __w->__left_->__right_;
437*4d6fc14bSjoerg                    }
438*4d6fc14bSjoerg                    // __w->__is_black_ is now true, __w may have null children
439*4d6fc14bSjoerg                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
440*4d6fc14bSjoerg                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
441*4d6fc14bSjoerg                    {
442*4d6fc14bSjoerg                        __w->__is_black_ = false;
443*4d6fc14bSjoerg                        __x = __w->__parent_unsafe();
444*4d6fc14bSjoerg                        // __x can no longer be null
445*4d6fc14bSjoerg                        if (__x == __root || !__x->__is_black_)
446*4d6fc14bSjoerg                        {
447*4d6fc14bSjoerg                            __x->__is_black_ = true;
448*4d6fc14bSjoerg                            break;
449*4d6fc14bSjoerg                        }
450*4d6fc14bSjoerg                        // reset sibling, and it still can't be null
451*4d6fc14bSjoerg                        __w = _VSTD::__tree_is_left_child(__x) ?
452*4d6fc14bSjoerg                                    __x->__parent_unsafe()->__right_ :
453*4d6fc14bSjoerg                                    __x->__parent_->__left_;
454*4d6fc14bSjoerg                        // continue;
455*4d6fc14bSjoerg                    }
456*4d6fc14bSjoerg                    else  // __w has a red child
457*4d6fc14bSjoerg                    {
458*4d6fc14bSjoerg                        if (__w->__right_ == nullptr || __w->__right_->__is_black_)
459*4d6fc14bSjoerg                        {
460*4d6fc14bSjoerg                            // __w left child is non-null and red
461*4d6fc14bSjoerg                            __w->__left_->__is_black_ = true;
462*4d6fc14bSjoerg                            __w->__is_black_ = false;
463*4d6fc14bSjoerg                            _VSTD::__tree_right_rotate(__w);
464*4d6fc14bSjoerg                            // __w is known not to be root, so root hasn't changed
465*4d6fc14bSjoerg                            // reset sibling, and it still can't be null
466*4d6fc14bSjoerg                            __w = __w->__parent_unsafe();
467*4d6fc14bSjoerg                        }
468*4d6fc14bSjoerg                        // __w has a right red child, left child may be null
469*4d6fc14bSjoerg                        __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
470*4d6fc14bSjoerg                        __w->__parent_unsafe()->__is_black_ = true;
471*4d6fc14bSjoerg                        __w->__right_->__is_black_ = true;
472*4d6fc14bSjoerg                        _VSTD::__tree_left_rotate(__w->__parent_unsafe());
473*4d6fc14bSjoerg                        break;
474*4d6fc14bSjoerg                    }
475*4d6fc14bSjoerg                }
476*4d6fc14bSjoerg                else
477*4d6fc14bSjoerg                {
478*4d6fc14bSjoerg                    if (!__w->__is_black_)
479*4d6fc14bSjoerg                    {
480*4d6fc14bSjoerg                        __w->__is_black_ = true;
481*4d6fc14bSjoerg                        __w->__parent_unsafe()->__is_black_ = false;
482*4d6fc14bSjoerg                        _VSTD::__tree_right_rotate(__w->__parent_unsafe());
483*4d6fc14bSjoerg                        // __x is still valid
484*4d6fc14bSjoerg                        // reset __root only if necessary
485*4d6fc14bSjoerg                        if (__root == __w->__right_)
486*4d6fc14bSjoerg                            __root = __w;
487*4d6fc14bSjoerg                        // reset sibling, and it still can't be null
488*4d6fc14bSjoerg                        __w = __w->__right_->__left_;
489*4d6fc14bSjoerg                    }
490*4d6fc14bSjoerg                    // __w->__is_black_ is now true, __w may have null children
491*4d6fc14bSjoerg                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
492*4d6fc14bSjoerg                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
493*4d6fc14bSjoerg                    {
494*4d6fc14bSjoerg                        __w->__is_black_ = false;
495*4d6fc14bSjoerg                        __x = __w->__parent_unsafe();
496*4d6fc14bSjoerg                        // __x can no longer be null
497*4d6fc14bSjoerg                        if (!__x->__is_black_ || __x == __root)
498*4d6fc14bSjoerg                        {
499*4d6fc14bSjoerg                            __x->__is_black_ = true;
500*4d6fc14bSjoerg                            break;
501*4d6fc14bSjoerg                        }
502*4d6fc14bSjoerg                        // reset sibling, and it still can't be null
503*4d6fc14bSjoerg                        __w = _VSTD::__tree_is_left_child(__x) ?
504*4d6fc14bSjoerg                                    __x->__parent_unsafe()->__right_ :
505*4d6fc14bSjoerg                                    __x->__parent_->__left_;
506*4d6fc14bSjoerg                        // continue;
507*4d6fc14bSjoerg                    }
508*4d6fc14bSjoerg                    else  // __w has a red child
509*4d6fc14bSjoerg                    {
510*4d6fc14bSjoerg                        if (__w->__left_ == nullptr || __w->__left_->__is_black_)
511*4d6fc14bSjoerg                        {
512*4d6fc14bSjoerg                            // __w right child is non-null and red
513*4d6fc14bSjoerg                            __w->__right_->__is_black_ = true;
514*4d6fc14bSjoerg                            __w->__is_black_ = false;
515*4d6fc14bSjoerg                            _VSTD::__tree_left_rotate(__w);
516*4d6fc14bSjoerg                            // __w is known not to be root, so root hasn't changed
517*4d6fc14bSjoerg                            // reset sibling, and it still can't be null
518*4d6fc14bSjoerg                            __w = __w->__parent_unsafe();
519*4d6fc14bSjoerg                        }
520*4d6fc14bSjoerg                        // __w has a left red child, right child may be null
521*4d6fc14bSjoerg                        __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
522*4d6fc14bSjoerg                        __w->__parent_unsafe()->__is_black_ = true;
523*4d6fc14bSjoerg                        __w->__left_->__is_black_ = true;
524*4d6fc14bSjoerg                        _VSTD::__tree_right_rotate(__w->__parent_unsafe());
525*4d6fc14bSjoerg                        break;
526*4d6fc14bSjoerg                    }
527*4d6fc14bSjoerg                }
528*4d6fc14bSjoerg            }
529*4d6fc14bSjoerg        }
530*4d6fc14bSjoerg    }
531*4d6fc14bSjoerg}
532*4d6fc14bSjoerg
533*4d6fc14bSjoerg// node traits
534*4d6fc14bSjoerg
535*4d6fc14bSjoerg
536*4d6fc14bSjoergtemplate <class _Tp>
537*4d6fc14bSjoergstruct __is_tree_value_type_imp : false_type {};
538*4d6fc14bSjoerg
539*4d6fc14bSjoergtemplate <class _Key, class _Value>
540*4d6fc14bSjoergstruct __is_tree_value_type_imp<__value_type<_Key, _Value> > : true_type {};
541*4d6fc14bSjoerg
542*4d6fc14bSjoergtemplate <class ..._Args>
543*4d6fc14bSjoergstruct __is_tree_value_type : false_type {};
544*4d6fc14bSjoerg
545*4d6fc14bSjoergtemplate <class _One>
546*4d6fc14bSjoergstruct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {};
547*4d6fc14bSjoerg
548*4d6fc14bSjoergtemplate <class _Tp>
549*4d6fc14bSjoergstruct __tree_key_value_types {
550*4d6fc14bSjoerg  typedef _Tp key_type;
551*4d6fc14bSjoerg  typedef _Tp __node_value_type;
552*4d6fc14bSjoerg  typedef _Tp __container_value_type;
553*4d6fc14bSjoerg  static const bool __is_map = false;
554*4d6fc14bSjoerg
555*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
556*4d6fc14bSjoerg  static key_type const& __get_key(_Tp const& __v) {
557*4d6fc14bSjoerg    return __v;
558*4d6fc14bSjoerg  }
559*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
560*4d6fc14bSjoerg  static __container_value_type const& __get_value(__node_value_type const& __v) {
561*4d6fc14bSjoerg    return __v;
562*4d6fc14bSjoerg  }
563*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
564*4d6fc14bSjoerg  static __container_value_type* __get_ptr(__node_value_type& __n) {
565*4d6fc14bSjoerg    return _VSTD::addressof(__n);
566*4d6fc14bSjoerg  }
567*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
568*4d6fc14bSjoerg  static __container_value_type&& __move(__node_value_type& __v) {
569*4d6fc14bSjoerg    return _VSTD::move(__v);
570*4d6fc14bSjoerg  }
571*4d6fc14bSjoerg};
572*4d6fc14bSjoerg
573*4d6fc14bSjoergtemplate <class _Key, class _Tp>
574*4d6fc14bSjoergstruct __tree_key_value_types<__value_type<_Key, _Tp> > {
575*4d6fc14bSjoerg  typedef _Key                                         key_type;
576*4d6fc14bSjoerg  typedef _Tp                                          mapped_type;
577*4d6fc14bSjoerg  typedef __value_type<_Key, _Tp>                      __node_value_type;
578*4d6fc14bSjoerg  typedef pair<const _Key, _Tp>                        __container_value_type;
579*4d6fc14bSjoerg  typedef __container_value_type                       __map_value_type;
580*4d6fc14bSjoerg  static const bool __is_map = true;
581*4d6fc14bSjoerg
582*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
583*4d6fc14bSjoerg  static key_type const&
584*4d6fc14bSjoerg  __get_key(__node_value_type const& __t) {
585*4d6fc14bSjoerg    return __t.__get_value().first;
586*4d6fc14bSjoerg  }
587*4d6fc14bSjoerg
588*4d6fc14bSjoerg  template <class _Up>
589*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
590*4d6fc14bSjoerg  static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
591*4d6fc14bSjoerg      key_type const&>::type
592*4d6fc14bSjoerg  __get_key(_Up& __t) {
593*4d6fc14bSjoerg    return __t.first;
594*4d6fc14bSjoerg  }
595*4d6fc14bSjoerg
596*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
597*4d6fc14bSjoerg  static __container_value_type const&
598*4d6fc14bSjoerg  __get_value(__node_value_type const& __t) {
599*4d6fc14bSjoerg    return __t.__get_value();
600*4d6fc14bSjoerg  }
601*4d6fc14bSjoerg
602*4d6fc14bSjoerg  template <class _Up>
603*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
604*4d6fc14bSjoerg  static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
605*4d6fc14bSjoerg      __container_value_type const&>::type
606*4d6fc14bSjoerg  __get_value(_Up& __t) {
607*4d6fc14bSjoerg    return __t;
608*4d6fc14bSjoerg  }
609*4d6fc14bSjoerg
610*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
611*4d6fc14bSjoerg  static __container_value_type* __get_ptr(__node_value_type& __n) {
612*4d6fc14bSjoerg    return _VSTD::addressof(__n.__get_value());
613*4d6fc14bSjoerg  }
614*4d6fc14bSjoerg
615*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
616*4d6fc14bSjoerg  static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
617*4d6fc14bSjoerg    return __v.__move();
618*4d6fc14bSjoerg  }
619*4d6fc14bSjoerg};
620*4d6fc14bSjoerg
621*4d6fc14bSjoergtemplate <class _VoidPtr>
622*4d6fc14bSjoergstruct __tree_node_base_types {
623*4d6fc14bSjoerg  typedef _VoidPtr                                               __void_pointer;
624*4d6fc14bSjoerg
625*4d6fc14bSjoerg  typedef __tree_node_base<__void_pointer>                      __node_base_type;
626*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
627*4d6fc14bSjoerg                                                             __node_base_pointer;
628*4d6fc14bSjoerg
629*4d6fc14bSjoerg  typedef __tree_end_node<__node_base_pointer>                  __end_node_type;
630*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
631*4d6fc14bSjoerg                                                             __end_node_pointer;
632*4d6fc14bSjoerg#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
633*4d6fc14bSjoerg  typedef __end_node_pointer __parent_pointer;
634*4d6fc14bSjoerg#else
635*4d6fc14bSjoerg  typedef typename conditional<
636*4d6fc14bSjoerg      is_pointer<__end_node_pointer>::value,
637*4d6fc14bSjoerg        __end_node_pointer,
638*4d6fc14bSjoerg        __node_base_pointer>::type __parent_pointer;
639*4d6fc14bSjoerg#endif
640*4d6fc14bSjoerg
641*4d6fc14bSjoergprivate:
642*4d6fc14bSjoerg  static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
643*4d6fc14bSjoerg                  "_VoidPtr does not point to unqualified void type");
644*4d6fc14bSjoerg};
645*4d6fc14bSjoerg
646*4d6fc14bSjoergtemplate <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>,
647*4d6fc14bSjoerg         bool = _KVTypes::__is_map>
648*4d6fc14bSjoergstruct __tree_map_pointer_types {};
649*4d6fc14bSjoerg
650*4d6fc14bSjoergtemplate <class _Tp, class _AllocPtr, class _KVTypes>
651*4d6fc14bSjoergstruct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
652*4d6fc14bSjoerg  typedef typename _KVTypes::__map_value_type   _Mv;
653*4d6fc14bSjoerg  typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
654*4d6fc14bSjoerg                                                       __map_value_type_pointer;
655*4d6fc14bSjoerg  typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
656*4d6fc14bSjoerg                                                 __const_map_value_type_pointer;
657*4d6fc14bSjoerg};
658*4d6fc14bSjoerg
659*4d6fc14bSjoergtemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
660*4d6fc14bSjoergstruct __tree_node_types;
661*4d6fc14bSjoerg
662*4d6fc14bSjoergtemplate <class _NodePtr, class _Tp, class _VoidPtr>
663*4d6fc14bSjoergstruct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> >
664*4d6fc14bSjoerg    : public __tree_node_base_types<_VoidPtr>,
665*4d6fc14bSjoerg             __tree_key_value_types<_Tp>,
666*4d6fc14bSjoerg             __tree_map_pointer_types<_Tp, _VoidPtr>
667*4d6fc14bSjoerg{
668*4d6fc14bSjoerg  typedef __tree_node_base_types<_VoidPtr> __base;
669*4d6fc14bSjoerg  typedef __tree_key_value_types<_Tp>      __key_base;
670*4d6fc14bSjoerg  typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base;
671*4d6fc14bSjoergpublic:
672*4d6fc14bSjoerg
673*4d6fc14bSjoerg  typedef typename pointer_traits<_NodePtr>::element_type       __node_type;
674*4d6fc14bSjoerg  typedef _NodePtr                                              __node_pointer;
675*4d6fc14bSjoerg
676*4d6fc14bSjoerg  typedef _Tp                                                 __node_value_type;
677*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
678*4d6fc14bSjoerg                                                      __node_value_type_pointer;
679*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
680*4d6fc14bSjoerg                                                __const_node_value_type_pointer;
681*4d6fc14bSjoerg#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
682*4d6fc14bSjoerg  typedef typename __base::__end_node_pointer __iter_pointer;
683*4d6fc14bSjoerg#else
684*4d6fc14bSjoerg  typedef typename conditional<
685*4d6fc14bSjoerg      is_pointer<__node_pointer>::value,
686*4d6fc14bSjoerg        typename __base::__end_node_pointer,
687*4d6fc14bSjoerg        __node_pointer>::type __iter_pointer;
688*4d6fc14bSjoerg#endif
689*4d6fc14bSjoergprivate:
690*4d6fc14bSjoerg    static_assert(!is_const<__node_type>::value,
691*4d6fc14bSjoerg                "_NodePtr should never be a pointer to const");
692*4d6fc14bSjoerg    static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
693*4d6fc14bSjoerg                          _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
694*4d6fc14bSjoerg};
695*4d6fc14bSjoerg
696*4d6fc14bSjoergtemplate <class _ValueTp, class _VoidPtr>
697*4d6fc14bSjoergstruct __make_tree_node_types {
698*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
699*4d6fc14bSjoerg                                                                        _NodePtr;
700*4d6fc14bSjoerg  typedef __tree_node_types<_NodePtr> type;
701*4d6fc14bSjoerg};
702*4d6fc14bSjoerg
703*4d6fc14bSjoerg// node
704*4d6fc14bSjoerg
705*4d6fc14bSjoergtemplate <class _Pointer>
706*4d6fc14bSjoergclass __tree_end_node
707*4d6fc14bSjoerg{
708*4d6fc14bSjoergpublic:
709*4d6fc14bSjoerg    typedef _Pointer pointer;
710*4d6fc14bSjoerg    pointer __left_;
711*4d6fc14bSjoerg
712*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
713*4d6fc14bSjoerg    __tree_end_node() _NOEXCEPT : __left_() {}
714*4d6fc14bSjoerg};
715*4d6fc14bSjoerg
716*4d6fc14bSjoergtemplate <class _VoidPtr>
717*4d6fc14bSjoergclass _LIBCPP_STANDALONE_DEBUG __tree_node_base
718*4d6fc14bSjoerg    : public __tree_node_base_types<_VoidPtr>::__end_node_type
719*4d6fc14bSjoerg{
720*4d6fc14bSjoerg    typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
721*4d6fc14bSjoerg
722*4d6fc14bSjoergpublic:
723*4d6fc14bSjoerg    typedef typename _NodeBaseTypes::__node_base_pointer pointer;
724*4d6fc14bSjoerg    typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
725*4d6fc14bSjoerg
726*4d6fc14bSjoerg    pointer          __right_;
727*4d6fc14bSjoerg    __parent_pointer __parent_;
728*4d6fc14bSjoerg    bool __is_black_;
729*4d6fc14bSjoerg
730*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
731*4d6fc14bSjoerg    pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
732*4d6fc14bSjoerg
733*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
734*4d6fc14bSjoerg    void __set_parent(pointer __p) {
735*4d6fc14bSjoerg        __parent_ = static_cast<__parent_pointer>(__p);
736*4d6fc14bSjoerg    }
737*4d6fc14bSjoerg
738*4d6fc14bSjoergprivate:
739*4d6fc14bSjoerg  ~__tree_node_base() _LIBCPP_EQUAL_DELETE;
740*4d6fc14bSjoerg  __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
741*4d6fc14bSjoerg  __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
742*4d6fc14bSjoerg};
743*4d6fc14bSjoerg
744*4d6fc14bSjoergtemplate <class _Tp, class _VoidPtr>
745*4d6fc14bSjoergclass _LIBCPP_STANDALONE_DEBUG __tree_node
746*4d6fc14bSjoerg    : public __tree_node_base<_VoidPtr>
747*4d6fc14bSjoerg{
748*4d6fc14bSjoergpublic:
749*4d6fc14bSjoerg    typedef _Tp __node_value_type;
750*4d6fc14bSjoerg
751*4d6fc14bSjoerg    __node_value_type __value_;
752*4d6fc14bSjoerg
753*4d6fc14bSjoergprivate:
754*4d6fc14bSjoerg  ~__tree_node() _LIBCPP_EQUAL_DELETE;
755*4d6fc14bSjoerg  __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE;
756*4d6fc14bSjoerg  __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE;
757*4d6fc14bSjoerg};
758*4d6fc14bSjoerg
759*4d6fc14bSjoerg
760*4d6fc14bSjoergtemplate <class _Allocator>
761*4d6fc14bSjoergclass __tree_node_destructor
762*4d6fc14bSjoerg{
763*4d6fc14bSjoerg    typedef _Allocator                                      allocator_type;
764*4d6fc14bSjoerg    typedef allocator_traits<allocator_type>                __alloc_traits;
765*4d6fc14bSjoerg
766*4d6fc14bSjoergpublic:
767*4d6fc14bSjoerg    typedef typename __alloc_traits::pointer                pointer;
768*4d6fc14bSjoergprivate:
769*4d6fc14bSjoerg    typedef __tree_node_types<pointer> _NodeTypes;
770*4d6fc14bSjoerg    allocator_type& __na_;
771*4d6fc14bSjoerg
772*4d6fc14bSjoerg
773*4d6fc14bSjoergpublic:
774*4d6fc14bSjoerg    bool __value_constructed;
775*4d6fc14bSjoerg
776*4d6fc14bSjoerg
777*4d6fc14bSjoerg    __tree_node_destructor(const __tree_node_destructor &) = default;
778*4d6fc14bSjoerg    __tree_node_destructor& operator=(const __tree_node_destructor&) = delete;
779*4d6fc14bSjoerg
780*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
781*4d6fc14bSjoerg    explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
782*4d6fc14bSjoerg        : __na_(__na),
783*4d6fc14bSjoerg          __value_constructed(__val)
784*4d6fc14bSjoerg        {}
785*4d6fc14bSjoerg
786*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
787*4d6fc14bSjoerg    void operator()(pointer __p) _NOEXCEPT
788*4d6fc14bSjoerg    {
789*4d6fc14bSjoerg        if (__value_constructed)
790*4d6fc14bSjoerg            __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
791*4d6fc14bSjoerg        if (__p)
792*4d6fc14bSjoerg            __alloc_traits::deallocate(__na_, __p, 1);
793*4d6fc14bSjoerg    }
794*4d6fc14bSjoerg
795*4d6fc14bSjoerg    template <class> friend class __map_node_destructor;
796*4d6fc14bSjoerg};
797*4d6fc14bSjoerg
798*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14
799*4d6fc14bSjoergtemplate <class _NodeType, class _Alloc>
800*4d6fc14bSjoergstruct __generic_container_node_destructor;
801*4d6fc14bSjoergtemplate <class _Tp, class _VoidPtr, class _Alloc>
802*4d6fc14bSjoergstruct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
803*4d6fc14bSjoerg    : __tree_node_destructor<_Alloc>
804*4d6fc14bSjoerg{
805*4d6fc14bSjoerg    using __tree_node_destructor<_Alloc>::__tree_node_destructor;
806*4d6fc14bSjoerg};
807*4d6fc14bSjoerg#endif
808*4d6fc14bSjoerg
809*4d6fc14bSjoergtemplate <class _Tp, class _NodePtr, class _DiffType>
810*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __tree_iterator
811*4d6fc14bSjoerg{
812*4d6fc14bSjoerg    typedef __tree_node_types<_NodePtr>                     _NodeTypes;
813*4d6fc14bSjoerg    typedef _NodePtr                                        __node_pointer;
814*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_base_pointer        __node_base_pointer;
815*4d6fc14bSjoerg    typedef typename _NodeTypes::__end_node_pointer         __end_node_pointer;
816*4d6fc14bSjoerg    typedef typename _NodeTypes::__iter_pointer             __iter_pointer;
817*4d6fc14bSjoerg    typedef pointer_traits<__node_pointer> __pointer_traits;
818*4d6fc14bSjoerg
819*4d6fc14bSjoerg    __iter_pointer __ptr_;
820*4d6fc14bSjoerg
821*4d6fc14bSjoergpublic:
822*4d6fc14bSjoerg    typedef bidirectional_iterator_tag                     iterator_category;
823*4d6fc14bSjoerg    typedef _Tp                                            value_type;
824*4d6fc14bSjoerg    typedef _DiffType                                      difference_type;
825*4d6fc14bSjoerg    typedef value_type&                                    reference;
826*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type_pointer pointer;
827*4d6fc14bSjoerg
828*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
829*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 11
830*4d6fc14bSjoerg    : __ptr_(nullptr)
831*4d6fc14bSjoerg#endif
832*4d6fc14bSjoerg    {}
833*4d6fc14bSjoerg
834*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY reference operator*() const
835*4d6fc14bSjoerg        {return __get_np()->__value_;}
836*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
837*4d6fc14bSjoerg        {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
838*4d6fc14bSjoerg
839*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
840*4d6fc14bSjoerg    __tree_iterator& operator++() {
841*4d6fc14bSjoerg      __ptr_ = static_cast<__iter_pointer>(
842*4d6fc14bSjoerg          _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
843*4d6fc14bSjoerg      return *this;
844*4d6fc14bSjoerg    }
845*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
846*4d6fc14bSjoerg    __tree_iterator operator++(int)
847*4d6fc14bSjoerg        {__tree_iterator __t(*this); ++(*this); return __t;}
848*4d6fc14bSjoerg
849*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
850*4d6fc14bSjoerg    __tree_iterator& operator--() {
851*4d6fc14bSjoerg      __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
852*4d6fc14bSjoerg          static_cast<__end_node_pointer>(__ptr_)));
853*4d6fc14bSjoerg      return *this;
854*4d6fc14bSjoerg    }
855*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
856*4d6fc14bSjoerg    __tree_iterator operator--(int)
857*4d6fc14bSjoerg        {__tree_iterator __t(*this); --(*this); return __t;}
858*4d6fc14bSjoerg
859*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
860*4d6fc14bSjoerg        bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
861*4d6fc14bSjoerg        {return __x.__ptr_ == __y.__ptr_;}
862*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
863*4d6fc14bSjoerg        bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
864*4d6fc14bSjoerg        {return !(__x == __y);}
865*4d6fc14bSjoerg
866*4d6fc14bSjoergprivate:
867*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
868*4d6fc14bSjoerg    explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
869*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
870*4d6fc14bSjoerg    explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
871*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
872*4d6fc14bSjoerg    __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
873*4d6fc14bSjoerg    template <class, class, class> friend class __tree;
874*4d6fc14bSjoerg    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
875*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
876*4d6fc14bSjoerg    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
877*4d6fc14bSjoerg    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
878*4d6fc14bSjoerg    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
879*4d6fc14bSjoerg    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
880*4d6fc14bSjoerg};
881*4d6fc14bSjoerg
882*4d6fc14bSjoergtemplate <class _Tp, class _NodePtr, class _DiffType>
883*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __tree_const_iterator
884*4d6fc14bSjoerg{
885*4d6fc14bSjoerg    typedef __tree_node_types<_NodePtr>                     _NodeTypes;
886*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_pointer             __node_pointer;
887*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_base_pointer        __node_base_pointer;
888*4d6fc14bSjoerg    typedef typename _NodeTypes::__end_node_pointer         __end_node_pointer;
889*4d6fc14bSjoerg    typedef typename _NodeTypes::__iter_pointer             __iter_pointer;
890*4d6fc14bSjoerg    typedef pointer_traits<__node_pointer> __pointer_traits;
891*4d6fc14bSjoerg
892*4d6fc14bSjoerg    __iter_pointer __ptr_;
893*4d6fc14bSjoerg
894*4d6fc14bSjoergpublic:
895*4d6fc14bSjoerg    typedef bidirectional_iterator_tag                           iterator_category;
896*4d6fc14bSjoerg    typedef _Tp                                                  value_type;
897*4d6fc14bSjoerg    typedef _DiffType                                            difference_type;
898*4d6fc14bSjoerg    typedef const value_type&                                    reference;
899*4d6fc14bSjoerg    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
900*4d6fc14bSjoerg
901*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
902*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 11
903*4d6fc14bSjoerg    : __ptr_(nullptr)
904*4d6fc14bSjoerg#endif
905*4d6fc14bSjoerg    {}
906*4d6fc14bSjoerg
907*4d6fc14bSjoergprivate:
908*4d6fc14bSjoerg    typedef __tree_iterator<value_type, __node_pointer, difference_type>
909*4d6fc14bSjoerg                                                           __non_const_iterator;
910*4d6fc14bSjoergpublic:
911*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
912*4d6fc14bSjoerg    __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
913*4d6fc14bSjoerg        : __ptr_(__p.__ptr_) {}
914*4d6fc14bSjoerg
915*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY reference operator*() const
916*4d6fc14bSjoerg        {return __get_np()->__value_;}
917*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
918*4d6fc14bSjoerg        {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
919*4d6fc14bSjoerg
920*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
921*4d6fc14bSjoerg    __tree_const_iterator& operator++() {
922*4d6fc14bSjoerg      __ptr_ = static_cast<__iter_pointer>(
923*4d6fc14bSjoerg          _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
924*4d6fc14bSjoerg      return *this;
925*4d6fc14bSjoerg    }
926*4d6fc14bSjoerg
927*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
928*4d6fc14bSjoerg    __tree_const_iterator operator++(int)
929*4d6fc14bSjoerg        {__tree_const_iterator __t(*this); ++(*this); return __t;}
930*4d6fc14bSjoerg
931*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
932*4d6fc14bSjoerg    __tree_const_iterator& operator--() {
933*4d6fc14bSjoerg      __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
934*4d6fc14bSjoerg          static_cast<__end_node_pointer>(__ptr_)));
935*4d6fc14bSjoerg      return *this;
936*4d6fc14bSjoerg    }
937*4d6fc14bSjoerg
938*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
939*4d6fc14bSjoerg    __tree_const_iterator operator--(int)
940*4d6fc14bSjoerg        {__tree_const_iterator __t(*this); --(*this); return __t;}
941*4d6fc14bSjoerg
942*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
943*4d6fc14bSjoerg        bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
944*4d6fc14bSjoerg        {return __x.__ptr_ == __y.__ptr_;}
945*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
946*4d6fc14bSjoerg        bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
947*4d6fc14bSjoerg        {return !(__x == __y);}
948*4d6fc14bSjoerg
949*4d6fc14bSjoergprivate:
950*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
951*4d6fc14bSjoerg    explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
952*4d6fc14bSjoerg        : __ptr_(__p) {}
953*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
954*4d6fc14bSjoerg    explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
955*4d6fc14bSjoerg        : __ptr_(__p) {}
956*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
957*4d6fc14bSjoerg    __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
958*4d6fc14bSjoerg
959*4d6fc14bSjoerg    template <class, class, class> friend class __tree;
960*4d6fc14bSjoerg    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
961*4d6fc14bSjoerg    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
962*4d6fc14bSjoerg    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
963*4d6fc14bSjoerg    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
964*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
965*4d6fc14bSjoerg
966*4d6fc14bSjoerg};
967*4d6fc14bSjoerg
968*4d6fc14bSjoergtemplate<class _Tp, class _Compare>
969*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
970*4d6fc14bSjoerg    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
971*4d6fc14bSjoerg        "the specified comparator type does not provide a viable const call operator")
972*4d6fc14bSjoerg#endif
973*4d6fc14bSjoergint __diagnose_non_const_comparator();
974*4d6fc14bSjoerg
975*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
976*4d6fc14bSjoergclass __tree
977*4d6fc14bSjoerg{
978*4d6fc14bSjoergpublic:
979*4d6fc14bSjoerg    typedef _Tp                                      value_type;
980*4d6fc14bSjoerg    typedef _Compare                                 value_compare;
981*4d6fc14bSjoerg    typedef _Allocator                               allocator_type;
982*4d6fc14bSjoerg
983*4d6fc14bSjoergprivate:
984*4d6fc14bSjoerg    typedef allocator_traits<allocator_type>         __alloc_traits;
985*4d6fc14bSjoerg    typedef typename __make_tree_node_types<value_type,
986*4d6fc14bSjoerg        typename __alloc_traits::void_pointer>::type
987*4d6fc14bSjoerg                                                    _NodeTypes;
988*4d6fc14bSjoerg    typedef typename _NodeTypes::key_type           key_type;
989*4d6fc14bSjoergpublic:
990*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type      __node_value_type;
991*4d6fc14bSjoerg    typedef typename _NodeTypes::__container_value_type __container_value_type;
992*4d6fc14bSjoerg
993*4d6fc14bSjoerg    typedef typename __alloc_traits::pointer         pointer;
994*4d6fc14bSjoerg    typedef typename __alloc_traits::const_pointer   const_pointer;
995*4d6fc14bSjoerg    typedef typename __alloc_traits::size_type       size_type;
996*4d6fc14bSjoerg    typedef typename __alloc_traits::difference_type difference_type;
997*4d6fc14bSjoerg
998*4d6fc14bSjoergpublic:
999*4d6fc14bSjoerg    typedef typename _NodeTypes::__void_pointer        __void_pointer;
1000*4d6fc14bSjoerg
1001*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_type           __node;
1002*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_pointer        __node_pointer;
1003*4d6fc14bSjoerg
1004*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_base_type      __node_base;
1005*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_base_pointer   __node_base_pointer;
1006*4d6fc14bSjoerg
1007*4d6fc14bSjoerg    typedef typename _NodeTypes::__end_node_type       __end_node_t;
1008*4d6fc14bSjoerg    typedef typename _NodeTypes::__end_node_pointer    __end_node_ptr;
1009*4d6fc14bSjoerg
1010*4d6fc14bSjoerg    typedef typename _NodeTypes::__parent_pointer      __parent_pointer;
1011*4d6fc14bSjoerg    typedef typename _NodeTypes::__iter_pointer        __iter_pointer;
1012*4d6fc14bSjoerg
1013*4d6fc14bSjoerg    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
1014*4d6fc14bSjoerg    typedef allocator_traits<__node_allocator>         __node_traits;
1015*4d6fc14bSjoerg
1016*4d6fc14bSjoergprivate:
1017*4d6fc14bSjoerg    // check for sane allocator pointer rebinding semantics. Rebinding the
1018*4d6fc14bSjoerg    // allocator for a new pointer type should be exactly the same as rebinding
1019*4d6fc14bSjoerg    // the pointer using 'pointer_traits'.
1020*4d6fc14bSjoerg    static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1021*4d6fc14bSjoerg                  "Allocator does not rebind pointers in a sane manner.");
1022*4d6fc14bSjoerg    typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1023*4d6fc14bSjoerg        __node_base_allocator;
1024*4d6fc14bSjoerg    typedef allocator_traits<__node_base_allocator> __node_base_traits;
1025*4d6fc14bSjoerg    static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1026*4d6fc14bSjoerg                 "Allocator does not rebind pointers in a sane manner.");
1027*4d6fc14bSjoerg
1028*4d6fc14bSjoergprivate:
1029*4d6fc14bSjoerg    __iter_pointer                                     __begin_node_;
1030*4d6fc14bSjoerg    __compressed_pair<__end_node_t, __node_allocator>  __pair1_;
1031*4d6fc14bSjoerg    __compressed_pair<size_type, value_compare>        __pair3_;
1032*4d6fc14bSjoerg
1033*4d6fc14bSjoergpublic:
1034*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1035*4d6fc14bSjoerg    __iter_pointer __end_node() _NOEXCEPT
1036*4d6fc14bSjoerg    {
1037*4d6fc14bSjoerg        return static_cast<__iter_pointer>(
1038*4d6fc14bSjoerg                pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
1039*4d6fc14bSjoerg        );
1040*4d6fc14bSjoerg    }
1041*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1042*4d6fc14bSjoerg    __iter_pointer __end_node() const _NOEXCEPT
1043*4d6fc14bSjoerg    {
1044*4d6fc14bSjoerg        return static_cast<__iter_pointer>(
1045*4d6fc14bSjoerg            pointer_traits<__end_node_ptr>::pointer_to(
1046*4d6fc14bSjoerg                const_cast<__end_node_t&>(__pair1_.first())
1047*4d6fc14bSjoerg            )
1048*4d6fc14bSjoerg        );
1049*4d6fc14bSjoerg    }
1050*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1051*4d6fc14bSjoerg          __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
1052*4d6fc14bSjoergprivate:
1053*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1054*4d6fc14bSjoerg    const __node_allocator& __node_alloc() const _NOEXCEPT
1055*4d6fc14bSjoerg        {return __pair1_.second();}
1056*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1057*4d6fc14bSjoerg          __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
1058*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1059*4d6fc14bSjoerg    const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
1060*4d6fc14bSjoergpublic:
1061*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1062*4d6fc14bSjoerg    allocator_type __alloc() const _NOEXCEPT
1063*4d6fc14bSjoerg        {return allocator_type(__node_alloc());}
1064*4d6fc14bSjoergprivate:
1065*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1066*4d6fc14bSjoerg          size_type& size() _NOEXCEPT {return __pair3_.first();}
1067*4d6fc14bSjoergpublic:
1068*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1069*4d6fc14bSjoerg    const size_type& size() const _NOEXCEPT {return __pair3_.first();}
1070*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1071*4d6fc14bSjoerg          value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
1072*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1073*4d6fc14bSjoerg    const value_compare& value_comp() const _NOEXCEPT
1074*4d6fc14bSjoerg        {return __pair3_.second();}
1075*4d6fc14bSjoergpublic:
1076*4d6fc14bSjoerg
1077*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1078*4d6fc14bSjoerg    __node_pointer __root() const _NOEXCEPT
1079*4d6fc14bSjoerg        {return static_cast<__node_pointer>(__end_node()->__left_);}
1080*4d6fc14bSjoerg
1081*4d6fc14bSjoerg    __node_base_pointer* __root_ptr() const _NOEXCEPT {
1082*4d6fc14bSjoerg        return _VSTD::addressof(__end_node()->__left_);
1083*4d6fc14bSjoerg    }
1084*4d6fc14bSjoerg
1085*4d6fc14bSjoerg    typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
1086*4d6fc14bSjoerg    typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
1087*4d6fc14bSjoerg
1088*4d6fc14bSjoerg    explicit __tree(const value_compare& __comp)
1089*4d6fc14bSjoerg        _NOEXCEPT_(
1090*4d6fc14bSjoerg            is_nothrow_default_constructible<__node_allocator>::value &&
1091*4d6fc14bSjoerg            is_nothrow_copy_constructible<value_compare>::value);
1092*4d6fc14bSjoerg    explicit __tree(const allocator_type& __a);
1093*4d6fc14bSjoerg    __tree(const value_compare& __comp, const allocator_type& __a);
1094*4d6fc14bSjoerg    __tree(const __tree& __t);
1095*4d6fc14bSjoerg    __tree& operator=(const __tree& __t);
1096*4d6fc14bSjoerg    template <class _ForwardIterator>
1097*4d6fc14bSjoerg        void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
1098*4d6fc14bSjoerg    template <class _InputIterator>
1099*4d6fc14bSjoerg        void __assign_multi(_InputIterator __first, _InputIterator __last);
1100*4d6fc14bSjoerg    __tree(__tree&& __t)
1101*4d6fc14bSjoerg        _NOEXCEPT_(
1102*4d6fc14bSjoerg            is_nothrow_move_constructible<__node_allocator>::value &&
1103*4d6fc14bSjoerg            is_nothrow_move_constructible<value_compare>::value);
1104*4d6fc14bSjoerg    __tree(__tree&& __t, const allocator_type& __a);
1105*4d6fc14bSjoerg    __tree& operator=(__tree&& __t)
1106*4d6fc14bSjoerg        _NOEXCEPT_(
1107*4d6fc14bSjoerg            __node_traits::propagate_on_container_move_assignment::value &&
1108*4d6fc14bSjoerg            is_nothrow_move_assignable<value_compare>::value &&
1109*4d6fc14bSjoerg            is_nothrow_move_assignable<__node_allocator>::value);
1110*4d6fc14bSjoerg    ~__tree();
1111*4d6fc14bSjoerg
1112*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1113*4d6fc14bSjoerg          iterator begin()  _NOEXCEPT {return       iterator(__begin_node());}
1114*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1115*4d6fc14bSjoerg    const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
1116*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1117*4d6fc14bSjoerg          iterator end() _NOEXCEPT {return       iterator(__end_node());}
1118*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1119*4d6fc14bSjoerg    const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
1120*4d6fc14bSjoerg
1121*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1122*4d6fc14bSjoerg    size_type max_size() const _NOEXCEPT
1123*4d6fc14bSjoerg        {return _VSTD::min<size_type>(
1124*4d6fc14bSjoerg                __node_traits::max_size(__node_alloc()),
1125*4d6fc14bSjoerg                numeric_limits<difference_type >::max());}
1126*4d6fc14bSjoerg
1127*4d6fc14bSjoerg    void clear() _NOEXCEPT;
1128*4d6fc14bSjoerg
1129*4d6fc14bSjoerg    void swap(__tree& __t)
1130*4d6fc14bSjoerg#if _LIBCPP_STD_VER <= 11
1131*4d6fc14bSjoerg        _NOEXCEPT_(
1132*4d6fc14bSjoerg            __is_nothrow_swappable<value_compare>::value
1133*4d6fc14bSjoerg            && (!__node_traits::propagate_on_container_swap::value ||
1134*4d6fc14bSjoerg                 __is_nothrow_swappable<__node_allocator>::value)
1135*4d6fc14bSjoerg            );
1136*4d6fc14bSjoerg#else
1137*4d6fc14bSjoerg        _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1138*4d6fc14bSjoerg#endif
1139*4d6fc14bSjoerg
1140*4d6fc14bSjoerg    template <class _Key, class ..._Args>
1141*4d6fc14bSjoerg    pair<iterator, bool>
1142*4d6fc14bSjoerg    __emplace_unique_key_args(_Key const&, _Args&&... __args);
1143*4d6fc14bSjoerg    template <class _Key, class ..._Args>
1144*4d6fc14bSjoerg    pair<iterator, bool>
1145*4d6fc14bSjoerg    __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
1146*4d6fc14bSjoerg
1147*4d6fc14bSjoerg    template <class... _Args>
1148*4d6fc14bSjoerg    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
1149*4d6fc14bSjoerg
1150*4d6fc14bSjoerg    template <class... _Args>
1151*4d6fc14bSjoerg    iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
1152*4d6fc14bSjoerg
1153*4d6fc14bSjoerg    template <class... _Args>
1154*4d6fc14bSjoerg    iterator __emplace_multi(_Args&&... __args);
1155*4d6fc14bSjoerg
1156*4d6fc14bSjoerg    template <class... _Args>
1157*4d6fc14bSjoerg    iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
1158*4d6fc14bSjoerg
1159*4d6fc14bSjoerg    template <class _Pp>
1160*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1161*4d6fc14bSjoerg    pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1162*4d6fc14bSjoerg        return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1163*4d6fc14bSjoerg                                            __can_extract_key<_Pp, key_type>());
1164*4d6fc14bSjoerg    }
1165*4d6fc14bSjoerg
1166*4d6fc14bSjoerg    template <class _First, class _Second>
1167*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1168*4d6fc14bSjoerg    typename enable_if<
1169*4d6fc14bSjoerg        __can_extract_map_key<_First, key_type, __container_value_type>::value,
1170*4d6fc14bSjoerg        pair<iterator, bool>
1171*4d6fc14bSjoerg    >::type __emplace_unique(_First&& __f, _Second&& __s) {
1172*4d6fc14bSjoerg        return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1173*4d6fc14bSjoerg                                              _VSTD::forward<_Second>(__s));
1174*4d6fc14bSjoerg    }
1175*4d6fc14bSjoerg
1176*4d6fc14bSjoerg    template <class... _Args>
1177*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1178*4d6fc14bSjoerg    pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1179*4d6fc14bSjoerg        return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1180*4d6fc14bSjoerg    }
1181*4d6fc14bSjoerg
1182*4d6fc14bSjoerg    template <class _Pp>
1183*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1184*4d6fc14bSjoerg    pair<iterator, bool>
1185*4d6fc14bSjoerg    __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1186*4d6fc14bSjoerg      return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1187*4d6fc14bSjoerg    }
1188*4d6fc14bSjoerg
1189*4d6fc14bSjoerg    template <class _Pp>
1190*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1191*4d6fc14bSjoerg    pair<iterator, bool>
1192*4d6fc14bSjoerg    __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1193*4d6fc14bSjoerg      return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1194*4d6fc14bSjoerg    }
1195*4d6fc14bSjoerg
1196*4d6fc14bSjoerg    template <class _Pp>
1197*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1198*4d6fc14bSjoerg    pair<iterator, bool>
1199*4d6fc14bSjoerg    __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1200*4d6fc14bSjoerg      return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1201*4d6fc14bSjoerg    }
1202*4d6fc14bSjoerg
1203*4d6fc14bSjoerg    template <class _Pp>
1204*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1205*4d6fc14bSjoerg    iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1206*4d6fc14bSjoerg        return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1207*4d6fc14bSjoerg                                            __can_extract_key<_Pp, key_type>());
1208*4d6fc14bSjoerg    }
1209*4d6fc14bSjoerg
1210*4d6fc14bSjoerg    template <class _First, class _Second>
1211*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1212*4d6fc14bSjoerg    typename enable_if<
1213*4d6fc14bSjoerg        __can_extract_map_key<_First, key_type, __container_value_type>::value,
1214*4d6fc14bSjoerg        iterator
1215*4d6fc14bSjoerg    >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
1216*4d6fc14bSjoerg        return __emplace_hint_unique_key_args(__p, __f,
1217*4d6fc14bSjoerg                                              _VSTD::forward<_First>(__f),
1218*4d6fc14bSjoerg                                              _VSTD::forward<_Second>(__s)).first;
1219*4d6fc14bSjoerg    }
1220*4d6fc14bSjoerg
1221*4d6fc14bSjoerg    template <class... _Args>
1222*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1223*4d6fc14bSjoerg    iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1224*4d6fc14bSjoerg        return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1225*4d6fc14bSjoerg    }
1226*4d6fc14bSjoerg
1227*4d6fc14bSjoerg    template <class _Pp>
1228*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1229*4d6fc14bSjoerg    iterator
1230*4d6fc14bSjoerg    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1231*4d6fc14bSjoerg      return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
1232*4d6fc14bSjoerg    }
1233*4d6fc14bSjoerg
1234*4d6fc14bSjoerg    template <class _Pp>
1235*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1236*4d6fc14bSjoerg    iterator
1237*4d6fc14bSjoerg    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1238*4d6fc14bSjoerg      return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)).first;
1239*4d6fc14bSjoerg    }
1240*4d6fc14bSjoerg
1241*4d6fc14bSjoerg    template <class _Pp>
1242*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1243*4d6fc14bSjoerg    iterator
1244*4d6fc14bSjoerg    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1245*4d6fc14bSjoerg      return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)).first;
1246*4d6fc14bSjoerg    }
1247*4d6fc14bSjoerg
1248*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1249*4d6fc14bSjoerg    pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
1250*4d6fc14bSjoerg        return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
1251*4d6fc14bSjoerg    }
1252*4d6fc14bSjoerg
1253*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1254*4d6fc14bSjoerg    iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
1255*4d6fc14bSjoerg        return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v).first;
1256*4d6fc14bSjoerg    }
1257*4d6fc14bSjoerg
1258*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1259*4d6fc14bSjoerg    pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
1260*4d6fc14bSjoerg        return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
1261*4d6fc14bSjoerg    }
1262*4d6fc14bSjoerg
1263*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1264*4d6fc14bSjoerg    iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
1265*4d6fc14bSjoerg        return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)).first;
1266*4d6fc14bSjoerg    }
1267*4d6fc14bSjoerg
1268*4d6fc14bSjoerg    template <class _Vp, class = typename enable_if<
1269*4d6fc14bSjoerg            !is_same<typename __unconstref<_Vp>::type,
1270*4d6fc14bSjoerg                     __container_value_type
1271*4d6fc14bSjoerg            >::value
1272*4d6fc14bSjoerg        >::type>
1273*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1274*4d6fc14bSjoerg    pair<iterator, bool> __insert_unique(_Vp&& __v) {
1275*4d6fc14bSjoerg        return __emplace_unique(_VSTD::forward<_Vp>(__v));
1276*4d6fc14bSjoerg    }
1277*4d6fc14bSjoerg
1278*4d6fc14bSjoerg    template <class _Vp, class = typename enable_if<
1279*4d6fc14bSjoerg            !is_same<typename __unconstref<_Vp>::type,
1280*4d6fc14bSjoerg                     __container_value_type
1281*4d6fc14bSjoerg            >::value
1282*4d6fc14bSjoerg        >::type>
1283*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1284*4d6fc14bSjoerg    iterator __insert_unique(const_iterator __p, _Vp&& __v) {
1285*4d6fc14bSjoerg        return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
1286*4d6fc14bSjoerg    }
1287*4d6fc14bSjoerg
1288*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1289*4d6fc14bSjoerg    iterator __insert_multi(__container_value_type&& __v) {
1290*4d6fc14bSjoerg        return __emplace_multi(_VSTD::move(__v));
1291*4d6fc14bSjoerg    }
1292*4d6fc14bSjoerg
1293*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1294*4d6fc14bSjoerg    iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
1295*4d6fc14bSjoerg        return __emplace_hint_multi(__p, _VSTD::move(__v));
1296*4d6fc14bSjoerg    }
1297*4d6fc14bSjoerg
1298*4d6fc14bSjoerg    template <class _Vp>
1299*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1300*4d6fc14bSjoerg    iterator __insert_multi(_Vp&& __v) {
1301*4d6fc14bSjoerg        return __emplace_multi(_VSTD::forward<_Vp>(__v));
1302*4d6fc14bSjoerg    }
1303*4d6fc14bSjoerg
1304*4d6fc14bSjoerg    template <class _Vp>
1305*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1306*4d6fc14bSjoerg    iterator __insert_multi(const_iterator __p, _Vp&& __v) {
1307*4d6fc14bSjoerg        return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
1308*4d6fc14bSjoerg    }
1309*4d6fc14bSjoerg
1310*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1311*4d6fc14bSjoerg    pair<iterator, bool> __node_assign_unique(const __container_value_type& __v, __node_pointer __dest);
1312*4d6fc14bSjoerg
1313*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1314*4d6fc14bSjoerg    iterator __node_insert_multi(__node_pointer __nd);
1315*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1316*4d6fc14bSjoerg    iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1317*4d6fc14bSjoerg
1318*4d6fc14bSjoerg
1319*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY iterator
1320*4d6fc14bSjoerg    __remove_node_pointer(__node_pointer) _NOEXCEPT;
1321*4d6fc14bSjoerg
1322*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14
1323*4d6fc14bSjoerg    template <class _NodeHandle, class _InsertReturnType>
1324*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1325*4d6fc14bSjoerg    _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
1326*4d6fc14bSjoerg    template <class _NodeHandle>
1327*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1328*4d6fc14bSjoerg    iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
1329*4d6fc14bSjoerg    template <class _Tree>
1330*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1331*4d6fc14bSjoerg    void __node_handle_merge_unique(_Tree& __source);
1332*4d6fc14bSjoerg
1333*4d6fc14bSjoerg    template <class _NodeHandle>
1334*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1335*4d6fc14bSjoerg    iterator __node_handle_insert_multi(_NodeHandle&&);
1336*4d6fc14bSjoerg    template <class _NodeHandle>
1337*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1338*4d6fc14bSjoerg    iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
1339*4d6fc14bSjoerg    template <class _Tree>
1340*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1341*4d6fc14bSjoerg    void __node_handle_merge_multi(_Tree& __source);
1342*4d6fc14bSjoerg
1343*4d6fc14bSjoerg
1344*4d6fc14bSjoerg    template <class _NodeHandle>
1345*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1346*4d6fc14bSjoerg    _NodeHandle __node_handle_extract(key_type const&);
1347*4d6fc14bSjoerg    template <class _NodeHandle>
1348*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1349*4d6fc14bSjoerg    _NodeHandle __node_handle_extract(const_iterator);
1350*4d6fc14bSjoerg#endif
1351*4d6fc14bSjoerg
1352*4d6fc14bSjoerg    iterator erase(const_iterator __p);
1353*4d6fc14bSjoerg    iterator erase(const_iterator __f, const_iterator __l);
1354*4d6fc14bSjoerg    template <class _Key>
1355*4d6fc14bSjoerg        size_type __erase_unique(const _Key& __k);
1356*4d6fc14bSjoerg    template <class _Key>
1357*4d6fc14bSjoerg        size_type __erase_multi(const _Key& __k);
1358*4d6fc14bSjoerg
1359*4d6fc14bSjoerg    void __insert_node_at(__parent_pointer     __parent,
1360*4d6fc14bSjoerg                          __node_base_pointer& __child,
1361*4d6fc14bSjoerg                          __node_base_pointer __new_node) _NOEXCEPT;
1362*4d6fc14bSjoerg
1363*4d6fc14bSjoerg    template <class _Key>
1364*4d6fc14bSjoerg        iterator find(const _Key& __v);
1365*4d6fc14bSjoerg    template <class _Key>
1366*4d6fc14bSjoerg        const_iterator find(const _Key& __v) const;
1367*4d6fc14bSjoerg
1368*4d6fc14bSjoerg    template <class _Key>
1369*4d6fc14bSjoerg        size_type __count_unique(const _Key& __k) const;
1370*4d6fc14bSjoerg    template <class _Key>
1371*4d6fc14bSjoerg        size_type __count_multi(const _Key& __k) const;
1372*4d6fc14bSjoerg
1373*4d6fc14bSjoerg    template <class _Key>
1374*4d6fc14bSjoerg        _LIBCPP_INLINE_VISIBILITY
1375*4d6fc14bSjoerg        iterator lower_bound(const _Key& __v)
1376*4d6fc14bSjoerg            {return __lower_bound(__v, __root(), __end_node());}
1377*4d6fc14bSjoerg    template <class _Key>
1378*4d6fc14bSjoerg        iterator __lower_bound(const _Key& __v,
1379*4d6fc14bSjoerg                               __node_pointer __root,
1380*4d6fc14bSjoerg                               __iter_pointer __result);
1381*4d6fc14bSjoerg    template <class _Key>
1382*4d6fc14bSjoerg        _LIBCPP_INLINE_VISIBILITY
1383*4d6fc14bSjoerg        const_iterator lower_bound(const _Key& __v) const
1384*4d6fc14bSjoerg            {return __lower_bound(__v, __root(), __end_node());}
1385*4d6fc14bSjoerg    template <class _Key>
1386*4d6fc14bSjoerg        const_iterator __lower_bound(const _Key& __v,
1387*4d6fc14bSjoerg                                     __node_pointer __root,
1388*4d6fc14bSjoerg                                     __iter_pointer __result) const;
1389*4d6fc14bSjoerg    template <class _Key>
1390*4d6fc14bSjoerg        _LIBCPP_INLINE_VISIBILITY
1391*4d6fc14bSjoerg        iterator upper_bound(const _Key& __v)
1392*4d6fc14bSjoerg            {return __upper_bound(__v, __root(), __end_node());}
1393*4d6fc14bSjoerg    template <class _Key>
1394*4d6fc14bSjoerg        iterator __upper_bound(const _Key& __v,
1395*4d6fc14bSjoerg                               __node_pointer __root,
1396*4d6fc14bSjoerg                               __iter_pointer __result);
1397*4d6fc14bSjoerg    template <class _Key>
1398*4d6fc14bSjoerg        _LIBCPP_INLINE_VISIBILITY
1399*4d6fc14bSjoerg        const_iterator upper_bound(const _Key& __v) const
1400*4d6fc14bSjoerg            {return __upper_bound(__v, __root(), __end_node());}
1401*4d6fc14bSjoerg    template <class _Key>
1402*4d6fc14bSjoerg        const_iterator __upper_bound(const _Key& __v,
1403*4d6fc14bSjoerg                                     __node_pointer __root,
1404*4d6fc14bSjoerg                                     __iter_pointer __result) const;
1405*4d6fc14bSjoerg    template <class _Key>
1406*4d6fc14bSjoerg        pair<iterator, iterator>
1407*4d6fc14bSjoerg        __equal_range_unique(const _Key& __k);
1408*4d6fc14bSjoerg    template <class _Key>
1409*4d6fc14bSjoerg        pair<const_iterator, const_iterator>
1410*4d6fc14bSjoerg        __equal_range_unique(const _Key& __k) const;
1411*4d6fc14bSjoerg
1412*4d6fc14bSjoerg    template <class _Key>
1413*4d6fc14bSjoerg        pair<iterator, iterator>
1414*4d6fc14bSjoerg        __equal_range_multi(const _Key& __k);
1415*4d6fc14bSjoerg    template <class _Key>
1416*4d6fc14bSjoerg        pair<const_iterator, const_iterator>
1417*4d6fc14bSjoerg        __equal_range_multi(const _Key& __k) const;
1418*4d6fc14bSjoerg
1419*4d6fc14bSjoerg    typedef __tree_node_destructor<__node_allocator> _Dp;
1420*4d6fc14bSjoerg    typedef unique_ptr<__node, _Dp> __node_holder;
1421*4d6fc14bSjoerg
1422*4d6fc14bSjoerg    __node_holder remove(const_iterator __p) _NOEXCEPT;
1423*4d6fc14bSjoergprivate:
1424*4d6fc14bSjoerg    __node_base_pointer&
1425*4d6fc14bSjoerg        __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1426*4d6fc14bSjoerg    __node_base_pointer&
1427*4d6fc14bSjoerg        __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1428*4d6fc14bSjoerg    __node_base_pointer&
1429*4d6fc14bSjoerg        __find_leaf(const_iterator __hint,
1430*4d6fc14bSjoerg                    __parent_pointer& __parent, const key_type& __v);
1431*4d6fc14bSjoerg    // FIXME: Make this function const qualified. Unfortunately doing so
1432*4d6fc14bSjoerg    // breaks existing code which uses non-const callable comparators.
1433*4d6fc14bSjoerg    template <class _Key>
1434*4d6fc14bSjoerg    __node_base_pointer&
1435*4d6fc14bSjoerg        __find_equal(__parent_pointer& __parent, const _Key& __v);
1436*4d6fc14bSjoerg    template <class _Key>
1437*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1438*4d6fc14bSjoerg    __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1439*4d6fc14bSjoerg      return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1440*4d6fc14bSjoerg    }
1441*4d6fc14bSjoerg    template <class _Key>
1442*4d6fc14bSjoerg    __node_base_pointer&
1443*4d6fc14bSjoerg        __find_equal(const_iterator __hint, __parent_pointer& __parent,
1444*4d6fc14bSjoerg                     __node_base_pointer& __dummy,
1445*4d6fc14bSjoerg                     const _Key& __v);
1446*4d6fc14bSjoerg
1447*4d6fc14bSjoerg    template <class ..._Args>
1448*4d6fc14bSjoerg    __node_holder __construct_node(_Args&& ...__args);
1449*4d6fc14bSjoerg
1450*4d6fc14bSjoerg    void destroy(__node_pointer __nd) _NOEXCEPT;
1451*4d6fc14bSjoerg
1452*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1453*4d6fc14bSjoerg    void __copy_assign_alloc(const __tree& __t)
1454*4d6fc14bSjoerg        {__copy_assign_alloc(__t, integral_constant<bool,
1455*4d6fc14bSjoerg             __node_traits::propagate_on_container_copy_assignment::value>());}
1456*4d6fc14bSjoerg
1457*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1458*4d6fc14bSjoerg    void __copy_assign_alloc(const __tree& __t, true_type)
1459*4d6fc14bSjoerg        {
1460*4d6fc14bSjoerg        if (__node_alloc() != __t.__node_alloc())
1461*4d6fc14bSjoerg            clear();
1462*4d6fc14bSjoerg        __node_alloc() = __t.__node_alloc();
1463*4d6fc14bSjoerg        }
1464*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1465*4d6fc14bSjoerg    void __copy_assign_alloc(const __tree&, false_type) {}
1466*4d6fc14bSjoerg
1467*4d6fc14bSjoerg    void __move_assign(__tree& __t, false_type);
1468*4d6fc14bSjoerg    void __move_assign(__tree& __t, true_type)
1469*4d6fc14bSjoerg        _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1470*4d6fc14bSjoerg                   is_nothrow_move_assignable<__node_allocator>::value);
1471*4d6fc14bSjoerg
1472*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1473*4d6fc14bSjoerg    void __move_assign_alloc(__tree& __t)
1474*4d6fc14bSjoerg        _NOEXCEPT_(
1475*4d6fc14bSjoerg            !__node_traits::propagate_on_container_move_assignment::value ||
1476*4d6fc14bSjoerg            is_nothrow_move_assignable<__node_allocator>::value)
1477*4d6fc14bSjoerg        {__move_assign_alloc(__t, integral_constant<bool,
1478*4d6fc14bSjoerg             __node_traits::propagate_on_container_move_assignment::value>());}
1479*4d6fc14bSjoerg
1480*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1481*4d6fc14bSjoerg    void __move_assign_alloc(__tree& __t, true_type)
1482*4d6fc14bSjoerg        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
1483*4d6fc14bSjoerg        {__node_alloc() = _VSTD::move(__t.__node_alloc());}
1484*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1485*4d6fc14bSjoerg    void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
1486*4d6fc14bSjoerg
1487*4d6fc14bSjoerg    struct _DetachedTreeCache {
1488*4d6fc14bSjoerg      _LIBCPP_INLINE_VISIBILITY
1489*4d6fc14bSjoerg      explicit _DetachedTreeCache(__tree *__t) _NOEXCEPT : __t_(__t),
1490*4d6fc14bSjoerg        __cache_root_(__detach_from_tree(__t)) {
1491*4d6fc14bSjoerg          __advance();
1492*4d6fc14bSjoerg        }
1493*4d6fc14bSjoerg
1494*4d6fc14bSjoerg      _LIBCPP_INLINE_VISIBILITY
1495*4d6fc14bSjoerg      __node_pointer __get() const _NOEXCEPT {
1496*4d6fc14bSjoerg        return __cache_elem_;
1497*4d6fc14bSjoerg      }
1498*4d6fc14bSjoerg
1499*4d6fc14bSjoerg      _LIBCPP_INLINE_VISIBILITY
1500*4d6fc14bSjoerg      void __advance() _NOEXCEPT {
1501*4d6fc14bSjoerg        __cache_elem_ = __cache_root_;
1502*4d6fc14bSjoerg        if (__cache_root_) {
1503*4d6fc14bSjoerg          __cache_root_ = __detach_next(__cache_root_);
1504*4d6fc14bSjoerg        }
1505*4d6fc14bSjoerg      }
1506*4d6fc14bSjoerg
1507*4d6fc14bSjoerg      _LIBCPP_INLINE_VISIBILITY
1508*4d6fc14bSjoerg      ~_DetachedTreeCache() {
1509*4d6fc14bSjoerg        __t_->destroy(__cache_elem_);
1510*4d6fc14bSjoerg        if (__cache_root_) {
1511*4d6fc14bSjoerg          while (__cache_root_->__parent_ != nullptr)
1512*4d6fc14bSjoerg            __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_);
1513*4d6fc14bSjoerg          __t_->destroy(__cache_root_);
1514*4d6fc14bSjoerg        }
1515*4d6fc14bSjoerg      }
1516*4d6fc14bSjoerg
1517*4d6fc14bSjoerg       _DetachedTreeCache(_DetachedTreeCache const&) = delete;
1518*4d6fc14bSjoerg       _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete;
1519*4d6fc14bSjoerg
1520*4d6fc14bSjoerg    private:
1521*4d6fc14bSjoerg      _LIBCPP_INLINE_VISIBILITY
1522*4d6fc14bSjoerg      static __node_pointer __detach_from_tree(__tree *__t) _NOEXCEPT;
1523*4d6fc14bSjoerg      _LIBCPP_INLINE_VISIBILITY
1524*4d6fc14bSjoerg      static __node_pointer __detach_next(__node_pointer) _NOEXCEPT;
1525*4d6fc14bSjoerg
1526*4d6fc14bSjoerg      __tree *__t_;
1527*4d6fc14bSjoerg      __node_pointer __cache_root_;
1528*4d6fc14bSjoerg      __node_pointer __cache_elem_;
1529*4d6fc14bSjoerg    };
1530*4d6fc14bSjoerg
1531*4d6fc14bSjoerg
1532*4d6fc14bSjoerg    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1533*4d6fc14bSjoerg    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
1534*4d6fc14bSjoerg};
1535*4d6fc14bSjoerg
1536*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1537*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
1538*4d6fc14bSjoerg        _NOEXCEPT_(
1539*4d6fc14bSjoerg            is_nothrow_default_constructible<__node_allocator>::value &&
1540*4d6fc14bSjoerg            is_nothrow_copy_constructible<value_compare>::value)
1541*4d6fc14bSjoerg    : __pair3_(0, __comp)
1542*4d6fc14bSjoerg{
1543*4d6fc14bSjoerg    __begin_node() = __end_node();
1544*4d6fc14bSjoerg}
1545*4d6fc14bSjoerg
1546*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1547*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
1548*4d6fc14bSjoerg    : __begin_node_(__iter_pointer()),
1549*4d6fc14bSjoerg      __pair1_(__default_init_tag(), __node_allocator(__a)),
1550*4d6fc14bSjoerg      __pair3_(0, __default_init_tag())
1551*4d6fc14bSjoerg{
1552*4d6fc14bSjoerg    __begin_node() = __end_node();
1553*4d6fc14bSjoerg}
1554*4d6fc14bSjoerg
1555*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1556*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1557*4d6fc14bSjoerg                                           const allocator_type& __a)
1558*4d6fc14bSjoerg    : __begin_node_(__iter_pointer()),
1559*4d6fc14bSjoerg      __pair1_(__default_init_tag(), __node_allocator(__a)),
1560*4d6fc14bSjoerg      __pair3_(0, __comp)
1561*4d6fc14bSjoerg{
1562*4d6fc14bSjoerg    __begin_node() = __end_node();
1563*4d6fc14bSjoerg}
1564*4d6fc14bSjoerg
1565*4d6fc14bSjoerg// Precondition:  size() != 0
1566*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1567*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1568*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree *__t) _NOEXCEPT
1569*4d6fc14bSjoerg{
1570*4d6fc14bSjoerg    __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node());
1571*4d6fc14bSjoerg    __t->__begin_node() = __t->__end_node();
1572*4d6fc14bSjoerg    __t->__end_node()->__left_->__parent_ = nullptr;
1573*4d6fc14bSjoerg    __t->__end_node()->__left_ = nullptr;
1574*4d6fc14bSjoerg    __t->size() = 0;
1575*4d6fc14bSjoerg    // __cache->__left_ == nullptr
1576*4d6fc14bSjoerg    if (__cache->__right_ != nullptr)
1577*4d6fc14bSjoerg        __cache = static_cast<__node_pointer>(__cache->__right_);
1578*4d6fc14bSjoerg    // __cache->__left_ == nullptr
1579*4d6fc14bSjoerg    // __cache->__right_ == nullptr
1580*4d6fc14bSjoerg    return __cache;
1581*4d6fc14bSjoerg}
1582*4d6fc14bSjoerg
1583*4d6fc14bSjoerg// Precondition:  __cache != nullptr
1584*4d6fc14bSjoerg//    __cache->left_ == nullptr
1585*4d6fc14bSjoerg//    __cache->right_ == nullptr
1586*4d6fc14bSjoerg//    This is no longer a red-black tree
1587*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1588*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1589*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT
1590*4d6fc14bSjoerg{
1591*4d6fc14bSjoerg    if (__cache->__parent_ == nullptr)
1592*4d6fc14bSjoerg        return nullptr;
1593*4d6fc14bSjoerg    if (_VSTD::__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
1594*4d6fc14bSjoerg    {
1595*4d6fc14bSjoerg        __cache->__parent_->__left_ = nullptr;
1596*4d6fc14bSjoerg        __cache = static_cast<__node_pointer>(__cache->__parent_);
1597*4d6fc14bSjoerg        if (__cache->__right_ == nullptr)
1598*4d6fc14bSjoerg            return __cache;
1599*4d6fc14bSjoerg        return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__right_));
1600*4d6fc14bSjoerg    }
1601*4d6fc14bSjoerg    // __cache is right child
1602*4d6fc14bSjoerg    __cache->__parent_unsafe()->__right_ = nullptr;
1603*4d6fc14bSjoerg    __cache = static_cast<__node_pointer>(__cache->__parent_);
1604*4d6fc14bSjoerg    if (__cache->__left_ == nullptr)
1605*4d6fc14bSjoerg        return __cache;
1606*4d6fc14bSjoerg    return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__left_));
1607*4d6fc14bSjoerg}
1608*4d6fc14bSjoerg
1609*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1610*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>&
1611*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1612*4d6fc14bSjoerg{
1613*4d6fc14bSjoerg    if (this != &__t)
1614*4d6fc14bSjoerg    {
1615*4d6fc14bSjoerg        value_comp() = __t.value_comp();
1616*4d6fc14bSjoerg        __copy_assign_alloc(__t);
1617*4d6fc14bSjoerg        __assign_multi(__t.begin(), __t.end());
1618*4d6fc14bSjoerg    }
1619*4d6fc14bSjoerg    return *this;
1620*4d6fc14bSjoerg}
1621*4d6fc14bSjoerg
1622*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1623*4d6fc14bSjoergtemplate <class _ForwardIterator>
1624*4d6fc14bSjoergvoid
1625*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last)
1626*4d6fc14bSjoerg{
1627*4d6fc14bSjoerg    typedef iterator_traits<_ForwardIterator> _ITraits;
1628*4d6fc14bSjoerg    typedef typename _ITraits::value_type _ItValueType;
1629*4d6fc14bSjoerg    static_assert((is_same<_ItValueType, __container_value_type>::value),
1630*4d6fc14bSjoerg                  "__assign_unique may only be called with the containers value type");
1631*4d6fc14bSjoerg    static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
1632*4d6fc14bSjoerg                  "__assign_unique requires a forward iterator");
1633*4d6fc14bSjoerg    if (size() != 0)
1634*4d6fc14bSjoerg    {
1635*4d6fc14bSjoerg        _DetachedTreeCache __cache(this);
1636*4d6fc14bSjoerg          for (; __cache.__get() != nullptr && __first != __last; ++__first) {
1637*4d6fc14bSjoerg              if (__node_assign_unique(*__first, __cache.__get()).second)
1638*4d6fc14bSjoerg                  __cache.__advance();
1639*4d6fc14bSjoerg            }
1640*4d6fc14bSjoerg    }
1641*4d6fc14bSjoerg    for (; __first != __last; ++__first)
1642*4d6fc14bSjoerg        __insert_unique(*__first);
1643*4d6fc14bSjoerg}
1644*4d6fc14bSjoerg
1645*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1646*4d6fc14bSjoergtemplate <class _InputIterator>
1647*4d6fc14bSjoergvoid
1648*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1649*4d6fc14bSjoerg{
1650*4d6fc14bSjoerg    typedef iterator_traits<_InputIterator> _ITraits;
1651*4d6fc14bSjoerg    typedef typename _ITraits::value_type _ItValueType;
1652*4d6fc14bSjoerg    static_assert((is_same<_ItValueType, __container_value_type>::value ||
1653*4d6fc14bSjoerg                  is_same<_ItValueType, __node_value_type>::value),
1654*4d6fc14bSjoerg                  "__assign_multi may only be called with the containers value type"
1655*4d6fc14bSjoerg                  " or the nodes value type");
1656*4d6fc14bSjoerg    if (size() != 0)
1657*4d6fc14bSjoerg    {
1658*4d6fc14bSjoerg        _DetachedTreeCache __cache(this);
1659*4d6fc14bSjoerg        for (; __cache.__get() && __first != __last; ++__first) {
1660*4d6fc14bSjoerg            __cache.__get()->__value_ = *__first;
1661*4d6fc14bSjoerg            __node_insert_multi(__cache.__get());
1662*4d6fc14bSjoerg            __cache.__advance();
1663*4d6fc14bSjoerg        }
1664*4d6fc14bSjoerg    }
1665*4d6fc14bSjoerg    for (; __first != __last; ++__first)
1666*4d6fc14bSjoerg        __insert_multi(_NodeTypes::__get_value(*__first));
1667*4d6fc14bSjoerg}
1668*4d6fc14bSjoerg
1669*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1670*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
1671*4d6fc14bSjoerg    : __begin_node_(__iter_pointer()),
1672*4d6fc14bSjoerg      __pair1_(__default_init_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())),
1673*4d6fc14bSjoerg      __pair3_(0, __t.value_comp())
1674*4d6fc14bSjoerg{
1675*4d6fc14bSjoerg    __begin_node() = __end_node();
1676*4d6fc14bSjoerg}
1677*4d6fc14bSjoerg
1678*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1679*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
1680*4d6fc14bSjoerg    _NOEXCEPT_(
1681*4d6fc14bSjoerg        is_nothrow_move_constructible<__node_allocator>::value &&
1682*4d6fc14bSjoerg        is_nothrow_move_constructible<value_compare>::value)
1683*4d6fc14bSjoerg    : __begin_node_(_VSTD::move(__t.__begin_node_)),
1684*4d6fc14bSjoerg      __pair1_(_VSTD::move(__t.__pair1_)),
1685*4d6fc14bSjoerg      __pair3_(_VSTD::move(__t.__pair3_))
1686*4d6fc14bSjoerg{
1687*4d6fc14bSjoerg    if (size() == 0)
1688*4d6fc14bSjoerg        __begin_node() = __end_node();
1689*4d6fc14bSjoerg    else
1690*4d6fc14bSjoerg    {
1691*4d6fc14bSjoerg        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
1692*4d6fc14bSjoerg        __t.__begin_node() = __t.__end_node();
1693*4d6fc14bSjoerg        __t.__end_node()->__left_ = nullptr;
1694*4d6fc14bSjoerg        __t.size() = 0;
1695*4d6fc14bSjoerg    }
1696*4d6fc14bSjoerg}
1697*4d6fc14bSjoerg
1698*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1699*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1700*4d6fc14bSjoerg    : __pair1_(__default_init_tag(), __node_allocator(__a)),
1701*4d6fc14bSjoerg      __pair3_(0, _VSTD::move(__t.value_comp()))
1702*4d6fc14bSjoerg{
1703*4d6fc14bSjoerg    if (__a == __t.__alloc())
1704*4d6fc14bSjoerg    {
1705*4d6fc14bSjoerg        if (__t.size() == 0)
1706*4d6fc14bSjoerg            __begin_node() = __end_node();
1707*4d6fc14bSjoerg        else
1708*4d6fc14bSjoerg        {
1709*4d6fc14bSjoerg            __begin_node() = __t.__begin_node();
1710*4d6fc14bSjoerg            __end_node()->__left_ = __t.__end_node()->__left_;
1711*4d6fc14bSjoerg            __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
1712*4d6fc14bSjoerg            size() = __t.size();
1713*4d6fc14bSjoerg            __t.__begin_node() = __t.__end_node();
1714*4d6fc14bSjoerg            __t.__end_node()->__left_ = nullptr;
1715*4d6fc14bSjoerg            __t.size() = 0;
1716*4d6fc14bSjoerg        }
1717*4d6fc14bSjoerg    }
1718*4d6fc14bSjoerg    else
1719*4d6fc14bSjoerg    {
1720*4d6fc14bSjoerg        __begin_node() = __end_node();
1721*4d6fc14bSjoerg    }
1722*4d6fc14bSjoerg}
1723*4d6fc14bSjoerg
1724*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1725*4d6fc14bSjoergvoid
1726*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
1727*4d6fc14bSjoerg    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1728*4d6fc14bSjoerg               is_nothrow_move_assignable<__node_allocator>::value)
1729*4d6fc14bSjoerg{
1730*4d6fc14bSjoerg    destroy(static_cast<__node_pointer>(__end_node()->__left_));
1731*4d6fc14bSjoerg    __begin_node_ = __t.__begin_node_;
1732*4d6fc14bSjoerg    __pair1_.first() = __t.__pair1_.first();
1733*4d6fc14bSjoerg    __move_assign_alloc(__t);
1734*4d6fc14bSjoerg    __pair3_ = _VSTD::move(__t.__pair3_);
1735*4d6fc14bSjoerg    if (size() == 0)
1736*4d6fc14bSjoerg        __begin_node() = __end_node();
1737*4d6fc14bSjoerg    else
1738*4d6fc14bSjoerg    {
1739*4d6fc14bSjoerg        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
1740*4d6fc14bSjoerg        __t.__begin_node() = __t.__end_node();
1741*4d6fc14bSjoerg        __t.__end_node()->__left_ = nullptr;
1742*4d6fc14bSjoerg        __t.size() = 0;
1743*4d6fc14bSjoerg    }
1744*4d6fc14bSjoerg}
1745*4d6fc14bSjoerg
1746*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1747*4d6fc14bSjoergvoid
1748*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1749*4d6fc14bSjoerg{
1750*4d6fc14bSjoerg    if (__node_alloc() == __t.__node_alloc())
1751*4d6fc14bSjoerg        __move_assign(__t, true_type());
1752*4d6fc14bSjoerg    else
1753*4d6fc14bSjoerg    {
1754*4d6fc14bSjoerg        value_comp() = _VSTD::move(__t.value_comp());
1755*4d6fc14bSjoerg        const_iterator __e = end();
1756*4d6fc14bSjoerg        if (size() != 0)
1757*4d6fc14bSjoerg        {
1758*4d6fc14bSjoerg            _DetachedTreeCache __cache(this);
1759*4d6fc14bSjoerg            while (__cache.__get() != nullptr && __t.size() != 0) {
1760*4d6fc14bSjoerg              __cache.__get()->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
1761*4d6fc14bSjoerg              __node_insert_multi(__cache.__get());
1762*4d6fc14bSjoerg              __cache.__advance();
1763*4d6fc14bSjoerg            }
1764*4d6fc14bSjoerg        }
1765*4d6fc14bSjoerg        while (__t.size() != 0)
1766*4d6fc14bSjoerg            __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
1767*4d6fc14bSjoerg    }
1768*4d6fc14bSjoerg}
1769*4d6fc14bSjoerg
1770*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1771*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>&
1772*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
1773*4d6fc14bSjoerg    _NOEXCEPT_(
1774*4d6fc14bSjoerg        __node_traits::propagate_on_container_move_assignment::value &&
1775*4d6fc14bSjoerg        is_nothrow_move_assignable<value_compare>::value &&
1776*4d6fc14bSjoerg        is_nothrow_move_assignable<__node_allocator>::value)
1777*4d6fc14bSjoerg
1778*4d6fc14bSjoerg{
1779*4d6fc14bSjoerg    __move_assign(__t, integral_constant<bool,
1780*4d6fc14bSjoerg                  __node_traits::propagate_on_container_move_assignment::value>());
1781*4d6fc14bSjoerg    return *this;
1782*4d6fc14bSjoerg}
1783*4d6fc14bSjoerg
1784*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1785*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::~__tree()
1786*4d6fc14bSjoerg{
1787*4d6fc14bSjoerg    static_assert((is_copy_constructible<value_compare>::value),
1788*4d6fc14bSjoerg                 "Comparator must be copy-constructible.");
1789*4d6fc14bSjoerg  destroy(__root());
1790*4d6fc14bSjoerg}
1791*4d6fc14bSjoerg
1792*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1793*4d6fc14bSjoergvoid
1794*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
1795*4d6fc14bSjoerg{
1796*4d6fc14bSjoerg    if (__nd != nullptr)
1797*4d6fc14bSjoerg    {
1798*4d6fc14bSjoerg        destroy(static_cast<__node_pointer>(__nd->__left_));
1799*4d6fc14bSjoerg        destroy(static_cast<__node_pointer>(__nd->__right_));
1800*4d6fc14bSjoerg        __node_allocator& __na = __node_alloc();
1801*4d6fc14bSjoerg        __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
1802*4d6fc14bSjoerg        __node_traits::deallocate(__na, __nd, 1);
1803*4d6fc14bSjoerg    }
1804*4d6fc14bSjoerg}
1805*4d6fc14bSjoerg
1806*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1807*4d6fc14bSjoergvoid
1808*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
1809*4d6fc14bSjoerg#if _LIBCPP_STD_VER <= 11
1810*4d6fc14bSjoerg        _NOEXCEPT_(
1811*4d6fc14bSjoerg            __is_nothrow_swappable<value_compare>::value
1812*4d6fc14bSjoerg            && (!__node_traits::propagate_on_container_swap::value ||
1813*4d6fc14bSjoerg                 __is_nothrow_swappable<__node_allocator>::value)
1814*4d6fc14bSjoerg            )
1815*4d6fc14bSjoerg#else
1816*4d6fc14bSjoerg        _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1817*4d6fc14bSjoerg#endif
1818*4d6fc14bSjoerg{
1819*4d6fc14bSjoerg    using _VSTD::swap;
1820*4d6fc14bSjoerg    swap(__begin_node_, __t.__begin_node_);
1821*4d6fc14bSjoerg    swap(__pair1_.first(), __t.__pair1_.first());
1822*4d6fc14bSjoerg    _VSTD::__swap_allocator(__node_alloc(), __t.__node_alloc());
1823*4d6fc14bSjoerg    __pair3_.swap(__t.__pair3_);
1824*4d6fc14bSjoerg    if (size() == 0)
1825*4d6fc14bSjoerg        __begin_node() = __end_node();
1826*4d6fc14bSjoerg    else
1827*4d6fc14bSjoerg        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
1828*4d6fc14bSjoerg    if (__t.size() == 0)
1829*4d6fc14bSjoerg        __t.__begin_node() = __t.__end_node();
1830*4d6fc14bSjoerg    else
1831*4d6fc14bSjoerg        __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
1832*4d6fc14bSjoerg}
1833*4d6fc14bSjoerg
1834*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1835*4d6fc14bSjoergvoid
1836*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
1837*4d6fc14bSjoerg{
1838*4d6fc14bSjoerg    destroy(__root());
1839*4d6fc14bSjoerg    size() = 0;
1840*4d6fc14bSjoerg    __begin_node() = __end_node();
1841*4d6fc14bSjoerg    __end_node()->__left_ = nullptr;
1842*4d6fc14bSjoerg}
1843*4d6fc14bSjoerg
1844*4d6fc14bSjoerg// Find lower_bound place to insert
1845*4d6fc14bSjoerg// Set __parent to parent of null leaf
1846*4d6fc14bSjoerg// Return reference to null leaf
1847*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1848*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1849*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
1850*4d6fc14bSjoerg                                                   const key_type& __v)
1851*4d6fc14bSjoerg{
1852*4d6fc14bSjoerg    __node_pointer __nd = __root();
1853*4d6fc14bSjoerg    if (__nd != nullptr)
1854*4d6fc14bSjoerg    {
1855*4d6fc14bSjoerg        while (true)
1856*4d6fc14bSjoerg        {
1857*4d6fc14bSjoerg            if (value_comp()(__nd->__value_, __v))
1858*4d6fc14bSjoerg            {
1859*4d6fc14bSjoerg                if (__nd->__right_ != nullptr)
1860*4d6fc14bSjoerg                    __nd = static_cast<__node_pointer>(__nd->__right_);
1861*4d6fc14bSjoerg                else
1862*4d6fc14bSjoerg                {
1863*4d6fc14bSjoerg                    __parent = static_cast<__parent_pointer>(__nd);
1864*4d6fc14bSjoerg                    return __nd->__right_;
1865*4d6fc14bSjoerg                }
1866*4d6fc14bSjoerg            }
1867*4d6fc14bSjoerg            else
1868*4d6fc14bSjoerg            {
1869*4d6fc14bSjoerg                if (__nd->__left_ != nullptr)
1870*4d6fc14bSjoerg                    __nd = static_cast<__node_pointer>(__nd->__left_);
1871*4d6fc14bSjoerg                else
1872*4d6fc14bSjoerg                {
1873*4d6fc14bSjoerg                    __parent = static_cast<__parent_pointer>(__nd);
1874*4d6fc14bSjoerg                    return __parent->__left_;
1875*4d6fc14bSjoerg                }
1876*4d6fc14bSjoerg            }
1877*4d6fc14bSjoerg        }
1878*4d6fc14bSjoerg    }
1879*4d6fc14bSjoerg    __parent = static_cast<__parent_pointer>(__end_node());
1880*4d6fc14bSjoerg    return __parent->__left_;
1881*4d6fc14bSjoerg}
1882*4d6fc14bSjoerg
1883*4d6fc14bSjoerg// Find upper_bound place to insert
1884*4d6fc14bSjoerg// Set __parent to parent of null leaf
1885*4d6fc14bSjoerg// Return reference to null leaf
1886*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1887*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1888*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
1889*4d6fc14bSjoerg                                                    const key_type& __v)
1890*4d6fc14bSjoerg{
1891*4d6fc14bSjoerg    __node_pointer __nd = __root();
1892*4d6fc14bSjoerg    if (__nd != nullptr)
1893*4d6fc14bSjoerg    {
1894*4d6fc14bSjoerg        while (true)
1895*4d6fc14bSjoerg        {
1896*4d6fc14bSjoerg            if (value_comp()(__v, __nd->__value_))
1897*4d6fc14bSjoerg            {
1898*4d6fc14bSjoerg                if (__nd->__left_ != nullptr)
1899*4d6fc14bSjoerg                    __nd = static_cast<__node_pointer>(__nd->__left_);
1900*4d6fc14bSjoerg                else
1901*4d6fc14bSjoerg                {
1902*4d6fc14bSjoerg                    __parent = static_cast<__parent_pointer>(__nd);
1903*4d6fc14bSjoerg                    return __parent->__left_;
1904*4d6fc14bSjoerg                }
1905*4d6fc14bSjoerg            }
1906*4d6fc14bSjoerg            else
1907*4d6fc14bSjoerg            {
1908*4d6fc14bSjoerg                if (__nd->__right_ != nullptr)
1909*4d6fc14bSjoerg                    __nd = static_cast<__node_pointer>(__nd->__right_);
1910*4d6fc14bSjoerg                else
1911*4d6fc14bSjoerg                {
1912*4d6fc14bSjoerg                    __parent = static_cast<__parent_pointer>(__nd);
1913*4d6fc14bSjoerg                    return __nd->__right_;
1914*4d6fc14bSjoerg                }
1915*4d6fc14bSjoerg            }
1916*4d6fc14bSjoerg        }
1917*4d6fc14bSjoerg    }
1918*4d6fc14bSjoerg    __parent = static_cast<__parent_pointer>(__end_node());
1919*4d6fc14bSjoerg    return __parent->__left_;
1920*4d6fc14bSjoerg}
1921*4d6fc14bSjoerg
1922*4d6fc14bSjoerg// Find leaf place to insert closest to __hint
1923*4d6fc14bSjoerg// First check prior to __hint.
1924*4d6fc14bSjoerg// Next check after __hint.
1925*4d6fc14bSjoerg// Next do O(log N) search.
1926*4d6fc14bSjoerg// Set __parent to parent of null leaf
1927*4d6fc14bSjoerg// Return reference to null leaf
1928*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1929*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1930*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
1931*4d6fc14bSjoerg                                               __parent_pointer& __parent,
1932*4d6fc14bSjoerg                                               const key_type& __v)
1933*4d6fc14bSjoerg{
1934*4d6fc14bSjoerg    if (__hint == end() || !value_comp()(*__hint, __v))  // check before
1935*4d6fc14bSjoerg    {
1936*4d6fc14bSjoerg        // __v <= *__hint
1937*4d6fc14bSjoerg        const_iterator __prior = __hint;
1938*4d6fc14bSjoerg        if (__prior == begin() || !value_comp()(__v, *--__prior))
1939*4d6fc14bSjoerg        {
1940*4d6fc14bSjoerg            // *prev(__hint) <= __v <= *__hint
1941*4d6fc14bSjoerg            if (__hint.__ptr_->__left_ == nullptr)
1942*4d6fc14bSjoerg            {
1943*4d6fc14bSjoerg                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
1944*4d6fc14bSjoerg                return __parent->__left_;
1945*4d6fc14bSjoerg            }
1946*4d6fc14bSjoerg            else
1947*4d6fc14bSjoerg            {
1948*4d6fc14bSjoerg                __parent = static_cast<__parent_pointer>(__prior.__ptr_);
1949*4d6fc14bSjoerg                return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
1950*4d6fc14bSjoerg            }
1951*4d6fc14bSjoerg        }
1952*4d6fc14bSjoerg        // __v < *prev(__hint)
1953*4d6fc14bSjoerg        return __find_leaf_high(__parent, __v);
1954*4d6fc14bSjoerg    }
1955*4d6fc14bSjoerg    // else __v > *__hint
1956*4d6fc14bSjoerg    return __find_leaf_low(__parent, __v);
1957*4d6fc14bSjoerg}
1958*4d6fc14bSjoerg
1959*4d6fc14bSjoerg// Find place to insert if __v doesn't exist
1960*4d6fc14bSjoerg// Set __parent to parent of null leaf
1961*4d6fc14bSjoerg// Return reference to null leaf
1962*4d6fc14bSjoerg// If __v exists, set parent to node of __v and return reference to node of __v
1963*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
1964*4d6fc14bSjoergtemplate <class _Key>
1965*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1966*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
1967*4d6fc14bSjoerg                                                const _Key& __v)
1968*4d6fc14bSjoerg{
1969*4d6fc14bSjoerg    __node_pointer __nd = __root();
1970*4d6fc14bSjoerg    __node_base_pointer* __nd_ptr = __root_ptr();
1971*4d6fc14bSjoerg    if (__nd != nullptr)
1972*4d6fc14bSjoerg    {
1973*4d6fc14bSjoerg        while (true)
1974*4d6fc14bSjoerg        {
1975*4d6fc14bSjoerg            if (value_comp()(__v, __nd->__value_))
1976*4d6fc14bSjoerg            {
1977*4d6fc14bSjoerg                if (__nd->__left_ != nullptr) {
1978*4d6fc14bSjoerg                    __nd_ptr = _VSTD::addressof(__nd->__left_);
1979*4d6fc14bSjoerg                    __nd = static_cast<__node_pointer>(__nd->__left_);
1980*4d6fc14bSjoerg                } else {
1981*4d6fc14bSjoerg                    __parent = static_cast<__parent_pointer>(__nd);
1982*4d6fc14bSjoerg                    return __parent->__left_;
1983*4d6fc14bSjoerg                }
1984*4d6fc14bSjoerg            }
1985*4d6fc14bSjoerg            else if (value_comp()(__nd->__value_, __v))
1986*4d6fc14bSjoerg            {
1987*4d6fc14bSjoerg                if (__nd->__right_ != nullptr) {
1988*4d6fc14bSjoerg                    __nd_ptr = _VSTD::addressof(__nd->__right_);
1989*4d6fc14bSjoerg                    __nd = static_cast<__node_pointer>(__nd->__right_);
1990*4d6fc14bSjoerg                } else {
1991*4d6fc14bSjoerg                    __parent = static_cast<__parent_pointer>(__nd);
1992*4d6fc14bSjoerg                    return __nd->__right_;
1993*4d6fc14bSjoerg                }
1994*4d6fc14bSjoerg            }
1995*4d6fc14bSjoerg            else
1996*4d6fc14bSjoerg            {
1997*4d6fc14bSjoerg                __parent = static_cast<__parent_pointer>(__nd);
1998*4d6fc14bSjoerg                return *__nd_ptr;
1999*4d6fc14bSjoerg            }
2000*4d6fc14bSjoerg        }
2001*4d6fc14bSjoerg    }
2002*4d6fc14bSjoerg    __parent = static_cast<__parent_pointer>(__end_node());
2003*4d6fc14bSjoerg    return __parent->__left_;
2004*4d6fc14bSjoerg}
2005*4d6fc14bSjoerg
2006*4d6fc14bSjoerg// Find place to insert if __v doesn't exist
2007*4d6fc14bSjoerg// First check prior to __hint.
2008*4d6fc14bSjoerg// Next check after __hint.
2009*4d6fc14bSjoerg// Next do O(log N) search.
2010*4d6fc14bSjoerg// Set __parent to parent of null leaf
2011*4d6fc14bSjoerg// Return reference to null leaf
2012*4d6fc14bSjoerg// If __v exists, set parent to node of __v and return reference to node of __v
2013*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2014*4d6fc14bSjoergtemplate <class _Key>
2015*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
2016*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
2017*4d6fc14bSjoerg                                                __parent_pointer& __parent,
2018*4d6fc14bSjoerg                                                __node_base_pointer& __dummy,
2019*4d6fc14bSjoerg                                                const _Key& __v)
2020*4d6fc14bSjoerg{
2021*4d6fc14bSjoerg    if (__hint == end() || value_comp()(__v, *__hint))  // check before
2022*4d6fc14bSjoerg    {
2023*4d6fc14bSjoerg        // __v < *__hint
2024*4d6fc14bSjoerg        const_iterator __prior = __hint;
2025*4d6fc14bSjoerg        if (__prior == begin() || value_comp()(*--__prior, __v))
2026*4d6fc14bSjoerg        {
2027*4d6fc14bSjoerg            // *prev(__hint) < __v < *__hint
2028*4d6fc14bSjoerg            if (__hint.__ptr_->__left_ == nullptr)
2029*4d6fc14bSjoerg            {
2030*4d6fc14bSjoerg                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2031*4d6fc14bSjoerg                return __parent->__left_;
2032*4d6fc14bSjoerg            }
2033*4d6fc14bSjoerg            else
2034*4d6fc14bSjoerg            {
2035*4d6fc14bSjoerg                __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2036*4d6fc14bSjoerg                return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
2037*4d6fc14bSjoerg            }
2038*4d6fc14bSjoerg        }
2039*4d6fc14bSjoerg        // __v <= *prev(__hint)
2040*4d6fc14bSjoerg        return __find_equal(__parent, __v);
2041*4d6fc14bSjoerg    }
2042*4d6fc14bSjoerg    else if (value_comp()(*__hint, __v))  // check after
2043*4d6fc14bSjoerg    {
2044*4d6fc14bSjoerg        // *__hint < __v
2045*4d6fc14bSjoerg        const_iterator __next = _VSTD::next(__hint);
2046*4d6fc14bSjoerg        if (__next == end() || value_comp()(__v, *__next))
2047*4d6fc14bSjoerg        {
2048*4d6fc14bSjoerg            // *__hint < __v < *_VSTD::next(__hint)
2049*4d6fc14bSjoerg            if (__hint.__get_np()->__right_ == nullptr)
2050*4d6fc14bSjoerg            {
2051*4d6fc14bSjoerg                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2052*4d6fc14bSjoerg                return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
2053*4d6fc14bSjoerg            }
2054*4d6fc14bSjoerg            else
2055*4d6fc14bSjoerg            {
2056*4d6fc14bSjoerg                __parent = static_cast<__parent_pointer>(__next.__ptr_);
2057*4d6fc14bSjoerg                return __parent->__left_;
2058*4d6fc14bSjoerg            }
2059*4d6fc14bSjoerg        }
2060*4d6fc14bSjoerg        // *next(__hint) <= __v
2061*4d6fc14bSjoerg        return __find_equal(__parent, __v);
2062*4d6fc14bSjoerg    }
2063*4d6fc14bSjoerg    // else __v == *__hint
2064*4d6fc14bSjoerg    __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2065*4d6fc14bSjoerg    __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2066*4d6fc14bSjoerg    return __dummy;
2067*4d6fc14bSjoerg}
2068*4d6fc14bSjoerg
2069*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2070*4d6fc14bSjoergvoid __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
2071*4d6fc14bSjoerg    __parent_pointer __parent, __node_base_pointer& __child,
2072*4d6fc14bSjoerg    __node_base_pointer __new_node) _NOEXCEPT
2073*4d6fc14bSjoerg{
2074*4d6fc14bSjoerg    __new_node->__left_   = nullptr;
2075*4d6fc14bSjoerg    __new_node->__right_  = nullptr;
2076*4d6fc14bSjoerg    __new_node->__parent_ = __parent;
2077*4d6fc14bSjoerg    // __new_node->__is_black_ is initialized in __tree_balance_after_insert
2078*4d6fc14bSjoerg    __child = __new_node;
2079*4d6fc14bSjoerg    if (__begin_node()->__left_ != nullptr)
2080*4d6fc14bSjoerg        __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
2081*4d6fc14bSjoerg    _VSTD::__tree_balance_after_insert(__end_node()->__left_, __child);
2082*4d6fc14bSjoerg    ++size();
2083*4d6fc14bSjoerg}
2084*4d6fc14bSjoerg
2085*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2086*4d6fc14bSjoergtemplate <class _Key, class... _Args>
2087*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2088*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
2089*4d6fc14bSjoerg{
2090*4d6fc14bSjoerg    __parent_pointer __parent;
2091*4d6fc14bSjoerg    __node_base_pointer& __child = __find_equal(__parent, __k);
2092*4d6fc14bSjoerg    __node_pointer __r = static_cast<__node_pointer>(__child);
2093*4d6fc14bSjoerg    bool __inserted = false;
2094*4d6fc14bSjoerg    if (__child == nullptr)
2095*4d6fc14bSjoerg    {
2096*4d6fc14bSjoerg        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2097*4d6fc14bSjoerg        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2098*4d6fc14bSjoerg        __r = __h.release();
2099*4d6fc14bSjoerg        __inserted = true;
2100*4d6fc14bSjoerg    }
2101*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__r), __inserted);
2102*4d6fc14bSjoerg}
2103*4d6fc14bSjoerg
2104*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2105*4d6fc14bSjoergtemplate <class _Key, class... _Args>
2106*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2107*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2108*4d6fc14bSjoerg    const_iterator __p, _Key const& __k, _Args&&... __args)
2109*4d6fc14bSjoerg{
2110*4d6fc14bSjoerg    __parent_pointer __parent;
2111*4d6fc14bSjoerg    __node_base_pointer __dummy;
2112*4d6fc14bSjoerg    __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
2113*4d6fc14bSjoerg    __node_pointer __r = static_cast<__node_pointer>(__child);
2114*4d6fc14bSjoerg    bool __inserted = false;
2115*4d6fc14bSjoerg    if (__child == nullptr)
2116*4d6fc14bSjoerg    {
2117*4d6fc14bSjoerg        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2118*4d6fc14bSjoerg        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2119*4d6fc14bSjoerg        __r = __h.release();
2120*4d6fc14bSjoerg        __inserted = true;
2121*4d6fc14bSjoerg    }
2122*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__r), __inserted);
2123*4d6fc14bSjoerg}
2124*4d6fc14bSjoerg
2125*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2126*4d6fc14bSjoergtemplate <class ..._Args>
2127*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_holder
2128*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
2129*4d6fc14bSjoerg{
2130*4d6fc14bSjoerg    static_assert(!__is_tree_value_type<_Args...>::value,
2131*4d6fc14bSjoerg                  "Cannot construct from __value_type");
2132*4d6fc14bSjoerg    __node_allocator& __na = __node_alloc();
2133*4d6fc14bSjoerg    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
2134*4d6fc14bSjoerg    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
2135*4d6fc14bSjoerg    __h.get_deleter().__value_constructed = true;
2136*4d6fc14bSjoerg    return __h;
2137*4d6fc14bSjoerg}
2138*4d6fc14bSjoerg
2139*4d6fc14bSjoerg
2140*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2141*4d6fc14bSjoergtemplate <class... _Args>
2142*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2143*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
2144*4d6fc14bSjoerg{
2145*4d6fc14bSjoerg    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2146*4d6fc14bSjoerg    __parent_pointer __parent;
2147*4d6fc14bSjoerg    __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
2148*4d6fc14bSjoerg    __node_pointer __r = static_cast<__node_pointer>(__child);
2149*4d6fc14bSjoerg    bool __inserted = false;
2150*4d6fc14bSjoerg    if (__child == nullptr)
2151*4d6fc14bSjoerg    {
2152*4d6fc14bSjoerg        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2153*4d6fc14bSjoerg        __r = __h.release();
2154*4d6fc14bSjoerg        __inserted = true;
2155*4d6fc14bSjoerg    }
2156*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__r), __inserted);
2157*4d6fc14bSjoerg}
2158*4d6fc14bSjoerg
2159*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2160*4d6fc14bSjoergtemplate <class... _Args>
2161*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2162*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
2163*4d6fc14bSjoerg{
2164*4d6fc14bSjoerg    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2165*4d6fc14bSjoerg    __parent_pointer __parent;
2166*4d6fc14bSjoerg    __node_base_pointer __dummy;
2167*4d6fc14bSjoerg    __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
2168*4d6fc14bSjoerg    __node_pointer __r = static_cast<__node_pointer>(__child);
2169*4d6fc14bSjoerg    if (__child == nullptr)
2170*4d6fc14bSjoerg    {
2171*4d6fc14bSjoerg        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2172*4d6fc14bSjoerg        __r = __h.release();
2173*4d6fc14bSjoerg    }
2174*4d6fc14bSjoerg    return iterator(__r);
2175*4d6fc14bSjoerg}
2176*4d6fc14bSjoerg
2177*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2178*4d6fc14bSjoergtemplate <class... _Args>
2179*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2180*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
2181*4d6fc14bSjoerg{
2182*4d6fc14bSjoerg    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2183*4d6fc14bSjoerg    __parent_pointer __parent;
2184*4d6fc14bSjoerg    __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
2185*4d6fc14bSjoerg    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2186*4d6fc14bSjoerg    return iterator(static_cast<__node_pointer>(__h.release()));
2187*4d6fc14bSjoerg}
2188*4d6fc14bSjoerg
2189*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2190*4d6fc14bSjoergtemplate <class... _Args>
2191*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2192*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
2193*4d6fc14bSjoerg                                                        _Args&&... __args)
2194*4d6fc14bSjoerg{
2195*4d6fc14bSjoerg    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2196*4d6fc14bSjoerg    __parent_pointer __parent;
2197*4d6fc14bSjoerg    __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
2198*4d6fc14bSjoerg    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2199*4d6fc14bSjoerg    return iterator(static_cast<__node_pointer>(__h.release()));
2200*4d6fc14bSjoerg}
2201*4d6fc14bSjoerg
2202*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2203*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2204*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_type& __v, __node_pointer __nd)
2205*4d6fc14bSjoerg{
2206*4d6fc14bSjoerg    __parent_pointer __parent;
2207*4d6fc14bSjoerg    __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__v));
2208*4d6fc14bSjoerg    __node_pointer __r = static_cast<__node_pointer>(__child);
2209*4d6fc14bSjoerg    bool __inserted = false;
2210*4d6fc14bSjoerg    if (__child == nullptr)
2211*4d6fc14bSjoerg    {
2212*4d6fc14bSjoerg        __nd->__value_ = __v;
2213*4d6fc14bSjoerg        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
2214*4d6fc14bSjoerg        __r = __nd;
2215*4d6fc14bSjoerg        __inserted = true;
2216*4d6fc14bSjoerg    }
2217*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__r), __inserted);
2218*4d6fc14bSjoerg}
2219*4d6fc14bSjoerg
2220*4d6fc14bSjoerg
2221*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2222*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2223*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
2224*4d6fc14bSjoerg{
2225*4d6fc14bSjoerg    __parent_pointer __parent;
2226*4d6fc14bSjoerg    __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
2227*4d6fc14bSjoerg    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
2228*4d6fc14bSjoerg    return iterator(__nd);
2229*4d6fc14bSjoerg}
2230*4d6fc14bSjoerg
2231*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2232*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2233*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
2234*4d6fc14bSjoerg                                                       __node_pointer __nd)
2235*4d6fc14bSjoerg{
2236*4d6fc14bSjoerg    __parent_pointer __parent;
2237*4d6fc14bSjoerg    __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
2238*4d6fc14bSjoerg    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
2239*4d6fc14bSjoerg    return iterator(__nd);
2240*4d6fc14bSjoerg}
2241*4d6fc14bSjoerg
2242*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2243*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2244*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
2245*4d6fc14bSjoerg{
2246*4d6fc14bSjoerg    iterator __r(__ptr);
2247*4d6fc14bSjoerg    ++__r;
2248*4d6fc14bSjoerg    if (__begin_node() == __ptr)
2249*4d6fc14bSjoerg        __begin_node() = __r.__ptr_;
2250*4d6fc14bSjoerg    --size();
2251*4d6fc14bSjoerg    _VSTD::__tree_remove(__end_node()->__left_,
2252*4d6fc14bSjoerg                         static_cast<__node_base_pointer>(__ptr));
2253*4d6fc14bSjoerg    return __r;
2254*4d6fc14bSjoerg}
2255*4d6fc14bSjoerg
2256*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14
2257*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2258*4d6fc14bSjoergtemplate <class _NodeHandle, class _InsertReturnType>
2259*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2260*4d6fc14bSjoerg_InsertReturnType
2261*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2262*4d6fc14bSjoerg    _NodeHandle&& __nh)
2263*4d6fc14bSjoerg{
2264*4d6fc14bSjoerg    if (__nh.empty())
2265*4d6fc14bSjoerg        return _InsertReturnType{end(), false, _NodeHandle()};
2266*4d6fc14bSjoerg
2267*4d6fc14bSjoerg    __node_pointer __ptr = __nh.__ptr_;
2268*4d6fc14bSjoerg    __parent_pointer __parent;
2269*4d6fc14bSjoerg    __node_base_pointer& __child = __find_equal(__parent,
2270*4d6fc14bSjoerg                                                __ptr->__value_);
2271*4d6fc14bSjoerg    if (__child != nullptr)
2272*4d6fc14bSjoerg        return _InsertReturnType{
2273*4d6fc14bSjoerg            iterator(static_cast<__node_pointer>(__child)),
2274*4d6fc14bSjoerg            false, _VSTD::move(__nh)};
2275*4d6fc14bSjoerg
2276*4d6fc14bSjoerg    __insert_node_at(__parent, __child,
2277*4d6fc14bSjoerg                     static_cast<__node_base_pointer>(__ptr));
2278*4d6fc14bSjoerg    __nh.__release_ptr();
2279*4d6fc14bSjoerg    return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
2280*4d6fc14bSjoerg}
2281*4d6fc14bSjoerg
2282*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2283*4d6fc14bSjoergtemplate <class _NodeHandle>
2284*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2285*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2286*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2287*4d6fc14bSjoerg    const_iterator __hint, _NodeHandle&& __nh)
2288*4d6fc14bSjoerg{
2289*4d6fc14bSjoerg    if (__nh.empty())
2290*4d6fc14bSjoerg        return end();
2291*4d6fc14bSjoerg
2292*4d6fc14bSjoerg    __node_pointer __ptr = __nh.__ptr_;
2293*4d6fc14bSjoerg    __parent_pointer __parent;
2294*4d6fc14bSjoerg    __node_base_pointer __dummy;
2295*4d6fc14bSjoerg    __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
2296*4d6fc14bSjoerg                                                __ptr->__value_);
2297*4d6fc14bSjoerg    __node_pointer __r = static_cast<__node_pointer>(__child);
2298*4d6fc14bSjoerg    if (__child == nullptr)
2299*4d6fc14bSjoerg    {
2300*4d6fc14bSjoerg        __insert_node_at(__parent, __child,
2301*4d6fc14bSjoerg                         static_cast<__node_base_pointer>(__ptr));
2302*4d6fc14bSjoerg        __r = __ptr;
2303*4d6fc14bSjoerg        __nh.__release_ptr();
2304*4d6fc14bSjoerg    }
2305*4d6fc14bSjoerg    return iterator(__r);
2306*4d6fc14bSjoerg}
2307*4d6fc14bSjoerg
2308*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2309*4d6fc14bSjoergtemplate <class _NodeHandle>
2310*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2311*4d6fc14bSjoerg_NodeHandle
2312*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
2313*4d6fc14bSjoerg{
2314*4d6fc14bSjoerg    iterator __it = find(__key);
2315*4d6fc14bSjoerg    if (__it == end())
2316*4d6fc14bSjoerg        return _NodeHandle();
2317*4d6fc14bSjoerg    return __node_handle_extract<_NodeHandle>(__it);
2318*4d6fc14bSjoerg}
2319*4d6fc14bSjoerg
2320*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2321*4d6fc14bSjoergtemplate <class _NodeHandle>
2322*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2323*4d6fc14bSjoerg_NodeHandle
2324*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
2325*4d6fc14bSjoerg{
2326*4d6fc14bSjoerg    __node_pointer __np = __p.__get_np();
2327*4d6fc14bSjoerg    __remove_node_pointer(__np);
2328*4d6fc14bSjoerg    return _NodeHandle(__np, __alloc());
2329*4d6fc14bSjoerg}
2330*4d6fc14bSjoerg
2331*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2332*4d6fc14bSjoergtemplate <class _Tree>
2333*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2334*4d6fc14bSjoergvoid
2335*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
2336*4d6fc14bSjoerg{
2337*4d6fc14bSjoerg    static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2338*4d6fc14bSjoerg
2339*4d6fc14bSjoerg    for (typename _Tree::iterator __i = __source.begin();
2340*4d6fc14bSjoerg         __i != __source.end();)
2341*4d6fc14bSjoerg    {
2342*4d6fc14bSjoerg        __node_pointer __src_ptr = __i.__get_np();
2343*4d6fc14bSjoerg        __parent_pointer __parent;
2344*4d6fc14bSjoerg        __node_base_pointer& __child =
2345*4d6fc14bSjoerg            __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
2346*4d6fc14bSjoerg        ++__i;
2347*4d6fc14bSjoerg        if (__child != nullptr)
2348*4d6fc14bSjoerg            continue;
2349*4d6fc14bSjoerg        __source.__remove_node_pointer(__src_ptr);
2350*4d6fc14bSjoerg        __insert_node_at(__parent, __child,
2351*4d6fc14bSjoerg                         static_cast<__node_base_pointer>(__src_ptr));
2352*4d6fc14bSjoerg    }
2353*4d6fc14bSjoerg}
2354*4d6fc14bSjoerg
2355*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2356*4d6fc14bSjoergtemplate <class _NodeHandle>
2357*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2358*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2359*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
2360*4d6fc14bSjoerg{
2361*4d6fc14bSjoerg    if (__nh.empty())
2362*4d6fc14bSjoerg        return end();
2363*4d6fc14bSjoerg    __node_pointer __ptr = __nh.__ptr_;
2364*4d6fc14bSjoerg    __parent_pointer __parent;
2365*4d6fc14bSjoerg    __node_base_pointer& __child = __find_leaf_high(
2366*4d6fc14bSjoerg        __parent, _NodeTypes::__get_key(__ptr->__value_));
2367*4d6fc14bSjoerg    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
2368*4d6fc14bSjoerg    __nh.__release_ptr();
2369*4d6fc14bSjoerg    return iterator(__ptr);
2370*4d6fc14bSjoerg}
2371*4d6fc14bSjoerg
2372*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2373*4d6fc14bSjoergtemplate <class _NodeHandle>
2374*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2375*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2376*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
2377*4d6fc14bSjoerg    const_iterator __hint, _NodeHandle&& __nh)
2378*4d6fc14bSjoerg{
2379*4d6fc14bSjoerg    if (__nh.empty())
2380*4d6fc14bSjoerg        return end();
2381*4d6fc14bSjoerg
2382*4d6fc14bSjoerg    __node_pointer __ptr = __nh.__ptr_;
2383*4d6fc14bSjoerg    __parent_pointer __parent;
2384*4d6fc14bSjoerg    __node_base_pointer& __child = __find_leaf(__hint, __parent,
2385*4d6fc14bSjoerg                                               _NodeTypes::__get_key(__ptr->__value_));
2386*4d6fc14bSjoerg    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
2387*4d6fc14bSjoerg    __nh.__release_ptr();
2388*4d6fc14bSjoerg    return iterator(__ptr);
2389*4d6fc14bSjoerg}
2390*4d6fc14bSjoerg
2391*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2392*4d6fc14bSjoergtemplate <class _Tree>
2393*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2394*4d6fc14bSjoergvoid
2395*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
2396*4d6fc14bSjoerg{
2397*4d6fc14bSjoerg    static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2398*4d6fc14bSjoerg
2399*4d6fc14bSjoerg    for (typename _Tree::iterator __i = __source.begin();
2400*4d6fc14bSjoerg         __i != __source.end();)
2401*4d6fc14bSjoerg    {
2402*4d6fc14bSjoerg        __node_pointer __src_ptr = __i.__get_np();
2403*4d6fc14bSjoerg        __parent_pointer __parent;
2404*4d6fc14bSjoerg        __node_base_pointer& __child = __find_leaf_high(
2405*4d6fc14bSjoerg            __parent, _NodeTypes::__get_key(__src_ptr->__value_));
2406*4d6fc14bSjoerg        ++__i;
2407*4d6fc14bSjoerg        __source.__remove_node_pointer(__src_ptr);
2408*4d6fc14bSjoerg        __insert_node_at(__parent, __child,
2409*4d6fc14bSjoerg                         static_cast<__node_base_pointer>(__src_ptr));
2410*4d6fc14bSjoerg    }
2411*4d6fc14bSjoerg}
2412*4d6fc14bSjoerg
2413*4d6fc14bSjoerg#endif // _LIBCPP_STD_VER > 14
2414*4d6fc14bSjoerg
2415*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2416*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2417*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
2418*4d6fc14bSjoerg{
2419*4d6fc14bSjoerg    __node_pointer __np = __p.__get_np();
2420*4d6fc14bSjoerg    iterator __r = __remove_node_pointer(__np);
2421*4d6fc14bSjoerg    __node_allocator& __na = __node_alloc();
2422*4d6fc14bSjoerg    __node_traits::destroy(__na, _NodeTypes::__get_ptr(
2423*4d6fc14bSjoerg        const_cast<__node_value_type&>(*__p)));
2424*4d6fc14bSjoerg    __node_traits::deallocate(__na, __np, 1);
2425*4d6fc14bSjoerg    return __r;
2426*4d6fc14bSjoerg}
2427*4d6fc14bSjoerg
2428*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2429*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2430*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
2431*4d6fc14bSjoerg{
2432*4d6fc14bSjoerg    while (__f != __l)
2433*4d6fc14bSjoerg        __f = erase(__f);
2434*4d6fc14bSjoerg    return iterator(__l.__ptr_);
2435*4d6fc14bSjoerg}
2436*4d6fc14bSjoerg
2437*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2438*4d6fc14bSjoergtemplate <class _Key>
2439*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::size_type
2440*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
2441*4d6fc14bSjoerg{
2442*4d6fc14bSjoerg    iterator __i = find(__k);
2443*4d6fc14bSjoerg    if (__i == end())
2444*4d6fc14bSjoerg        return 0;
2445*4d6fc14bSjoerg    erase(__i);
2446*4d6fc14bSjoerg    return 1;
2447*4d6fc14bSjoerg}
2448*4d6fc14bSjoerg
2449*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2450*4d6fc14bSjoergtemplate <class _Key>
2451*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::size_type
2452*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
2453*4d6fc14bSjoerg{
2454*4d6fc14bSjoerg    pair<iterator, iterator> __p = __equal_range_multi(__k);
2455*4d6fc14bSjoerg    size_type __r = 0;
2456*4d6fc14bSjoerg    for (; __p.first != __p.second; ++__r)
2457*4d6fc14bSjoerg        __p.first = erase(__p.first);
2458*4d6fc14bSjoerg    return __r;
2459*4d6fc14bSjoerg}
2460*4d6fc14bSjoerg
2461*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2462*4d6fc14bSjoergtemplate <class _Key>
2463*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2464*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
2465*4d6fc14bSjoerg{
2466*4d6fc14bSjoerg    iterator __p = __lower_bound(__v, __root(), __end_node());
2467*4d6fc14bSjoerg    if (__p != end() && !value_comp()(__v, *__p))
2468*4d6fc14bSjoerg        return __p;
2469*4d6fc14bSjoerg    return end();
2470*4d6fc14bSjoerg}
2471*4d6fc14bSjoerg
2472*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2473*4d6fc14bSjoergtemplate <class _Key>
2474*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::const_iterator
2475*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
2476*4d6fc14bSjoerg{
2477*4d6fc14bSjoerg    const_iterator __p = __lower_bound(__v, __root(), __end_node());
2478*4d6fc14bSjoerg    if (__p != end() && !value_comp()(__v, *__p))
2479*4d6fc14bSjoerg        return __p;
2480*4d6fc14bSjoerg    return end();
2481*4d6fc14bSjoerg}
2482*4d6fc14bSjoerg
2483*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2484*4d6fc14bSjoergtemplate <class _Key>
2485*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::size_type
2486*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
2487*4d6fc14bSjoerg{
2488*4d6fc14bSjoerg    __node_pointer __rt = __root();
2489*4d6fc14bSjoerg    while (__rt != nullptr)
2490*4d6fc14bSjoerg    {
2491*4d6fc14bSjoerg        if (value_comp()(__k, __rt->__value_))
2492*4d6fc14bSjoerg        {
2493*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__left_);
2494*4d6fc14bSjoerg        }
2495*4d6fc14bSjoerg        else if (value_comp()(__rt->__value_, __k))
2496*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__right_);
2497*4d6fc14bSjoerg        else
2498*4d6fc14bSjoerg            return 1;
2499*4d6fc14bSjoerg    }
2500*4d6fc14bSjoerg    return 0;
2501*4d6fc14bSjoerg}
2502*4d6fc14bSjoerg
2503*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2504*4d6fc14bSjoergtemplate <class _Key>
2505*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::size_type
2506*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
2507*4d6fc14bSjoerg{
2508*4d6fc14bSjoerg    __iter_pointer __result = __end_node();
2509*4d6fc14bSjoerg    __node_pointer __rt = __root();
2510*4d6fc14bSjoerg    while (__rt != nullptr)
2511*4d6fc14bSjoerg    {
2512*4d6fc14bSjoerg        if (value_comp()(__k, __rt->__value_))
2513*4d6fc14bSjoerg        {
2514*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__rt);
2515*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__left_);
2516*4d6fc14bSjoerg        }
2517*4d6fc14bSjoerg        else if (value_comp()(__rt->__value_, __k))
2518*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__right_);
2519*4d6fc14bSjoerg        else
2520*4d6fc14bSjoerg            return _VSTD::distance(
2521*4d6fc14bSjoerg                __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
2522*4d6fc14bSjoerg                __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
2523*4d6fc14bSjoerg            );
2524*4d6fc14bSjoerg    }
2525*4d6fc14bSjoerg    return 0;
2526*4d6fc14bSjoerg}
2527*4d6fc14bSjoerg
2528*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2529*4d6fc14bSjoergtemplate <class _Key>
2530*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2531*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2532*4d6fc14bSjoerg                                                 __node_pointer __root,
2533*4d6fc14bSjoerg                                                 __iter_pointer __result)
2534*4d6fc14bSjoerg{
2535*4d6fc14bSjoerg    while (__root != nullptr)
2536*4d6fc14bSjoerg    {
2537*4d6fc14bSjoerg        if (!value_comp()(__root->__value_, __v))
2538*4d6fc14bSjoerg        {
2539*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__root);
2540*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__left_);
2541*4d6fc14bSjoerg        }
2542*4d6fc14bSjoerg        else
2543*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__right_);
2544*4d6fc14bSjoerg    }
2545*4d6fc14bSjoerg    return iterator(__result);
2546*4d6fc14bSjoerg}
2547*4d6fc14bSjoerg
2548*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2549*4d6fc14bSjoergtemplate <class _Key>
2550*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::const_iterator
2551*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2552*4d6fc14bSjoerg                                                 __node_pointer __root,
2553*4d6fc14bSjoerg                                                 __iter_pointer __result) const
2554*4d6fc14bSjoerg{
2555*4d6fc14bSjoerg    while (__root != nullptr)
2556*4d6fc14bSjoerg    {
2557*4d6fc14bSjoerg        if (!value_comp()(__root->__value_, __v))
2558*4d6fc14bSjoerg        {
2559*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__root);
2560*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__left_);
2561*4d6fc14bSjoerg        }
2562*4d6fc14bSjoerg        else
2563*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__right_);
2564*4d6fc14bSjoerg    }
2565*4d6fc14bSjoerg    return const_iterator(__result);
2566*4d6fc14bSjoerg}
2567*4d6fc14bSjoerg
2568*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2569*4d6fc14bSjoergtemplate <class _Key>
2570*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::iterator
2571*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2572*4d6fc14bSjoerg                                                 __node_pointer __root,
2573*4d6fc14bSjoerg                                                 __iter_pointer __result)
2574*4d6fc14bSjoerg{
2575*4d6fc14bSjoerg    while (__root != nullptr)
2576*4d6fc14bSjoerg    {
2577*4d6fc14bSjoerg        if (value_comp()(__v, __root->__value_))
2578*4d6fc14bSjoerg        {
2579*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__root);
2580*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__left_);
2581*4d6fc14bSjoerg        }
2582*4d6fc14bSjoerg        else
2583*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__right_);
2584*4d6fc14bSjoerg    }
2585*4d6fc14bSjoerg    return iterator(__result);
2586*4d6fc14bSjoerg}
2587*4d6fc14bSjoerg
2588*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2589*4d6fc14bSjoergtemplate <class _Key>
2590*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::const_iterator
2591*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2592*4d6fc14bSjoerg                                                 __node_pointer __root,
2593*4d6fc14bSjoerg                                                 __iter_pointer __result) const
2594*4d6fc14bSjoerg{
2595*4d6fc14bSjoerg    while (__root != nullptr)
2596*4d6fc14bSjoerg    {
2597*4d6fc14bSjoerg        if (value_comp()(__v, __root->__value_))
2598*4d6fc14bSjoerg        {
2599*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__root);
2600*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__left_);
2601*4d6fc14bSjoerg        }
2602*4d6fc14bSjoerg        else
2603*4d6fc14bSjoerg            __root = static_cast<__node_pointer>(__root->__right_);
2604*4d6fc14bSjoerg    }
2605*4d6fc14bSjoerg    return const_iterator(__result);
2606*4d6fc14bSjoerg}
2607*4d6fc14bSjoerg
2608*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2609*4d6fc14bSjoergtemplate <class _Key>
2610*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2611*4d6fc14bSjoerg     typename __tree<_Tp, _Compare, _Allocator>::iterator>
2612*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2613*4d6fc14bSjoerg{
2614*4d6fc14bSjoerg    typedef pair<iterator, iterator> _Pp;
2615*4d6fc14bSjoerg    __iter_pointer __result = __end_node();
2616*4d6fc14bSjoerg    __node_pointer __rt = __root();
2617*4d6fc14bSjoerg    while (__rt != nullptr)
2618*4d6fc14bSjoerg    {
2619*4d6fc14bSjoerg        if (value_comp()(__k, __rt->__value_))
2620*4d6fc14bSjoerg        {
2621*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__rt);
2622*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__left_);
2623*4d6fc14bSjoerg        }
2624*4d6fc14bSjoerg        else if (value_comp()(__rt->__value_, __k))
2625*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__right_);
2626*4d6fc14bSjoerg        else
2627*4d6fc14bSjoerg            return _Pp(iterator(__rt),
2628*4d6fc14bSjoerg                      iterator(
2629*4d6fc14bSjoerg                          __rt->__right_ != nullptr ?
2630*4d6fc14bSjoerg                              static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
2631*4d6fc14bSjoerg                            : __result));
2632*4d6fc14bSjoerg    }
2633*4d6fc14bSjoerg    return _Pp(iterator(__result), iterator(__result));
2634*4d6fc14bSjoerg}
2635*4d6fc14bSjoerg
2636*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2637*4d6fc14bSjoergtemplate <class _Key>
2638*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2639*4d6fc14bSjoerg     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2640*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2641*4d6fc14bSjoerg{
2642*4d6fc14bSjoerg    typedef pair<const_iterator, const_iterator> _Pp;
2643*4d6fc14bSjoerg    __iter_pointer __result = __end_node();
2644*4d6fc14bSjoerg    __node_pointer __rt = __root();
2645*4d6fc14bSjoerg    while (__rt != nullptr)
2646*4d6fc14bSjoerg    {
2647*4d6fc14bSjoerg        if (value_comp()(__k, __rt->__value_))
2648*4d6fc14bSjoerg        {
2649*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__rt);
2650*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__left_);
2651*4d6fc14bSjoerg        }
2652*4d6fc14bSjoerg        else if (value_comp()(__rt->__value_, __k))
2653*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__right_);
2654*4d6fc14bSjoerg        else
2655*4d6fc14bSjoerg            return _Pp(const_iterator(__rt),
2656*4d6fc14bSjoerg                      const_iterator(
2657*4d6fc14bSjoerg                          __rt->__right_ != nullptr ?
2658*4d6fc14bSjoerg                              static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
2659*4d6fc14bSjoerg                            : __result));
2660*4d6fc14bSjoerg    }
2661*4d6fc14bSjoerg    return _Pp(const_iterator(__result), const_iterator(__result));
2662*4d6fc14bSjoerg}
2663*4d6fc14bSjoerg
2664*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2665*4d6fc14bSjoergtemplate <class _Key>
2666*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2667*4d6fc14bSjoerg     typename __tree<_Tp, _Compare, _Allocator>::iterator>
2668*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2669*4d6fc14bSjoerg{
2670*4d6fc14bSjoerg    typedef pair<iterator, iterator> _Pp;
2671*4d6fc14bSjoerg    __iter_pointer __result = __end_node();
2672*4d6fc14bSjoerg    __node_pointer __rt = __root();
2673*4d6fc14bSjoerg    while (__rt != nullptr)
2674*4d6fc14bSjoerg    {
2675*4d6fc14bSjoerg        if (value_comp()(__k, __rt->__value_))
2676*4d6fc14bSjoerg        {
2677*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__rt);
2678*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__left_);
2679*4d6fc14bSjoerg        }
2680*4d6fc14bSjoerg        else if (value_comp()(__rt->__value_, __k))
2681*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__right_);
2682*4d6fc14bSjoerg        else
2683*4d6fc14bSjoerg            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
2684*4d6fc14bSjoerg                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2685*4d6fc14bSjoerg    }
2686*4d6fc14bSjoerg    return _Pp(iterator(__result), iterator(__result));
2687*4d6fc14bSjoerg}
2688*4d6fc14bSjoerg
2689*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2690*4d6fc14bSjoergtemplate <class _Key>
2691*4d6fc14bSjoergpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2692*4d6fc14bSjoerg     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2693*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2694*4d6fc14bSjoerg{
2695*4d6fc14bSjoerg    typedef pair<const_iterator, const_iterator> _Pp;
2696*4d6fc14bSjoerg    __iter_pointer __result = __end_node();
2697*4d6fc14bSjoerg    __node_pointer __rt = __root();
2698*4d6fc14bSjoerg    while (__rt != nullptr)
2699*4d6fc14bSjoerg    {
2700*4d6fc14bSjoerg        if (value_comp()(__k, __rt->__value_))
2701*4d6fc14bSjoerg        {
2702*4d6fc14bSjoerg            __result = static_cast<__iter_pointer>(__rt);
2703*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__left_);
2704*4d6fc14bSjoerg        }
2705*4d6fc14bSjoerg        else if (value_comp()(__rt->__value_, __k))
2706*4d6fc14bSjoerg            __rt = static_cast<__node_pointer>(__rt->__right_);
2707*4d6fc14bSjoerg        else
2708*4d6fc14bSjoerg            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
2709*4d6fc14bSjoerg                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2710*4d6fc14bSjoerg    }
2711*4d6fc14bSjoerg    return _Pp(const_iterator(__result), const_iterator(__result));
2712*4d6fc14bSjoerg}
2713*4d6fc14bSjoerg
2714*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2715*4d6fc14bSjoergtypename __tree<_Tp, _Compare, _Allocator>::__node_holder
2716*4d6fc14bSjoerg__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
2717*4d6fc14bSjoerg{
2718*4d6fc14bSjoerg    __node_pointer __np = __p.__get_np();
2719*4d6fc14bSjoerg    if (__begin_node() == __p.__ptr_)
2720*4d6fc14bSjoerg    {
2721*4d6fc14bSjoerg        if (__np->__right_ != nullptr)
2722*4d6fc14bSjoerg            __begin_node() = static_cast<__iter_pointer>(__np->__right_);
2723*4d6fc14bSjoerg        else
2724*4d6fc14bSjoerg            __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
2725*4d6fc14bSjoerg    }
2726*4d6fc14bSjoerg    --size();
2727*4d6fc14bSjoerg    _VSTD::__tree_remove(__end_node()->__left_,
2728*4d6fc14bSjoerg                         static_cast<__node_base_pointer>(__np));
2729*4d6fc14bSjoerg    return __node_holder(__np, _Dp(__node_alloc(), true));
2730*4d6fc14bSjoerg}
2731*4d6fc14bSjoerg
2732*4d6fc14bSjoergtemplate <class _Tp, class _Compare, class _Allocator>
2733*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
2734*4d6fc14bSjoergvoid
2735*4d6fc14bSjoergswap(__tree<_Tp, _Compare, _Allocator>& __x,
2736*4d6fc14bSjoerg     __tree<_Tp, _Compare, _Allocator>& __y)
2737*4d6fc14bSjoerg    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2738*4d6fc14bSjoerg{
2739*4d6fc14bSjoerg    __x.swap(__y);
2740*4d6fc14bSjoerg}
2741*4d6fc14bSjoerg
2742*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD
2743*4d6fc14bSjoerg
2744*4d6fc14bSjoerg_LIBCPP_POP_MACROS
2745*4d6fc14bSjoerg
2746*4d6fc14bSjoerg#endif // _LIBCPP___TREE
2747