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