xref: /llvm-project-15.0.7/libcxx/include/__tree (revision f4fb72e6)
13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP___TREE
113e519524SHoward Hinnant#define _LIBCPP___TREE
123e519524SHoward Hinnant
132e2f3158SNikolas Klauser#include <__algorithm/min.h>
143cd4531bSNikolas Klauser#include <__assert>
153e519524SHoward Hinnant#include <__config>
163cd4531bSNikolas Klauser#include <__debug>
173cd4531bSNikolas Klauser#include <__iterator/distance.h>
183cd4531bSNikolas Klauser#include <__iterator/iterator_traits.h>
193cd4531bSNikolas Klauser#include <__iterator/next.h>
20*f4fb72e6SNikolas Klauser#include <__memory/swap_allocator.h>
216adbc83eSChristopher Di Bella#include <__utility/forward.h>
2252915d78SNikolas Klauser#include <__utility/swap.h>
2369d5a666SChristopher Di Bella#include <limits>
243e519524SHoward Hinnant#include <memory>
253e519524SHoward Hinnant#include <stdexcept>
263e519524SHoward Hinnant
27073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
283e519524SHoward Hinnant#  pragma GCC system_header
29073458b1SHoward Hinnant#endif
303e519524SHoward Hinnant
31a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS
32a016efb1SEric Fiselier#include <__undef_macros>
33a016efb1SEric Fiselier
34a016efb1SEric Fiselier
353e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
363e519524SHoward Hinnant
3728166dd9SMarshall Clowtemplate <class, class, class, class> class _LIBCPP_TEMPLATE_VIS map;
3828166dd9SMarshall Clowtemplate <class, class, class, class> class _LIBCPP_TEMPLATE_VIS multimap;
3928166dd9SMarshall Clowtemplate <class, class, class> class _LIBCPP_TEMPLATE_VIS set;
4028166dd9SMarshall Clowtemplate <class, class, class> class _LIBCPP_TEMPLATE_VIS multiset;
4128166dd9SMarshall Clow
42ce53420eSHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator> class __tree;
43ce53420eSHoward Hinnanttemplate <class _Tp, class _NodePtr, class _DiffType>
44e2f2d1edSEric Fiselier    class _LIBCPP_TEMPLATE_VIS __tree_iterator;
45ce53420eSHoward Hinnanttemplate <class _Tp, class _ConstNodePtr, class _DiffType>
46e2f2d1edSEric Fiselier    class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
473e519524SHoward Hinnant
48089a7cc5SEric Fiseliertemplate <class _Pointer> class __tree_end_node;
49089a7cc5SEric Fiseliertemplate <class _VoidPtr> class __tree_node_base;
50089a7cc5SEric Fiseliertemplate <class _Tp, class _VoidPtr> class __tree_node;
51089a7cc5SEric Fiselier
52089a7cc5SEric Fiseliertemplate <class _Key, class _Value>
53089a7cc5SEric Fiselierstruct __value_type;
54089a7cc5SEric Fiselier
55089a7cc5SEric Fiseliertemplate <class _Allocator> class __map_node_destructor;
56e2f2d1edSEric Fiseliertemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
57e2f2d1edSEric Fiseliertemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
58089a7cc5SEric Fiselier
593e519524SHoward Hinnant/*
603e519524SHoward Hinnant
613e519524SHoward Hinnant_NodePtr algorithms
623e519524SHoward Hinnant
633e519524SHoward HinnantThe algorithms taking _NodePtr are red black tree algorithms.  Those
643e519524SHoward Hinnantalgorithms taking a parameter named __root should assume that __root
653e519524SHoward Hinnantpoints to a proper red black tree (unless otherwise specified).
663e519524SHoward Hinnant
673e519524SHoward HinnantEach algorithm herein assumes that __root->__parent_ points to a non-null
683e519524SHoward Hinnantstructure which has a member __left_ which points back to __root.  No other
693e519524SHoward Hinnantmember is read or written to at __root->__parent_.
703e519524SHoward Hinnant
713e519524SHoward Hinnant__root->__parent_ will be referred to below (in comments only) as end_node.
723e519524SHoward Hinnantend_node->__left_ is an externably accessible lvalue for __root, and can be
733e519524SHoward Hinnantchanged by node insertion and removal (without explicit reference to end_node).
743e519524SHoward Hinnant
753e519524SHoward HinnantAll nodes (with the exception of end_node), even the node referred to as
763e519524SHoward Hinnant__root, have a non-null __parent_ field.
773e519524SHoward Hinnant
783e519524SHoward Hinnant*/
793e519524SHoward Hinnant
803e519524SHoward Hinnant// Returns:  true if __x is a left child of its parent, else false
813e519524SHoward Hinnant// Precondition:  __x != nullptr.
823e519524SHoward Hinnanttemplate <class _NodePtr>
83f5ab703fSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
843e519524SHoward Hinnantbool
85e6913510SHoward Hinnant__tree_is_left_child(_NodePtr __x) _NOEXCEPT
863e519524SHoward Hinnant{
873e519524SHoward Hinnant    return __x == __x->__parent_->__left_;
883e519524SHoward Hinnant}
893e519524SHoward Hinnant
907e680f15SJoerg Sonnenberger// Determines if the subtree rooted at __x is a proper red black subtree.  If
913e519524SHoward Hinnant//    __x is a proper subtree, returns the black height (null counts as 1).  If
923e519524SHoward Hinnant//    __x is an improper subtree, returns 0.
933e519524SHoward Hinnanttemplate <class _NodePtr>
943e519524SHoward Hinnantunsigned
953e519524SHoward Hinnant__tree_sub_invariant(_NodePtr __x)
963e519524SHoward Hinnant{
973e519524SHoward Hinnant    if (__x == nullptr)
983e519524SHoward Hinnant        return 1;
993e519524SHoward Hinnant    // parent consistency checked by caller
1003e519524SHoward Hinnant    // check __x->__left_ consistency
1013e519524SHoward Hinnant    if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
1023e519524SHoward Hinnant        return 0;
1033e519524SHoward Hinnant    // check __x->__right_ consistency
1043e519524SHoward Hinnant    if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
1053e519524SHoward Hinnant        return 0;
1063e519524SHoward Hinnant    // check __x->__left_ != __x->__right_ unless both are nullptr
1073e519524SHoward Hinnant    if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
1083e519524SHoward Hinnant        return 0;
1093e519524SHoward Hinnant    // If this is red, neither child can be red
1103e519524SHoward Hinnant    if (!__x->__is_black_)
1113e519524SHoward Hinnant    {
1123e519524SHoward Hinnant        if (__x->__left_ && !__x->__left_->__is_black_)
1133e519524SHoward Hinnant            return 0;
1143e519524SHoward Hinnant        if (__x->__right_ && !__x->__right_->__is_black_)
1153e519524SHoward Hinnant            return 0;
1163e519524SHoward Hinnant    }
117781c476cSArthur O'Dwyer    unsigned __h = _VSTD::__tree_sub_invariant(__x->__left_);
1183e519524SHoward Hinnant    if (__h == 0)
1193e519524SHoward Hinnant        return 0;  // invalid left subtree
120781c476cSArthur O'Dwyer    if (__h != _VSTD::__tree_sub_invariant(__x->__right_))
1213e519524SHoward Hinnant        return 0;  // invalid or different height right subtree
1223e519524SHoward Hinnant    return __h + __x->__is_black_;  // return black height of this node
1233e519524SHoward Hinnant}
1243e519524SHoward Hinnant
1257e680f15SJoerg Sonnenberger// Determines if the red black tree rooted at __root is a proper red black tree.
1263e519524SHoward Hinnant//    __root == nullptr is a proper tree.  Returns true is __root is a proper
1273e519524SHoward Hinnant//    red black tree, else returns false.
1283e519524SHoward Hinnanttemplate <class _NodePtr>
1293e519524SHoward Hinnantbool
1303e519524SHoward Hinnant__tree_invariant(_NodePtr __root)
1313e519524SHoward Hinnant{
1323e519524SHoward Hinnant    if (__root == nullptr)
1333e519524SHoward Hinnant        return true;
1343e519524SHoward Hinnant    // check __x->__parent_ consistency
1353e519524SHoward Hinnant    if (__root->__parent_ == nullptr)
1363e519524SHoward Hinnant        return false;
137781c476cSArthur O'Dwyer    if (!_VSTD::__tree_is_left_child(__root))
1383e519524SHoward Hinnant        return false;
1393e519524SHoward Hinnant    // root must be black
1403e519524SHoward Hinnant    if (!__root->__is_black_)
1413e519524SHoward Hinnant        return false;
1423e519524SHoward Hinnant    // do normal node checks
143781c476cSArthur O'Dwyer    return _VSTD::__tree_sub_invariant(__root) != 0;
1443e519524SHoward Hinnant}
1453e519524SHoward Hinnant
1463e519524SHoward Hinnant// Returns:  pointer to the left-most node under __x.
1473e519524SHoward Hinnanttemplate <class _NodePtr>
148f5ab703fSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1493e519524SHoward Hinnant_NodePtr
150e6913510SHoward Hinnant__tree_min(_NodePtr __x) _NOEXCEPT
1513e519524SHoward Hinnant{
152990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
1533e519524SHoward Hinnant    while (__x->__left_ != nullptr)
1543e519524SHoward Hinnant        __x = __x->__left_;
1553e519524SHoward Hinnant    return __x;
1563e519524SHoward Hinnant}
1573e519524SHoward Hinnant
1583e519524SHoward Hinnant// Returns:  pointer to the right-most node under __x.
1593e519524SHoward Hinnanttemplate <class _NodePtr>
160f5ab703fSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1613e519524SHoward Hinnant_NodePtr
162e6913510SHoward Hinnant__tree_max(_NodePtr __x) _NOEXCEPT
1633e519524SHoward Hinnant{
164990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
1653e519524SHoward Hinnant    while (__x->__right_ != nullptr)
1663e519524SHoward Hinnant        __x = __x->__right_;
1673e519524SHoward Hinnant    return __x;
1683e519524SHoward Hinnant}
1693e519524SHoward Hinnant
1703e519524SHoward Hinnant// Returns:  pointer to the next in-order node after __x.
1713e519524SHoward Hinnanttemplate <class _NodePtr>
1723e519524SHoward Hinnant_NodePtr
173e6913510SHoward Hinnant__tree_next(_NodePtr __x) _NOEXCEPT
1743e519524SHoward Hinnant{
175990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
1763e519524SHoward Hinnant    if (__x->__right_ != nullptr)
177781c476cSArthur O'Dwyer        return _VSTD::__tree_min(__x->__right_);
178781c476cSArthur O'Dwyer    while (!_VSTD::__tree_is_left_child(__x))
179d05b10abSEric Fiselier        __x = __x->__parent_unsafe();
180d05b10abSEric Fiselier    return __x->__parent_unsafe();
181d05b10abSEric Fiselier}
182d05b10abSEric Fiselier
183d05b10abSEric Fiseliertemplate <class _EndNodePtr, class _NodePtr>
184d05b10abSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
185d05b10abSEric Fiselier_EndNodePtr
186d05b10abSEric Fiselier__tree_next_iter(_NodePtr __x) _NOEXCEPT
187d05b10abSEric Fiselier{
188990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
189d05b10abSEric Fiselier    if (__x->__right_ != nullptr)
190781c476cSArthur O'Dwyer        return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_));
191781c476cSArthur O'Dwyer    while (!_VSTD::__tree_is_left_child(__x))
192d05b10abSEric Fiselier        __x = __x->__parent_unsafe();
193d05b10abSEric Fiselier    return static_cast<_EndNodePtr>(__x->__parent_);
1943e519524SHoward Hinnant}
1953e519524SHoward Hinnant
1963e519524SHoward Hinnant// Returns:  pointer to the previous in-order node before __x.
197d05b10abSEric Fiselier// Note: __x may be the end node.
198d05b10abSEric Fiseliertemplate <class _NodePtr, class _EndNodePtr>
199d05b10abSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
2003e519524SHoward Hinnant_NodePtr
201d05b10abSEric Fiselier__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
2023e519524SHoward Hinnant{
203990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
2043e519524SHoward Hinnant    if (__x->__left_ != nullptr)
205781c476cSArthur O'Dwyer        return _VSTD::__tree_max(__x->__left_);
206d05b10abSEric Fiselier    _NodePtr __xx = static_cast<_NodePtr>(__x);
207781c476cSArthur O'Dwyer    while (_VSTD::__tree_is_left_child(__xx))
208d05b10abSEric Fiselier        __xx = __xx->__parent_unsafe();
209d05b10abSEric Fiselier    return __xx->__parent_unsafe();
2103e519524SHoward Hinnant}
2113e519524SHoward Hinnant
2123e519524SHoward Hinnant// Returns:  pointer to a node which has no children
2133e519524SHoward Hinnanttemplate <class _NodePtr>
2143e519524SHoward Hinnant_NodePtr
215e6913510SHoward Hinnant__tree_leaf(_NodePtr __x) _NOEXCEPT
2163e519524SHoward Hinnant{
217990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
2183e519524SHoward Hinnant    while (true)
2193e519524SHoward Hinnant    {
2203e519524SHoward Hinnant        if (__x->__left_ != nullptr)
2213e519524SHoward Hinnant        {
2223e519524SHoward Hinnant            __x = __x->__left_;
2233e519524SHoward Hinnant            continue;
2243e519524SHoward Hinnant        }
2253e519524SHoward Hinnant        if (__x->__right_ != nullptr)
2263e519524SHoward Hinnant        {
2273e519524SHoward Hinnant            __x = __x->__right_;
2283e519524SHoward Hinnant            continue;
2293e519524SHoward Hinnant        }
2303e519524SHoward Hinnant        break;
2313e519524SHoward Hinnant    }
2323e519524SHoward Hinnant    return __x;
2333e519524SHoward Hinnant}
2343e519524SHoward Hinnant
2353e519524SHoward Hinnant// Effects:  Makes __x->__right_ the subtree root with __x as its left child
2363e519524SHoward Hinnant//           while preserving in-order order.
2373e519524SHoward Hinnanttemplate <class _NodePtr>
2383e519524SHoward Hinnantvoid
239e6913510SHoward Hinnant__tree_left_rotate(_NodePtr __x) _NOEXCEPT
2403e519524SHoward Hinnant{
241990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
242990ea392SLouis Dionne    _LIBCPP_ASSERT(__x->__right_ != nullptr, "node should have a right child");
2433e519524SHoward Hinnant    _NodePtr __y = __x->__right_;
2443e519524SHoward Hinnant    __x->__right_ = __y->__left_;
2453e519524SHoward Hinnant    if (__x->__right_ != nullptr)
246d05b10abSEric Fiselier        __x->__right_->__set_parent(__x);
2473e519524SHoward Hinnant    __y->__parent_ = __x->__parent_;
248781c476cSArthur O'Dwyer    if (_VSTD::__tree_is_left_child(__x))
2493e519524SHoward Hinnant        __x->__parent_->__left_ = __y;
2503e519524SHoward Hinnant    else
251d05b10abSEric Fiselier        __x->__parent_unsafe()->__right_ = __y;
2523e519524SHoward Hinnant    __y->__left_ = __x;
253d05b10abSEric Fiselier    __x->__set_parent(__y);
2543e519524SHoward Hinnant}
2553e519524SHoward Hinnant
2563e519524SHoward Hinnant// Effects:  Makes __x->__left_ the subtree root with __x as its right child
2573e519524SHoward Hinnant//           while preserving in-order order.
2583e519524SHoward Hinnanttemplate <class _NodePtr>
2593e519524SHoward Hinnantvoid
260e6913510SHoward Hinnant__tree_right_rotate(_NodePtr __x) _NOEXCEPT
2613e519524SHoward Hinnant{
262990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
263990ea392SLouis Dionne    _LIBCPP_ASSERT(__x->__left_ != nullptr, "node should have a left child");
2643e519524SHoward Hinnant    _NodePtr __y = __x->__left_;
2653e519524SHoward Hinnant    __x->__left_ = __y->__right_;
2663e519524SHoward Hinnant    if (__x->__left_ != nullptr)
267d05b10abSEric Fiselier        __x->__left_->__set_parent(__x);
2683e519524SHoward Hinnant    __y->__parent_ = __x->__parent_;
269781c476cSArthur O'Dwyer    if (_VSTD::__tree_is_left_child(__x))
2703e519524SHoward Hinnant        __x->__parent_->__left_ = __y;
2713e519524SHoward Hinnant    else
272d05b10abSEric Fiselier        __x->__parent_unsafe()->__right_ = __y;
2733e519524SHoward Hinnant    __y->__right_ = __x;
274d05b10abSEric Fiselier    __x->__set_parent(__y);
2753e519524SHoward Hinnant}
2763e519524SHoward Hinnant
2773e519524SHoward Hinnant// Effects:  Rebalances __root after attaching __x to a leaf.
278990ea392SLouis Dionne// Precondition:  __x has no children.
2793e519524SHoward Hinnant//                __x == __root or == a direct or indirect child of __root.
2803e519524SHoward Hinnant//                If __x were to be unlinked from __root (setting __root to
2813e519524SHoward Hinnant//                  nullptr if __root == __x), __tree_invariant(__root) == true.
2823e519524SHoward Hinnant// Postcondition: __tree_invariant(end_node->__left_) == true.  end_node->__left_
2833e519524SHoward Hinnant//                may be different than the value passed in as __root.
2843e519524SHoward Hinnanttemplate <class _NodePtr>
2853e519524SHoward Hinnantvoid
286e6913510SHoward Hinnant__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
2873e519524SHoward Hinnant{
288990ea392SLouis Dionne    _LIBCPP_ASSERT(__root != nullptr, "Root of the tree shouldn't be null");
289990ea392SLouis Dionne    _LIBCPP_ASSERT(__x != nullptr, "Can't attach null node to a leaf");
2903e519524SHoward Hinnant    __x->__is_black_ = __x == __root;
291d05b10abSEric Fiselier    while (__x != __root && !__x->__parent_unsafe()->__is_black_)
2923e519524SHoward Hinnant    {
2933e519524SHoward Hinnant        // __x->__parent_ != __root because __x->__parent_->__is_black == false
294781c476cSArthur O'Dwyer        if (_VSTD::__tree_is_left_child(__x->__parent_unsafe()))
2953e519524SHoward Hinnant        {
296d05b10abSEric Fiselier            _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
2973e519524SHoward Hinnant            if (__y != nullptr && !__y->__is_black_)
2983e519524SHoward Hinnant            {
299d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3003e519524SHoward Hinnant                __x->__is_black_ = true;
301d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3023e519524SHoward Hinnant                __x->__is_black_ = __x == __root;
3033e519524SHoward Hinnant                __y->__is_black_ = true;
3043e519524SHoward Hinnant            }
3053e519524SHoward Hinnant            else
3063e519524SHoward Hinnant            {
307781c476cSArthur O'Dwyer                if (!_VSTD::__tree_is_left_child(__x))
3083e519524SHoward Hinnant                {
309d05b10abSEric Fiselier                    __x = __x->__parent_unsafe();
310781c476cSArthur O'Dwyer                    _VSTD::__tree_left_rotate(__x);
3113e519524SHoward Hinnant                }
312d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3133e519524SHoward Hinnant                __x->__is_black_ = true;
314d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3153e519524SHoward Hinnant                __x->__is_black_ = false;
316781c476cSArthur O'Dwyer                _VSTD::__tree_right_rotate(__x);
3173e519524SHoward Hinnant                break;
3183e519524SHoward Hinnant            }
3193e519524SHoward Hinnant        }
3203e519524SHoward Hinnant        else
3213e519524SHoward Hinnant        {
322d05b10abSEric Fiselier            _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
3233e519524SHoward Hinnant            if (__y != nullptr && !__y->__is_black_)
3243e519524SHoward Hinnant            {
325d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3263e519524SHoward Hinnant                __x->__is_black_ = true;
327d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3283e519524SHoward Hinnant                __x->__is_black_ = __x == __root;
3293e519524SHoward Hinnant                __y->__is_black_ = true;
3303e519524SHoward Hinnant            }
3313e519524SHoward Hinnant            else
3323e519524SHoward Hinnant            {
333781c476cSArthur O'Dwyer                if (_VSTD::__tree_is_left_child(__x))
3343e519524SHoward Hinnant                {
335d05b10abSEric Fiselier                    __x = __x->__parent_unsafe();
336781c476cSArthur O'Dwyer                    _VSTD::__tree_right_rotate(__x);
3373e519524SHoward Hinnant                }
338d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3393e519524SHoward Hinnant                __x->__is_black_ = true;
340d05b10abSEric Fiselier                __x = __x->__parent_unsafe();
3413e519524SHoward Hinnant                __x->__is_black_ = false;
342781c476cSArthur O'Dwyer                _VSTD::__tree_left_rotate(__x);
3433e519524SHoward Hinnant                break;
3443e519524SHoward Hinnant            }
3453e519524SHoward Hinnant        }
3463e519524SHoward Hinnant    }
3473e519524SHoward Hinnant}
3483e519524SHoward Hinnant
349990ea392SLouis Dionne// Precondition:  __z == __root or == a direct or indirect child of __root.
3503e519524SHoward Hinnant// Effects:  unlinks __z from the tree rooted at __root, rebalancing as needed.
3513e519524SHoward Hinnant// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
3523e519524SHoward Hinnant//                nor any of its children refer to __z.  end_node->__left_
3533e519524SHoward Hinnant//                may be different than the value passed in as __root.
3543e519524SHoward Hinnanttemplate <class _NodePtr>
3553e519524SHoward Hinnantvoid
356e6913510SHoward Hinnant__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
3573e519524SHoward Hinnant{
358990ea392SLouis Dionne    _LIBCPP_ASSERT(__root != nullptr, "Root node should not be null");
359990ea392SLouis Dionne    _LIBCPP_ASSERT(__z != nullptr, "The node to remove should not be null");
360990ea392SLouis Dionne    _LIBCPP_DEBUG_ASSERT(__tree_invariant(__root), "The tree invariants should hold");
3613e519524SHoward Hinnant    // __z will be removed from the tree.  Client still needs to destruct/deallocate it
3623e519524SHoward Hinnant    // __y is either __z, or if __z has two children, __tree_next(__z).
3633e519524SHoward Hinnant    // __y will have at most one child.
3643e519524SHoward Hinnant    // __y will be the initial hole in the tree (make the hole at a leaf)
3653e519524SHoward Hinnant    _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
366781c476cSArthur O'Dwyer                    __z : _VSTD::__tree_next(__z);
3673e519524SHoward Hinnant    // __x is __y's possibly null single child
3683e519524SHoward Hinnant    _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
3693e519524SHoward Hinnant    // __w is __x's possibly null uncle (will become __x's sibling)
3703e519524SHoward Hinnant    _NodePtr __w = nullptr;
3713e519524SHoward Hinnant    // link __x to __y's parent, and find __w
3723e519524SHoward Hinnant    if (__x != nullptr)
3733e519524SHoward Hinnant        __x->__parent_ = __y->__parent_;
374781c476cSArthur O'Dwyer    if (_VSTD::__tree_is_left_child(__y))
3753e519524SHoward Hinnant    {
3763e519524SHoward Hinnant        __y->__parent_->__left_ = __x;
3773e519524SHoward Hinnant        if (__y != __root)
378d05b10abSEric Fiselier            __w = __y->__parent_unsafe()->__right_;
3793e519524SHoward Hinnant        else
3803e519524SHoward Hinnant            __root = __x;  // __w == nullptr
3813e519524SHoward Hinnant    }
3823e519524SHoward Hinnant    else
3833e519524SHoward Hinnant    {
384d05b10abSEric Fiselier        __y->__parent_unsafe()->__right_ = __x;
3853e519524SHoward Hinnant        // __y can't be root if it is a right child
3863e519524SHoward Hinnant        __w = __y->__parent_->__left_;
3873e519524SHoward Hinnant    }
3883e519524SHoward Hinnant    bool __removed_black = __y->__is_black_;
3893e519524SHoward Hinnant    // If we didn't remove __z, do so now by splicing in __y for __z,
3903e519524SHoward Hinnant    //    but copy __z's color.  This does not impact __x or __w.
3913e519524SHoward Hinnant    if (__y != __z)
3923e519524SHoward Hinnant    {
3933e519524SHoward Hinnant        // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
3943e519524SHoward Hinnant        __y->__parent_ = __z->__parent_;
395781c476cSArthur O'Dwyer        if (_VSTD::__tree_is_left_child(__z))
3963e519524SHoward Hinnant            __y->__parent_->__left_ = __y;
3973e519524SHoward Hinnant        else
398d05b10abSEric Fiselier            __y->__parent_unsafe()->__right_ = __y;
3993e519524SHoward Hinnant        __y->__left_ = __z->__left_;
400d05b10abSEric Fiselier        __y->__left_->__set_parent(__y);
4013e519524SHoward Hinnant        __y->__right_ = __z->__right_;
4023e519524SHoward Hinnant        if (__y->__right_ != nullptr)
403d05b10abSEric Fiselier            __y->__right_->__set_parent(__y);
4043e519524SHoward Hinnant        __y->__is_black_ = __z->__is_black_;
4053e519524SHoward Hinnant        if (__root == __z)
4063e519524SHoward Hinnant            __root = __y;
4073e519524SHoward Hinnant    }
4083e519524SHoward Hinnant    // There is no need to rebalance if we removed a red, or if we removed
4093e519524SHoward Hinnant    //     the last node.
4103e519524SHoward Hinnant    if (__removed_black && __root != nullptr)
4113e519524SHoward Hinnant    {
4123e519524SHoward Hinnant        // Rebalance:
4133e519524SHoward Hinnant        // __x has an implicit black color (transferred from the removed __y)
4143e519524SHoward Hinnant        //    associated with it, no matter what its color is.
4153e519524SHoward Hinnant        // If __x is __root (in which case it can't be null), it is supposed
4163e519524SHoward Hinnant        //    to be black anyway, and if it is doubly black, then the double
4173e519524SHoward Hinnant        //    can just be ignored.
4183e519524SHoward Hinnant        // If __x is red (in which case it can't be null), then it can absorb
4193e519524SHoward Hinnant        //    the implicit black just by setting its color to black.
4203e519524SHoward Hinnant        // Since __y was black and only had one child (which __x points to), __x
4213e519524SHoward Hinnant        //   is either red with no children, else null, otherwise __y would have
4223e519524SHoward Hinnant        //   different black heights under left and right pointers.
4233e519524SHoward Hinnant        // if (__x == __root || __x != nullptr && !__x->__is_black_)
4243e519524SHoward Hinnant        if (__x != nullptr)
4253e519524SHoward Hinnant            __x->__is_black_ = true;
4263e519524SHoward Hinnant        else
4273e519524SHoward Hinnant        {
4283e519524SHoward Hinnant            //  Else __x isn't root, and is "doubly black", even though it may
4293e519524SHoward Hinnant            //     be null.  __w can not be null here, else the parent would
4303e519524SHoward Hinnant            //     see a black height >= 2 on the __x side and a black height
4313e519524SHoward Hinnant            //     of 1 on the __w side (__w must be a non-null black or a red
4323e519524SHoward Hinnant            //     with a non-null black child).
4333e519524SHoward Hinnant            while (true)
4343e519524SHoward Hinnant            {
435781c476cSArthur O'Dwyer                if (!_VSTD::__tree_is_left_child(__w))  // if x is left child
4363e519524SHoward Hinnant                {
4373e519524SHoward Hinnant                    if (!__w->__is_black_)
4383e519524SHoward Hinnant                    {
4393e519524SHoward Hinnant                        __w->__is_black_ = true;
440d05b10abSEric Fiselier                        __w->__parent_unsafe()->__is_black_ = false;
441781c476cSArthur O'Dwyer                        _VSTD::__tree_left_rotate(__w->__parent_unsafe());
4423e519524SHoward Hinnant                        // __x is still valid
4433e519524SHoward Hinnant                        // reset __root only if necessary
4443e519524SHoward Hinnant                        if (__root == __w->__left_)
4453e519524SHoward Hinnant                            __root = __w;
4463e519524SHoward Hinnant                        // reset sibling, and it still can't be null
4473e519524SHoward Hinnant                        __w = __w->__left_->__right_;
4483e519524SHoward Hinnant                    }
4493e519524SHoward Hinnant                    // __w->__is_black_ is now true, __w may have null children
4503e519524SHoward Hinnant                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
4513e519524SHoward Hinnant                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
4523e519524SHoward Hinnant                    {
4533e519524SHoward Hinnant                        __w->__is_black_ = false;
454d05b10abSEric Fiselier                        __x = __w->__parent_unsafe();
4553e519524SHoward Hinnant                        // __x can no longer be null
4563e519524SHoward Hinnant                        if (__x == __root || !__x->__is_black_)
4573e519524SHoward Hinnant                        {
4583e519524SHoward Hinnant                            __x->__is_black_ = true;
4593e519524SHoward Hinnant                            break;
4603e519524SHoward Hinnant                        }
4613e519524SHoward Hinnant                        // reset sibling, and it still can't be null
462781c476cSArthur O'Dwyer                        __w = _VSTD::__tree_is_left_child(__x) ?
463d05b10abSEric Fiselier                                    __x->__parent_unsafe()->__right_ :
4643e519524SHoward Hinnant                                    __x->__parent_->__left_;
4653e519524SHoward Hinnant                        // continue;
4663e519524SHoward Hinnant                    }
4673e519524SHoward Hinnant                    else  // __w has a red child
4683e519524SHoward Hinnant                    {
4693e519524SHoward Hinnant                        if (__w->__right_ == nullptr || __w->__right_->__is_black_)
4703e519524SHoward Hinnant                        {
4713e519524SHoward Hinnant                            // __w left child is non-null and red
4723e519524SHoward Hinnant                            __w->__left_->__is_black_ = true;
4733e519524SHoward Hinnant                            __w->__is_black_ = false;
474781c476cSArthur O'Dwyer                            _VSTD::__tree_right_rotate(__w);
4753e519524SHoward Hinnant                            // __w is known not to be root, so root hasn't changed
4763e519524SHoward Hinnant                            // reset sibling, and it still can't be null
477d05b10abSEric Fiselier                            __w = __w->__parent_unsafe();
4783e519524SHoward Hinnant                        }
4793e519524SHoward Hinnant                        // __w has a right red child, left child may be null
480d05b10abSEric Fiselier                        __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
481d05b10abSEric Fiselier                        __w->__parent_unsafe()->__is_black_ = true;
4823e519524SHoward Hinnant                        __w->__right_->__is_black_ = true;
483781c476cSArthur O'Dwyer                        _VSTD::__tree_left_rotate(__w->__parent_unsafe());
4843e519524SHoward Hinnant                        break;
4853e519524SHoward Hinnant                    }
4863e519524SHoward Hinnant                }
4873e519524SHoward Hinnant                else
4883e519524SHoward Hinnant                {
4893e519524SHoward Hinnant                    if (!__w->__is_black_)
4903e519524SHoward Hinnant                    {
4913e519524SHoward Hinnant                        __w->__is_black_ = true;
492d05b10abSEric Fiselier                        __w->__parent_unsafe()->__is_black_ = false;
493781c476cSArthur O'Dwyer                        _VSTD::__tree_right_rotate(__w->__parent_unsafe());
4943e519524SHoward Hinnant                        // __x is still valid
4953e519524SHoward Hinnant                        // reset __root only if necessary
4963e519524SHoward Hinnant                        if (__root == __w->__right_)
4973e519524SHoward Hinnant                            __root = __w;
4983e519524SHoward Hinnant                        // reset sibling, and it still can't be null
4993e519524SHoward Hinnant                        __w = __w->__right_->__left_;
5003e519524SHoward Hinnant                    }
5013e519524SHoward Hinnant                    // __w->__is_black_ is now true, __w may have null children
5023e519524SHoward Hinnant                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
5033e519524SHoward Hinnant                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
5043e519524SHoward Hinnant                    {
5053e519524SHoward Hinnant                        __w->__is_black_ = false;
506d05b10abSEric Fiselier                        __x = __w->__parent_unsafe();
5073e519524SHoward Hinnant                        // __x can no longer be null
5083e519524SHoward Hinnant                        if (!__x->__is_black_ || __x == __root)
5093e519524SHoward Hinnant                        {
5103e519524SHoward Hinnant                            __x->__is_black_ = true;
5113e519524SHoward Hinnant                            break;
5123e519524SHoward Hinnant                        }
5133e519524SHoward Hinnant                        // reset sibling, and it still can't be null
514781c476cSArthur O'Dwyer                        __w = _VSTD::__tree_is_left_child(__x) ?
515d05b10abSEric Fiselier                                    __x->__parent_unsafe()->__right_ :
5163e519524SHoward Hinnant                                    __x->__parent_->__left_;
5173e519524SHoward Hinnant                        // continue;
5183e519524SHoward Hinnant                    }
5193e519524SHoward Hinnant                    else  // __w has a red child
5203e519524SHoward Hinnant                    {
5213e519524SHoward Hinnant                        if (__w->__left_ == nullptr || __w->__left_->__is_black_)
5223e519524SHoward Hinnant                        {
5233e519524SHoward Hinnant                            // __w right child is non-null and red
5243e519524SHoward Hinnant                            __w->__right_->__is_black_ = true;
5253e519524SHoward Hinnant                            __w->__is_black_ = false;
526781c476cSArthur O'Dwyer                            _VSTD::__tree_left_rotate(__w);
5273e519524SHoward Hinnant                            // __w is known not to be root, so root hasn't changed
5283e519524SHoward Hinnant                            // reset sibling, and it still can't be null
529d05b10abSEric Fiselier                            __w = __w->__parent_unsafe();
5303e519524SHoward Hinnant                        }
5313e519524SHoward Hinnant                        // __w has a left red child, right child may be null
532d05b10abSEric Fiselier                        __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
533d05b10abSEric Fiselier                        __w->__parent_unsafe()->__is_black_ = true;
5343e519524SHoward Hinnant                        __w->__left_->__is_black_ = true;
535781c476cSArthur O'Dwyer                        _VSTD::__tree_right_rotate(__w->__parent_unsafe());
5363e519524SHoward Hinnant                        break;
5373e519524SHoward Hinnant                    }
5383e519524SHoward Hinnant                }
5393e519524SHoward Hinnant            }
5403e519524SHoward Hinnant        }
5413e519524SHoward Hinnant    }
5423e519524SHoward Hinnant}
5433e519524SHoward Hinnant
544089a7cc5SEric Fiselier// node traits
545089a7cc5SEric Fiselier
5465e3ea4ddSEric Fiselier
5475e3ea4ddSEric Fiseliertemplate <class _Tp>
5485e3ea4ddSEric Fiselierstruct __is_tree_value_type_imp : false_type {};
5495e3ea4ddSEric Fiselier
5505e3ea4ddSEric Fiseliertemplate <class _Key, class _Value>
5515e3ea4ddSEric Fiselierstruct __is_tree_value_type_imp<__value_type<_Key, _Value> > : true_type {};
5525e3ea4ddSEric Fiselier
5535e3ea4ddSEric Fiseliertemplate <class ..._Args>
5545e3ea4ddSEric Fiselierstruct __is_tree_value_type : false_type {};
5555e3ea4ddSEric Fiselier
5565e3ea4ddSEric Fiseliertemplate <class _One>
557f7558068SNikolas Klauserstruct __is_tree_value_type<_One> : __is_tree_value_type_imp<__uncvref_t<_One> > {};
5585e3ea4ddSEric Fiselier
559089a7cc5SEric Fiseliertemplate <class _Tp>
560089a7cc5SEric Fiselierstruct __tree_key_value_types {
561089a7cc5SEric Fiselier  typedef _Tp key_type;
562089a7cc5SEric Fiselier  typedef _Tp __node_value_type;
563089a7cc5SEric Fiselier  typedef _Tp __container_value_type;
564089a7cc5SEric Fiselier  static const bool __is_map = false;
5655e3ea4ddSEric Fiselier
5665e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
5675e3ea4ddSEric Fiselier  static key_type const& __get_key(_Tp const& __v) {
5685e3ea4ddSEric Fiselier    return __v;
5695e3ea4ddSEric Fiselier  }
5705e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
5715e3ea4ddSEric Fiselier  static __container_value_type const& __get_value(__node_value_type const& __v) {
5725e3ea4ddSEric Fiselier    return __v;
5735e3ea4ddSEric Fiselier  }
5745e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
5755e3ea4ddSEric Fiselier  static __container_value_type* __get_ptr(__node_value_type& __n) {
5765e3ea4ddSEric Fiselier    return _VSTD::addressof(__n);
5775e3ea4ddSEric Fiselier  }
5785e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
5795e3ea4ddSEric Fiselier  static __container_value_type&& __move(__node_value_type& __v) {
5805e3ea4ddSEric Fiselier    return _VSTD::move(__v);
5815e3ea4ddSEric Fiselier  }
582089a7cc5SEric Fiselier};
583089a7cc5SEric Fiselier
584089a7cc5SEric Fiseliertemplate <class _Key, class _Tp>
585089a7cc5SEric Fiselierstruct __tree_key_value_types<__value_type<_Key, _Tp> > {
586089a7cc5SEric Fiselier  typedef _Key                                         key_type;
587089a7cc5SEric Fiselier  typedef _Tp                                          mapped_type;
588089a7cc5SEric Fiselier  typedef __value_type<_Key, _Tp>                      __node_value_type;
589089a7cc5SEric Fiselier  typedef pair<const _Key, _Tp>                        __container_value_type;
590089a7cc5SEric Fiselier  typedef __container_value_type                       __map_value_type;
591089a7cc5SEric Fiselier  static const bool __is_map = true;
5925e3ea4ddSEric Fiselier
5935e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
5945e3ea4ddSEric Fiselier  static key_type const&
5955e3ea4ddSEric Fiselier  __get_key(__node_value_type const& __t) {
596f52318b4SErik Pilkington    return __t.__get_value().first;
5975e3ea4ddSEric Fiselier  }
5985e3ea4ddSEric Fiselier
5995e3ea4ddSEric Fiselier  template <class _Up>
6005e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
6014887d047SNikolas Klauser  static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, key_type const&>
6025e3ea4ddSEric Fiselier  __get_key(_Up& __t) {
6035e3ea4ddSEric Fiselier    return __t.first;
6045e3ea4ddSEric Fiselier  }
6055e3ea4ddSEric Fiselier
6065e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
6075e3ea4ddSEric Fiselier  static __container_value_type const&
6085e3ea4ddSEric Fiselier  __get_value(__node_value_type const& __t) {
609f52318b4SErik Pilkington    return __t.__get_value();
6105e3ea4ddSEric Fiselier  }
6115e3ea4ddSEric Fiselier
6125e3ea4ddSEric Fiselier  template <class _Up>
6135e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
6144887d047SNikolas Klauser  static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&>
6155e3ea4ddSEric Fiselier  __get_value(_Up& __t) {
6165e3ea4ddSEric Fiselier    return __t;
6175e3ea4ddSEric Fiselier  }
6185e3ea4ddSEric Fiselier
6195e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
6205e3ea4ddSEric Fiselier  static __container_value_type* __get_ptr(__node_value_type& __n) {
621f52318b4SErik Pilkington    return _VSTD::addressof(__n.__get_value());
6225e3ea4ddSEric Fiselier  }
6235e3ea4ddSEric Fiselier
6245e3ea4ddSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
625f52318b4SErik Pilkington  static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
626f52318b4SErik Pilkington    return __v.__move();
6275e3ea4ddSEric Fiselier  }
628089a7cc5SEric Fiselier};
629089a7cc5SEric Fiselier
630089a7cc5SEric Fiseliertemplate <class _VoidPtr>
631089a7cc5SEric Fiselierstruct __tree_node_base_types {
632089a7cc5SEric Fiselier  typedef _VoidPtr                                               __void_pointer;
633089a7cc5SEric Fiselier
634089a7cc5SEric Fiselier  typedef __tree_node_base<__void_pointer>                      __node_base_type;
635089a7cc5SEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
636089a7cc5SEric Fiselier                                                             __node_base_pointer;
637089a7cc5SEric Fiselier
638089a7cc5SEric Fiselier  typedef __tree_end_node<__node_base_pointer>                  __end_node_type;
639089a7cc5SEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
640089a7cc5SEric Fiselier                                                             __end_node_pointer;
641d05b10abSEric Fiselier#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
642d05b10abSEric Fiselier  typedef __end_node_pointer __parent_pointer;
643d05b10abSEric Fiselier#else
644d05b10abSEric Fiselier  typedef typename conditional<
645d05b10abSEric Fiselier      is_pointer<__end_node_pointer>::value,
646d05b10abSEric Fiselier        __end_node_pointer,
647d05b10abSEric Fiselier        __node_base_pointer>::type __parent_pointer;
648d05b10abSEric Fiselier#endif
649d05b10abSEric Fiselier
650089a7cc5SEric Fiselierprivate:
651089a7cc5SEric Fiselier  static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
652089a7cc5SEric Fiselier                  "_VoidPtr does not point to unqualified void type");
653089a7cc5SEric Fiselier};
654089a7cc5SEric Fiselier
655089a7cc5SEric Fiseliertemplate <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>,
656089a7cc5SEric Fiselier         bool = _KVTypes::__is_map>
657089a7cc5SEric Fiselierstruct __tree_map_pointer_types {};
658089a7cc5SEric Fiselier
659089a7cc5SEric Fiseliertemplate <class _Tp, class _AllocPtr, class _KVTypes>
660089a7cc5SEric Fiselierstruct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
661089a7cc5SEric Fiselier  typedef typename _KVTypes::__map_value_type   _Mv;
662089a7cc5SEric Fiselier  typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
663089a7cc5SEric Fiselier                                                       __map_value_type_pointer;
664089a7cc5SEric Fiselier  typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
665089a7cc5SEric Fiselier                                                 __const_map_value_type_pointer;
666089a7cc5SEric Fiselier};
667089a7cc5SEric Fiselier
668089a7cc5SEric Fiseliertemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
669089a7cc5SEric Fiselierstruct __tree_node_types;
670089a7cc5SEric Fiselier
671089a7cc5SEric Fiseliertemplate <class _NodePtr, class _Tp, class _VoidPtr>
672089a7cc5SEric Fiselierstruct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> >
673089a7cc5SEric Fiselier    : public __tree_node_base_types<_VoidPtr>,
674089a7cc5SEric Fiselier             __tree_key_value_types<_Tp>,
675089a7cc5SEric Fiselier             __tree_map_pointer_types<_Tp, _VoidPtr>
676089a7cc5SEric Fiselier{
677089a7cc5SEric Fiselier  typedef __tree_node_base_types<_VoidPtr> __base;
678089a7cc5SEric Fiselier  typedef __tree_key_value_types<_Tp>      __key_base;
679089a7cc5SEric Fiselier  typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base;
680089a7cc5SEric Fiselierpublic:
681089a7cc5SEric Fiselier
682089a7cc5SEric Fiselier  typedef typename pointer_traits<_NodePtr>::element_type       __node_type;
683089a7cc5SEric Fiselier  typedef _NodePtr                                              __node_pointer;
684089a7cc5SEric Fiselier
685089a7cc5SEric Fiselier  typedef _Tp                                                 __node_value_type;
686089a7cc5SEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
687089a7cc5SEric Fiselier                                                      __node_value_type_pointer;
688089a7cc5SEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
689089a7cc5SEric Fiselier                                                __const_node_value_type_pointer;
690d05b10abSEric Fiselier#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
691d05b10abSEric Fiselier  typedef typename __base::__end_node_pointer __iter_pointer;
692d05b10abSEric Fiselier#else
693d05b10abSEric Fiselier  typedef typename conditional<
694d05b10abSEric Fiselier      is_pointer<__node_pointer>::value,
695d05b10abSEric Fiselier        typename __base::__end_node_pointer,
696d05b10abSEric Fiselier        __node_pointer>::type __iter_pointer;
697d05b10abSEric Fiselier#endif
698089a7cc5SEric Fiselierprivate:
699089a7cc5SEric Fiselier    static_assert(!is_const<__node_type>::value,
700089a7cc5SEric Fiselier                "_NodePtr should never be a pointer to const");
701089a7cc5SEric Fiselier    static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
702089a7cc5SEric Fiselier                          _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
703089a7cc5SEric Fiselier};
704089a7cc5SEric Fiselier
705089a7cc5SEric Fiseliertemplate <class _ValueTp, class _VoidPtr>
706089a7cc5SEric Fiselierstruct __make_tree_node_types {
707089a7cc5SEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
708089a7cc5SEric Fiselier                                                                        _NodePtr;
709089a7cc5SEric Fiselier  typedef __tree_node_types<_NodePtr> type;
710089a7cc5SEric Fiselier};
711089a7cc5SEric Fiselier
7123e519524SHoward Hinnant// node
7133e519524SHoward Hinnant
7143e519524SHoward Hinnanttemplate <class _Pointer>
7153e519524SHoward Hinnantclass __tree_end_node
7163e519524SHoward Hinnant{
7173e519524SHoward Hinnantpublic:
7183e519524SHoward Hinnant    typedef _Pointer pointer;
7193e519524SHoward Hinnant    pointer __left_;
7203e519524SHoward Hinnant
721f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
722e6913510SHoward Hinnant    __tree_end_node() _NOEXCEPT : __left_() {}
7233e519524SHoward Hinnant};
7243e519524SHoward Hinnant
7253e519524SHoward Hinnanttemplate <class _VoidPtr>
7267c2f5827SAmy Huangclass _LIBCPP_STANDALONE_DEBUG __tree_node_base
727089a7cc5SEric Fiselier    : public __tree_node_base_types<_VoidPtr>::__end_node_type
7283e519524SHoward Hinnant{
729089a7cc5SEric Fiselier    typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
730089a7cc5SEric Fiselier
7313e519524SHoward Hinnantpublic:
732089a7cc5SEric Fiselier    typedef typename _NodeBaseTypes::__node_base_pointer pointer;
733d05b10abSEric Fiselier    typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
7343e519524SHoward Hinnant
7353e519524SHoward Hinnant    pointer          __right_;
736d05b10abSEric Fiselier    __parent_pointer __parent_;
7373e519524SHoward Hinnant    bool __is_black_;
7383e519524SHoward Hinnant
739d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
740d05b10abSEric Fiselier    pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
741d05b10abSEric Fiselier
742d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
743d05b10abSEric Fiselier    void __set_parent(pointer __p) {
744d05b10abSEric Fiselier        __parent_ = static_cast<__parent_pointer>(__p);
745d05b10abSEric Fiselier    }
746d05b10abSEric Fiselier
7475e3ea4ddSEric Fiselierprivate:
748d7d70601SArthur O'Dwyer  ~__tree_node_base() = delete;
749d7d70601SArthur O'Dwyer  __tree_node_base(__tree_node_base const&) = delete;
750d7d70601SArthur O'Dwyer  __tree_node_base& operator=(__tree_node_base const&) = delete;
7513e519524SHoward Hinnant};
7523e519524SHoward Hinnant
7533e519524SHoward Hinnanttemplate <class _Tp, class _VoidPtr>
7547c2f5827SAmy Huangclass _LIBCPP_STANDALONE_DEBUG __tree_node
7553e519524SHoward Hinnant    : public __tree_node_base<_VoidPtr>
7563e519524SHoward Hinnant{
7573e519524SHoward Hinnantpublic:
758089a7cc5SEric Fiselier    typedef _Tp __node_value_type;
7593e519524SHoward Hinnant
760089a7cc5SEric Fiselier    __node_value_type __value_;
7613e519524SHoward Hinnant
7625e3ea4ddSEric Fiselierprivate:
763d7d70601SArthur O'Dwyer  ~__tree_node() = delete;
764d7d70601SArthur O'Dwyer  __tree_node(__tree_node const&) = delete;
765d7d70601SArthur O'Dwyer  __tree_node& operator=(__tree_node const&) = delete;
7663e519524SHoward Hinnant};
7673e519524SHoward Hinnant
7685e3ea4ddSEric Fiselier
7695e3ea4ddSEric Fiseliertemplate <class _Allocator>
7705e3ea4ddSEric Fiselierclass __tree_node_destructor
7715e3ea4ddSEric Fiselier{
7725e3ea4ddSEric Fiselier    typedef _Allocator                                      allocator_type;
7735e3ea4ddSEric Fiselier    typedef allocator_traits<allocator_type>                __alloc_traits;
7745e3ea4ddSEric Fiselier
7755e3ea4ddSEric Fiselierpublic:
7765e3ea4ddSEric Fiselier    typedef typename __alloc_traits::pointer                pointer;
7775e3ea4ddSEric Fiselierprivate:
7785e3ea4ddSEric Fiselier    typedef __tree_node_types<pointer> _NodeTypes;
7795e3ea4ddSEric Fiselier    allocator_type& __na_;
7805e3ea4ddSEric Fiselier
7815e3ea4ddSEric Fiselier
7825e3ea4ddSEric Fiselierpublic:
7835e3ea4ddSEric Fiselier    bool __value_constructed;
7845e3ea4ddSEric Fiselier
785f97936faSEric Fiselier
786f97936faSEric Fiselier    __tree_node_destructor(const __tree_node_destructor &) = default;
787f97936faSEric Fiselier    __tree_node_destructor& operator=(const __tree_node_destructor&) = delete;
788f97936faSEric Fiselier
7895e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
7905e3ea4ddSEric Fiselier    explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
7915e3ea4ddSEric Fiselier        : __na_(__na),
7925e3ea4ddSEric Fiselier          __value_constructed(__val)
7935e3ea4ddSEric Fiselier        {}
7945e3ea4ddSEric Fiselier
7955e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
7965e3ea4ddSEric Fiselier    void operator()(pointer __p) _NOEXCEPT
7975e3ea4ddSEric Fiselier    {
7985e3ea4ddSEric Fiselier        if (__value_constructed)
7995e3ea4ddSEric Fiselier            __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
8005e3ea4ddSEric Fiselier        if (__p)
8015e3ea4ddSEric Fiselier            __alloc_traits::deallocate(__na_, __p, 1);
8025e3ea4ddSEric Fiselier    }
8035e3ea4ddSEric Fiselier
8045e3ea4ddSEric Fiselier    template <class> friend class __map_node_destructor;
8055e3ea4ddSEric Fiselier};
8065e3ea4ddSEric Fiselier
807b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14
808b0386a51SErik Pilkingtontemplate <class _NodeType, class _Alloc>
809b0386a51SErik Pilkingtonstruct __generic_container_node_destructor;
810b0386a51SErik Pilkingtontemplate <class _Tp, class _VoidPtr, class _Alloc>
811b0386a51SErik Pilkingtonstruct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
812b0386a51SErik Pilkington    : __tree_node_destructor<_Alloc>
813b0386a51SErik Pilkington{
814b0386a51SErik Pilkington    using __tree_node_destructor<_Alloc>::__tree_node_destructor;
815b0386a51SErik Pilkington};
816b0386a51SErik Pilkington#endif
8175e3ea4ddSEric Fiselier
8183e519524SHoward Hinnanttemplate <class _Tp, class _NodePtr, class _DiffType>
819e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __tree_iterator
8203e519524SHoward Hinnant{
821089a7cc5SEric Fiselier    typedef __tree_node_types<_NodePtr>                     _NodeTypes;
8223e519524SHoward Hinnant    typedef _NodePtr                                        __node_pointer;
823089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_base_pointer        __node_base_pointer;
824d05b10abSEric Fiselier    typedef typename _NodeTypes::__end_node_pointer         __end_node_pointer;
825d05b10abSEric Fiselier    typedef typename _NodeTypes::__iter_pointer             __iter_pointer;
826089a7cc5SEric Fiselier    typedef pointer_traits<__node_pointer> __pointer_traits;
8273e519524SHoward Hinnant
828d05b10abSEric Fiselier    __iter_pointer __ptr_;
8293e519524SHoward Hinnant
8303e519524SHoward Hinnantpublic:
8313e519524SHoward Hinnant    typedef bidirectional_iterator_tag                     iterator_category;
8323e519524SHoward Hinnant    typedef _Tp                                            value_type;
8333e519524SHoward Hinnant    typedef _DiffType                                      difference_type;
8343e519524SHoward Hinnant    typedef value_type&                                    reference;
835089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_value_type_pointer pointer;
8363e519524SHoward Hinnant
8372472b928SMarshall Clow    _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
8382472b928SMarshall Clow#if _LIBCPP_STD_VER > 11
8392472b928SMarshall Clow    : __ptr_(nullptr)
8402472b928SMarshall Clow#endif
8412472b928SMarshall Clow    {}
8423e519524SHoward Hinnant
843d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY reference operator*() const
844d05b10abSEric Fiselier        {return __get_np()->__value_;}
84507d3eccdSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
846d05b10abSEric Fiselier        {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
8473e519524SHoward Hinnant
848f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
849b3be398cSEric Fiselier    __tree_iterator& operator++() {
850d05b10abSEric Fiselier      __ptr_ = static_cast<__iter_pointer>(
851781c476cSArthur O'Dwyer          _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
852b3be398cSEric Fiselier      return *this;
853b3be398cSEric Fiselier    }
854f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8553e519524SHoward Hinnant    __tree_iterator operator++(int)
8563e519524SHoward Hinnant        {__tree_iterator __t(*this); ++(*this); return __t;}
8573e519524SHoward Hinnant
858f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
859b3be398cSEric Fiselier    __tree_iterator& operator--() {
860781c476cSArthur O'Dwyer      __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
861d05b10abSEric Fiselier          static_cast<__end_node_pointer>(__ptr_)));
862b3be398cSEric Fiselier      return *this;
863b3be398cSEric Fiselier    }
864f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8653e519524SHoward Hinnant    __tree_iterator operator--(int)
8663e519524SHoward Hinnant        {__tree_iterator __t(*this); --(*this); return __t;}
8673e519524SHoward Hinnant
868f5ab703fSHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
869f5ab703fSHoward Hinnant        bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
8703e519524SHoward Hinnant        {return __x.__ptr_ == __y.__ptr_;}
871f5ab703fSHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
872f5ab703fSHoward Hinnant        bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
8733e519524SHoward Hinnant        {return !(__x == __y);}
8743e519524SHoward Hinnant
8753e519524SHoward Hinnantprivate:
876f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8771052ee39SHoward Hinnant    explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
878d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
879d05b10abSEric Fiselier    explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
880d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
881d05b10abSEric Fiselier    __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
8823e519524SHoward Hinnant    template <class, class, class> friend class __tree;
883e2f2d1edSEric Fiselier    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
884e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
885e2f2d1edSEric Fiselier    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
886e2f2d1edSEric Fiselier    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
887e2f2d1edSEric Fiselier    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
888e2f2d1edSEric Fiselier    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
8893e519524SHoward Hinnant};
8903e519524SHoward Hinnant
891089a7cc5SEric Fiseliertemplate <class _Tp, class _NodePtr, class _DiffType>
892e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __tree_const_iterator
8933e519524SHoward Hinnant{
894089a7cc5SEric Fiselier    typedef __tree_node_types<_NodePtr>                     _NodeTypes;
895089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_pointer             __node_pointer;
896089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_base_pointer        __node_base_pointer;
897d05b10abSEric Fiselier    typedef typename _NodeTypes::__end_node_pointer         __end_node_pointer;
898d05b10abSEric Fiselier    typedef typename _NodeTypes::__iter_pointer             __iter_pointer;
899089a7cc5SEric Fiselier    typedef pointer_traits<__node_pointer> __pointer_traits;
9003e519524SHoward Hinnant
901d05b10abSEric Fiselier    __iter_pointer __ptr_;
9023e519524SHoward Hinnant
9033e519524SHoward Hinnantpublic:
9043e519524SHoward Hinnant    typedef bidirectional_iterator_tag                           iterator_category;
9053e519524SHoward Hinnant    typedef _Tp                                                  value_type;
9063e519524SHoward Hinnant    typedef _DiffType                                            difference_type;
9073e519524SHoward Hinnant    typedef const value_type&                                    reference;
908089a7cc5SEric Fiselier    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
9093e519524SHoward Hinnant
9102472b928SMarshall Clow    _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
9112472b928SMarshall Clow#if _LIBCPP_STD_VER > 11
9122472b928SMarshall Clow    : __ptr_(nullptr)
9132472b928SMarshall Clow#endif
9142472b928SMarshall Clow    {}
9152472b928SMarshall Clow
9163e519524SHoward Hinnantprivate:
917089a7cc5SEric Fiselier    typedef __tree_iterator<value_type, __node_pointer, difference_type>
9183e519524SHoward Hinnant                                                           __non_const_iterator;
9193e519524SHoward Hinnantpublic:
920f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9211052ee39SHoward Hinnant    __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
9221052ee39SHoward Hinnant        : __ptr_(__p.__ptr_) {}
9233e519524SHoward Hinnant
924d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY reference operator*() const
925d05b10abSEric Fiselier        {return __get_np()->__value_;}
92607d3eccdSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
927d05b10abSEric Fiselier        {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
9283e519524SHoward Hinnant
929f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
930b3be398cSEric Fiselier    __tree_const_iterator& operator++() {
931d05b10abSEric Fiselier      __ptr_ = static_cast<__iter_pointer>(
932781c476cSArthur O'Dwyer          _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
933b3be398cSEric Fiselier      return *this;
934b3be398cSEric Fiselier    }
935b3be398cSEric Fiselier
936f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9373e519524SHoward Hinnant    __tree_const_iterator operator++(int)
9383e519524SHoward Hinnant        {__tree_const_iterator __t(*this); ++(*this); return __t;}
9393e519524SHoward Hinnant
940f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
941b3be398cSEric Fiselier    __tree_const_iterator& operator--() {
942781c476cSArthur O'Dwyer      __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
943d05b10abSEric Fiselier          static_cast<__end_node_pointer>(__ptr_)));
944b3be398cSEric Fiselier      return *this;
945b3be398cSEric Fiselier    }
946b3be398cSEric Fiselier
947f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9483e519524SHoward Hinnant    __tree_const_iterator operator--(int)
9493e519524SHoward Hinnant        {__tree_const_iterator __t(*this); --(*this); return __t;}
9503e519524SHoward Hinnant
951f5ab703fSHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
952f5ab703fSHoward Hinnant        bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
9533e519524SHoward Hinnant        {return __x.__ptr_ == __y.__ptr_;}
954f5ab703fSHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
955f5ab703fSHoward Hinnant        bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
9563e519524SHoward Hinnant        {return !(__x == __y);}
9573e519524SHoward Hinnant
9583e519524SHoward Hinnantprivate:
959f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9601052ee39SHoward Hinnant    explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
9611052ee39SHoward Hinnant        : __ptr_(__p) {}
962d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
963d05b10abSEric Fiselier    explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
964d05b10abSEric Fiselier        : __ptr_(__p) {}
965d05b10abSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
966d05b10abSEric Fiselier    __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
967d05b10abSEric Fiselier
9683e519524SHoward Hinnant    template <class, class, class> friend class __tree;
969e2f2d1edSEric Fiselier    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
970e2f2d1edSEric Fiselier    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
971e2f2d1edSEric Fiselier    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
972e2f2d1edSEric Fiselier    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
973e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
974d05b10abSEric Fiselier
9753e519524SHoward Hinnant};
9763e519524SHoward Hinnant
9773560fbf3SLouis Dionnetemplate<class _Tp, class _Compare>
978b1e7a12eSEric Fiselier#ifndef _LIBCPP_CXX03_LANG
979d586f92cSArthur O'Dwyer    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
9807c142fccSLouis Dionne        "the specified comparator type does not provide a viable const call operator")
9813560fbf3SLouis Dionne#endif
9823560fbf3SLouis Dionneint __diagnose_non_const_comparator();
983b1e7a12eSEric Fiselier
9843e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
9853e519524SHoward Hinnantclass __tree
9863e519524SHoward Hinnant{
9873e519524SHoward Hinnantpublic:
9883e519524SHoward Hinnant    typedef _Tp                                      value_type;
9893e519524SHoward Hinnant    typedef _Compare                                 value_compare;
9903e519524SHoward Hinnant    typedef _Allocator                               allocator_type;
991089a7cc5SEric Fiselier
992089a7cc5SEric Fiselierprivate:
9933e519524SHoward Hinnant    typedef allocator_traits<allocator_type>         __alloc_traits;
994089a7cc5SEric Fiselier    typedef typename __make_tree_node_types<value_type,
995089a7cc5SEric Fiselier        typename __alloc_traits::void_pointer>::type
996089a7cc5SEric Fiselier                                                    _NodeTypes;
9975e3ea4ddSEric Fiselier    typedef typename _NodeTypes::key_type           key_type;
998089a7cc5SEric Fiselierpublic:
999089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_value_type      __node_value_type;
1000089a7cc5SEric Fiselier    typedef typename _NodeTypes::__container_value_type __container_value_type;
1001089a7cc5SEric Fiselier
10023e519524SHoward Hinnant    typedef typename __alloc_traits::pointer         pointer;
10033e519524SHoward Hinnant    typedef typename __alloc_traits::const_pointer   const_pointer;
10043e519524SHoward Hinnant    typedef typename __alloc_traits::size_type       size_type;
10053e519524SHoward Hinnant    typedef typename __alloc_traits::difference_type difference_type;
10063e519524SHoward Hinnant
1007089a7cc5SEric Fiselierpublic:
1008089a7cc5SEric Fiselier    typedef typename _NodeTypes::__void_pointer        __void_pointer;
100907d3eccdSHoward Hinnant
1010089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_type           __node;
1011089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_pointer        __node_pointer;
1012089a7cc5SEric Fiselier
1013089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_base_type      __node_base;
1014089a7cc5SEric Fiselier    typedef typename _NodeTypes::__node_base_pointer   __node_base_pointer;
1015089a7cc5SEric Fiselier
1016089a7cc5SEric Fiselier    typedef typename _NodeTypes::__end_node_type       __end_node_t;
1017089a7cc5SEric Fiselier    typedef typename _NodeTypes::__end_node_pointer    __end_node_ptr;
1018089a7cc5SEric Fiselier
1019d05b10abSEric Fiselier    typedef typename _NodeTypes::__parent_pointer      __parent_pointer;
1020d05b10abSEric Fiselier    typedef typename _NodeTypes::__iter_pointer        __iter_pointer;
1021d05b10abSEric Fiselier
10221f508014SMarshall Clow    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
10233e519524SHoward Hinnant    typedef allocator_traits<__node_allocator>         __node_traits;
10243e519524SHoward Hinnant
1025089a7cc5SEric Fiselierprivate:
1026089a7cc5SEric Fiselier    // check for sane allocator pointer rebinding semantics. Rebinding the
1027089a7cc5SEric Fiselier    // allocator for a new pointer type should be exactly the same as rebinding
1028089a7cc5SEric Fiselier    // the pointer using 'pointer_traits'.
1029089a7cc5SEric Fiselier    static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1030089a7cc5SEric Fiselier                  "Allocator does not rebind pointers in a sane manner.");
1031089a7cc5SEric Fiselier    typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1032089a7cc5SEric Fiselier        __node_base_allocator;
1033089a7cc5SEric Fiselier    typedef allocator_traits<__node_base_allocator> __node_base_traits;
1034089a7cc5SEric Fiselier    static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1035089a7cc5SEric Fiselier                 "Allocator does not rebind pointers in a sane manner.");
1036089a7cc5SEric Fiselier
1037089a7cc5SEric Fiselierprivate:
1038d05b10abSEric Fiselier    __iter_pointer                                     __begin_node_;
10393e519524SHoward Hinnant    __compressed_pair<__end_node_t, __node_allocator>  __pair1_;
10403e519524SHoward Hinnant    __compressed_pair<size_type, value_compare>        __pair3_;
10413e519524SHoward Hinnant
10423e519524SHoward Hinnantpublic:
1043f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1044d05b10abSEric Fiselier    __iter_pointer __end_node() _NOEXCEPT
10453e519524SHoward Hinnant    {
1046d05b10abSEric Fiselier        return static_cast<__iter_pointer>(
10473e519524SHoward Hinnant                pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
10483e519524SHoward Hinnant        );
10493e519524SHoward Hinnant    }
1050f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1051d05b10abSEric Fiselier    __iter_pointer __end_node() const _NOEXCEPT
10523e519524SHoward Hinnant    {
1053d05b10abSEric Fiselier        return static_cast<__iter_pointer>(
10540594ad71SEric Fiselier            pointer_traits<__end_node_ptr>::pointer_to(
10550594ad71SEric Fiselier                const_cast<__end_node_t&>(__pair1_.first())
10560594ad71SEric Fiselier            )
10573e519524SHoward Hinnant        );
10583e519524SHoward Hinnant    }
1059f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10601052ee39SHoward Hinnant          __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
10613e519524SHoward Hinnantprivate:
1062f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10631052ee39SHoward Hinnant    const __node_allocator& __node_alloc() const _NOEXCEPT
10641052ee39SHoward Hinnant        {return __pair1_.second();}
1065f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1066d05b10abSEric Fiselier          __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
1067f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1068d05b10abSEric Fiselier    const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
10693e519524SHoward Hinnantpublic:
1070f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10711052ee39SHoward Hinnant    allocator_type __alloc() const _NOEXCEPT
10721052ee39SHoward Hinnant        {return allocator_type(__node_alloc());}
10733e519524SHoward Hinnantprivate:
1074f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10751052ee39SHoward Hinnant          size_type& size() _NOEXCEPT {return __pair3_.first();}
10763e519524SHoward Hinnantpublic:
1077f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10781052ee39SHoward Hinnant    const size_type& size() const _NOEXCEPT {return __pair3_.first();}
1079f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10801052ee39SHoward Hinnant          value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
1081f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10821052ee39SHoward Hinnant    const value_compare& value_comp() const _NOEXCEPT
10831052ee39SHoward Hinnant        {return __pair3_.second();}
10843e519524SHoward Hinnantpublic:
10850594ad71SEric Fiselier
1086f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10870594ad71SEric Fiselier    __node_pointer __root() const _NOEXCEPT
10883e519524SHoward Hinnant        {return static_cast<__node_pointer>(__end_node()->__left_);}
10893e519524SHoward Hinnant
1090d05b10abSEric Fiselier    __node_base_pointer* __root_ptr() const _NOEXCEPT {
1091d05b10abSEric Fiselier        return _VSTD::addressof(__end_node()->__left_);
1092d05b10abSEric Fiselier    }
1093d05b10abSEric Fiselier
10943e519524SHoward Hinnant    typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
109507d3eccdSHoward Hinnant    typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
10963e519524SHoward Hinnant
10971052ee39SHoward Hinnant    explicit __tree(const value_compare& __comp)
10981052ee39SHoward Hinnant        _NOEXCEPT_(
10991052ee39SHoward Hinnant            is_nothrow_default_constructible<__node_allocator>::value &&
11001052ee39SHoward Hinnant            is_nothrow_copy_constructible<value_compare>::value);
11013e519524SHoward Hinnant    explicit __tree(const allocator_type& __a);
11023e519524SHoward Hinnant    __tree(const value_compare& __comp, const allocator_type& __a);
11033e519524SHoward Hinnant    __tree(const __tree& __t);
11043e519524SHoward Hinnant    __tree& operator=(const __tree& __t);
110541798c05SEric Fiselier    template <class _ForwardIterator>
110641798c05SEric Fiselier        void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
11073e519524SHoward Hinnant    template <class _InputIterator>
11083e519524SHoward Hinnant        void __assign_multi(_InputIterator __first, _InputIterator __last);
11091052ee39SHoward Hinnant    __tree(__tree&& __t)
11101052ee39SHoward Hinnant        _NOEXCEPT_(
11111052ee39SHoward Hinnant            is_nothrow_move_constructible<__node_allocator>::value &&
11121052ee39SHoward Hinnant            is_nothrow_move_constructible<value_compare>::value);
11133e519524SHoward Hinnant    __tree(__tree&& __t, const allocator_type& __a);
11141052ee39SHoward Hinnant    __tree& operator=(__tree&& __t)
11151052ee39SHoward Hinnant        _NOEXCEPT_(
11161052ee39SHoward Hinnant            __node_traits::propagate_on_container_move_assignment::value &&
11171052ee39SHoward Hinnant            is_nothrow_move_assignable<value_compare>::value &&
11181052ee39SHoward Hinnant            is_nothrow_move_assignable<__node_allocator>::value);
11193e519524SHoward Hinnant    ~__tree();
11203e519524SHoward Hinnant
1121f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
11221052ee39SHoward Hinnant          iterator begin()  _NOEXCEPT {return       iterator(__begin_node());}
1123f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
11241052ee39SHoward Hinnant    const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
1125f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
11261052ee39SHoward Hinnant          iterator end() _NOEXCEPT {return       iterator(__end_node());}
1127f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
11281052ee39SHoward Hinnant    const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
11293e519524SHoward Hinnant
1130f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
11311052ee39SHoward Hinnant    size_type max_size() const _NOEXCEPT
1132d586f92cSArthur O'Dwyer        {return _VSTD::min<size_type>(
113355b31b4eSEric Fiselier                __node_traits::max_size(__node_alloc()),
113455b31b4eSEric Fiselier                numeric_limits<difference_type >::max());}
11353e519524SHoward Hinnant
11361052ee39SHoward Hinnant    void clear() _NOEXCEPT;
11373e519524SHoward Hinnant
11381052ee39SHoward Hinnant    void swap(__tree& __t)
1139f8563f32SDimitry Andric#if _LIBCPP_STD_VER <= 11
11401052ee39SHoward Hinnant        _NOEXCEPT_(
1141e3fbe143SMarshall Clow            __is_nothrow_swappable<value_compare>::value
1142e3fbe143SMarshall Clow            && (!__node_traits::propagate_on_container_swap::value ||
1143e3fbe143SMarshall Clow                 __is_nothrow_swappable<__node_allocator>::value)
1144e3fbe143SMarshall Clow            );
1145f8563f32SDimitry Andric#else
1146f8563f32SDimitry Andric        _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1147f8563f32SDimitry Andric#endif
11485e3ea4ddSEric Fiselier
11495e3ea4ddSEric Fiselier    template <class _Key, class ..._Args>
11503e519524SHoward Hinnant    pair<iterator, bool>
11515e3ea4ddSEric Fiselier    __emplace_unique_key_args(_Key const&, _Args&&... __args);
11525e3ea4ddSEric Fiselier    template <class _Key, class ..._Args>
1153d4dd9613SMark de Wever    pair<iterator, bool>
11545e3ea4ddSEric Fiselier    __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
11553e519524SHoward Hinnant
11563e519524SHoward Hinnant    template <class... _Args>
1157fa1f613fSEric Fiselier    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
11585e3ea4ddSEric Fiselier
11593e519524SHoward Hinnant    template <class... _Args>
1160fa1f613fSEric Fiselier    iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
11613e519524SHoward Hinnant
11625e3ea4ddSEric Fiselier    template <class... _Args>
11635e3ea4ddSEric Fiselier    iterator __emplace_multi(_Args&&... __args);
11643e519524SHoward Hinnant
11655e3ea4ddSEric Fiselier    template <class... _Args>
11665e3ea4ddSEric Fiselier    iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
1167fa1f613fSEric Fiselier
1168fa1f613fSEric Fiselier    template <class _Pp>
1169fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1170fa1f613fSEric Fiselier    pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1171fa1f613fSEric Fiselier        return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1172fa1f613fSEric Fiselier                                            __can_extract_key<_Pp, key_type>());
1173fa1f613fSEric Fiselier    }
1174fa1f613fSEric Fiselier
117550088684SEric Fiselier    template <class _First, class _Second>
117650088684SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
11774887d047SNikolas Klauser    __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair<iterator, bool> >
11784887d047SNikolas Klauser    __emplace_unique(_First&& __f, _Second&& __s) {
117950088684SEric Fiselier        return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
118050088684SEric Fiselier                                              _VSTD::forward<_Second>(__s));
118150088684SEric Fiselier    }
118250088684SEric Fiselier
1183fa1f613fSEric Fiselier    template <class... _Args>
1184fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1185fa1f613fSEric Fiselier    pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1186fa1f613fSEric Fiselier        return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1187fa1f613fSEric Fiselier    }
1188fa1f613fSEric Fiselier
1189fa1f613fSEric Fiselier    template <class _Pp>
1190fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1191fa1f613fSEric Fiselier    pair<iterator, bool>
1192fa1f613fSEric Fiselier    __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1193fa1f613fSEric Fiselier      return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1194fa1f613fSEric Fiselier    }
1195fa1f613fSEric Fiselier
1196fa1f613fSEric Fiselier    template <class _Pp>
1197fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1198fa1f613fSEric Fiselier    pair<iterator, bool>
1199fa1f613fSEric Fiselier    __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1200fa1f613fSEric Fiselier      return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1201fa1f613fSEric Fiselier    }
1202fa1f613fSEric Fiselier
1203fa1f613fSEric Fiselier    template <class _Pp>
1204fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1205fa1f613fSEric Fiselier    pair<iterator, bool>
1206fa1f613fSEric Fiselier    __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1207fa1f613fSEric Fiselier      return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1208fa1f613fSEric Fiselier    }
1209fa1f613fSEric Fiselier
1210fa1f613fSEric Fiselier    template <class _Pp>
1211fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1212fa1f613fSEric Fiselier    iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1213fa1f613fSEric Fiselier        return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1214fa1f613fSEric Fiselier                                            __can_extract_key<_Pp, key_type>());
1215fa1f613fSEric Fiselier    }
1216fa1f613fSEric Fiselier
121750088684SEric Fiselier    template <class _First, class _Second>
121850088684SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12194887d047SNikolas Klauser    __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, iterator>
12204887d047SNikolas Klauser    __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
122150088684SEric Fiselier        return __emplace_hint_unique_key_args(__p, __f,
122250088684SEric Fiselier                                              _VSTD::forward<_First>(__f),
1223d4dd9613SMark de Wever                                              _VSTD::forward<_Second>(__s)).first;
122450088684SEric Fiselier    }
122550088684SEric Fiselier
1226fa1f613fSEric Fiselier    template <class... _Args>
1227fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1228fa1f613fSEric Fiselier    iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1229fa1f613fSEric Fiselier        return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1230fa1f613fSEric Fiselier    }
1231fa1f613fSEric Fiselier
1232fa1f613fSEric Fiselier    template <class _Pp>
1233fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1234fa1f613fSEric Fiselier    iterator
1235fa1f613fSEric Fiselier    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1236fa1f613fSEric Fiselier      return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
1237fa1f613fSEric Fiselier    }
1238fa1f613fSEric Fiselier
1239fa1f613fSEric Fiselier    template <class _Pp>
1240fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1241fa1f613fSEric Fiselier    iterator
1242fa1f613fSEric Fiselier    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1243d4dd9613SMark de Wever      return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)).first;
1244fa1f613fSEric Fiselier    }
1245fa1f613fSEric Fiselier
1246fa1f613fSEric Fiselier    template <class _Pp>
1247fa1f613fSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1248fa1f613fSEric Fiselier    iterator
1249fa1f613fSEric Fiselier    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1250d4dd9613SMark de Wever      return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)).first;
1251fa1f613fSEric Fiselier    }
1252fa1f613fSEric Fiselier
12535e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12545e3ea4ddSEric Fiselier    pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
12555e3ea4ddSEric Fiselier        return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
12565e3ea4ddSEric Fiselier    }
12575e3ea4ddSEric Fiselier
12585e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12595e3ea4ddSEric Fiselier    iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
1260d4dd9613SMark de Wever        return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v).first;
12615e3ea4ddSEric Fiselier    }
12625e3ea4ddSEric Fiselier
12635e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12645e3ea4ddSEric Fiselier    pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
12655e3ea4ddSEric Fiselier        return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
12665e3ea4ddSEric Fiselier    }
12675e3ea4ddSEric Fiselier
12685e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12695e3ea4ddSEric Fiselier    iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
1270d4dd9613SMark de Wever        return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)).first;
12715e3ea4ddSEric Fiselier    }
12725e3ea4ddSEric Fiselier
12734887d047SNikolas Klauser    template <class _Vp,
12744887d047SNikolas Klauser              class = __enable_if_t<!is_same<typename __unconstref<_Vp>::type, __container_value_type>::value> >
12755e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12765e3ea4ddSEric Fiselier    pair<iterator, bool> __insert_unique(_Vp&& __v) {
12775e3ea4ddSEric Fiselier        return __emplace_unique(_VSTD::forward<_Vp>(__v));
12785e3ea4ddSEric Fiselier    }
12795e3ea4ddSEric Fiselier
12804887d047SNikolas Klauser    template <class _Vp,
12814887d047SNikolas Klauser              class = __enable_if_t<!is_same<typename __unconstref<_Vp>::type, __container_value_type>::value> >
12825e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12835e3ea4ddSEric Fiselier    iterator __insert_unique(const_iterator __p, _Vp&& __v) {
12845e3ea4ddSEric Fiselier        return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
12855e3ea4ddSEric Fiselier    }
12865e3ea4ddSEric Fiselier
12875e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12885e3ea4ddSEric Fiselier    iterator __insert_multi(__container_value_type&& __v) {
12895e3ea4ddSEric Fiselier        return __emplace_multi(_VSTD::move(__v));
12905e3ea4ddSEric Fiselier    }
12915e3ea4ddSEric Fiselier
12925e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12935e3ea4ddSEric Fiselier    iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
12945e3ea4ddSEric Fiselier        return __emplace_hint_multi(__p, _VSTD::move(__v));
12955e3ea4ddSEric Fiselier    }
12965e3ea4ddSEric Fiselier
12975e3ea4ddSEric Fiselier    template <class _Vp>
12985e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
12995e3ea4ddSEric Fiselier    iterator __insert_multi(_Vp&& __v) {
13005e3ea4ddSEric Fiselier        return __emplace_multi(_VSTD::forward<_Vp>(__v));
13015e3ea4ddSEric Fiselier    }
13025e3ea4ddSEric Fiselier
13035e3ea4ddSEric Fiselier    template <class _Vp>
13045e3ea4ddSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
13055e3ea4ddSEric Fiselier    iterator __insert_multi(const_iterator __p, _Vp&& __v) {
13065e3ea4ddSEric Fiselier        return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
13075e3ea4ddSEric Fiselier    }
13085e3ea4ddSEric Fiselier
13095c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
131041798c05SEric Fiselier    pair<iterator, bool> __node_assign_unique(const __container_value_type& __v, __node_pointer __dest);
13113e519524SHoward Hinnant
13125c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
13133e519524SHoward Hinnant    iterator __node_insert_multi(__node_pointer __nd);
13145c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
13153e519524SHoward Hinnant    iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
13163e519524SHoward Hinnant
1317b0386a51SErik Pilkington
13185c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY iterator
13195c4e07aeSErik Pilkington    __remove_node_pointer(__node_pointer) _NOEXCEPT;
1320b0386a51SErik Pilkington
1321b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14
1322b0386a51SErik Pilkington    template <class _NodeHandle, class _InsertReturnType>
1323b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1324b0386a51SErik Pilkington    _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
1325b0386a51SErik Pilkington    template <class _NodeHandle>
1326b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1327b0386a51SErik Pilkington    iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
13285c4e07aeSErik Pilkington    template <class _Tree>
13295c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
13305c4e07aeSErik Pilkington    void __node_handle_merge_unique(_Tree& __source);
1331b0386a51SErik Pilkington
1332b0386a51SErik Pilkington    template <class _NodeHandle>
1333b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1334b0386a51SErik Pilkington    iterator __node_handle_insert_multi(_NodeHandle&&);
1335b0386a51SErik Pilkington    template <class _NodeHandle>
1336b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1337b0386a51SErik Pilkington    iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
13385c4e07aeSErik Pilkington    template <class _Tree>
13395c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
13405c4e07aeSErik Pilkington    void __node_handle_merge_multi(_Tree& __source);
1341b0386a51SErik Pilkington
1342b0386a51SErik Pilkington
1343b0386a51SErik Pilkington    template <class _NodeHandle>
1344b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1345b0386a51SErik Pilkington    _NodeHandle __node_handle_extract(key_type const&);
1346b0386a51SErik Pilkington    template <class _NodeHandle>
1347b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1348b0386a51SErik Pilkington    _NodeHandle __node_handle_extract(const_iterator);
1349b0386a51SErik Pilkington#endif
1350b0386a51SErik Pilkington
13513e519524SHoward Hinnant    iterator erase(const_iterator __p);
13523e519524SHoward Hinnant    iterator erase(const_iterator __f, const_iterator __l);
13533e519524SHoward Hinnant    template <class _Key>
13543e519524SHoward Hinnant        size_type __erase_unique(const _Key& __k);
13553e519524SHoward Hinnant    template <class _Key>
13563e519524SHoward Hinnant        size_type __erase_multi(const _Key& __k);
13573e519524SHoward Hinnant
1358d05b10abSEric Fiselier    void __insert_node_at(__parent_pointer     __parent,
13593e519524SHoward Hinnant                          __node_base_pointer& __child,
13605c4e07aeSErik Pilkington                          __node_base_pointer __new_node) _NOEXCEPT;
13613e519524SHoward Hinnant
13623e519524SHoward Hinnant    template <class _Key>
13633e519524SHoward Hinnant        iterator find(const _Key& __v);
13643e519524SHoward Hinnant    template <class _Key>
13653e519524SHoward Hinnant        const_iterator find(const _Key& __v) const;
13663e519524SHoward Hinnant
13673e519524SHoward Hinnant    template <class _Key>
13683e519524SHoward Hinnant        size_type __count_unique(const _Key& __k) const;
13693e519524SHoward Hinnant    template <class _Key>
13703e519524SHoward Hinnant        size_type __count_multi(const _Key& __k) const;
13713e519524SHoward Hinnant
13723e519524SHoward Hinnant    template <class _Key>
1373f5ab703fSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
13743e519524SHoward Hinnant        iterator lower_bound(const _Key& __v)
13753e519524SHoward Hinnant            {return __lower_bound(__v, __root(), __end_node());}
13763e519524SHoward Hinnant    template <class _Key>
13773e519524SHoward Hinnant        iterator __lower_bound(const _Key& __v,
13783e519524SHoward Hinnant                               __node_pointer __root,
1379d05b10abSEric Fiselier                               __iter_pointer __result);
13803e519524SHoward Hinnant    template <class _Key>
1381f5ab703fSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
13823e519524SHoward Hinnant        const_iterator lower_bound(const _Key& __v) const
13833e519524SHoward Hinnant            {return __lower_bound(__v, __root(), __end_node());}
13843e519524SHoward Hinnant    template <class _Key>
13853e519524SHoward Hinnant        const_iterator __lower_bound(const _Key& __v,
13860594ad71SEric Fiselier                                     __node_pointer __root,
1387d05b10abSEric Fiselier                                     __iter_pointer __result) const;
13883e519524SHoward Hinnant    template <class _Key>
1389f5ab703fSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
13903e519524SHoward Hinnant        iterator upper_bound(const _Key& __v)
13913e519524SHoward Hinnant            {return __upper_bound(__v, __root(), __end_node());}
13923e519524SHoward Hinnant    template <class _Key>
13933e519524SHoward Hinnant        iterator __upper_bound(const _Key& __v,
13943e519524SHoward Hinnant                               __node_pointer __root,
1395d05b10abSEric Fiselier                               __iter_pointer __result);
13963e519524SHoward Hinnant    template <class _Key>
1397f5ab703fSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
13983e519524SHoward Hinnant        const_iterator upper_bound(const _Key& __v) const
13993e519524SHoward Hinnant            {return __upper_bound(__v, __root(), __end_node());}
14003e519524SHoward Hinnant    template <class _Key>
14013e519524SHoward Hinnant        const_iterator __upper_bound(const _Key& __v,
14020594ad71SEric Fiselier                                     __node_pointer __root,
1403d05b10abSEric Fiselier                                     __iter_pointer __result) const;
14043e519524SHoward Hinnant    template <class _Key>
14053e519524SHoward Hinnant        pair<iterator, iterator>
14063e519524SHoward Hinnant        __equal_range_unique(const _Key& __k);
14073e519524SHoward Hinnant    template <class _Key>
14083e519524SHoward Hinnant        pair<const_iterator, const_iterator>
14093e519524SHoward Hinnant        __equal_range_unique(const _Key& __k) const;
14103e519524SHoward Hinnant
14113e519524SHoward Hinnant    template <class _Key>
14123e519524SHoward Hinnant        pair<iterator, iterator>
14133e519524SHoward Hinnant        __equal_range_multi(const _Key& __k);
14143e519524SHoward Hinnant    template <class _Key>
14153e519524SHoward Hinnant        pair<const_iterator, const_iterator>
14163e519524SHoward Hinnant        __equal_range_multi(const _Key& __k) const;
14173e519524SHoward Hinnant
1418c003db1fSHoward Hinnant    typedef __tree_node_destructor<__node_allocator> _Dp;
1419c003db1fSHoward Hinnant    typedef unique_ptr<__node, _Dp> __node_holder;
14203e519524SHoward Hinnant
1421e6913510SHoward Hinnant    __node_holder remove(const_iterator __p) _NOEXCEPT;
14223e519524SHoward Hinnantprivate:
1423d05b10abSEric Fiselier    __node_base_pointer&
1424d05b10abSEric Fiselier        __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1425d05b10abSEric Fiselier    __node_base_pointer&
1426d05b10abSEric Fiselier        __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1427d05b10abSEric Fiselier    __node_base_pointer&
14283e519524SHoward Hinnant        __find_leaf(const_iterator __hint,
1429d05b10abSEric Fiselier                    __parent_pointer& __parent, const key_type& __v);
1430b6f19174SArthur O'Dwyer    // FIXME: Make this function const qualified. Unfortunately doing so
1431cb5cbc8bSEric Fiselier    // breaks existing code which uses non-const callable comparators.
14323e519524SHoward Hinnant    template <class _Key>
1433d05b10abSEric Fiselier    __node_base_pointer&
1434d05b10abSEric Fiselier        __find_equal(__parent_pointer& __parent, const _Key& __v);
14353e519524SHoward Hinnant    template <class _Key>
1436cb5cbc8bSEric Fiselier    _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1437cb5cbc8bSEric Fiselier    __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1438cb5cbc8bSEric Fiselier      return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1439cb5cbc8bSEric Fiselier    }
1440cb5cbc8bSEric Fiselier    template <class _Key>
1441d05b10abSEric Fiselier    __node_base_pointer&
1442d05b10abSEric Fiselier        __find_equal(const_iterator __hint, __parent_pointer& __parent,
1443d05b10abSEric Fiselier                     __node_base_pointer& __dummy,
14443e519524SHoward Hinnant                     const _Key& __v);
14453e519524SHoward Hinnant
14463e519524SHoward Hinnant    template <class ..._Args>
14473e519524SHoward Hinnant    __node_holder __construct_node(_Args&& ...__args);
14483e519524SHoward Hinnant
14491052ee39SHoward Hinnant    void destroy(__node_pointer __nd) _NOEXCEPT;
14503e519524SHoward Hinnant
1451f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
14523e519524SHoward Hinnant    void __copy_assign_alloc(const __tree& __t)
14533e519524SHoward Hinnant        {__copy_assign_alloc(__t, integral_constant<bool,
14543e519524SHoward Hinnant             __node_traits::propagate_on_container_copy_assignment::value>());}
14553e519524SHoward Hinnant
1456f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
14573e519524SHoward Hinnant    void __copy_assign_alloc(const __tree& __t, true_type)
1458d4e8659dSMarshall Clow        {
1459d4e8659dSMarshall Clow        if (__node_alloc() != __t.__node_alloc())
1460d4e8659dSMarshall Clow            clear();
1461d4e8659dSMarshall Clow        __node_alloc() = __t.__node_alloc();
1462d4e8659dSMarshall Clow        }
1463f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1464fd838227SEric Fiselier    void __copy_assign_alloc(const __tree&, false_type) {}
14653e519524SHoward Hinnant
14663e519524SHoward Hinnant    void __move_assign(__tree& __t, false_type);
14671052ee39SHoward Hinnant    void __move_assign(__tree& __t, true_type)
14681052ee39SHoward Hinnant        _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
14691052ee39SHoward Hinnant                   is_nothrow_move_assignable<__node_allocator>::value);
14703e519524SHoward Hinnant
1471f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
14723e519524SHoward Hinnant    void __move_assign_alloc(__tree& __t)
14731052ee39SHoward Hinnant        _NOEXCEPT_(
14741052ee39SHoward Hinnant            !__node_traits::propagate_on_container_move_assignment::value ||
14751052ee39SHoward Hinnant            is_nothrow_move_assignable<__node_allocator>::value)
14763e519524SHoward Hinnant        {__move_assign_alloc(__t, integral_constant<bool,
14773e519524SHoward Hinnant             __node_traits::propagate_on_container_move_assignment::value>());}
14783e519524SHoward Hinnant
1479f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
14803e519524SHoward Hinnant    void __move_assign_alloc(__tree& __t, true_type)
14811052ee39SHoward Hinnant        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
1482ce48a113SHoward Hinnant        {__node_alloc() = _VSTD::move(__t.__node_alloc());}
1483f5ab703fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1484fd838227SEric Fiselier    void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
14853e519524SHoward Hinnant
148641798c05SEric Fiselier    struct _DetachedTreeCache {
148741798c05SEric Fiselier      _LIBCPP_INLINE_VISIBILITY
148841798c05SEric Fiselier      explicit _DetachedTreeCache(__tree *__t) _NOEXCEPT : __t_(__t),
148941798c05SEric Fiselier        __cache_root_(__detach_from_tree(__t)) {
149041798c05SEric Fiselier          __advance();
149141798c05SEric Fiselier        }
149241798c05SEric Fiselier
149341798c05SEric Fiselier      _LIBCPP_INLINE_VISIBILITY
149441798c05SEric Fiselier      __node_pointer __get() const _NOEXCEPT {
149541798c05SEric Fiselier        return __cache_elem_;
149641798c05SEric Fiselier      }
149741798c05SEric Fiselier
149841798c05SEric Fiselier      _LIBCPP_INLINE_VISIBILITY
149941798c05SEric Fiselier      void __advance() _NOEXCEPT {
150041798c05SEric Fiselier        __cache_elem_ = __cache_root_;
150141798c05SEric Fiselier        if (__cache_root_) {
150241798c05SEric Fiselier          __cache_root_ = __detach_next(__cache_root_);
150341798c05SEric Fiselier        }
150441798c05SEric Fiselier      }
150541798c05SEric Fiselier
150641798c05SEric Fiselier      _LIBCPP_INLINE_VISIBILITY
150741798c05SEric Fiselier      ~_DetachedTreeCache() {
150841798c05SEric Fiselier        __t_->destroy(__cache_elem_);
150941798c05SEric Fiselier        if (__cache_root_) {
151041798c05SEric Fiselier          while (__cache_root_->__parent_ != nullptr)
151141798c05SEric Fiselier            __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_);
151241798c05SEric Fiselier          __t_->destroy(__cache_root_);
151341798c05SEric Fiselier        }
151441798c05SEric Fiselier      }
151541798c05SEric Fiselier
151641798c05SEric Fiselier       _DetachedTreeCache(_DetachedTreeCache const&) = delete;
151741798c05SEric Fiselier       _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete;
151841798c05SEric Fiselier
151941798c05SEric Fiselier    private:
152041798c05SEric Fiselier      _LIBCPP_INLINE_VISIBILITY
152141798c05SEric Fiselier      static __node_pointer __detach_from_tree(__tree *__t) _NOEXCEPT;
152241798c05SEric Fiselier      _LIBCPP_INLINE_VISIBILITY
152341798c05SEric Fiselier      static __node_pointer __detach_next(__node_pointer) _NOEXCEPT;
152441798c05SEric Fiselier
152541798c05SEric Fiselier      __tree *__t_;
152641798c05SEric Fiselier      __node_pointer __cache_root_;
152741798c05SEric Fiselier      __node_pointer __cache_elem_;
152841798c05SEric Fiselier    };
152941798c05SEric Fiselier
153007d3eccdSHoward Hinnant
1531e2f2d1edSEric Fiselier    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1532e2f2d1edSEric Fiselier    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
15333e519524SHoward Hinnant};
15343e519524SHoward Hinnant
15353e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
15363e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
15371052ee39SHoward Hinnant        _NOEXCEPT_(
15381052ee39SHoward Hinnant            is_nothrow_default_constructible<__node_allocator>::value &&
15391052ee39SHoward Hinnant            is_nothrow_copy_constructible<value_compare>::value)
15403e519524SHoward Hinnant    : __pair3_(0, __comp)
15413e519524SHoward Hinnant{
15423e519524SHoward Hinnant    __begin_node() = __end_node();
15433e519524SHoward Hinnant}
15443e519524SHoward Hinnant
15453e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
15463e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
1547d05b10abSEric Fiselier    : __begin_node_(__iter_pointer()),
1548549545b6SEric Fiselier      __pair1_(__default_init_tag(), __node_allocator(__a)),
1549549545b6SEric Fiselier      __pair3_(0, __default_init_tag())
15503e519524SHoward Hinnant{
15513e519524SHoward Hinnant    __begin_node() = __end_node();
15523e519524SHoward Hinnant}
15533e519524SHoward Hinnant
15543e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
15553e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
15563e519524SHoward Hinnant                                           const allocator_type& __a)
1557d05b10abSEric Fiselier    : __begin_node_(__iter_pointer()),
1558549545b6SEric Fiselier      __pair1_(__default_init_tag(), __node_allocator(__a)),
15593e519524SHoward Hinnant      __pair3_(0, __comp)
15603e519524SHoward Hinnant{
15613e519524SHoward Hinnant    __begin_node() = __end_node();
15623e519524SHoward Hinnant}
15633e519524SHoward Hinnant
15643e519524SHoward Hinnant// Precondition:  size() != 0
15653e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
15663e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::__node_pointer
156741798c05SEric Fiselier__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree *__t) _NOEXCEPT
15683e519524SHoward Hinnant{
156941798c05SEric Fiselier    __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node());
157041798c05SEric Fiselier    __t->__begin_node() = __t->__end_node();
157141798c05SEric Fiselier    __t->__end_node()->__left_->__parent_ = nullptr;
157241798c05SEric Fiselier    __t->__end_node()->__left_ = nullptr;
157341798c05SEric Fiselier    __t->size() = 0;
15743e519524SHoward Hinnant    // __cache->__left_ == nullptr
15753e519524SHoward Hinnant    if (__cache->__right_ != nullptr)
15763e519524SHoward Hinnant        __cache = static_cast<__node_pointer>(__cache->__right_);
15773e519524SHoward Hinnant    // __cache->__left_ == nullptr
15783e519524SHoward Hinnant    // __cache->__right_ == nullptr
15793e519524SHoward Hinnant    return __cache;
15803e519524SHoward Hinnant}
15813e519524SHoward Hinnant
15823e519524SHoward Hinnant// Precondition:  __cache != nullptr
15833e519524SHoward Hinnant//    __cache->left_ == nullptr
15843e519524SHoward Hinnant//    __cache->right_ == nullptr
15853e519524SHoward Hinnant//    This is no longer a red-black tree
15863e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
15873e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::__node_pointer
158841798c05SEric Fiselier__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT
15893e519524SHoward Hinnant{
15903e519524SHoward Hinnant    if (__cache->__parent_ == nullptr)
15913e519524SHoward Hinnant        return nullptr;
1592781c476cSArthur O'Dwyer    if (_VSTD::__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
15933e519524SHoward Hinnant    {
15943e519524SHoward Hinnant        __cache->__parent_->__left_ = nullptr;
15953e519524SHoward Hinnant        __cache = static_cast<__node_pointer>(__cache->__parent_);
15963e519524SHoward Hinnant        if (__cache->__right_ == nullptr)
15973e519524SHoward Hinnant            return __cache;
1598781c476cSArthur O'Dwyer        return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__right_));
15993e519524SHoward Hinnant    }
16003e519524SHoward Hinnant    // __cache is right child
1601d05b10abSEric Fiselier    __cache->__parent_unsafe()->__right_ = nullptr;
16023e519524SHoward Hinnant    __cache = static_cast<__node_pointer>(__cache->__parent_);
16033e519524SHoward Hinnant    if (__cache->__left_ == nullptr)
16043e519524SHoward Hinnant        return __cache;
1605781c476cSArthur O'Dwyer    return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__left_));
16063e519524SHoward Hinnant}
16073e519524SHoward Hinnant
16083e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
16093e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>&
16103e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
16113e519524SHoward Hinnant{
1612b8608b87SMark de Wever    if (this != _VSTD::addressof(__t))
16133e519524SHoward Hinnant    {
16143e519524SHoward Hinnant        value_comp() = __t.value_comp();
16153e519524SHoward Hinnant        __copy_assign_alloc(__t);
16163e519524SHoward Hinnant        __assign_multi(__t.begin(), __t.end());
16173e519524SHoward Hinnant    }
16183e519524SHoward Hinnant    return *this;
16193e519524SHoward Hinnant}
16203e519524SHoward Hinnant
16213e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
162241798c05SEric Fiseliertemplate <class _ForwardIterator>
16233e519524SHoward Hinnantvoid
162441798c05SEric Fiselier__tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last)
16253e519524SHoward Hinnant{
162641798c05SEric Fiselier    typedef iterator_traits<_ForwardIterator> _ITraits;
16275e3ea4ddSEric Fiselier    typedef typename _ITraits::value_type _ItValueType;
16285e3ea4ddSEric Fiselier    static_assert((is_same<_ItValueType, __container_value_type>::value),
16295e3ea4ddSEric Fiselier                  "__assign_unique may only be called with the containers value type");
1630f82dba01SEric Fiselier    static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
163141798c05SEric Fiselier                  "__assign_unique requires a forward iterator");
16323e519524SHoward Hinnant    if (size() != 0)
16333e519524SHoward Hinnant    {
163441798c05SEric Fiselier        _DetachedTreeCache __cache(this);
163541798c05SEric Fiselier          for (; __cache.__get() != nullptr && __first != __last; ++__first) {
163641798c05SEric Fiselier              if (__node_assign_unique(*__first, __cache.__get()).second)
163741798c05SEric Fiselier                  __cache.__advance();
16383e519524SHoward Hinnant            }
16393e519524SHoward Hinnant    }
16403e519524SHoward Hinnant    for (; __first != __last; ++__first)
16413e519524SHoward Hinnant        __insert_unique(*__first);
16423e519524SHoward Hinnant}
16433e519524SHoward Hinnant
16443e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
16453e519524SHoward Hinnanttemplate <class _InputIterator>
16463e519524SHoward Hinnantvoid
16473e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
16483e519524SHoward Hinnant{
16495e3ea4ddSEric Fiselier    typedef iterator_traits<_InputIterator> _ITraits;
16505e3ea4ddSEric Fiselier    typedef typename _ITraits::value_type _ItValueType;
16515e3ea4ddSEric Fiselier    static_assert((is_same<_ItValueType, __container_value_type>::value ||
16525e3ea4ddSEric Fiselier                  is_same<_ItValueType, __node_value_type>::value),
16535e3ea4ddSEric Fiselier                  "__assign_multi may only be called with the containers value type"
16545e3ea4ddSEric Fiselier                  " or the nodes value type");
16553e519524SHoward Hinnant    if (size() != 0)
16563e519524SHoward Hinnant    {
165741798c05SEric Fiselier        _DetachedTreeCache __cache(this);
165841798c05SEric Fiselier        for (; __cache.__get() && __first != __last; ++__first) {
165941798c05SEric Fiselier            __cache.__get()->__value_ = *__first;
166041798c05SEric Fiselier            __node_insert_multi(__cache.__get());
166141798c05SEric Fiselier            __cache.__advance();
16623e519524SHoward Hinnant        }
16633e519524SHoward Hinnant    }
16643e519524SHoward Hinnant    for (; __first != __last; ++__first)
16655e3ea4ddSEric Fiselier        __insert_multi(_NodeTypes::__get_value(*__first));
16663e519524SHoward Hinnant}
16673e519524SHoward Hinnant
16683e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
16693e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
1670d05b10abSEric Fiselier    : __begin_node_(__iter_pointer()),
1671549545b6SEric Fiselier      __pair1_(__default_init_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())),
16723e519524SHoward Hinnant      __pair3_(0, __t.value_comp())
16733e519524SHoward Hinnant{
16743e519524SHoward Hinnant    __begin_node() = __end_node();
16753e519524SHoward Hinnant}
16763e519524SHoward Hinnant
16773e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
16783e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
16791052ee39SHoward Hinnant    _NOEXCEPT_(
16801052ee39SHoward Hinnant        is_nothrow_move_constructible<__node_allocator>::value &&
16811052ee39SHoward Hinnant        is_nothrow_move_constructible<value_compare>::value)
1682ce48a113SHoward Hinnant    : __begin_node_(_VSTD::move(__t.__begin_node_)),
1683ce48a113SHoward Hinnant      __pair1_(_VSTD::move(__t.__pair1_)),
1684ce48a113SHoward Hinnant      __pair3_(_VSTD::move(__t.__pair3_))
16853e519524SHoward Hinnant{
16863e519524SHoward Hinnant    if (size() == 0)
16873e519524SHoward Hinnant        __begin_node() = __end_node();
16883e519524SHoward Hinnant    else
16893e519524SHoward Hinnant    {
1690d05b10abSEric Fiselier        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
16913e519524SHoward Hinnant        __t.__begin_node() = __t.__end_node();
16923e519524SHoward Hinnant        __t.__end_node()->__left_ = nullptr;
16933e519524SHoward Hinnant        __t.size() = 0;
16943e519524SHoward Hinnant    }
16953e519524SHoward Hinnant}
16963e519524SHoward Hinnant
16973e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
16983e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1699549545b6SEric Fiselier    : __pair1_(__default_init_tag(), __node_allocator(__a)),
1700ce48a113SHoward Hinnant      __pair3_(0, _VSTD::move(__t.value_comp()))
17013e519524SHoward Hinnant{
17023e519524SHoward Hinnant    if (__a == __t.__alloc())
17033e519524SHoward Hinnant    {
17043e519524SHoward Hinnant        if (__t.size() == 0)
17053e519524SHoward Hinnant            __begin_node() = __end_node();
17063e519524SHoward Hinnant        else
17073e519524SHoward Hinnant        {
17083e519524SHoward Hinnant            __begin_node() = __t.__begin_node();
17093e519524SHoward Hinnant            __end_node()->__left_ = __t.__end_node()->__left_;
1710d05b10abSEric Fiselier            __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
17113e519524SHoward Hinnant            size() = __t.size();
17123e519524SHoward Hinnant            __t.__begin_node() = __t.__end_node();
17133e519524SHoward Hinnant            __t.__end_node()->__left_ = nullptr;
17143e519524SHoward Hinnant            __t.size() = 0;
17153e519524SHoward Hinnant        }
17163e519524SHoward Hinnant    }
17173e519524SHoward Hinnant    else
17183e519524SHoward Hinnant    {
17193e519524SHoward Hinnant        __begin_node() = __end_node();
17203e519524SHoward Hinnant    }
17213e519524SHoward Hinnant}
17223e519524SHoward Hinnant
17233e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
17243e519524SHoward Hinnantvoid
17253e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
17261052ee39SHoward Hinnant    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
17271052ee39SHoward Hinnant               is_nothrow_move_assignable<__node_allocator>::value)
17283e519524SHoward Hinnant{
17293e519524SHoward Hinnant    destroy(static_cast<__node_pointer>(__end_node()->__left_));
17303e519524SHoward Hinnant    __begin_node_ = __t.__begin_node_;
17313e519524SHoward Hinnant    __pair1_.first() = __t.__pair1_.first();
17323e519524SHoward Hinnant    __move_assign_alloc(__t);
1733ce48a113SHoward Hinnant    __pair3_ = _VSTD::move(__t.__pair3_);
17343e519524SHoward Hinnant    if (size() == 0)
17353e519524SHoward Hinnant        __begin_node() = __end_node();
17363e519524SHoward Hinnant    else
17373e519524SHoward Hinnant    {
1738d05b10abSEric Fiselier        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
17393e519524SHoward Hinnant        __t.__begin_node() = __t.__end_node();
17403e519524SHoward Hinnant        __t.__end_node()->__left_ = nullptr;
17413e519524SHoward Hinnant        __t.size() = 0;
17423e519524SHoward Hinnant    }
17433e519524SHoward Hinnant}
17443e519524SHoward Hinnant
17453e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
17463e519524SHoward Hinnantvoid
17473e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
17483e519524SHoward Hinnant{
17493e519524SHoward Hinnant    if (__node_alloc() == __t.__node_alloc())
17503e519524SHoward Hinnant        __move_assign(__t, true_type());
17513e519524SHoward Hinnant    else
17523e519524SHoward Hinnant    {
1753ce48a113SHoward Hinnant        value_comp() = _VSTD::move(__t.value_comp());
17543e519524SHoward Hinnant        const_iterator __e = end();
17553e519524SHoward Hinnant        if (size() != 0)
17563e519524SHoward Hinnant        {
175741798c05SEric Fiselier            _DetachedTreeCache __cache(this);
175841798c05SEric Fiselier            while (__cache.__get() != nullptr && __t.size() != 0) {
175941798c05SEric Fiselier              __cache.__get()->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
176041798c05SEric Fiselier              __node_insert_multi(__cache.__get());
176141798c05SEric Fiselier              __cache.__advance();
17623e519524SHoward Hinnant            }
17633e519524SHoward Hinnant        }
17643e519524SHoward Hinnant        while (__t.size() != 0)
17655e3ea4ddSEric Fiselier            __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
17663e519524SHoward Hinnant    }
17673e519524SHoward Hinnant}
17683e519524SHoward Hinnant
17693e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
17703e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>&
17713e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
17721052ee39SHoward Hinnant    _NOEXCEPT_(
17731052ee39SHoward Hinnant        __node_traits::propagate_on_container_move_assignment::value &&
17741052ee39SHoward Hinnant        is_nothrow_move_assignable<value_compare>::value &&
17751052ee39SHoward Hinnant        is_nothrow_move_assignable<__node_allocator>::value)
17761052ee39SHoward Hinnant
17773e519524SHoward Hinnant{
17783e519524SHoward Hinnant    __move_assign(__t, integral_constant<bool,
17793e519524SHoward Hinnant                  __node_traits::propagate_on_container_move_assignment::value>());
17803e519524SHoward Hinnant    return *this;
17813e519524SHoward Hinnant}
17823e519524SHoward Hinnant
17833e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
17843e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::~__tree()
17853e519524SHoward Hinnant{
17863b8669edSMarshall Clow    static_assert((is_copy_constructible<value_compare>::value),
17873b8669edSMarshall Clow                 "Comparator must be copy-constructible.");
17883e519524SHoward Hinnant  destroy(__root());
17893e519524SHoward Hinnant}
17903e519524SHoward Hinnant
17913e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
17923e519524SHoward Hinnantvoid
17931052ee39SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
17943e519524SHoward Hinnant{
17953e519524SHoward Hinnant    if (__nd != nullptr)
17963e519524SHoward Hinnant    {
17973e519524SHoward Hinnant        destroy(static_cast<__node_pointer>(__nd->__left_));
17983e519524SHoward Hinnant        destroy(static_cast<__node_pointer>(__nd->__right_));
17993e519524SHoward Hinnant        __node_allocator& __na = __node_alloc();
18005e3ea4ddSEric Fiselier        __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
18013e519524SHoward Hinnant        __node_traits::deallocate(__na, __nd, 1);
18023e519524SHoward Hinnant    }
18033e519524SHoward Hinnant}
18043e519524SHoward Hinnant
18053e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
18063e519524SHoward Hinnantvoid
18073e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
1808f8563f32SDimitry Andric#if _LIBCPP_STD_VER <= 11
18091052ee39SHoward Hinnant        _NOEXCEPT_(
1810e3fbe143SMarshall Clow            __is_nothrow_swappable<value_compare>::value
1811e3fbe143SMarshall Clow            && (!__node_traits::propagate_on_container_swap::value ||
1812e3fbe143SMarshall Clow                 __is_nothrow_swappable<__node_allocator>::value)
1813e3fbe143SMarshall Clow            )
1814f8563f32SDimitry Andric#else
1815f8563f32SDimitry Andric        _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1816f8563f32SDimitry Andric#endif
18173e519524SHoward Hinnant{
1818ce48a113SHoward Hinnant    using _VSTD::swap;
18193e519524SHoward Hinnant    swap(__begin_node_, __t.__begin_node_);
18203e519524SHoward Hinnant    swap(__pair1_.first(), __t.__pair1_.first());
18216e965df6SArthur O'Dwyer    _VSTD::__swap_allocator(__node_alloc(), __t.__node_alloc());
18223e519524SHoward Hinnant    __pair3_.swap(__t.__pair3_);
18233e519524SHoward Hinnant    if (size() == 0)
18243e519524SHoward Hinnant        __begin_node() = __end_node();
18253e519524SHoward Hinnant    else
1826d05b10abSEric Fiselier        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
18273e519524SHoward Hinnant    if (__t.size() == 0)
18283e519524SHoward Hinnant        __t.__begin_node() = __t.__end_node();
18293e519524SHoward Hinnant    else
1830d05b10abSEric Fiselier        __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
18313e519524SHoward Hinnant}
18323e519524SHoward Hinnant
18333e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
18343e519524SHoward Hinnantvoid
18351052ee39SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
18363e519524SHoward Hinnant{
18373e519524SHoward Hinnant    destroy(__root());
18383e519524SHoward Hinnant    size() = 0;
18393e519524SHoward Hinnant    __begin_node() = __end_node();
18403e519524SHoward Hinnant    __end_node()->__left_ = nullptr;
18413e519524SHoward Hinnant}
18423e519524SHoward Hinnant
18433e519524SHoward Hinnant// Find lower_bound place to insert
18443e519524SHoward Hinnant// Set __parent to parent of null leaf
18453e519524SHoward Hinnant// Return reference to null leaf
18463e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
1847d05b10abSEric Fiseliertypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1848d05b10abSEric Fiselier__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
18495e3ea4ddSEric Fiselier                                                   const key_type& __v)
18503e519524SHoward Hinnant{
18513e519524SHoward Hinnant    __node_pointer __nd = __root();
18523e519524SHoward Hinnant    if (__nd != nullptr)
18533e519524SHoward Hinnant    {
18543e519524SHoward Hinnant        while (true)
18553e519524SHoward Hinnant        {
18563e519524SHoward Hinnant            if (value_comp()(__nd->__value_, __v))
18573e519524SHoward Hinnant            {
18583e519524SHoward Hinnant                if (__nd->__right_ != nullptr)
18593e519524SHoward Hinnant                    __nd = static_cast<__node_pointer>(__nd->__right_);
18603e519524SHoward Hinnant                else
18613e519524SHoward Hinnant                {
1862d05b10abSEric Fiselier                    __parent = static_cast<__parent_pointer>(__nd);
1863d05b10abSEric Fiselier                    return __nd->__right_;
18643e519524SHoward Hinnant                }
18653e519524SHoward Hinnant            }
18663e519524SHoward Hinnant            else
18673e519524SHoward Hinnant            {
18683e519524SHoward Hinnant                if (__nd->__left_ != nullptr)
18693e519524SHoward Hinnant                    __nd = static_cast<__node_pointer>(__nd->__left_);
18703e519524SHoward Hinnant                else
18713e519524SHoward Hinnant                {
1872d05b10abSEric Fiselier                    __parent = static_cast<__parent_pointer>(__nd);
18733e519524SHoward Hinnant                    return __parent->__left_;
18743e519524SHoward Hinnant                }
18753e519524SHoward Hinnant            }
18763e519524SHoward Hinnant        }
18773e519524SHoward Hinnant    }
1878d05b10abSEric Fiselier    __parent = static_cast<__parent_pointer>(__end_node());
18793e519524SHoward Hinnant    return __parent->__left_;
18803e519524SHoward Hinnant}
18813e519524SHoward Hinnant
18823e519524SHoward Hinnant// Find upper_bound place to insert
18833e519524SHoward Hinnant// Set __parent to parent of null leaf
18843e519524SHoward Hinnant// Return reference to null leaf
18853e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
1886d05b10abSEric Fiseliertypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1887d05b10abSEric Fiselier__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
18885e3ea4ddSEric Fiselier                                                    const key_type& __v)
18893e519524SHoward Hinnant{
18903e519524SHoward Hinnant    __node_pointer __nd = __root();
18913e519524SHoward Hinnant    if (__nd != nullptr)
18923e519524SHoward Hinnant    {
18933e519524SHoward Hinnant        while (true)
18943e519524SHoward Hinnant        {
18953e519524SHoward Hinnant            if (value_comp()(__v, __nd->__value_))
18963e519524SHoward Hinnant            {
18973e519524SHoward Hinnant                if (__nd->__left_ != nullptr)
18983e519524SHoward Hinnant                    __nd = static_cast<__node_pointer>(__nd->__left_);
18993e519524SHoward Hinnant                else
19003e519524SHoward Hinnant                {
1901d05b10abSEric Fiselier                    __parent = static_cast<__parent_pointer>(__nd);
19023e519524SHoward Hinnant                    return __parent->__left_;
19033e519524SHoward Hinnant                }
19043e519524SHoward Hinnant            }
19053e519524SHoward Hinnant            else
19063e519524SHoward Hinnant            {
19073e519524SHoward Hinnant                if (__nd->__right_ != nullptr)
19083e519524SHoward Hinnant                    __nd = static_cast<__node_pointer>(__nd->__right_);
19093e519524SHoward Hinnant                else
19103e519524SHoward Hinnant                {
1911d05b10abSEric Fiselier                    __parent = static_cast<__parent_pointer>(__nd);
1912d05b10abSEric Fiselier                    return __nd->__right_;
19133e519524SHoward Hinnant                }
19143e519524SHoward Hinnant            }
19153e519524SHoward Hinnant        }
19163e519524SHoward Hinnant    }
1917d05b10abSEric Fiselier    __parent = static_cast<__parent_pointer>(__end_node());
19183e519524SHoward Hinnant    return __parent->__left_;
19193e519524SHoward Hinnant}
19203e519524SHoward Hinnant
19213e519524SHoward Hinnant// Find leaf place to insert closest to __hint
19223e519524SHoward Hinnant// First check prior to __hint.
19233e519524SHoward Hinnant// Next check after __hint.
19243e519524SHoward Hinnant// Next do O(log N) search.
19253e519524SHoward Hinnant// Set __parent to parent of null leaf
19263e519524SHoward Hinnant// Return reference to null leaf
19273e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
1928d05b10abSEric Fiseliertypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
19293e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
1930d05b10abSEric Fiselier                                               __parent_pointer& __parent,
19315e3ea4ddSEric Fiselier                                               const key_type& __v)
19323e519524SHoward Hinnant{
19333e519524SHoward Hinnant    if (__hint == end() || !value_comp()(*__hint, __v))  // check before
19343e519524SHoward Hinnant    {
19353e519524SHoward Hinnant        // __v <= *__hint
19363e519524SHoward Hinnant        const_iterator __prior = __hint;
19373e519524SHoward Hinnant        if (__prior == begin() || !value_comp()(__v, *--__prior))
19383e519524SHoward Hinnant        {
19393e519524SHoward Hinnant            // *prev(__hint) <= __v <= *__hint
19403e519524SHoward Hinnant            if (__hint.__ptr_->__left_ == nullptr)
19413e519524SHoward Hinnant            {
1942d05b10abSEric Fiselier                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
19433e519524SHoward Hinnant                return __parent->__left_;
19443e519524SHoward Hinnant            }
19453e519524SHoward Hinnant            else
19463e519524SHoward Hinnant            {
1947d05b10abSEric Fiselier                __parent = static_cast<__parent_pointer>(__prior.__ptr_);
1948d05b10abSEric Fiselier                return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
19493e519524SHoward Hinnant            }
19503e519524SHoward Hinnant        }
19513e519524SHoward Hinnant        // __v < *prev(__hint)
19523e519524SHoward Hinnant        return __find_leaf_high(__parent, __v);
19533e519524SHoward Hinnant    }
19543e519524SHoward Hinnant    // else __v > *__hint
19553e519524SHoward Hinnant    return __find_leaf_low(__parent, __v);
19563e519524SHoward Hinnant}
19573e519524SHoward Hinnant
19583e519524SHoward Hinnant// Find place to insert if __v doesn't exist
19593e519524SHoward Hinnant// Set __parent to parent of null leaf
19603e519524SHoward Hinnant// Return reference to null leaf
19613e519524SHoward Hinnant// If __v exists, set parent to node of __v and return reference to node of __v
19623e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
19633e519524SHoward Hinnanttemplate <class _Key>
1964d05b10abSEric Fiseliertypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1965d05b10abSEric Fiselier__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
19663e519524SHoward Hinnant                                                const _Key& __v)
19673e519524SHoward Hinnant{
19683e519524SHoward Hinnant    __node_pointer __nd = __root();
1969d05b10abSEric Fiselier    __node_base_pointer* __nd_ptr = __root_ptr();
19703e519524SHoward Hinnant    if (__nd != nullptr)
19713e519524SHoward Hinnant    {
19723e519524SHoward Hinnant        while (true)
19733e519524SHoward Hinnant        {
19743e519524SHoward Hinnant            if (value_comp()(__v, __nd->__value_))
19753e519524SHoward Hinnant            {
1976d05b10abSEric Fiselier                if (__nd->__left_ != nullptr) {
1977d05b10abSEric Fiselier                    __nd_ptr = _VSTD::addressof(__nd->__left_);
19783e519524SHoward Hinnant                    __nd = static_cast<__node_pointer>(__nd->__left_);
1979d05b10abSEric Fiselier                } else {
1980d05b10abSEric Fiselier                    __parent = static_cast<__parent_pointer>(__nd);
19813e519524SHoward Hinnant                    return __parent->__left_;
19823e519524SHoward Hinnant                }
19833e519524SHoward Hinnant            }
19843e519524SHoward Hinnant            else if (value_comp()(__nd->__value_, __v))
19853e519524SHoward Hinnant            {
1986d05b10abSEric Fiselier                if (__nd->__right_ != nullptr) {
1987d05b10abSEric Fiselier                    __nd_ptr = _VSTD::addressof(__nd->__right_);
19883e519524SHoward Hinnant                    __nd = static_cast<__node_pointer>(__nd->__right_);
1989d05b10abSEric Fiselier                } else {
1990d05b10abSEric Fiselier                    __parent = static_cast<__parent_pointer>(__nd);
1991d05b10abSEric Fiselier                    return __nd->__right_;
19923e519524SHoward Hinnant                }
19933e519524SHoward Hinnant            }
19943e519524SHoward Hinnant            else
19953e519524SHoward Hinnant            {
1996d05b10abSEric Fiselier                __parent = static_cast<__parent_pointer>(__nd);
1997d05b10abSEric Fiselier                return *__nd_ptr;
19983e519524SHoward Hinnant            }
19993e519524SHoward Hinnant        }
20003e519524SHoward Hinnant    }
2001d05b10abSEric Fiselier    __parent = static_cast<__parent_pointer>(__end_node());
20023e519524SHoward Hinnant    return __parent->__left_;
20033e519524SHoward Hinnant}
20043e519524SHoward Hinnant
20053e519524SHoward Hinnant// Find place to insert if __v doesn't exist
20063e519524SHoward Hinnant// First check prior to __hint.
20073e519524SHoward Hinnant// Next check after __hint.
20083e519524SHoward Hinnant// Next do O(log N) search.
20093e519524SHoward Hinnant// Set __parent to parent of null leaf
20103e519524SHoward Hinnant// Return reference to null leaf
20113e519524SHoward Hinnant// If __v exists, set parent to node of __v and return reference to node of __v
20123e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
20133e519524SHoward Hinnanttemplate <class _Key>
2014d05b10abSEric Fiseliertypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
20153e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
2016d05b10abSEric Fiselier                                                __parent_pointer& __parent,
2017d05b10abSEric Fiselier                                                __node_base_pointer& __dummy,
20183e519524SHoward Hinnant                                                const _Key& __v)
20193e519524SHoward Hinnant{
20203e519524SHoward Hinnant    if (__hint == end() || value_comp()(__v, *__hint))  // check before
20213e519524SHoward Hinnant    {
20223e519524SHoward Hinnant        // __v < *__hint
20233e519524SHoward Hinnant        const_iterator __prior = __hint;
20243e519524SHoward Hinnant        if (__prior == begin() || value_comp()(*--__prior, __v))
20253e519524SHoward Hinnant        {
20263e519524SHoward Hinnant            // *prev(__hint) < __v < *__hint
20273e519524SHoward Hinnant            if (__hint.__ptr_->__left_ == nullptr)
20283e519524SHoward Hinnant            {
2029d05b10abSEric Fiselier                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
20303e519524SHoward Hinnant                return __parent->__left_;
20313e519524SHoward Hinnant            }
20323e519524SHoward Hinnant            else
20333e519524SHoward Hinnant            {
2034d05b10abSEric Fiselier                __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2035d05b10abSEric Fiselier                return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
20363e519524SHoward Hinnant            }
20373e519524SHoward Hinnant        }
20383e519524SHoward Hinnant        // __v <= *prev(__hint)
20393e519524SHoward Hinnant        return __find_equal(__parent, __v);
20403e519524SHoward Hinnant    }
20413e519524SHoward Hinnant    else if (value_comp()(*__hint, __v))  // check after
20423e519524SHoward Hinnant    {
20433e519524SHoward Hinnant        // *__hint < __v
2044ce48a113SHoward Hinnant        const_iterator __next = _VSTD::next(__hint);
20453e519524SHoward Hinnant        if (__next == end() || value_comp()(__v, *__next))
20463e519524SHoward Hinnant        {
2047ce48a113SHoward Hinnant            // *__hint < __v < *_VSTD::next(__hint)
2048d05b10abSEric Fiselier            if (__hint.__get_np()->__right_ == nullptr)
20493e519524SHoward Hinnant            {
2050d05b10abSEric Fiselier                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2051d05b10abSEric Fiselier                return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
20523e519524SHoward Hinnant            }
20533e519524SHoward Hinnant            else
20543e519524SHoward Hinnant            {
2055d05b10abSEric Fiselier                __parent = static_cast<__parent_pointer>(__next.__ptr_);
20563e519524SHoward Hinnant                return __parent->__left_;
20573e519524SHoward Hinnant            }
20583e519524SHoward Hinnant        }
20593e519524SHoward Hinnant        // *next(__hint) <= __v
20603e519524SHoward Hinnant        return __find_equal(__parent, __v);
20613e519524SHoward Hinnant    }
20623e519524SHoward Hinnant    // else __v == *__hint
2063d05b10abSEric Fiselier    __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2064d05b10abSEric Fiselier    __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2065d05b10abSEric Fiselier    return __dummy;
20663e519524SHoward Hinnant}
20673e519524SHoward Hinnant
20683e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
20695c4e07aeSErik Pilkingtonvoid __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
20705c4e07aeSErik Pilkington    __parent_pointer __parent, __node_base_pointer& __child,
20715c4e07aeSErik Pilkington    __node_base_pointer __new_node) _NOEXCEPT
20723e519524SHoward Hinnant{
20733e519524SHoward Hinnant    __new_node->__left_   = nullptr;
20743e519524SHoward Hinnant    __new_node->__right_  = nullptr;
20753e519524SHoward Hinnant    __new_node->__parent_ = __parent;
20765e3ea4ddSEric Fiselier    // __new_node->__is_black_ is initialized in __tree_balance_after_insert
20773e519524SHoward Hinnant    __child = __new_node;
20783e519524SHoward Hinnant    if (__begin_node()->__left_ != nullptr)
2079d05b10abSEric Fiselier        __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
2080781c476cSArthur O'Dwyer    _VSTD::__tree_balance_after_insert(__end_node()->__left_, __child);
20813e519524SHoward Hinnant    ++size();
20823e519524SHoward Hinnant}
20833e519524SHoward Hinnant
20845e3ea4ddSEric Fiseliertemplate <class _Tp, class _Compare, class _Allocator>
20855e3ea4ddSEric Fiseliertemplate <class _Key, class... _Args>
20865e3ea4ddSEric Fiselierpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
20875e3ea4ddSEric Fiselier__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
20885e3ea4ddSEric Fiselier{
2089d05b10abSEric Fiselier    __parent_pointer __parent;
20905e3ea4ddSEric Fiselier    __node_base_pointer& __child = __find_equal(__parent, __k);
20915e3ea4ddSEric Fiselier    __node_pointer __r = static_cast<__node_pointer>(__child);
20925e3ea4ddSEric Fiselier    bool __inserted = false;
20935e3ea4ddSEric Fiselier    if (__child == nullptr)
20945e3ea4ddSEric Fiselier    {
20955e3ea4ddSEric Fiselier        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
20965e3ea4ddSEric Fiselier        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
20975e3ea4ddSEric Fiselier        __r = __h.release();
20985e3ea4ddSEric Fiselier        __inserted = true;
20995e3ea4ddSEric Fiselier    }
21005e3ea4ddSEric Fiselier    return pair<iterator, bool>(iterator(__r), __inserted);
21015e3ea4ddSEric Fiselier}
21025e3ea4ddSEric Fiselier
21035e3ea4ddSEric Fiseliertemplate <class _Tp, class _Compare, class _Allocator>
21045e3ea4ddSEric Fiseliertemplate <class _Key, class... _Args>
2105d4dd9613SMark de Weverpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
21065e3ea4ddSEric Fiselier__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
21075e3ea4ddSEric Fiselier    const_iterator __p, _Key const& __k, _Args&&... __args)
21085e3ea4ddSEric Fiselier{
2109d05b10abSEric Fiselier    __parent_pointer __parent;
2110d05b10abSEric Fiselier    __node_base_pointer __dummy;
2111d05b10abSEric Fiselier    __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
21125e3ea4ddSEric Fiselier    __node_pointer __r = static_cast<__node_pointer>(__child);
2113d4dd9613SMark de Wever    bool __inserted = false;
21145e3ea4ddSEric Fiselier    if (__child == nullptr)
21155e3ea4ddSEric Fiselier    {
21165e3ea4ddSEric Fiselier        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
21175e3ea4ddSEric Fiselier        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
21185e3ea4ddSEric Fiselier        __r = __h.release();
2119d4dd9613SMark de Wever        __inserted = true;
21205e3ea4ddSEric Fiselier    }
2121d4dd9613SMark de Wever    return pair<iterator, bool>(iterator(__r), __inserted);
21225e3ea4ddSEric Fiselier}
21235e3ea4ddSEric Fiselier
21243e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
21253e519524SHoward Hinnanttemplate <class ..._Args>
21263e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::__node_holder
21273e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
21283e519524SHoward Hinnant{
21295e3ea4ddSEric Fiselier    static_assert(!__is_tree_value_type<_Args...>::value,
21305e3ea4ddSEric Fiselier                  "Cannot construct from __value_type");
21313e519524SHoward Hinnant    __node_allocator& __na = __node_alloc();
2132c003db1fSHoward Hinnant    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
21335e3ea4ddSEric Fiselier    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
21343e519524SHoward Hinnant    __h.get_deleter().__value_constructed = true;
21353e519524SHoward Hinnant    return __h;
21363e519524SHoward Hinnant}
21373e519524SHoward Hinnant
21385e3ea4ddSEric Fiselier
21393e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
21403e519524SHoward Hinnanttemplate <class... _Args>
21413e519524SHoward Hinnantpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2142fa1f613fSEric Fiselier__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
21433e519524SHoward Hinnant{
2144ce48a113SHoward Hinnant    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2145d05b10abSEric Fiselier    __parent_pointer __parent;
21463e519524SHoward Hinnant    __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
21473e519524SHoward Hinnant    __node_pointer __r = static_cast<__node_pointer>(__child);
21483e519524SHoward Hinnant    bool __inserted = false;
21493e519524SHoward Hinnant    if (__child == nullptr)
21503e519524SHoward Hinnant    {
215107d3eccdSHoward Hinnant        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
21523e519524SHoward Hinnant        __r = __h.release();
21533e519524SHoward Hinnant        __inserted = true;
21543e519524SHoward Hinnant    }
21553e519524SHoward Hinnant    return pair<iterator, bool>(iterator(__r), __inserted);
21563e519524SHoward Hinnant}
21573e519524SHoward Hinnant
21583e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
21593e519524SHoward Hinnanttemplate <class... _Args>
21603e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
2161fa1f613fSEric Fiselier__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
21623e519524SHoward Hinnant{
2163ce48a113SHoward Hinnant    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2164d05b10abSEric Fiselier    __parent_pointer __parent;
2165d05b10abSEric Fiselier    __node_base_pointer __dummy;
2166d05b10abSEric Fiselier    __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
21673e519524SHoward Hinnant    __node_pointer __r = static_cast<__node_pointer>(__child);
21683e519524SHoward Hinnant    if (__child == nullptr)
21693e519524SHoward Hinnant    {
217007d3eccdSHoward Hinnant        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
21713e519524SHoward Hinnant        __r = __h.release();
21723e519524SHoward Hinnant    }
21733e519524SHoward Hinnant    return iterator(__r);
21743e519524SHoward Hinnant}
21753e519524SHoward Hinnant
21763e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
21773e519524SHoward Hinnanttemplate <class... _Args>
21783e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
21793e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
21803e519524SHoward Hinnant{
2181ce48a113SHoward Hinnant    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2182d05b10abSEric Fiselier    __parent_pointer __parent;
21835e3ea4ddSEric Fiselier    __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
218407d3eccdSHoward Hinnant    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
21853e519524SHoward Hinnant    return iterator(static_cast<__node_pointer>(__h.release()));
21863e519524SHoward Hinnant}
21873e519524SHoward Hinnant
21883e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
21893e519524SHoward Hinnanttemplate <class... _Args>
21903e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
21913e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
21923e519524SHoward Hinnant                                                        _Args&&... __args)
21933e519524SHoward Hinnant{
2194ce48a113SHoward Hinnant    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2195d05b10abSEric Fiselier    __parent_pointer __parent;
21965e3ea4ddSEric Fiselier    __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
219707d3eccdSHoward Hinnant    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
21983e519524SHoward Hinnant    return iterator(static_cast<__node_pointer>(__h.release()));
21993e519524SHoward Hinnant}
22003e519524SHoward Hinnant
22013e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
22023e519524SHoward Hinnantpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
220341798c05SEric Fiselier__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_type& __v, __node_pointer __nd)
22043e519524SHoward Hinnant{
2205d05b10abSEric Fiselier    __parent_pointer __parent;
220641798c05SEric Fiselier    __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__v));
22073e519524SHoward Hinnant    __node_pointer __r = static_cast<__node_pointer>(__child);
22083e519524SHoward Hinnant    bool __inserted = false;
22093e519524SHoward Hinnant    if (__child == nullptr)
22103e519524SHoward Hinnant    {
221141798c05SEric Fiselier        __nd->__value_ = __v;
221207d3eccdSHoward Hinnant        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
22133e519524SHoward Hinnant        __r = __nd;
22143e519524SHoward Hinnant        __inserted = true;
22153e519524SHoward Hinnant    }
22163e519524SHoward Hinnant    return pair<iterator, bool>(iterator(__r), __inserted);
22173e519524SHoward Hinnant}
22183e519524SHoward Hinnant
22193e519524SHoward Hinnant
22203e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
22213e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
22223e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
22233e519524SHoward Hinnant{
2224d05b10abSEric Fiselier    __parent_pointer __parent;
22255e3ea4ddSEric Fiselier    __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
222607d3eccdSHoward Hinnant    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
22273e519524SHoward Hinnant    return iterator(__nd);
22283e519524SHoward Hinnant}
22293e519524SHoward Hinnant
22303e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
22313e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
22323e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
22333e519524SHoward Hinnant                                                       __node_pointer __nd)
22343e519524SHoward Hinnant{
2235d05b10abSEric Fiselier    __parent_pointer __parent;
22365e3ea4ddSEric Fiselier    __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
223707d3eccdSHoward Hinnant    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
22383e519524SHoward Hinnant    return iterator(__nd);
22393e519524SHoward Hinnant}
22403e519524SHoward Hinnant
22413e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
22423e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
22435c4e07aeSErik Pilkington__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
2244b0386a51SErik Pilkington{
2245b0386a51SErik Pilkington    iterator __r(__ptr);
2246b0386a51SErik Pilkington    ++__r;
2247b0386a51SErik Pilkington    if (__begin_node() == __ptr)
2248b0386a51SErik Pilkington        __begin_node() = __r.__ptr_;
2249b0386a51SErik Pilkington    --size();
2250781c476cSArthur O'Dwyer    _VSTD::__tree_remove(__end_node()->__left_,
2251b0386a51SErik Pilkington                         static_cast<__node_base_pointer>(__ptr));
2252b0386a51SErik Pilkington    return __r;
2253b0386a51SErik Pilkington}
2254b0386a51SErik Pilkington
2255b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14
2256b0386a51SErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
2257b0386a51SErik Pilkingtontemplate <class _NodeHandle, class _InsertReturnType>
2258b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2259b0386a51SErik Pilkington_InsertReturnType
2260b0386a51SErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2261b0386a51SErik Pilkington    _NodeHandle&& __nh)
2262b0386a51SErik Pilkington{
2263b0386a51SErik Pilkington    if (__nh.empty())
2264b0386a51SErik Pilkington        return _InsertReturnType{end(), false, _NodeHandle()};
2265b0386a51SErik Pilkington
2266b0386a51SErik Pilkington    __node_pointer __ptr = __nh.__ptr_;
2267b0386a51SErik Pilkington    __parent_pointer __parent;
2268b0386a51SErik Pilkington    __node_base_pointer& __child = __find_equal(__parent,
2269b0386a51SErik Pilkington                                                __ptr->__value_);
2270b0386a51SErik Pilkington    if (__child != nullptr)
2271b0386a51SErik Pilkington        return _InsertReturnType{
2272b0386a51SErik Pilkington            iterator(static_cast<__node_pointer>(__child)),
2273b0386a51SErik Pilkington            false, _VSTD::move(__nh)};
2274b0386a51SErik Pilkington
2275b0386a51SErik Pilkington    __insert_node_at(__parent, __child,
2276b0386a51SErik Pilkington                     static_cast<__node_base_pointer>(__ptr));
22776886f1e3SEric Fiselier    __nh.__release_ptr();
2278b0386a51SErik Pilkington    return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
2279b0386a51SErik Pilkington}
2280b0386a51SErik Pilkington
2281b0386a51SErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
2282b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2283b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2284b0386a51SErik Pilkingtontypename __tree<_Tp, _Compare, _Allocator>::iterator
2285b0386a51SErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2286b0386a51SErik Pilkington    const_iterator __hint, _NodeHandle&& __nh)
2287b0386a51SErik Pilkington{
2288b0386a51SErik Pilkington    if (__nh.empty())
2289b0386a51SErik Pilkington        return end();
2290b0386a51SErik Pilkington
2291b0386a51SErik Pilkington    __node_pointer __ptr = __nh.__ptr_;
2292b0386a51SErik Pilkington    __parent_pointer __parent;
2293b0386a51SErik Pilkington    __node_base_pointer __dummy;
2294b0386a51SErik Pilkington    __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
2295b0386a51SErik Pilkington                                                __ptr->__value_);
2296b0386a51SErik Pilkington    __node_pointer __r = static_cast<__node_pointer>(__child);
2297b0386a51SErik Pilkington    if (__child == nullptr)
2298b0386a51SErik Pilkington    {
2299b0386a51SErik Pilkington        __insert_node_at(__parent, __child,
2300b0386a51SErik Pilkington                         static_cast<__node_base_pointer>(__ptr));
2301b0386a51SErik Pilkington        __r = __ptr;
23026886f1e3SEric Fiselier        __nh.__release_ptr();
2303b0386a51SErik Pilkington    }
2304b0386a51SErik Pilkington    return iterator(__r);
2305b0386a51SErik Pilkington}
2306b0386a51SErik Pilkington
2307b0386a51SErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
2308b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2309b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2310b0386a51SErik Pilkington_NodeHandle
2311b0386a51SErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
2312b0386a51SErik Pilkington{
2313b0386a51SErik Pilkington    iterator __it = find(__key);
2314b0386a51SErik Pilkington    if (__it == end())
2315b0386a51SErik Pilkington        return _NodeHandle();
2316b0386a51SErik Pilkington    return __node_handle_extract<_NodeHandle>(__it);
2317b0386a51SErik Pilkington}
2318b0386a51SErik Pilkington
2319b0386a51SErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
2320b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2321b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2322b0386a51SErik Pilkington_NodeHandle
2323b0386a51SErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
2324b0386a51SErik Pilkington{
2325b0386a51SErik Pilkington    __node_pointer __np = __p.__get_np();
2326b0386a51SErik Pilkington    __remove_node_pointer(__np);
2327b0386a51SErik Pilkington    return _NodeHandle(__np, __alloc());
2328b0386a51SErik Pilkington}
2329b0386a51SErik Pilkington
2330b0386a51SErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
23315c4e07aeSErik Pilkingtontemplate <class _Tree>
23325c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY
23335c4e07aeSErik Pilkingtonvoid
23345c4e07aeSErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
23355c4e07aeSErik Pilkington{
23365c4e07aeSErik Pilkington    static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
23375c4e07aeSErik Pilkington
23385c4e07aeSErik Pilkington    for (typename _Tree::iterator __i = __source.begin();
23395c4e07aeSErik Pilkington         __i != __source.end();)
23405c4e07aeSErik Pilkington    {
23415c4e07aeSErik Pilkington        __node_pointer __src_ptr = __i.__get_np();
23425c4e07aeSErik Pilkington        __parent_pointer __parent;
23435c4e07aeSErik Pilkington        __node_base_pointer& __child =
23445c4e07aeSErik Pilkington            __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
23455c4e07aeSErik Pilkington        ++__i;
23465c4e07aeSErik Pilkington        if (__child != nullptr)
23475c4e07aeSErik Pilkington            continue;
23485c4e07aeSErik Pilkington        __source.__remove_node_pointer(__src_ptr);
23495c4e07aeSErik Pilkington        __insert_node_at(__parent, __child,
23505c4e07aeSErik Pilkington                         static_cast<__node_base_pointer>(__src_ptr));
23515c4e07aeSErik Pilkington    }
23525c4e07aeSErik Pilkington}
23535c4e07aeSErik Pilkington
23545c4e07aeSErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
2355b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2356b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2357b0386a51SErik Pilkingtontypename __tree<_Tp, _Compare, _Allocator>::iterator
2358b0386a51SErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
2359b0386a51SErik Pilkington{
2360b0386a51SErik Pilkington    if (__nh.empty())
2361b0386a51SErik Pilkington        return end();
2362b0386a51SErik Pilkington    __node_pointer __ptr = __nh.__ptr_;
2363b0386a51SErik Pilkington    __parent_pointer __parent;
2364b0386a51SErik Pilkington    __node_base_pointer& __child = __find_leaf_high(
2365b0386a51SErik Pilkington        __parent, _NodeTypes::__get_key(__ptr->__value_));
2366b0386a51SErik Pilkington    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
23676886f1e3SEric Fiselier    __nh.__release_ptr();
2368b0386a51SErik Pilkington    return iterator(__ptr);
2369b0386a51SErik Pilkington}
2370b0386a51SErik Pilkington
2371b0386a51SErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
2372b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2373b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2374b0386a51SErik Pilkingtontypename __tree<_Tp, _Compare, _Allocator>::iterator
2375b0386a51SErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
2376b0386a51SErik Pilkington    const_iterator __hint, _NodeHandle&& __nh)
2377b0386a51SErik Pilkington{
2378b0386a51SErik Pilkington    if (__nh.empty())
2379b0386a51SErik Pilkington        return end();
2380b0386a51SErik Pilkington
2381b0386a51SErik Pilkington    __node_pointer __ptr = __nh.__ptr_;
2382b0386a51SErik Pilkington    __parent_pointer __parent;
2383b0386a51SErik Pilkington    __node_base_pointer& __child = __find_leaf(__hint, __parent,
2384b0386a51SErik Pilkington                                               _NodeTypes::__get_key(__ptr->__value_));
2385b0386a51SErik Pilkington    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
23866886f1e3SEric Fiselier    __nh.__release_ptr();
2387b0386a51SErik Pilkington    return iterator(__ptr);
2388b0386a51SErik Pilkington}
2389b0386a51SErik Pilkington
23905c4e07aeSErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
23915c4e07aeSErik Pilkingtontemplate <class _Tree>
23925c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY
23935c4e07aeSErik Pilkingtonvoid
23945c4e07aeSErik Pilkington__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
23955c4e07aeSErik Pilkington{
23965c4e07aeSErik Pilkington    static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
23975c4e07aeSErik Pilkington
23985c4e07aeSErik Pilkington    for (typename _Tree::iterator __i = __source.begin();
23995c4e07aeSErik Pilkington         __i != __source.end();)
24005c4e07aeSErik Pilkington    {
24015c4e07aeSErik Pilkington        __node_pointer __src_ptr = __i.__get_np();
24025c4e07aeSErik Pilkington        __parent_pointer __parent;
24035c4e07aeSErik Pilkington        __node_base_pointer& __child = __find_leaf_high(
24045c4e07aeSErik Pilkington            __parent, _NodeTypes::__get_key(__src_ptr->__value_));
24055c4e07aeSErik Pilkington        ++__i;
24065c4e07aeSErik Pilkington        __source.__remove_node_pointer(__src_ptr);
24075c4e07aeSErik Pilkington        __insert_node_at(__parent, __child,
24085c4e07aeSErik Pilkington                         static_cast<__node_base_pointer>(__src_ptr));
24095c4e07aeSErik Pilkington    }
24105c4e07aeSErik Pilkington}
24115c4e07aeSErik Pilkington
2412b0386a51SErik Pilkington#endif // _LIBCPP_STD_VER > 14
2413b0386a51SErik Pilkington
2414b0386a51SErik Pilkingtontemplate <class _Tp, class _Compare, class _Allocator>
2415b0386a51SErik Pilkingtontypename __tree<_Tp, _Compare, _Allocator>::iterator
24163e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
24173e519524SHoward Hinnant{
2418d05b10abSEric Fiselier    __node_pointer __np = __p.__get_np();
2419b0386a51SErik Pilkington    iterator __r = __remove_node_pointer(__np);
24203e519524SHoward Hinnant    __node_allocator& __na = __node_alloc();
24215e3ea4ddSEric Fiselier    __node_traits::destroy(__na, _NodeTypes::__get_ptr(
24225e3ea4ddSEric Fiselier        const_cast<__node_value_type&>(*__p)));
24233e519524SHoward Hinnant    __node_traits::deallocate(__na, __np, 1);
24243e519524SHoward Hinnant    return __r;
24253e519524SHoward Hinnant}
24263e519524SHoward Hinnant
24273e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
24283e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
24293e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
24303e519524SHoward Hinnant{
24313e519524SHoward Hinnant    while (__f != __l)
24323e519524SHoward Hinnant        __f = erase(__f);
243307d3eccdSHoward Hinnant    return iterator(__l.__ptr_);
24343e519524SHoward Hinnant}
24353e519524SHoward Hinnant
24363e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
24373e519524SHoward Hinnanttemplate <class _Key>
24383e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::size_type
24393e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
24403e519524SHoward Hinnant{
24413e519524SHoward Hinnant    iterator __i = find(__k);
24423e519524SHoward Hinnant    if (__i == end())
24433e519524SHoward Hinnant        return 0;
24443e519524SHoward Hinnant    erase(__i);
24453e519524SHoward Hinnant    return 1;
24463e519524SHoward Hinnant}
24473e519524SHoward Hinnant
24483e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
24493e519524SHoward Hinnanttemplate <class _Key>
24503e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::size_type
24513e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
24523e519524SHoward Hinnant{
24533e519524SHoward Hinnant    pair<iterator, iterator> __p = __equal_range_multi(__k);
24543e519524SHoward Hinnant    size_type __r = 0;
24553e519524SHoward Hinnant    for (; __p.first != __p.second; ++__r)
24563e519524SHoward Hinnant        __p.first = erase(__p.first);
24573e519524SHoward Hinnant    return __r;
24583e519524SHoward Hinnant}
24593e519524SHoward Hinnant
24603e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
24613e519524SHoward Hinnanttemplate <class _Key>
24623e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
24633e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
24643e519524SHoward Hinnant{
24653e519524SHoward Hinnant    iterator __p = __lower_bound(__v, __root(), __end_node());
24663e519524SHoward Hinnant    if (__p != end() && !value_comp()(__v, *__p))
24673e519524SHoward Hinnant        return __p;
24683e519524SHoward Hinnant    return end();
24693e519524SHoward Hinnant}
24703e519524SHoward Hinnant
24713e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
24723e519524SHoward Hinnanttemplate <class _Key>
24733e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::const_iterator
24743e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
24753e519524SHoward Hinnant{
24763e519524SHoward Hinnant    const_iterator __p = __lower_bound(__v, __root(), __end_node());
24773e519524SHoward Hinnant    if (__p != end() && !value_comp()(__v, *__p))
24783e519524SHoward Hinnant        return __p;
24793e519524SHoward Hinnant    return end();
24803e519524SHoward Hinnant}
24813e519524SHoward Hinnant
24823e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
24833e519524SHoward Hinnanttemplate <class _Key>
24843e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::size_type
24853e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
24863e519524SHoward Hinnant{
24870594ad71SEric Fiselier    __node_pointer __rt = __root();
24883e519524SHoward Hinnant    while (__rt != nullptr)
24893e519524SHoward Hinnant    {
24903e519524SHoward Hinnant        if (value_comp()(__k, __rt->__value_))
24913e519524SHoward Hinnant        {
24920594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__left_);
24933e519524SHoward Hinnant        }
24943e519524SHoward Hinnant        else if (value_comp()(__rt->__value_, __k))
24950594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__right_);
24963e519524SHoward Hinnant        else
24973e519524SHoward Hinnant            return 1;
24983e519524SHoward Hinnant    }
24993e519524SHoward Hinnant    return 0;
25003e519524SHoward Hinnant}
25013e519524SHoward Hinnant
25023e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
25033e519524SHoward Hinnanttemplate <class _Key>
25043e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::size_type
25053e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
25063e519524SHoward Hinnant{
2507d05b10abSEric Fiselier    __iter_pointer __result = __end_node();
25080594ad71SEric Fiselier    __node_pointer __rt = __root();
25093e519524SHoward Hinnant    while (__rt != nullptr)
25103e519524SHoward Hinnant    {
25113e519524SHoward Hinnant        if (value_comp()(__k, __rt->__value_))
25123e519524SHoward Hinnant        {
2513d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__rt);
25140594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__left_);
25153e519524SHoward Hinnant        }
25163e519524SHoward Hinnant        else if (value_comp()(__rt->__value_, __k))
25170594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__right_);
25183e519524SHoward Hinnant        else
2519ce48a113SHoward Hinnant            return _VSTD::distance(
2520d05b10abSEric Fiselier                __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
25210594ad71SEric Fiselier                __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
25223e519524SHoward Hinnant            );
25233e519524SHoward Hinnant    }
25243e519524SHoward Hinnant    return 0;
25253e519524SHoward Hinnant}
25263e519524SHoward Hinnant
25273e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
25283e519524SHoward Hinnanttemplate <class _Key>
25293e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
25303e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
25313e519524SHoward Hinnant                                                 __node_pointer __root,
2532d05b10abSEric Fiselier                                                 __iter_pointer __result)
25333e519524SHoward Hinnant{
25343e519524SHoward Hinnant    while (__root != nullptr)
25353e519524SHoward Hinnant    {
25363e519524SHoward Hinnant        if (!value_comp()(__root->__value_, __v))
25373e519524SHoward Hinnant        {
2538d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__root);
25393e519524SHoward Hinnant            __root = static_cast<__node_pointer>(__root->__left_);
25403e519524SHoward Hinnant        }
25413e519524SHoward Hinnant        else
25423e519524SHoward Hinnant            __root = static_cast<__node_pointer>(__root->__right_);
25433e519524SHoward Hinnant    }
25443e519524SHoward Hinnant    return iterator(__result);
25453e519524SHoward Hinnant}
25463e519524SHoward Hinnant
25473e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
25483e519524SHoward Hinnanttemplate <class _Key>
25493e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::const_iterator
25503e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
25510594ad71SEric Fiselier                                                 __node_pointer __root,
2552d05b10abSEric Fiselier                                                 __iter_pointer __result) const
25533e519524SHoward Hinnant{
25543e519524SHoward Hinnant    while (__root != nullptr)
25553e519524SHoward Hinnant    {
25563e519524SHoward Hinnant        if (!value_comp()(__root->__value_, __v))
25573e519524SHoward Hinnant        {
2558d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__root);
25590594ad71SEric Fiselier            __root = static_cast<__node_pointer>(__root->__left_);
25603e519524SHoward Hinnant        }
25613e519524SHoward Hinnant        else
25620594ad71SEric Fiselier            __root = static_cast<__node_pointer>(__root->__right_);
25633e519524SHoward Hinnant    }
25643e519524SHoward Hinnant    return const_iterator(__result);
25653e519524SHoward Hinnant}
25663e519524SHoward Hinnant
25673e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
25683e519524SHoward Hinnanttemplate <class _Key>
25693e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::iterator
25703e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
25713e519524SHoward Hinnant                                                 __node_pointer __root,
2572d05b10abSEric Fiselier                                                 __iter_pointer __result)
25733e519524SHoward Hinnant{
25743e519524SHoward Hinnant    while (__root != nullptr)
25753e519524SHoward Hinnant    {
25763e519524SHoward Hinnant        if (value_comp()(__v, __root->__value_))
25773e519524SHoward Hinnant        {
2578d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__root);
25793e519524SHoward Hinnant            __root = static_cast<__node_pointer>(__root->__left_);
25803e519524SHoward Hinnant        }
25813e519524SHoward Hinnant        else
25823e519524SHoward Hinnant            __root = static_cast<__node_pointer>(__root->__right_);
25833e519524SHoward Hinnant    }
25843e519524SHoward Hinnant    return iterator(__result);
25853e519524SHoward Hinnant}
25863e519524SHoward Hinnant
25873e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
25883e519524SHoward Hinnanttemplate <class _Key>
25893e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::const_iterator
25903e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
25910594ad71SEric Fiselier                                                 __node_pointer __root,
2592d05b10abSEric Fiselier                                                 __iter_pointer __result) const
25933e519524SHoward Hinnant{
25943e519524SHoward Hinnant    while (__root != nullptr)
25953e519524SHoward Hinnant    {
25963e519524SHoward Hinnant        if (value_comp()(__v, __root->__value_))
25973e519524SHoward Hinnant        {
2598d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__root);
25990594ad71SEric Fiselier            __root = static_cast<__node_pointer>(__root->__left_);
26003e519524SHoward Hinnant        }
26013e519524SHoward Hinnant        else
26020594ad71SEric Fiselier            __root = static_cast<__node_pointer>(__root->__right_);
26033e519524SHoward Hinnant    }
26043e519524SHoward Hinnant    return const_iterator(__result);
26053e519524SHoward Hinnant}
26063e519524SHoward Hinnant
26073e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
26083e519524SHoward Hinnanttemplate <class _Key>
26093e519524SHoward Hinnantpair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
26103e519524SHoward Hinnant     typename __tree<_Tp, _Compare, _Allocator>::iterator>
26113e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
26123e519524SHoward Hinnant{
2613c003db1fSHoward Hinnant    typedef pair<iterator, iterator> _Pp;
2614d05b10abSEric Fiselier    __iter_pointer __result = __end_node();
26153e519524SHoward Hinnant    __node_pointer __rt = __root();
26163e519524SHoward Hinnant    while (__rt != nullptr)
26173e519524SHoward Hinnant    {
26183e519524SHoward Hinnant        if (value_comp()(__k, __rt->__value_))
26193e519524SHoward Hinnant        {
2620d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__rt);
26213e519524SHoward Hinnant            __rt = static_cast<__node_pointer>(__rt->__left_);
26223e519524SHoward Hinnant        }
26233e519524SHoward Hinnant        else if (value_comp()(__rt->__value_, __k))
26243e519524SHoward Hinnant            __rt = static_cast<__node_pointer>(__rt->__right_);
26253e519524SHoward Hinnant        else
2626c003db1fSHoward Hinnant            return _Pp(iterator(__rt),
26273e519524SHoward Hinnant                      iterator(
26283e519524SHoward Hinnant                          __rt->__right_ != nullptr ?
2629781c476cSArthur O'Dwyer                              static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
26303e519524SHoward Hinnant                            : __result));
26313e519524SHoward Hinnant    }
2632c003db1fSHoward Hinnant    return _Pp(iterator(__result), iterator(__result));
26333e519524SHoward Hinnant}
26343e519524SHoward Hinnant
26353e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
26363e519524SHoward Hinnanttemplate <class _Key>
26373e519524SHoward Hinnantpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
26383e519524SHoward Hinnant     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
26393e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
26403e519524SHoward Hinnant{
2641c003db1fSHoward Hinnant    typedef pair<const_iterator, const_iterator> _Pp;
2642d05b10abSEric Fiselier    __iter_pointer __result = __end_node();
26430594ad71SEric Fiselier    __node_pointer __rt = __root();
26443e519524SHoward Hinnant    while (__rt != nullptr)
26453e519524SHoward Hinnant    {
26463e519524SHoward Hinnant        if (value_comp()(__k, __rt->__value_))
26473e519524SHoward Hinnant        {
2648d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__rt);
26490594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__left_);
26503e519524SHoward Hinnant        }
26513e519524SHoward Hinnant        else if (value_comp()(__rt->__value_, __k))
26520594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__right_);
26533e519524SHoward Hinnant        else
2654c003db1fSHoward Hinnant            return _Pp(const_iterator(__rt),
26553e519524SHoward Hinnant                      const_iterator(
26563e519524SHoward Hinnant                          __rt->__right_ != nullptr ?
2657781c476cSArthur O'Dwyer                              static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
26583e519524SHoward Hinnant                            : __result));
26593e519524SHoward Hinnant    }
2660c003db1fSHoward Hinnant    return _Pp(const_iterator(__result), const_iterator(__result));
26613e519524SHoward Hinnant}
26623e519524SHoward Hinnant
26633e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
26643e519524SHoward Hinnanttemplate <class _Key>
26653e519524SHoward Hinnantpair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
26663e519524SHoward Hinnant     typename __tree<_Tp, _Compare, _Allocator>::iterator>
26673e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
26683e519524SHoward Hinnant{
2669c003db1fSHoward Hinnant    typedef pair<iterator, iterator> _Pp;
2670d05b10abSEric Fiselier    __iter_pointer __result = __end_node();
26713e519524SHoward Hinnant    __node_pointer __rt = __root();
26723e519524SHoward Hinnant    while (__rt != nullptr)
26733e519524SHoward Hinnant    {
26743e519524SHoward Hinnant        if (value_comp()(__k, __rt->__value_))
26753e519524SHoward Hinnant        {
2676d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__rt);
26773e519524SHoward Hinnant            __rt = static_cast<__node_pointer>(__rt->__left_);
26783e519524SHoward Hinnant        }
26793e519524SHoward Hinnant        else if (value_comp()(__rt->__value_, __k))
26803e519524SHoward Hinnant            __rt = static_cast<__node_pointer>(__rt->__right_);
26813e519524SHoward Hinnant        else
2682d05b10abSEric Fiselier            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
26833e519524SHoward Hinnant                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
26843e519524SHoward Hinnant    }
2685c003db1fSHoward Hinnant    return _Pp(iterator(__result), iterator(__result));
26863e519524SHoward Hinnant}
26873e519524SHoward Hinnant
26883e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
26893e519524SHoward Hinnanttemplate <class _Key>
26903e519524SHoward Hinnantpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
26913e519524SHoward Hinnant     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
26923e519524SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
26933e519524SHoward Hinnant{
2694c003db1fSHoward Hinnant    typedef pair<const_iterator, const_iterator> _Pp;
2695d05b10abSEric Fiselier    __iter_pointer __result = __end_node();
26960594ad71SEric Fiselier    __node_pointer __rt = __root();
26973e519524SHoward Hinnant    while (__rt != nullptr)
26983e519524SHoward Hinnant    {
26993e519524SHoward Hinnant        if (value_comp()(__k, __rt->__value_))
27003e519524SHoward Hinnant        {
2701d05b10abSEric Fiselier            __result = static_cast<__iter_pointer>(__rt);
27020594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__left_);
27033e519524SHoward Hinnant        }
27043e519524SHoward Hinnant        else if (value_comp()(__rt->__value_, __k))
27050594ad71SEric Fiselier            __rt = static_cast<__node_pointer>(__rt->__right_);
27063e519524SHoward Hinnant        else
2707d05b10abSEric Fiselier            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
27080594ad71SEric Fiselier                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
27093e519524SHoward Hinnant    }
2710c003db1fSHoward Hinnant    return _Pp(const_iterator(__result), const_iterator(__result));
27113e519524SHoward Hinnant}
27123e519524SHoward Hinnant
27133e519524SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
27143e519524SHoward Hinnanttypename __tree<_Tp, _Compare, _Allocator>::__node_holder
2715e6913510SHoward Hinnant__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
27163e519524SHoward Hinnant{
2717d05b10abSEric Fiselier    __node_pointer __np = __p.__get_np();
2718d05b10abSEric Fiselier    if (__begin_node() == __p.__ptr_)
27193e519524SHoward Hinnant    {
27203e519524SHoward Hinnant        if (__np->__right_ != nullptr)
2721d05b10abSEric Fiselier            __begin_node() = static_cast<__iter_pointer>(__np->__right_);
27223e519524SHoward Hinnant        else
2723d05b10abSEric Fiselier            __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
27243e519524SHoward Hinnant    }
27253e519524SHoward Hinnant    --size();
2726781c476cSArthur O'Dwyer    _VSTD::__tree_remove(__end_node()->__left_,
27273e519524SHoward Hinnant                         static_cast<__node_base_pointer>(__np));
2728d5f461caSMarshall Clow    return __node_holder(__np, _Dp(__node_alloc(), true));
27293e519524SHoward Hinnant}
27303e519524SHoward Hinnant
27311052ee39SHoward Hinnanttemplate <class _Tp, class _Compare, class _Allocator>
27321052ee39SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
27331052ee39SHoward Hinnantvoid
27341052ee39SHoward Hinnantswap(__tree<_Tp, _Compare, _Allocator>& __x,
27351052ee39SHoward Hinnant     __tree<_Tp, _Compare, _Allocator>& __y)
27361052ee39SHoward Hinnant    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
27371052ee39SHoward Hinnant{
27381052ee39SHoward Hinnant    __x.swap(__y);
27391052ee39SHoward Hinnant}
27401052ee39SHoward Hinnant
27413e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
27423e519524SHoward Hinnant
2743a016efb1SEric Fiselier_LIBCPP_POP_MACROS
2744a016efb1SEric Fiselier
27453e519524SHoward Hinnant#endif // _LIBCPP___TREE
2746