// -*- 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/make_transparent.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&& __transparent            = std::__as_transparent(value_comp());
  auto __comp = __lazy_synth_three_way_comparator<__make_transparent_t<_Compare>, _Key, value_type>(__transparent);

  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
