// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___TREE
#define _LIBCPP___TREE

#include <__algorithm/min.h>
#include <__assert>
#include <__config>
#include <__fwd/pair.h>
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
#include <__memory/addressof.h>
#include <__memory/allocator_traits.h>
#include <__memory/compressed_pair.h>
#include <__memory/construct_at.h>
#include <__memory/pointer_traits.h>
#include <__memory/swap_allocator.h>
#include <__memory/unique_ptr.h>
#include <__new/launder.h>
#include <__type_traits/copy_cvref.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/invoke.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_specialization.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/remove_const.h>
#include <__utility/forward.h>
#include <__utility/lazy_synth_three_way_comparator.h>
#include <__utility/move.h>
#include <__utility/pair.h>
#include <__utility/swap.h>
#include <__utility/try_key_extraction.h>
#include <limits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_DIAGNOSTIC_PUSH
// GCC complains about the backslashes at the end, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121528
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wcomment")
// __tree is a red-black-tree implementation used for the associative containers (i.e. (multi)map/set). It stores
// - (1) a pointer to the node with the smallest (i.e. leftmost) element, namely __begin_node_
// - (2) the number of nodes in the tree, namely __size_
// - (3) a pointer to the root of the tree, namely __end_node_
//
// Storing (1) and (2) is required to allow for constant time lookups. A tree looks like this in memory:
//
//      __end_node_
//           |
//          root
//         /    \
//       l1       r1
//      /  \     /  \
//    ...  ... ...  ...
//
// All nodes except __end_node_ have a __left_ and __right_ pointer as well as a __parent_ pointer.
// __end_node_ only contains a __left_ pointer, which points to the root of the tree.
// This layout allows for iteration through the tree without a need for special handling of the end node. See
// __tree_next_iter and __tree_prev_iter for more details.
_LIBCPP_DIAGNOSTIC_POP

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Pointer>
class __tree_end_node;
template <class _VoidPtr>
class __tree_node_base;
template <class _Tp, class _VoidPtr>
class __tree_node;

template <class _Key, class _Value>
struct __value_type;

/*

_NodePtr algorithms

The algorithms taking _NodePtr are red black tree algorithms.  Those
algorithms taking a parameter named __root should assume that __root
points to a proper red black tree (unless otherwise specified).

Each algorithm herein assumes that __root->__parent_ points to a non-null
structure which has a member __left_ which points back to __root.  No other
member is read or written to at __root->__parent_.

__root->__parent_ will be referred to below (in comments only) as end_node.
end_node->__left_ is an externably accessible lvalue for __root, and can be
changed by node insertion and removal (without explicit reference to end_node).

All nodes (with the exception of end_node), even the node referred to as
__root, have a non-null __parent_ field.

*/

// Returns:  true if __x is a left child of its parent, else false
// Precondition:  __x != nullptr.
template <class _NodePtr>
inline _LIBCPP_HIDE_FROM_ABI bool __tree_is_left_child(_NodePtr __x) _NOEXCEPT {
  return __x == __x->__parent_->__left_;
}

// Determines if the subtree rooted at __x is a proper red black subtree.  If
//    __x is a proper subtree, returns the black height (null counts as 1).  If
//    __x is an improper subtree, returns 0.
template <class _NodePtr>
unsigned __tree_sub_invariant(_NodePtr __x) {
  if (__x == nullptr)
    return 1;
  // parent consistency checked by caller
  // check __x->__left_ consistency
  if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
    return 0;
  // check __x->__right_ consistency
  if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
    return 0;
  // check __x->__left_ != __x->__right_ unless both are nullptr
  if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
    return 0;
  // If this is red, neither child can be red
  if (!__x->__is_black_) {
    if (__x->__left_ && !__x->__left_->__is_black_)
      return 0;
    if (__x->__right_ && !__x->__right_->__is_black_)
      return 0;
  }
  unsigned __h = std::__tree_sub_invariant(__x->__left_);
  if (__h == 0)
    return 0; // invalid left subtree
  if (__h != std::__tree_sub_invariant(__x->__right_))
    return 0;                    // invalid or different height right subtree
  return __h + __x->__is_black_; // return black height of this node
}

// Determines if the red black tree rooted at __root is a proper red black tree.
//    __root == nullptr is a proper tree.  Returns true if __root is a proper
//    red black tree, else returns false.
template <class _NodePtr>
_LIBCPP_HIDE_FROM_ABI bool __tree_invariant(_NodePtr __root) {
  if (__root == nullptr)
    return true;
  // check __x->__parent_ consistency
  if (__root->__parent_ == nullptr)
    return false;
  if (!std::__tree_is_left_child(__root))
    return false;
  // root must be black
  if (!__root->__is_black_)
    return false;
  // do normal node checks
  return std::__tree_sub_invariant(__root) != 0;
}

// Returns:  pointer to the left-most node under __x.
template <class _NodePtr>
inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_min(_NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
  while (__x->__left_ != nullptr)
    __x = __x->__left_;
  return __x;
}

// Returns:  pointer to the right-most node under __x.
template <class _NodePtr>
inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_max(_NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
  while (__x->__right_ != nullptr)
    __x = __x->__right_;
  return __x;
}

// Returns:  pointer to the next in-order node after __x.
template <class _NodePtr>
_LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
  if (__x->__right_ != nullptr)
    return std::__tree_min(__x->__right_);
  while (!std::__tree_is_left_child(__x))
    __x = __x->__parent_unsafe();
  return __x->__parent_unsafe();
}

// __tree_next_iter and __tree_prev_iter implement iteration through the tree. The order is as follows:
// left sub-tree -> node -> right sub-tree. When the right-most node of a sub-tree is reached, we walk up the tree until
// we find a node where we were in the left sub-tree. We are _always_ in a left sub-tree, since the __end_node_ points
// to the actual root of the tree through a __left_ pointer. Incrementing the end() pointer is UB, so we can assume that
// never happens.
template <class _EndNodePtr, class _NodePtr>
inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
  if (__x->__right_ != nullptr)
    return static_cast<_EndNodePtr>(std::__tree_min(__x->__right_));
  while (!std::__tree_is_left_child(__x))
    __x = __x->__parent_unsafe();
  return static_cast<_EndNodePtr>(__x->__parent_);
}

// Returns:  pointer to the previous in-order node before __x.
// Note: __x may be the end node.
template <class _NodePtr, class _EndNodePtr>
inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
  if (__x->__left_ != nullptr)
    return std::__tree_max(__x->__left_);
  _NodePtr __xx = static_cast<_NodePtr>(__x);
  while (std::__tree_is_left_child(__xx))
    __xx = __xx->__parent_unsafe();
  return __xx->__parent_unsafe();
}

// Returns:  pointer to a node which has no children
template <class _NodePtr>
_LIBCPP_HIDE_FROM_ABI _NodePtr __tree_leaf(_NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
  while (true) {
    if (__x->__left_ != nullptr) {
      __x = __x->__left_;
      continue;
    }
    if (__x->__right_ != nullptr) {
      __x = __x->__right_;
      continue;
    }
    break;
  }
  return __x;
}

// Effects:  Makes __x->__right_ the subtree root with __x as its left child
//           while preserving in-order order.
template <class _NodePtr>
_LIBCPP_HIDE_FROM_ABI void __tree_left_rotate(_NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
  _LIBCPP_ASSERT_INTERNAL(__x->__right_ != nullptr, "node should have a right child");
  _NodePtr __y  = __x->__right_;
  __x->__right_ = __y->__left_;
  if (__x->__right_ != nullptr)
    __x->__right_->__set_parent(__x);
  __y->__parent_ = __x->__parent_;
  if (std::__tree_is_left_child(__x))
    __x->__parent_->__left_ = __y;
  else
    __x->__parent_unsafe()->__right_ = __y;
  __y->__left_ = __x;
  __x->__set_parent(__y);
}

// Effects:  Makes __x->__left_ the subtree root with __x as its right child
//           while preserving in-order order.
template <class _NodePtr>
_LIBCPP_HIDE_FROM_ABI void __tree_right_rotate(_NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
  _LIBCPP_ASSERT_INTERNAL(__x->__left_ != nullptr, "node should have a left child");
  _NodePtr __y = __x->__left_;
  __x->__left_ = __y->__right_;
  if (__x->__left_ != nullptr)
    __x->__left_->__set_parent(__x);
  __y->__parent_ = __x->__parent_;
  if (std::__tree_is_left_child(__x))
    __x->__parent_->__left_ = __y;
  else
    __x->__parent_unsafe()->__right_ = __y;
  __y->__right_ = __x;
  __x->__set_parent(__y);
}

// Effects:  Rebalances __root after attaching __x to a leaf.
// Precondition:  __x has no children.
//                __x == __root or == a direct or indirect child of __root.
//                If __x were to be unlinked from __root (setting __root to
//                  nullptr if __root == __x), __tree_invariant(__root) == true.
// Postcondition: __tree_invariant(end_node->__left_) == true.  end_node->__left_
//                may be different than the value passed in as __root.
template <class _NodePtr>
_LIBCPP_HIDE_FROM_ABI void __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root of the tree shouldn't be null");
  _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Can't attach null node to a leaf");
  __x->__is_black_ = __x == __root;
  while (__x != __root && !__x->__parent_unsafe()->__is_black_) {
    // __x->__parent_ != __root because __x->__parent_->__is_black == false
    if (std::__tree_is_left_child(__x->__parent_unsafe())) {
      _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
      if (__y != nullptr && !__y->__is_black_) {
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = true;
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = __x == __root;
        __y->__is_black_ = true;
      } else {
        if (!std::__tree_is_left_child(__x)) {
          __x = __x->__parent_unsafe();
          std::__tree_left_rotate(__x);
        }
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = true;
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = false;
        std::__tree_right_rotate(__x);
        break;
      }
    } else {
      _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
      if (__y != nullptr && !__y->__is_black_) {
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = true;
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = __x == __root;
        __y->__is_black_ = true;
      } else {
        if (std::__tree_is_left_child(__x)) {
          __x = __x->__parent_unsafe();
          std::__tree_right_rotate(__x);
        }
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = true;
        __x              = __x->__parent_unsafe();
        __x->__is_black_ = false;
        std::__tree_left_rotate(__x);
        break;
      }
    }
  }
}

// Precondition:  __z == __root or == a direct or indirect child of __root.
// Effects:  unlinks __z from the tree rooted at __root, rebalancing as needed.
// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
//                nor any of its children refer to __z.  end_node->__left_
//                may be different than the value passed in as __root.
template <class _NodePtr>
_LIBCPP_HIDE_FROM_ABI void __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT {
  _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root node should not be null");
  _LIBCPP_ASSERT_INTERNAL(__z != nullptr, "The node to remove should not be null");
  _LIBCPP_ASSERT_INTERNAL(std::__tree_invariant(__root), "The tree invariants should hold");
  // __z will be removed from the tree.  Client still needs to destruct/deallocate it
  // __y is either __z, or if __z has two children, __tree_next(__z).
  // __y will have at most one child.
  // __y will be the initial hole in the tree (make the hole at a leaf)
  _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ? __z : std::__tree_next(__z);
  // __x is __y's possibly null single child
  _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
  // __w is __x's possibly null uncle (will become __x's sibling)
  _NodePtr __w = nullptr;
  // link __x to __y's parent, and find __w
  if (__x != nullptr)
    __x->__parent_ = __y->__parent_;
  if (std::__tree_is_left_child(__y)) {
    __y->__parent_->__left_ = __x;
    if (__y != __root)
      __w = __y->__parent_unsafe()->__right_;
    else
      __root = __x; // __w == nullptr
  } else {
    __y->__parent_unsafe()->__right_ = __x;
    // __y can't be root if it is a right child
    __w = __y->__parent_->__left_;
  }
  bool __removed_black = __y->__is_black_;
  // If we didn't remove __z, do so now by splicing in __y for __z,
  //    but copy __z's color.  This does not impact __x or __w.
  if (__y != __z) {
    // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
    __y->__parent_ = __z->__parent_;
    if (std::__tree_is_left_child(__z))
      __y->__parent_->__left_ = __y;
    else
      __y->__parent_unsafe()->__right_ = __y;
    __y->__left_ = __z->__left_;
    __y->__left_->__set_parent(__y);
    __y->__right_ = __z->__right_;
    if (__y->__right_ != nullptr)
      __y->__right_->__set_parent(__y);
    __y->__is_black_ = __z->__is_black_;
    if (__root == __z)
      __root = __y;
  }
  // There is no need to rebalance if we removed a red, or if we removed
  //     the last node.
  if (__removed_black && __root != nullptr) {
    // Rebalance:
    // __x has an implicit black color (transferred from the removed __y)
    //    associated with it, no matter what its color is.
    // If __x is __root (in which case it can't be null), it is supposed
    //    to be black anyway, and if it is doubly black, then the double
    //    can just be ignored.
    // If __x is red (in which case it can't be null), then it can absorb
    //    the implicit black just by setting its color to black.
    // Since __y was black and only had one child (which __x points to), __x
    //   is either red with no children, else null, otherwise __y would have
    //   different black heights under left and right pointers.
    // if (__x == __root || __x != nullptr && !__x->__is_black_)
    if (__x != nullptr)
      __x->__is_black_ = true;
    else {
      //  Else __x isn't root, and is "doubly black", even though it may
      //     be null.  __w can not be null here, else the parent would
      //     see a black height >= 2 on the __x side and a black height
      //     of 1 on the __w side (__w must be a non-null black or a red
      //     with a non-null black child).
      while (true) {
        if (!std::__tree_is_left_child(__w)) // if x is left child
        {
          if (!__w->__is_black_) {
            __w->__is_black_                    = true;
            __w->__parent_unsafe()->__is_black_ = false;
            std::__tree_left_rotate(__w->__parent_unsafe());
            // __x is still valid
            // reset __root only if necessary
            if (__root == __w->__left_)
              __root = __w;
            // reset sibling, and it still can't be null
            __w = __w->__left_->__right_;
          }
          // __w->__is_black_ is now true, __w may have null children
          if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
              (__w->__right_ == nullptr || __w->__right_->__is_black_)) {
            __w->__is_black_ = false;
            __x              = __w->__parent_unsafe();
            // __x can no longer be null
            if (__x == __root || !__x->__is_black_) {
              __x->__is_black_ = true;
              break;
            }
            // reset sibling, and it still can't be null
            __w = std::__tree_is_left_child(__x) ? __x->__parent_unsafe()->__right_ : __x->__parent_->__left_;
            // continue;
          } else // __w has a red child
          {
            if (__w->__right_ == nullptr || __w->__right_->__is_black_) {
              // __w left child is non-null and red
              __w->__left_->__is_black_ = true;
              __w->__is_black_          = false;
              std::__tree_right_rotate(__w);
              // __w is known not to be root, so root hasn't changed
              // reset sibling, and it still can't be null
              __w = __w->__parent_unsafe();
            }
            // __w has a right red child, left child may be null
            __w->__is_black_                    = __w->__parent_unsafe()->__is_black_;
            __w->__parent_unsafe()->__is_black_ = true;
            __w->__right_->__is_black_          = true;
            std::__tree_left_rotate(__w->__parent_unsafe());
            break;
          }
        } else {
          if (!__w->__is_black_) {
            __w->__is_black_                    = true;
            __w->__parent_unsafe()->__is_black_ = false;
            std::__tree_right_rotate(__w->__parent_unsafe());
            // __x is still valid
            // reset __root only if necessary
            if (__root == __w->__right_)
              __root = __w;
            // reset sibling, and it still can't be null
            __w = __w->__right_->__left_;
          }
          // __w->__is_black_ is now true, __w may have null children
          if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
              (__w->__right_ == nullptr || __w->__right_->__is_black_)) {
            __w->__is_black_ = false;
            __x              = __w->__parent_unsafe();
            // __x can no longer be null
            if (!__x->__is_black_ || __x == __root) {
              __x->__is_black_ = true;
              break;
            }
            // reset sibling, and it still can't be null
            __w = std::__tree_is_left_child(__x) ? __x->__parent_unsafe()->__right_ : __x->__parent_->__left_;
            // continue;
          } else // __w has a red child
          {
            if (__w->__left_ == nullptr || __w->__left_->__is_black_) {
              // __w right child is non-null and red
              __w->__right_->__is_black_ = true;
              __w->__is_black_           = false;
              std::__tree_left_rotate(__w);
              // __w is known not to be root, so root hasn't changed
              // reset sibling, and it still can't be null
              __w = __w->__parent_unsafe();
            }
            // __w has a left red child, right child may be null
            __w->__is_black_                    = __w->__parent_unsafe()->__is_black_;
            __w->__parent_unsafe()->__is_black_ = true;
            __w->__left_->__is_black_           = true;
            std::__tree_right_rotate(__w->__parent_unsafe());
            break;
          }
        }
      }
    }
  }
}

// node traits

template <class _Tp>
inline const bool __is_tree_value_type_v = __is_specialization_v<_Tp, __value_type>;

template <class _Tp>
struct __get_tree_key_type {
  using type _LIBCPP_NODEBUG = _Tp;
};

template <class _Key, class _ValueT>
struct __get_tree_key_type<__value_type<_Key, _ValueT> > {
  using type _LIBCPP_NODEBUG = _Key;
};

template <class _Tp>
using __get_tree_key_type_t _LIBCPP_NODEBUG = typename __get_tree_key_type<_Tp>::type;

template <class _Tp>
struct __get_node_value_type {
  using type _LIBCPP_NODEBUG = _Tp;
};

template <class _Key, class _ValueT>
struct __get_node_value_type<__value_type<_Key, _ValueT> > {
  using type _LIBCPP_NODEBUG = pair<const _Key, _ValueT>;
};

template <class _Tp>
using __get_node_value_type_t _LIBCPP_NODEBUG = typename __get_node_value_type<_Tp>::type;

template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
struct __tree_node_types;

template <class _NodePtr, class _Tp, class _VoidPtr>
struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > {
  using __node_base_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> >;
  using __end_node_pointer _LIBCPP_NODEBUG  = __rebind_pointer_t<_VoidPtr, __tree_end_node<__node_base_pointer> >;

private:
  static_assert(is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value,
                "_VoidPtr does not point to unqualified void type");
};

// node

template <class _Pointer>
class __tree_end_node {
public:
  using pointer = _Pointer;
  pointer __left_;

  _LIBCPP_HIDE_FROM_ABI __tree_end_node() _NOEXCEPT : __left_() {}
};

template <class _VoidPtr>
class __tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
public:
  using pointer                            = __rebind_pointer_t<_VoidPtr, __tree_node_base>;
  using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<_VoidPtr, __tree_end_node<pointer> >;

  pointer __right_;
  __end_node_pointer __parent_;
  bool __is_black_;

  _LIBCPP_HIDE_FROM_ABI pointer __parent_unsafe() const { return static_cast<pointer>(__parent_); }

  _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = static_cast<__end_node_pointer>(__p); }

  _LIBCPP_HIDE_FROM_ABI __tree_node_base()             = default;
  __tree_node_base(__tree_node_base const&)            = delete;
  __tree_node_base& operator=(__tree_node_base const&) = delete;
};

template <class _Tp, class _VoidPtr>
class __tree_node : public __tree_node_base<_VoidPtr> {
public:
  using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;

// We use a union to avoid initialization during member initialization, which allows us
// to use the allocator from the container to construct the `__node_value_type` in the
// memory provided by the union member
#ifndef _LIBCPP_CXX03_LANG

private:
  union {
    __node_value_type __value_;
  };

public:
  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
#else

private:
  _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];

public:
  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *reinterpret_cast<__node_value_type*>(__buffer_); }
#endif

  template <class _Alloc, class... _Args>
  _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
    allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
  }
  ~__tree_node()                             = delete;
  __tree_node(__tree_node const&)            = delete;
  __tree_node& operator=(__tree_node const&) = delete;
};

template <class _Allocator>
class __tree_node_destructor {
  using allocator_type                 = _Allocator;
  using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;

public:
  using pointer = typename __alloc_traits::pointer;

private:
  allocator_type& __na_;

public:
  bool __value_constructed;

  _LIBCPP_HIDE_FROM_ABI __tree_node_destructor(const __tree_node_destructor&) = default;
  __tree_node_destructor& operator=(const __tree_node_destructor&)            = delete;

  _LIBCPP_HIDE_FROM_ABI explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
      : __na_(__na),
        __value_constructed(__val) {}

  _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
    if (__value_constructed)
      __alloc_traits::destroy(__na_, std::addressof(__p->__get_value()));
    if (__p)
      __alloc_traits::deallocate(__na_, __p, 1);
  }

  template <class>
  friend class __map_node_destructor;
};

#if _LIBCPP_STD_VER >= 17
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;
template <class _Tp, class _VoidPtr, class _Alloc>
struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> : __tree_node_destructor<_Alloc> {
  using __tree_node_destructor<_Alloc>::__tree_node_destructor;
};
#endif

template <class _Tp, class _NodePtr, class _DiffType>
class __tree_iterator {
  using _NodeTypes _LIBCPP_NODEBUG = __tree_node_types<_NodePtr>;
  // NOLINTNEXTLINE(libcpp-nodebug-on-aliases) lldb relies on this alias for pretty printing
  using __node_pointer                      = _NodePtr;
  using __node_base_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__node_base_pointer;
  using __end_node_pointer _LIBCPP_NODEBUG  = typename _NodeTypes::__end_node_pointer;

  __end_node_pointer __ptr_;

public:
  using iterator_category = bidirectional_iterator_tag;
  using value_type        = __get_node_value_type_t<_Tp>;
  using difference_type   = _DiffType;
  using reference         = value_type&;
  using pointer           = __rebind_pointer_t<_NodePtr, value_type>;

  _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}

  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
  _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
    return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
  }

  _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator++() {
    __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
    return *this;
  }
  _LIBCPP_HIDE_FROM_ABI __tree_iterator operator++(int) {
    __tree_iterator __t(*this);
    ++(*this);
    return __t;
  }

  _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator--() {
    __ptr_ = static_cast<__end_node_pointer>(std::__tree_prev_iter<__node_base_pointer>(__ptr_));
    return *this;
  }
  _LIBCPP_HIDE_FROM_ABI __tree_iterator operator--(int) {
    __tree_iterator __t(*this);
    --(*this);
    return __t;
  }

  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) {
    return __x.__ptr_ == __y.__ptr_;
  }
  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) {
    return !(__x == __y);
  }

private:
  _LIBCPP_HIDE_FROM_ABI explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
  _LIBCPP_HIDE_FROM_ABI explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
  _LIBCPP_HIDE_FROM_ABI __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
  template <class, class, class>
  friend class __tree;
  template <class, class, class>
  friend class __tree_const_iterator;
};

template <class _Tp, class _NodePtr, class _DiffType>
class __tree_const_iterator {
  using _NodeTypes _LIBCPP_NODEBUG = __tree_node_types<_NodePtr>;
  // NOLINTNEXTLINE(libcpp-nodebug-on-aliases) lldb relies on this alias for pretty printing
  using __node_pointer                      = _NodePtr;
  using __node_base_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__node_base_pointer;
  using __end_node_pointer _LIBCPP_NODEBUG  = typename _NodeTypes::__end_node_pointer;

  __end_node_pointer __ptr_;

public:
  using iterator_category                    = bidirectional_iterator_tag;
  using value_type                           = __get_node_value_type_t<_Tp>;
  using difference_type                      = _DiffType;
  using reference                            = const value_type&;
  using pointer                              = __rebind_pointer_t<_NodePtr, const value_type>;
  using __non_const_iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, __node_pointer, difference_type>;

  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}

  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}

  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
  _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
    return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
  }

  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator++() {
    __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
    return *this;
  }

  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator operator++(int) {
    __tree_const_iterator __t(*this);
    ++(*this);
    return __t;
  }

  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator--() {
    __ptr_ = static_cast<__end_node_pointer>(std::__tree_prev_iter<__node_base_pointer>(__ptr_));
    return *this;
  }

  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator operator--(int) {
    __tree_const_iterator __t(*this);
    --(*this);
    return __t;
  }

  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {
    return __x.__ptr_ == __y.__ptr_;
  }
  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {
    return !(__x == __y);
  }

private:
  _LIBCPP_HIDE_FROM_ABI explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
  _LIBCPP_HIDE_FROM_ABI explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
  _LIBCPP_HIDE_FROM_ABI __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }

  template <class, class, class>
  friend class __tree;
};

template <class _Tp, class _Compare>
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp const&>,
                         "the specified comparator type does not provide a viable const call operator")
#endif
int __diagnose_non_const_comparator();

template <class _Tp, class _Compare, class _Allocator>
class __tree {
public:
  using value_type     = __get_node_value_type_t<_Tp>;
  using value_compare  = _Compare;
  using allocator_type = _Allocator;

private:
  using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
  using key_type                       = __get_tree_key_type_t<_Tp>;

public:
  using pointer         = typename __alloc_traits::pointer;
  using const_pointer   = typename __alloc_traits::const_pointer;
  using size_type       = typename __alloc_traits::size_type;
  using difference_type = typename __alloc_traits::difference_type;

  using __void_pointer _LIBCPP_NODEBUG = typename __alloc_traits::void_pointer;

  using __node _LIBCPP_NODEBUG = __tree_node<_Tp, __void_pointer>;
  // NOLINTNEXTLINE(libcpp-nodebug-on-aliases) lldb relies on this alias for pretty printing
  using __node_pointer = __rebind_pointer_t<__void_pointer, __node>;

  using __node_base _LIBCPP_NODEBUG         = __tree_node_base<__void_pointer>;
  using __node_base_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<__void_pointer, __node_base>;

  using __end_node_t _LIBCPP_NODEBUG       = __tree_end_node<__node_base_pointer>;
  using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<__void_pointer, __end_node_t>;

  using __parent_pointer _LIBCPP_NODEBUG = __end_node_pointer; // TODO: Remove this once the uses in <map> are removed

  using __node_allocator _LIBCPP_NODEBUG = __rebind_alloc<__alloc_traits, __node>;
  using __node_traits _LIBCPP_NODEBUG    = allocator_traits<__node_allocator>;

// TODO(LLVM 22): Remove this check
#ifndef _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
  static_assert(sizeof(__node_base_pointer) == sizeof(__end_node_pointer) && _LIBCPP_ALIGNOF(__node_base_pointer) ==
                    _LIBCPP_ALIGNOF(__end_node_pointer),
                "It looks like you are using std::__tree (an implementation detail for (multi)map/set) with a fancy "
                "pointer type that thas a different representation depending on whether it points to a __tree base "
                "pointer or a __tree node pointer (both of which are implementation details of the standard library). "
                "This means that your ABI is being broken between LLVM 19 and LLVM 20. If you don't care about your "
                "ABI being broken, define the _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB macro to silence this "
                "diagnostic.");
#endif

private:
  // check for sane allocator pointer rebinding semantics. Rebinding the
  // allocator for a new pointer type should be exactly the same as rebinding
  // the pointer using 'pointer_traits'.
  static_assert(is_same<__node_pointer, typename __node_traits::pointer>::value,
                "Allocator does not rebind pointers in a sane manner.");
  using __node_base_allocator _LIBCPP_NODEBUG = __rebind_alloc<__node_traits, __node_base>;
  using __node_base_traits _LIBCPP_NODEBUG    = allocator_traits<__node_base_allocator>;
  static_assert(is_same<__node_base_pointer, typename __node_base_traits::pointer>::value,
                "Allocator does not rebind pointers in a sane manner.");

private:
  __end_node_pointer __begin_node_;
  _LIBCPP_COMPRESSED_PAIR(__end_node_t, __end_node_, __node_allocator, __node_alloc_);
  _LIBCPP_COMPRESSED_PAIR(size_type, __size_, value_compare, __value_comp_);

public:
  _LIBCPP_HIDE_FROM_ABI __end_node_pointer __end_node() _NOEXCEPT {
    return pointer_traits<__end_node_pointer>::pointer_to(__end_node_);
  }
  _LIBCPP_HIDE_FROM_ABI __end_node_pointer __end_node() const _NOEXCEPT {
    return pointer_traits<__end_node_pointer>::pointer_to(const_cast<__end_node_t&>(__end_node_));
  }
  _LIBCPP_HIDE_FROM_ABI __node_allocator& __node_alloc() _NOEXCEPT { return __node_alloc_; }

private:
  _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __node_alloc_; }

public:
  _LIBCPP_HIDE_FROM_ABI allocator_type __alloc() const _NOEXCEPT { return allocator_type(__node_alloc()); }

  _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
  _LIBCPP_HIDE_FROM_ABI value_compare& value_comp() _NOEXCEPT { return __value_comp_; }
  _LIBCPP_HIDE_FROM_ABI const value_compare& value_comp() const _NOEXCEPT { return __value_comp_; }

public:
  _LIBCPP_HIDE_FROM_ABI __node_pointer __root() const _NOEXCEPT {
    return static_cast<__node_pointer>(__end_node()->__left_);
  }

  _LIBCPP_HIDE_FROM_ABI __node_base_pointer* __root_ptr() const _NOEXCEPT {
    return std::addressof(__end_node()->__left_);
  }

  using iterator       = __tree_iterator<_Tp, __node_pointer, difference_type>;
  using const_iterator = __tree_const_iterator<_Tp, __node_pointer, difference_type>;

  _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp) _NOEXCEPT_(
      is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value)
      : __size_(0), __value_comp_(__comp) {
    __begin_node_ = __end_node();
  }

  _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a)
      : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0) {
    __begin_node_ = __end_node();
  }

  _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a)
      : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(__comp) {
    __begin_node_ = __end_node();
  }

  _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t);
  _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t);
  template <class _ForwardIterator>
  _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
  template <class _InputIterator>
  _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
  _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(
      is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
  _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);

  _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
      _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
                 ((__node_traits::propagate_on_container_move_assignment::value &&
                   is_nothrow_move_assignable<__node_allocator>::value) ||
                  allocator_traits<__node_allocator>::is_always_equal::value)) {
    __move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
    return *this;
  }

  _LIBCPP_HIDE_FROM_ABI ~__tree() {
    static_assert(is_copy_constructible<value_compare>::value, "Comparator must be copy-constructible.");
    destroy(__root());
  }

  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node_); }
  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__begin_node_); }
  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(__end_node()); }
  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(__end_node()); }

  _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
    return std::min<size_type>(__node_traits::max_size(__node_alloc()), numeric_limits<difference_type >::max());
  }

  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;

  _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t)
#if _LIBCPP_STD_VER <= 11
      _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
                 (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>));
#else
      _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>);
#endif

  template <class... _Args>
  _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);

  template <class... _Args>
  _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);

  template <class... _Args>
  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Args&&... __args) {
    return std::__try_key_extraction<key_type>(
        [this](const key_type& __key, _Args&&... __args2) {
          auto [__parent, __child] = __find_equal(__key);
          __node_pointer __r       = static_cast<__node_pointer>(__child);
          bool __inserted          = false;
          if (__child == nullptr) {
            __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
            __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
            __r        = __h.release();
            __inserted = true;
          }
          return pair<iterator, bool>(iterator(__r), __inserted);
        },
        [this](_Args&&... __args2) {
          __node_holder __h        = __construct_node(std::forward<_Args>(__args2)...);
          auto [__parent, __child] = __find_equal(__h->__get_value());
          __node_pointer __r       = static_cast<__node_pointer>(__child);
          bool __inserted          = false;
          if (__child == nullptr) {
            __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
            __r        = __h.release();
            __inserted = true;
          }
          return pair<iterator, bool>(iterator(__r), __inserted);
        },
        std::forward<_Args>(__args)...);
  }

  template <class... _Args>
  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
    return std::__try_key_extraction<key_type>(
        [this, __p](const key_type& __key, _Args&&... __args2) {
          __node_base_pointer __dummy;
          auto [__parent, __child] = __find_equal(__p, __dummy, __key);
          __node_pointer __r       = static_cast<__node_pointer>(__child);
          bool __inserted          = false;
          if (__child == nullptr) {
            __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
            __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
            __r        = __h.release();
            __inserted = true;
          }
          return pair<iterator, bool>(iterator(__r), __inserted);
        },
        [this, __p](_Args&&... __args2) {
          __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
          __node_base_pointer __dummy;
          auto [__parent, __child] = __find_equal(__p, __dummy, __h->__get_value());
          __node_pointer __r       = static_cast<__node_pointer>(__child);
          if (__child == nullptr) {
            __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
            __r = __h.release();
          }
          return pair<iterator, bool>(iterator(__r), __child == nullptr);
        },
        std::forward<_Args>(__args)...);
  }

  template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI void
  __insert_unique_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) {
    __emplace_hint_unique(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
  }

  template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(const_iterator __p, _Tp&& __value) {
    __emplace_hint_unique(__p, std::move(__value));
  }

  template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, value_type&& __value) {
    __emplace_hint_multi(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
  }

  template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, _Tp&& __value) {
    __emplace_hint_multi(__p, std::move(__value));
  }

  template <class _InIter, class _Sent>
  _LIBCPP_HIDE_FROM_ABI void __insert_range_multi(_InIter __first, _Sent __last) {
    if (__first == __last)
      return;

    if (__root() == nullptr) { // Make sure we always have a root node
      __insert_node_at(
          __end_node(), __end_node()->__left_, static_cast<__node_base_pointer>(__construct_node(*__first).release()));
      ++__first;
    }

    auto __max_node = static_cast<__node_pointer>(std::__tree_max(static_cast<__node_base_pointer>(__root())));

    for (; __first != __last; ++__first) {
      __node_holder __nd = __construct_node(*__first);
      // Always check the max node first. This optimizes for sorted ranges inserted at the end.
      if (!value_comp()(__nd->__get_value(), __max_node->__get_value())) { // __node >= __max_val
        __insert_node_at(static_cast<__end_node_pointer>(__max_node),
                         __max_node->__right_,
                         static_cast<__node_base_pointer>(__nd.get()));
        __max_node = __nd.release();
      } else {
        __end_node_pointer __parent;
        __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__get_value());
        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
      }
    }
  }

  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __node_assign_unique(const value_type& __v, __node_pointer __dest);

  _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd);
  _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);

  template <class _InIter, class _Sent>
  _LIBCPP_HIDE_FROM_ABI void __insert_range_unique(_InIter __first, _Sent __last) {
    if (__first == __last)
      return;

    if (__root() == nullptr) {
      __insert_node_at(
          __end_node(), __end_node()->__left_, static_cast<__node_base_pointer>(__construct_node(*__first).release()));
      ++__first;
    }

    auto __max_node = static_cast<__node_pointer>(std::__tree_max(static_cast<__node_base_pointer>(__root())));

    using __reference = decltype(*__first);

    for (; __first != __last; ++__first) {
      std::__try_key_extraction<key_type>(
          [this, &__max_node](const key_type& __key, __reference&& __val) {
            if (value_comp()(__max_node->__get_value(), __key)) { // __key > __max_node
              __node_holder __nd = __construct_node(std::forward<__reference>(__val));
              __insert_node_at(static_cast<__end_node_pointer>(__max_node),
                               __max_node->__right_,
                               static_cast<__node_base_pointer>(__nd.get()));
              __max_node = __nd.release();
            } else {
              auto [__parent, __child] = __find_equal(__key);
              if (__child == nullptr) {
                __node_holder __nd = __construct_node(std::forward<__reference>(__val));
                __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
              }
            }
          },
          [this, &__max_node](__reference&& __val) {
            __node_holder __nd = __construct_node(std::forward<__reference>(__val));
            if (value_comp()(__max_node->__get_value(), __nd->__get_value())) { // __node > __max_node
              __insert_node_at(static_cast<__end_node_pointer>(__max_node),
                               __max_node->__right_,
                               static_cast<__node_base_pointer>(__nd.get()));
              __max_node = __nd.release();
            } else {
              auto [__parent, __child] = __find_equal(__nd->__get_value());
              if (__child == nullptr) {
                __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
              }
            }
          },
          *__first);
    }
  }

  _LIBCPP_HIDE_FROM_ABI iterator __remove_node_pointer(__node_pointer) _NOEXCEPT;

#if _LIBCPP_STD_VER >= 17
  template <class _NodeHandle, class _InsertReturnType>
  _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
  template <class _NodeHandle>
  _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
  template <class _Tree>
  _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(_Tree& __source);

  template <class _NodeHandle>
  _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&&);
  template <class _NodeHandle>
  _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
  template <class _Tree>
  _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Tree& __source);

  template <class _NodeHandle>
  _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const&);
  template <class _NodeHandle>
  _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator);
#endif

  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);

  _LIBCPP_HIDE_FROM_ABI void
  __insert_node_at(__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT;

  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __key) {
    auto [__, __match] = __find_equal(__key);
    if (__match == nullptr)
      return end();
    return iterator(static_cast<__node_pointer>(__match));
  }

  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __key) const {
    auto [__, __match] = __find_equal(__key);
    if (__match == nullptr)
      return end();
    return const_iterator(static_cast<__node_pointer>(__match));
  }

  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;

  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Key& __v) {
    return __lower_bound(__v, __root(), __end_node());
  }
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI iterator __lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Key& __v) const {
    return __lower_bound(__v, __root(), __end_node());
  }
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI const_iterator
  __lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Key& __v) {
    return __upper_bound(__v, __root(), __end_node());
  }
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI iterator __upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Key& __v) const {
    return __upper_bound(__v, __root(), __end_node());
  }
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI const_iterator
  __upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_unique(const _Key& __k);
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_unique(const _Key& __k) const;

  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_multi(const _Key& __k);
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const;

  using _Dp _LIBCPP_NODEBUG           = __tree_node_destructor<__node_allocator>;
  using __node_holder _LIBCPP_NODEBUG = unique_ptr<__node, _Dp>;

  _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;

  // FIXME: Make this function const qualified. Unfortunately doing so
  // breaks existing code which uses non-const callable comparators.
  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v);

  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v) const {
    return const_cast<__tree*>(this)->__find_equal(__v);
  }

  template <class _Key>
  _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&>
  __find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v);

  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t) {
    __copy_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
  }

  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t, true_type) {
    if (__node_alloc() != __t.__node_alloc())
      clear();
    __node_alloc() = __t.__node_alloc();
  }
  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree&, false_type) {}

private:
  _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_low(__end_node_pointer& __parent, const value_type& __v);

  _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_high(__end_node_pointer& __parent, const value_type& __v);

  _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
  __find_leaf(const_iterator __hint, __end_node_pointer& __parent, const value_type& __v);

  template <class... _Args>
  _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args);

  // TODO: Make this _LIBCPP_HIDE_FROM_ABI
  _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT { (__tree_deleter(__node_alloc_))(__nd); }

  _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type);
  _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type) _NOEXCEPT_(
      is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value);

  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t)
      _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
                 is_nothrow_move_assignable<__node_allocator>::value) {
    __move_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
  }

  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t, true_type)
      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
    __node_alloc() = std::move(__t.__node_alloc());
  }
  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}

  template <class _From, class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI static void __assign_value(__get_node_value_type_t<value_type>& __lhs, _From&& __rhs) {
    using __key_type = __remove_const_t<typename value_type::first_type>;

    // This is technically UB, since the object was constructed as `const`.
    // Clang doesn't optimize on this currently though.
    const_cast<__key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, __key_type>&&>(__rhs.first);
    __lhs.second                         = std::forward<_From>(__rhs).second;
  }

  template <class _To, class _From, class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI static void __assign_value(_To& __lhs, _From&& __rhs) {
    __lhs = std::forward<_From>(__rhs);
  }

  struct _DetachedTreeCache {
    _LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache(__tree* __t) _NOEXCEPT
        : __t_(__t),
          __cache_root_(__detach_from_tree(__t)) {
      __advance();
    }

    _LIBCPP_HIDE_FROM_ABI __node_pointer __get() const _NOEXCEPT { return __cache_elem_; }

    _LIBCPP_HIDE_FROM_ABI void __advance() _NOEXCEPT {
      __cache_elem_ = __cache_root_;
      if (__cache_root_) {
        __cache_root_ = __detach_next(__cache_root_);
      }
    }

    _LIBCPP_HIDE_FROM_ABI ~_DetachedTreeCache() {
      __t_->destroy(__cache_elem_);
      if (__cache_root_) {
        while (__cache_root_->__parent_ != nullptr)
          __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_);
        __t_->destroy(__cache_root_);
      }
    }

    _DetachedTreeCache(_DetachedTreeCache const&)            = delete;
    _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete;

  private:
    _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_from_tree(__tree* __t) _NOEXCEPT;
    _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_next(__node_pointer) _NOEXCEPT;

    __tree* __t_;
    __node_pointer __cache_root_;
    __node_pointer __cache_elem_;
  };

  class __tree_deleter {
    __node_allocator& __alloc_;

  public:
    using pointer = __node_pointer;

    _LIBCPP_HIDE_FROM_ABI __tree_deleter(__node_allocator& __alloc) : __alloc_(__alloc) {}

#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
    _LIBCPP_HIDE_FROM_ABI
#endif
    void
    operator()(__node_pointer __ptr) {
      if (!__ptr)
        return;

      (*this)(static_cast<__node_pointer>(__ptr->__left_));

      auto __right = __ptr->__right_;

      __node_traits::destroy(__alloc_, std::addressof(__ptr->__get_value()));
      __node_traits::deallocate(__alloc_, __ptr, 1);

      (*this)(static_cast<__node_pointer>(__right));
    }
  };

  // This copy construction will always produce a correct red-black-tree assuming the incoming tree is correct, since we
  // copy the exact structure 1:1. Since this is for copy construction _only_ we know that we get a correct tree. If we
  // didn't get a correct tree, the invariants of __tree are broken and we have a much bigger problem than an improperly
  // balanced tree.
#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
  _LIBCPP_HIDE_FROM_ABI
#endif
  __node_pointer
  __copy_construct_tree(__node_pointer __src) {
    if (!__src)
      return nullptr;

    __node_holder __new_node = __construct_node(__src->__get_value());

    unique_ptr<__node, __tree_deleter> __left(
        __copy_construct_tree(static_cast<__node_pointer>(__src->__left_)), __node_alloc_);
    __node_pointer __right = __copy_construct_tree(static_cast<__node_pointer>(__src->__right_));

    __node_pointer __new_node_ptr = __new_node.release();

    __new_node_ptr->__is_black_ = __src->__is_black_;
    __new_node_ptr->__left_     = static_cast<__node_base_pointer>(__left.release());
    __new_node_ptr->__right_    = static_cast<__node_base_pointer>(__right);
    if (__new_node_ptr->__left_)
      __new_node_ptr->__left_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
    if (__new_node_ptr->__right_)
      __new_node_ptr->__right_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
    return __new_node_ptr;
  }

  // This copy assignment will always produce a correct red-black-tree assuming the incoming tree is correct, since our
  // own tree is a red-black-tree and the incoming tree is a red-black-tree. The invariants of a red-black-tree are
  // temporarily not met until all of the incoming red-black tree is copied.
#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
  _LIBCPP_HIDE_FROM_ABI
#endif
  __node_pointer
  __copy_assign_tree(__node_pointer __dest, __node_pointer __src) {
    if (!__src) {
      destroy(__dest);
      return nullptr;
    }

    __assign_value(__dest->__get_value(), __src->__get_value());
    __dest->__is_black_ = __src->__is_black_;

    // If we already have a left node in the destination tree, reuse it and copy-assign recursively
    if (__dest->__left_) {
      __dest->__left_ = static_cast<__node_base_pointer>(__copy_assign_tree(
          static_cast<__node_pointer>(__dest->__left_), static_cast<__node_pointer>(__src->__left_)));

      // Otherwise, we must create new nodes; copy-construct from here on
    } else if (__src->__left_) {
      auto __new_left       = __copy_construct_tree(static_cast<__node_pointer>(__src->__left_));
      __dest->__left_       = static_cast<__node_base_pointer>(__new_left);
      __new_left->__parent_ = static_cast<__end_node_pointer>(__dest);
    }

    // Identical to the left case above, just for the right nodes
    if (__dest->__right_) {
      __dest->__right_ = static_cast<__node_base_pointer>(__copy_assign_tree(
          static_cast<__node_pointer>(__dest->__right_), static_cast<__node_pointer>(__src->__right_)));
    } else if (__src->__right_) {
      auto __new_right       = __copy_construct_tree(static_cast<__node_pointer>(__src->__right_));
      __dest->__right_       = static_cast<__node_base_pointer>(__new_right);
      __new_right->__parent_ = static_cast<__end_node_pointer>(__dest);
    }

    return __dest;
  }
};

// Precondition:  __size_ != 0
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree* __t) _NOEXCEPT {
  __node_pointer __cache                = static_cast<__node_pointer>(__t->__begin_node_);
  __t->__begin_node_                    = __t->__end_node();
  __t->__end_node()->__left_->__parent_ = nullptr;
  __t->__end_node()->__left_            = nullptr;
  __t->__size_                          = 0;
  // __cache->__left_ == nullptr
  if (__cache->__right_ != nullptr)
    __cache = static_cast<__node_pointer>(__cache->__right_);
  // __cache->__left_ == nullptr
  // __cache->__right_ == nullptr
  return __cache;
}

// Precondition:  __cache != nullptr
//    __cache->left_ == nullptr
//    __cache->right_ == nullptr
//    This is no longer a red-black tree
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT {
  if (__cache->__parent_ == nullptr)
    return nullptr;
  if (std::__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) {
    __cache->__parent_->__left_ = nullptr;
    __cache                     = static_cast<__node_pointer>(__cache->__parent_);
    if (__cache->__right_ == nullptr)
      return __cache;
    return static_cast<__node_pointer>(std::__tree_leaf(__cache->__right_));
  }
  // __cache is right child
  __cache->__parent_unsafe()->__right_ = nullptr;
  __cache                              = static_cast<__node_pointer>(__cache->__parent_);
  if (__cache->__left_ == nullptr)
    return __cache;
  return static_cast<__node_pointer>(std::__tree_leaf(__cache->__left_));
}

template <class _Tp, class _Compare, class _Allocator>
__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) {
  if (this == std::addressof(__t))
    return *this;

  value_comp() = __t.value_comp();
  __copy_assign_alloc(__t);

  if (__size_ != 0) {
    *__root_ptr() = static_cast<__node_base_pointer>(__copy_assign_tree(__root(), __t.__root()));
  } else {
    *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
    if (__root())
      __root()->__parent_ = __end_node();
  }
  __begin_node_ =
      __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node();
  __size_ = __t.size();

  return *this;
}

template <class _Tp, class _Compare, class _Allocator>
template <class _ForwardIterator>
void __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last) {
  using _ITraits     = iterator_traits<_ForwardIterator>;
  using _ItValueType = typename _ITraits::value_type;
  static_assert(
      is_same<_ItValueType, value_type>::value, "__assign_unique may only be called with the containers value type");
  static_assert(
      __has_forward_iterator_category<_ForwardIterator>::value, "__assign_unique requires a forward iterator");
  if (__size_ != 0) {
    _DetachedTreeCache __cache(this);
    for (; __cache.__get() != nullptr && __first != __last; ++__first) {
      if (__node_assign_unique(*__first, __cache.__get()).second)
        __cache.__advance();
    }
  }
  for (; __first != __last; ++__first)
    __emplace_unique(*__first);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _InputIterator>
void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) {
  using _ITraits     = iterator_traits<_InputIterator>;
  using _ItValueType = typename _ITraits::value_type;
  static_assert(
      is_same<_ItValueType, value_type>::value, "__assign_multi may only be called with the containers value_type");
  if (__size_ != 0) {
    _DetachedTreeCache __cache(this);
    for (; __cache.__get() && __first != __last; ++__first) {
      __assign_value(__cache.__get()->__get_value(), *__first);
      __node_insert_multi(__cache.__get());
      __cache.__advance();
    }
  }
  const_iterator __e = end();
  for (; __first != __last; ++__first)
    __emplace_hint_multi(__e, *__first);
}

template <class _Tp, class _Compare, class _Allocator>
__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
    : __begin_node_(__end_node()),
      __node_alloc_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
      __size_(0),
      __value_comp_(__t.value_comp()) {
  if (__t.size() == 0)
    return;

  *__root_ptr()       = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
  __root()->__parent_ = __end_node();
  __begin_node_       = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
  __size_             = __t.size();
}

template <class _Tp, class _Compare, class _Allocator>
__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
    is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value)
    : __begin_node_(std::move(__t.__begin_node_)),
      __end_node_(std::move(__t.__end_node_)),
      __node_alloc_(std::move(__t.__node_alloc_)),
      __size_(__t.__size_),
      __value_comp_(std::move(__t.__value_comp_)) {
  if (__size_ == 0)
    __begin_node_ = __end_node();
  else {
    __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
    __t.__begin_node_                = __t.__end_node();
    __t.__end_node()->__left_        = nullptr;
    __t.__size_                      = 0;
  }
}

template <class _Tp, class _Compare, class _Allocator>
__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
    : __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(std::move(__t.value_comp())) {
  if (__a == __t.__alloc()) {
    if (__t.__size_ == 0)
      __begin_node_ = __end_node();
    else {
      __begin_node_                    = __t.__begin_node_;
      __end_node()->__left_            = __t.__end_node()->__left_;
      __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
      __size_                          = __t.__size_;
      __t.__begin_node_                = __t.__end_node();
      __t.__end_node()->__left_        = nullptr;
      __t.__size_                      = 0;
    }
  } else {
    __begin_node_ = __end_node();
  }
}

template <class _Tp, class _Compare, class _Allocator>
void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value) {
  destroy(static_cast<__node_pointer>(__end_node()->__left_));
  __begin_node_ = __t.__begin_node_;
  __end_node_   = __t.__end_node_;
  __move_assign_alloc(__t);
  __size_       = __t.__size_;
  __value_comp_ = std::move(__t.__value_comp_);
  if (__size_ == 0)
    __begin_node_ = __end_node();
  else {
    __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
    __t.__begin_node_                = __t.__end_node();
    __t.__end_node()->__left_        = nullptr;
    __t.__size_                      = 0;
  }
}

template <class _Tp, class _Compare, class _Allocator>
void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
  if (__node_alloc() == __t.__node_alloc())
    __move_assign(__t, true_type());
  else {
    value_comp()       = std::move(__t.value_comp());
    const_iterator __e = end();
    if (__size_ != 0) {
      _DetachedTreeCache __cache(this);
      while (__cache.__get() != nullptr && __t.__size_ != 0) {
        __assign_value(__cache.__get()->__get_value(), std::move(__t.remove(__t.begin())->__get_value()));
        __node_insert_multi(__cache.__get());
        __cache.__advance();
      }
    }
    while (__t.__size_ != 0) {
      __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__get_value()));
    }
  }
}

template <class _Tp, class _Compare, class _Allocator>
void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
#if _LIBCPP_STD_VER <= 11
    _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
               (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>))
#else
    _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>)
#endif
{
  using std::swap;
  swap(__begin_node_, __t.__begin_node_);
  swap(__end_node_, __t.__end_node_);
  std::__swap_allocator(__node_alloc(), __t.__node_alloc());
  swap(__size_, __t.__size_);
  swap(__value_comp_, __t.__value_comp_);
  if (__size_ == 0)
    __begin_node_ = __end_node();
  else
    __end_node()->__left_->__parent_ = __end_node();
  if (__t.__size_ == 0)
    __t.__begin_node_ = __t.__end_node();
  else
    __t.__end_node()->__left_->__parent_ = __t.__end_node();
}

template <class _Tp, class _Compare, class _Allocator>
void __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT {
  destroy(__root());
  __size_               = 0;
  __begin_node_         = __end_node();
  __end_node()->__left_ = nullptr;
}

// Find lower_bound place to insert
// Set __parent to parent of null leaf
// Return reference to null leaf
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__end_node_pointer& __parent, const value_type& __v) {
  __node_pointer __nd = __root();
  if (__nd != nullptr) {
    while (true) {
      if (value_comp()(__nd->__get_value(), __v)) {
        if (__nd->__right_ != nullptr)
          __nd = static_cast<__node_pointer>(__nd->__right_);
        else {
          __parent = static_cast<__end_node_pointer>(__nd);
          return __nd->__right_;
        }
      } else {
        if (__nd->__left_ != nullptr)
          __nd = static_cast<__node_pointer>(__nd->__left_);
        else {
          __parent = static_cast<__end_node_pointer>(__nd);
          return __parent->__left_;
        }
      }
    }
  }
  __parent = __end_node();
  return __parent->__left_;
}

// Find upper_bound place to insert
// Set __parent to parent of null leaf
// Return reference to null leaf
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__end_node_pointer& __parent, const value_type& __v) {
  __node_pointer __nd = __root();
  if (__nd != nullptr) {
    while (true) {
      if (value_comp()(__v, __nd->__get_value())) {
        if (__nd->__left_ != nullptr)
          __nd = static_cast<__node_pointer>(__nd->__left_);
        else {
          __parent = static_cast<__end_node_pointer>(__nd);
          return __parent->__left_;
        }
      } else {
        if (__nd->__right_ != nullptr)
          __nd = static_cast<__node_pointer>(__nd->__right_);
        else {
          __parent = static_cast<__end_node_pointer>(__nd);
          return __nd->__right_;
        }
      }
    }
  }
  __parent = __end_node();
  return __parent->__left_;
}

// Find leaf place to insert closest to __hint
// First check prior to __hint.
// Next check after __hint.
// Next do O(log N) search.
// Set __parent to parent of null leaf
// Return reference to null leaf
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_leaf(
    const_iterator __hint, __end_node_pointer& __parent, const value_type& __v) {
  if (__hint == end() || !value_comp()(*__hint, __v)) // check before
  {
    // __v <= *__hint
    const_iterator __prior = __hint;
    if (__prior == begin() || !value_comp()(__v, *--__prior)) {
      // *prev(__hint) <= __v <= *__hint
      if (__hint.__ptr_->__left_ == nullptr) {
        __parent = static_cast<__end_node_pointer>(__hint.__ptr_);
        return __parent->__left_;
      } else {
        __parent = static_cast<__end_node_pointer>(__prior.__ptr_);
        return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
      }
    }
    // __v < *prev(__hint)
    return __find_leaf_high(__parent, __v);
  }
  // else __v > *__hint
  return __find_leaf_low(__parent, __v);
}

// Find __v
// If __v exists, return the parent of the node of __v and a reference to the pointer to the node of __v.
// If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
_LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
                           typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
__tree<_Tp, _Compare, _Allocator>::__find_equal(const _Key& __v) {
  using _Pair = pair<__end_node_pointer, __node_base_pointer&>;

  __node_pointer __nd = __root();

  if (__nd == nullptr) {
    auto __end = __end_node();
    return _Pair(__end, __end->__left_);
  }

  __node_base_pointer* __node_ptr = __root_ptr();
  auto __comp                     = __lazy_synth_three_way_comparator<_Compare, _Key, value_type>(value_comp());

  while (true) {
    auto __comp_res = __comp(__v, __nd->__get_value());

    if (__comp_res.__less()) {
      if (__nd->__left_ == nullptr)
        return _Pair(static_cast<__end_node_pointer>(__nd), __nd->__left_);

      __node_ptr = std::addressof(__nd->__left_);
      __nd       = static_cast<__node_pointer>(__nd->__left_);
    } else if (__comp_res.__greater()) {
      if (__nd->__right_ == nullptr)
        return _Pair(static_cast<__end_node_pointer>(__nd), __nd->__right_);

      __node_ptr = std::addressof(__nd->__right_);
      __nd       = static_cast<__node_pointer>(__nd->__right_);
    } else {
      return _Pair(static_cast<__end_node_pointer>(__nd), *__node_ptr);
    }
  }
}

// Find __v
// First check prior to __hint.
// Next check after __hint.
// Next do O(log N) search.
// If __v exists, return the parent of the node of __v and a reference to the pointer to the node of __v.
// If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
_LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
                           typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v) {
  using _Pair = pair<__end_node_pointer, __node_base_pointer&>;

  if (__hint == end() || value_comp()(__v, *__hint)) { // check before
    // __v < *__hint
    const_iterator __prior = __hint;
    if (__prior == begin() || value_comp()(*--__prior, __v)) {
      // *prev(__hint) < __v < *__hint
      if (__hint.__ptr_->__left_ == nullptr)
        return _Pair(__hint.__ptr_, __hint.__ptr_->__left_);
      return _Pair(__prior.__ptr_, static_cast<__node_pointer>(__prior.__ptr_)->__right_);
    }
    // __v <= *prev(__hint)
    return __find_equal(__v);
  }

  if (value_comp()(*__hint, __v)) { // check after
    // *__hint < __v
    const_iterator __next = std::next(__hint);
    if (__next == end() || value_comp()(__v, *__next)) {
      // *__hint < __v < *std::next(__hint)
      if (__hint.__get_np()->__right_ == nullptr)
        return _Pair(__hint.__ptr_, static_cast<__node_pointer>(__hint.__ptr_)->__right_);
      return _Pair(__next.__ptr_, __next.__ptr_->__left_);
    }
    // *next(__hint) <= __v
    return __find_equal(__v);
  }

  // else __v == *__hint
  __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
  return _Pair(__hint.__ptr_, __dummy);
}

template <class _Tp, class _Compare, class _Allocator>
void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
    __end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT {
  __new_node->__left_   = nullptr;
  __new_node->__right_  = nullptr;
  __new_node->__parent_ = __parent;
  // __new_node->__is_black_ is initialized in __tree_balance_after_insert
  __child = __new_node;
  if (__begin_node_->__left_ != nullptr)
    __begin_node_ = static_cast<__end_node_pointer>(__begin_node_->__left_);
  std::__tree_balance_after_insert(__end_node()->__left_, __child);
  ++__size_;
}

template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
typename __tree<_Tp, _Compare, _Allocator>::__node_holder
__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
  __node_allocator& __na = __node_alloc();
  __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
  std::__construct_at(std::addressof(*__h), __na, std::forward<_Args>(__args)...);
  __h.get_deleter().__value_constructed = true;
  return __h;
}

template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) {
  __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
  __end_node_pointer __parent;
  __node_base_pointer& __child = __find_leaf_high(__parent, __h->__get_value());
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
  return iterator(static_cast<__node_pointer>(__h.release()));
}

template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) {
  __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
  __end_node_pointer __parent;
  __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__get_value());
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
  return iterator(static_cast<__node_pointer>(__h.release()));
}

template <class _Tp, class _Compare, class _Allocator>
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, __node_pointer __nd) {
  auto [__parent, __child] = __find_equal(__v);
  __node_pointer __r       = static_cast<__node_pointer>(__child);
  bool __inserted          = false;
  if (__child == nullptr) {
    __assign_value(__nd->__get_value(), __v);
    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
    __r        = __nd;
    __inserted = true;
  }
  return pair<iterator, bool>(iterator(__r), __inserted);
}

template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) {
  __end_node_pointer __parent;
  __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__get_value());
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
  return iterator(__nd);
}

template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) {
  __end_node_pointer __parent;
  __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__get_value());
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
  return iterator(__nd);
}

template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT {
  iterator __r(__ptr);
  ++__r;
  if (__begin_node_ == __ptr)
    __begin_node_ = __r.__ptr_;
  --__size_;
  std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__ptr));
  return __r;
}

#if _LIBCPP_STD_VER >= 17
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle, class _InsertReturnType>
_LIBCPP_HIDE_FROM_ABI _InsertReturnType
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __nh) {
  if (__nh.empty())
    return _InsertReturnType{end(), false, _NodeHandle()};

  __node_pointer __ptr = __nh.__ptr_;
  auto [__parent, __child] = __find_equal(__ptr->__get_value());
  if (__child != nullptr)
    return _InsertReturnType{iterator(static_cast<__node_pointer>(__child)), false, std::move(__nh)};

  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
  __nh.__release_ptr();
  return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
}

template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __hint, _NodeHandle&& __nh) {
  if (__nh.empty())
    return end();

  __node_pointer __ptr = __nh.__ptr_;
  __node_base_pointer __dummy;
  auto [__parent, __child] = __find_equal(__hint, __dummy, __ptr->__get_value());
  __node_pointer __r       = static_cast<__node_pointer>(__child);
  if (__child == nullptr) {
    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
    __r = __ptr;
    __nh.__release_ptr();
  }
  return iterator(__r);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) {
  iterator __it = find(__key);
  if (__it == end())
    return _NodeHandle();
  return __node_handle_extract<_NodeHandle>(__it);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) {
  __node_pointer __np = __p.__get_np();
  __remove_node_pointer(__np);
  return _NodeHandle(__np, __alloc());
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Tree>
_LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) {
  static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");

  for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
    __node_pointer __src_ptr = __i.__get_np();
    auto [__parent, __child] = __find_equal(__src_ptr->__get_value());
    ++__i;
    if (__child != nullptr)
      continue;
    __source.__remove_node_pointer(__src_ptr);
    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr));
  }
}

template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh) {
  if (__nh.empty())
    return end();
  __node_pointer __ptr = __nh.__ptr_;
  __end_node_pointer __parent;
  __node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__get_value());
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
  __nh.__release_ptr();
  return iterator(__ptr);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh) {
  if (__nh.empty())
    return end();

  __node_pointer __ptr = __nh.__ptr_;
  __end_node_pointer __parent;
  __node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__get_value());
  __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
  __nh.__release_ptr();
  return iterator(__ptr);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Tree>
_LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) {
  static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");

  for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
    __node_pointer __src_ptr = __i.__get_np();
    __end_node_pointer __parent;
    __node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__get_value());
    ++__i;
    __source.__remove_node_pointer(__src_ptr);
    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr));
  }
}

#endif // _LIBCPP_STD_VER >= 17

template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) {
  __node_pointer __np    = __p.__get_np();
  iterator __r           = __remove_node_pointer(__np);
  __node_allocator& __na = __node_alloc();
  __node_traits::destroy(__na, std::addressof(const_cast<value_type&>(*__p)));
  __node_traits::deallocate(__na, __np, 1);
  return __r;
}

template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) {
  while (__f != __l)
    __f = erase(__f);
  return iterator(__l.__ptr_);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) {
  iterator __i = find(__k);
  if (__i == end())
    return 0;
  erase(__i);
  return 1;
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) {
  pair<iterator, iterator> __p = __equal_range_multi(__k);
  size_type __r                = 0;
  for (; __p.first != __p.second; ++__r)
    __p.first = erase(__p.first);
  return __r;
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const {
  __node_pointer __rt = __root();
  auto __comp         = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
  while (__rt != nullptr) {
    auto __comp_res = __comp(__k, __rt->__get_value());
    if (__comp_res.__less()) {
      __rt = static_cast<__node_pointer>(__rt->__left_);
    } else if (__comp_res.__greater())
      __rt = static_cast<__node_pointer>(__rt->__right_);
    else
      return 1;
  }
  return 0;
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const {
  __end_node_pointer __result = __end_node();
  __node_pointer __rt         = __root();
  auto __comp                 = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
  while (__rt != nullptr) {
    auto __comp_res = __comp(__k, __rt->__get_value());
    if (__comp_res.__less()) {
      __result = static_cast<__end_node_pointer>(__rt);
      __rt     = static_cast<__node_pointer>(__rt->__left_);
    } else if (__comp_res.__greater())
      __rt = static_cast<__node_pointer>(__rt->__right_);
    else
      return std::distance(
          __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
          __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
  }
  return 0;
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
  while (__root != nullptr) {
    if (!value_comp()(__root->__get_value(), __v)) {
      __result = static_cast<__end_node_pointer>(__root);
      __root   = static_cast<__node_pointer>(__root->__left_);
    } else
      __root = static_cast<__node_pointer>(__root->__right_);
  }
  return iterator(__result);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(
    const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
  while (__root != nullptr) {
    if (!value_comp()(__root->__get_value(), __v)) {
      __result = static_cast<__end_node_pointer>(__root);
      __root   = static_cast<__node_pointer>(__root->__left_);
    } else
      __root = static_cast<__node_pointer>(__root->__right_);
  }
  return const_iterator(__result);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
  while (__root != nullptr) {
    if (value_comp()(__v, __root->__get_value())) {
      __result = static_cast<__end_node_pointer>(__root);
      __root   = static_cast<__node_pointer>(__root->__left_);
    } else
      __root = static_cast<__node_pointer>(__root->__right_);
  }
  return iterator(__result);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(
    const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
  while (__root != nullptr) {
    if (value_comp()(__v, __root->__get_value())) {
      __result = static_cast<__end_node_pointer>(__root);
      __root   = static_cast<__node_pointer>(__root->__left_);
    } else
      __root = static_cast<__node_pointer>(__root->__right_);
  }
  return const_iterator(__result);
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
  using _Pp                   = pair<iterator, iterator>;
  __end_node_pointer __result = __end_node();
  __node_pointer __rt         = __root();
  auto __comp                 = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
  while (__rt != nullptr) {
    auto __comp_res = __comp(__k, __rt->__get_value());
    if (__comp_res.__less()) {
      __result = static_cast<__end_node_pointer>(__rt);
      __rt     = static_cast<__node_pointer>(__rt->__left_);
    } else if (__comp_res.__greater())
      __rt = static_cast<__node_pointer>(__rt->__right_);
    else
      return _Pp(iterator(__rt),
                 iterator(__rt->__right_ != nullptr ? static_cast<__end_node_pointer>(std::__tree_min(__rt->__right_))
                                                    : __result));
  }
  return _Pp(iterator(__result), iterator(__result));
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const {
  using _Pp                   = pair<const_iterator, const_iterator>;
  __end_node_pointer __result = __end_node();
  __node_pointer __rt         = __root();
  auto __comp                 = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
  while (__rt != nullptr) {
    auto __comp_res = __comp(__k, __rt->__get_value());
    if (__comp_res.__less()) {
      __result = static_cast<__end_node_pointer>(__rt);
      __rt     = static_cast<__node_pointer>(__rt->__left_);
    } else if (__comp_res.__greater())
      __rt = static_cast<__node_pointer>(__rt->__right_);
    else
      return _Pp(
          const_iterator(__rt),
          const_iterator(
              __rt->__right_ != nullptr ? static_cast<__end_node_pointer>(std::__tree_min(__rt->__right_)) : __result));
  }
  return _Pp(const_iterator(__result), const_iterator(__result));
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
  using _Pp                   = pair<iterator, iterator>;
  __end_node_pointer __result = __end_node();
  __node_pointer __rt         = __root();
  auto __comp                 = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
  while (__rt != nullptr) {
    auto __comp_res = __comp(__k, __rt->__get_value());
    if (__comp_res.__less()) {
      __result = static_cast<__end_node_pointer>(__rt);
      __rt     = static_cast<__node_pointer>(__rt->__left_);
    } else if (__comp_res.__greater())
      __rt = static_cast<__node_pointer>(__rt->__right_);
    else
      return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
                 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
  }
  return _Pp(iterator(__result), iterator(__result));
}

template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const {
  using _Pp                   = pair<const_iterator, const_iterator>;
  __end_node_pointer __result = __end_node();
  __node_pointer __rt         = __root();
  auto __comp                 = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
  while (__rt != nullptr) {
    auto __comp_res = __comp(__k, __rt->__get_value());
    if (__comp_res.__less()) {
      __result = static_cast<__end_node_pointer>(__rt);
      __rt     = static_cast<__node_pointer>(__rt->__left_);
    } else if (__comp_res.__greater())
      __rt = static_cast<__node_pointer>(__rt->__right_);
    else
      return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
                 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
  }
  return _Pp(const_iterator(__result), const_iterator(__result));
}

template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::__node_holder
__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT {
  __node_pointer __np = __p.__get_np();
  if (__begin_node_ == __p.__ptr_) {
    if (__np->__right_ != nullptr)
      __begin_node_ = static_cast<__end_node_pointer>(__np->__right_);
    else
      __begin_node_ = static_cast<__end_node_pointer>(__np->__parent_);
  }
  --__size_;
  std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np));
  return __node_holder(__np, _Dp(__node_alloc(), true));
}

template <class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI void swap(__tree<_Tp, _Compare, _Allocator>& __x, __tree<_Tp, _Compare, _Allocator>& __y)
    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
  __x.swap(__y);
}

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___TREE
