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