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