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