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