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