xref: /minix3/external/bsd/libc++/dist/libcxx/include/__tree (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
14684ddb6SLionel Sambuc// -*- C++ -*-
24684ddb6SLionel Sambuc//===----------------------------------------------------------------------===//
34684ddb6SLionel Sambuc//
44684ddb6SLionel Sambuc//                     The LLVM Compiler Infrastructure
54684ddb6SLionel Sambuc//
64684ddb6SLionel Sambuc// This file is dual licensed under the MIT and the University of Illinois Open
74684ddb6SLionel Sambuc// Source Licenses. See LICENSE.TXT for details.
84684ddb6SLionel Sambuc//
94684ddb6SLionel Sambuc//===----------------------------------------------------------------------===//
104684ddb6SLionel Sambuc
114684ddb6SLionel Sambuc#ifndef _LIBCPP___TREE
124684ddb6SLionel Sambuc#define _LIBCPP___TREE
134684ddb6SLionel Sambuc
144684ddb6SLionel Sambuc#include <__config>
154684ddb6SLionel Sambuc#include <iterator>
164684ddb6SLionel Sambuc#include <memory>
174684ddb6SLionel Sambuc#include <stdexcept>
184684ddb6SLionel Sambuc#include <algorithm>
194684ddb6SLionel Sambuc
204684ddb6SLionel Sambuc#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
214684ddb6SLionel Sambuc#pragma GCC system_header
224684ddb6SLionel Sambuc#endif
234684ddb6SLionel Sambuc
244684ddb6SLionel Sambuc_LIBCPP_BEGIN_NAMESPACE_STD
254684ddb6SLionel Sambuc
264684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator> class __tree;
274684ddb6SLionel Sambuctemplate <class _Tp, class _NodePtr, class _DiffType>
284684ddb6SLionel Sambuc    class _LIBCPP_TYPE_VIS_ONLY __tree_iterator;
294684ddb6SLionel Sambuctemplate <class _Tp, class _ConstNodePtr, class _DiffType>
304684ddb6SLionel Sambuc    class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
314684ddb6SLionel Sambuc
324684ddb6SLionel Sambuc/*
334684ddb6SLionel Sambuc
344684ddb6SLionel Sambuc_NodePtr algorithms
354684ddb6SLionel Sambuc
364684ddb6SLionel SambucThe algorithms taking _NodePtr are red black tree algorithms.  Those
374684ddb6SLionel Sambucalgorithms taking a parameter named __root should assume that __root
384684ddb6SLionel Sambucpoints to a proper red black tree (unless otherwise specified).
394684ddb6SLionel Sambuc
404684ddb6SLionel SambucEach algorithm herein assumes that __root->__parent_ points to a non-null
414684ddb6SLionel Sambucstructure which has a member __left_ which points back to __root.  No other
424684ddb6SLionel Sambucmember is read or written to at __root->__parent_.
434684ddb6SLionel Sambuc
444684ddb6SLionel Sambuc__root->__parent_ will be referred to below (in comments only) as end_node.
454684ddb6SLionel Sambucend_node->__left_ is an externably accessible lvalue for __root, and can be
464684ddb6SLionel Sambucchanged by node insertion and removal (without explicit reference to end_node).
474684ddb6SLionel Sambuc
484684ddb6SLionel SambucAll nodes (with the exception of end_node), even the node referred to as
494684ddb6SLionel Sambuc__root, have a non-null __parent_ field.
504684ddb6SLionel Sambuc
514684ddb6SLionel Sambuc*/
524684ddb6SLionel Sambuc
534684ddb6SLionel Sambuc// Returns:  true if __x is a left child of its parent, else false
544684ddb6SLionel Sambuc// Precondition:  __x != nullptr.
554684ddb6SLionel Sambuctemplate <class _NodePtr>
564684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
574684ddb6SLionel Sambucbool
584684ddb6SLionel Sambuc__tree_is_left_child(_NodePtr __x) _NOEXCEPT
594684ddb6SLionel Sambuc{
604684ddb6SLionel Sambuc    return __x == __x->__parent_->__left_;
614684ddb6SLionel Sambuc}
624684ddb6SLionel Sambuc
634684ddb6SLionel Sambuc// Determintes if the subtree rooted at __x is a proper red black subtree.  If
644684ddb6SLionel Sambuc//    __x is a proper subtree, returns the black height (null counts as 1).  If
654684ddb6SLionel Sambuc//    __x is an improper subtree, returns 0.
664684ddb6SLionel Sambuctemplate <class _NodePtr>
674684ddb6SLionel Sambucunsigned
684684ddb6SLionel Sambuc__tree_sub_invariant(_NodePtr __x)
694684ddb6SLionel Sambuc{
704684ddb6SLionel Sambuc    if (__x == nullptr)
714684ddb6SLionel Sambuc        return 1;
724684ddb6SLionel Sambuc    // parent consistency checked by caller
734684ddb6SLionel Sambuc    // check __x->__left_ consistency
744684ddb6SLionel Sambuc    if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
754684ddb6SLionel Sambuc        return 0;
764684ddb6SLionel Sambuc    // check __x->__right_ consistency
774684ddb6SLionel Sambuc    if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
784684ddb6SLionel Sambuc        return 0;
794684ddb6SLionel Sambuc    // check __x->__left_ != __x->__right_ unless both are nullptr
804684ddb6SLionel Sambuc    if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
814684ddb6SLionel Sambuc        return 0;
824684ddb6SLionel Sambuc    // If this is red, neither child can be red
834684ddb6SLionel Sambuc    if (!__x->__is_black_)
844684ddb6SLionel Sambuc    {
854684ddb6SLionel Sambuc        if (__x->__left_ && !__x->__left_->__is_black_)
864684ddb6SLionel Sambuc            return 0;
874684ddb6SLionel Sambuc        if (__x->__right_ && !__x->__right_->__is_black_)
884684ddb6SLionel Sambuc            return 0;
894684ddb6SLionel Sambuc    }
904684ddb6SLionel Sambuc    unsigned __h = __tree_sub_invariant(__x->__left_);
914684ddb6SLionel Sambuc    if (__h == 0)
924684ddb6SLionel Sambuc        return 0;  // invalid left subtree
934684ddb6SLionel Sambuc    if (__h != __tree_sub_invariant(__x->__right_))
944684ddb6SLionel Sambuc        return 0;  // invalid or different height right subtree
954684ddb6SLionel Sambuc    return __h + __x->__is_black_;  // return black height of this node
964684ddb6SLionel Sambuc}
974684ddb6SLionel Sambuc
984684ddb6SLionel Sambuc// Determintes if the red black tree rooted at __root is a proper red black tree.
994684ddb6SLionel Sambuc//    __root == nullptr is a proper tree.  Returns true is __root is a proper
1004684ddb6SLionel Sambuc//    red black tree, else returns false.
1014684ddb6SLionel Sambuctemplate <class _NodePtr>
1024684ddb6SLionel Sambucbool
1034684ddb6SLionel Sambuc__tree_invariant(_NodePtr __root)
1044684ddb6SLionel Sambuc{
1054684ddb6SLionel Sambuc    if (__root == nullptr)
1064684ddb6SLionel Sambuc        return true;
1074684ddb6SLionel Sambuc    // check __x->__parent_ consistency
1084684ddb6SLionel Sambuc    if (__root->__parent_ == nullptr)
1094684ddb6SLionel Sambuc        return false;
1104684ddb6SLionel Sambuc    if (!__tree_is_left_child(__root))
1114684ddb6SLionel Sambuc        return false;
1124684ddb6SLionel Sambuc    // root must be black
1134684ddb6SLionel Sambuc    if (!__root->__is_black_)
1144684ddb6SLionel Sambuc        return false;
1154684ddb6SLionel Sambuc    // do normal node checks
1164684ddb6SLionel Sambuc    return __tree_sub_invariant(__root) != 0;
1174684ddb6SLionel Sambuc}
1184684ddb6SLionel Sambuc
1194684ddb6SLionel Sambuc// Returns:  pointer to the left-most node under __x.
1204684ddb6SLionel Sambuc// Precondition:  __x != nullptr.
1214684ddb6SLionel Sambuctemplate <class _NodePtr>
1224684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
1234684ddb6SLionel Sambuc_NodePtr
1244684ddb6SLionel Sambuc__tree_min(_NodePtr __x) _NOEXCEPT
1254684ddb6SLionel Sambuc{
1264684ddb6SLionel Sambuc    while (__x->__left_ != nullptr)
1274684ddb6SLionel Sambuc        __x = __x->__left_;
1284684ddb6SLionel Sambuc    return __x;
1294684ddb6SLionel Sambuc}
1304684ddb6SLionel Sambuc
1314684ddb6SLionel Sambuc// Returns:  pointer to the right-most node under __x.
1324684ddb6SLionel Sambuc// Precondition:  __x != nullptr.
1334684ddb6SLionel Sambuctemplate <class _NodePtr>
1344684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
1354684ddb6SLionel Sambuc_NodePtr
1364684ddb6SLionel Sambuc__tree_max(_NodePtr __x) _NOEXCEPT
1374684ddb6SLionel Sambuc{
1384684ddb6SLionel Sambuc    while (__x->__right_ != nullptr)
1394684ddb6SLionel Sambuc        __x = __x->__right_;
1404684ddb6SLionel Sambuc    return __x;
1414684ddb6SLionel Sambuc}
1424684ddb6SLionel Sambuc
1434684ddb6SLionel Sambuc// Returns:  pointer to the next in-order node after __x.
1444684ddb6SLionel Sambuc// Precondition:  __x != nullptr.
1454684ddb6SLionel Sambuctemplate <class _NodePtr>
1464684ddb6SLionel Sambuc_NodePtr
1474684ddb6SLionel Sambuc__tree_next(_NodePtr __x) _NOEXCEPT
1484684ddb6SLionel Sambuc{
1494684ddb6SLionel Sambuc    if (__x->__right_ != nullptr)
1504684ddb6SLionel Sambuc        return __tree_min(__x->__right_);
1514684ddb6SLionel Sambuc    while (!__tree_is_left_child(__x))
1524684ddb6SLionel Sambuc        __x = __x->__parent_;
1534684ddb6SLionel Sambuc    return __x->__parent_;
1544684ddb6SLionel Sambuc}
1554684ddb6SLionel Sambuc
1564684ddb6SLionel Sambuc// Returns:  pointer to the previous in-order node before __x.
1574684ddb6SLionel Sambuc// Precondition:  __x != nullptr.
1584684ddb6SLionel Sambuctemplate <class _NodePtr>
1594684ddb6SLionel Sambuc_NodePtr
1604684ddb6SLionel Sambuc__tree_prev(_NodePtr __x) _NOEXCEPT
1614684ddb6SLionel Sambuc{
1624684ddb6SLionel Sambuc    if (__x->__left_ != nullptr)
1634684ddb6SLionel Sambuc        return __tree_max(__x->__left_);
1644684ddb6SLionel Sambuc    while (__tree_is_left_child(__x))
1654684ddb6SLionel Sambuc        __x = __x->__parent_;
1664684ddb6SLionel Sambuc    return __x->__parent_;
1674684ddb6SLionel Sambuc}
1684684ddb6SLionel Sambuc
1694684ddb6SLionel Sambuc// Returns:  pointer to a node which has no children
1704684ddb6SLionel Sambuc// Precondition:  __x != nullptr.
1714684ddb6SLionel Sambuctemplate <class _NodePtr>
1724684ddb6SLionel Sambuc_NodePtr
1734684ddb6SLionel Sambuc__tree_leaf(_NodePtr __x) _NOEXCEPT
1744684ddb6SLionel Sambuc{
1754684ddb6SLionel Sambuc    while (true)
1764684ddb6SLionel Sambuc    {
1774684ddb6SLionel Sambuc        if (__x->__left_ != nullptr)
1784684ddb6SLionel Sambuc        {
1794684ddb6SLionel Sambuc            __x = __x->__left_;
1804684ddb6SLionel Sambuc            continue;
1814684ddb6SLionel Sambuc        }
1824684ddb6SLionel Sambuc        if (__x->__right_ != nullptr)
1834684ddb6SLionel Sambuc        {
1844684ddb6SLionel Sambuc            __x = __x->__right_;
1854684ddb6SLionel Sambuc            continue;
1864684ddb6SLionel Sambuc        }
1874684ddb6SLionel Sambuc        break;
1884684ddb6SLionel Sambuc    }
1894684ddb6SLionel Sambuc    return __x;
1904684ddb6SLionel Sambuc}
1914684ddb6SLionel Sambuc
1924684ddb6SLionel Sambuc// Effects:  Makes __x->__right_ the subtree root with __x as its left child
1934684ddb6SLionel Sambuc//           while preserving in-order order.
1944684ddb6SLionel Sambuc// Precondition:  __x->__right_ != nullptr
1954684ddb6SLionel Sambuctemplate <class _NodePtr>
1964684ddb6SLionel Sambucvoid
1974684ddb6SLionel Sambuc__tree_left_rotate(_NodePtr __x) _NOEXCEPT
1984684ddb6SLionel Sambuc{
1994684ddb6SLionel Sambuc    _NodePtr __y = __x->__right_;
2004684ddb6SLionel Sambuc    __x->__right_ = __y->__left_;
2014684ddb6SLionel Sambuc    if (__x->__right_ != nullptr)
2024684ddb6SLionel Sambuc        __x->__right_->__parent_ = __x;
2034684ddb6SLionel Sambuc    __y->__parent_ = __x->__parent_;
2044684ddb6SLionel Sambuc    if (__tree_is_left_child(__x))
2054684ddb6SLionel Sambuc        __x->__parent_->__left_ = __y;
2064684ddb6SLionel Sambuc    else
2074684ddb6SLionel Sambuc        __x->__parent_->__right_ = __y;
2084684ddb6SLionel Sambuc    __y->__left_ = __x;
2094684ddb6SLionel Sambuc    __x->__parent_ = __y;
2104684ddb6SLionel Sambuc}
2114684ddb6SLionel Sambuc
2124684ddb6SLionel Sambuc// Effects:  Makes __x->__left_ the subtree root with __x as its right child
2134684ddb6SLionel Sambuc//           while preserving in-order order.
2144684ddb6SLionel Sambuc// Precondition:  __x->__left_ != nullptr
2154684ddb6SLionel Sambuctemplate <class _NodePtr>
2164684ddb6SLionel Sambucvoid
2174684ddb6SLionel Sambuc__tree_right_rotate(_NodePtr __x) _NOEXCEPT
2184684ddb6SLionel Sambuc{
2194684ddb6SLionel Sambuc    _NodePtr __y = __x->__left_;
2204684ddb6SLionel Sambuc    __x->__left_ = __y->__right_;
2214684ddb6SLionel Sambuc    if (__x->__left_ != nullptr)
2224684ddb6SLionel Sambuc        __x->__left_->__parent_ = __x;
2234684ddb6SLionel Sambuc    __y->__parent_ = __x->__parent_;
2244684ddb6SLionel Sambuc    if (__tree_is_left_child(__x))
2254684ddb6SLionel Sambuc        __x->__parent_->__left_ = __y;
2264684ddb6SLionel Sambuc    else
2274684ddb6SLionel Sambuc        __x->__parent_->__right_ = __y;
2284684ddb6SLionel Sambuc    __y->__right_ = __x;
2294684ddb6SLionel Sambuc    __x->__parent_ = __y;
2304684ddb6SLionel Sambuc}
2314684ddb6SLionel Sambuc
2324684ddb6SLionel Sambuc// Effects:  Rebalances __root after attaching __x to a leaf.
2334684ddb6SLionel Sambuc// Precondition:  __root != nulptr && __x != nullptr.
2344684ddb6SLionel Sambuc//                __x has no children.
2354684ddb6SLionel Sambuc//                __x == __root or == a direct or indirect child of __root.
2364684ddb6SLionel Sambuc//                If __x were to be unlinked from __root (setting __root to
2374684ddb6SLionel Sambuc//                  nullptr if __root == __x), __tree_invariant(__root) == true.
2384684ddb6SLionel Sambuc// Postcondition: __tree_invariant(end_node->__left_) == true.  end_node->__left_
2394684ddb6SLionel Sambuc//                may be different than the value passed in as __root.
2404684ddb6SLionel Sambuctemplate <class _NodePtr>
2414684ddb6SLionel Sambucvoid
2424684ddb6SLionel Sambuc__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
2434684ddb6SLionel Sambuc{
2444684ddb6SLionel Sambuc    __x->__is_black_ = __x == __root;
2454684ddb6SLionel Sambuc    while (__x != __root && !__x->__parent_->__is_black_)
2464684ddb6SLionel Sambuc    {
2474684ddb6SLionel Sambuc        // __x->__parent_ != __root because __x->__parent_->__is_black == false
2484684ddb6SLionel Sambuc        if (__tree_is_left_child(__x->__parent_))
2494684ddb6SLionel Sambuc        {
2504684ddb6SLionel Sambuc            _NodePtr __y = __x->__parent_->__parent_->__right_;
2514684ddb6SLionel Sambuc            if (__y != nullptr && !__y->__is_black_)
2524684ddb6SLionel Sambuc            {
2534684ddb6SLionel Sambuc                __x = __x->__parent_;
2544684ddb6SLionel Sambuc                __x->__is_black_ = true;
2554684ddb6SLionel Sambuc                __x = __x->__parent_;
2564684ddb6SLionel Sambuc                __x->__is_black_ = __x == __root;
2574684ddb6SLionel Sambuc                __y->__is_black_ = true;
2584684ddb6SLionel Sambuc            }
2594684ddb6SLionel Sambuc            else
2604684ddb6SLionel Sambuc            {
2614684ddb6SLionel Sambuc                if (!__tree_is_left_child(__x))
2624684ddb6SLionel Sambuc                {
2634684ddb6SLionel Sambuc                    __x = __x->__parent_;
2644684ddb6SLionel Sambuc                    __tree_left_rotate(__x);
2654684ddb6SLionel Sambuc                }
2664684ddb6SLionel Sambuc                __x = __x->__parent_;
2674684ddb6SLionel Sambuc                __x->__is_black_ = true;
2684684ddb6SLionel Sambuc                __x = __x->__parent_;
2694684ddb6SLionel Sambuc                __x->__is_black_ = false;
2704684ddb6SLionel Sambuc                __tree_right_rotate(__x);
2714684ddb6SLionel Sambuc                break;
2724684ddb6SLionel Sambuc            }
2734684ddb6SLionel Sambuc        }
2744684ddb6SLionel Sambuc        else
2754684ddb6SLionel Sambuc        {
2764684ddb6SLionel Sambuc            _NodePtr __y = __x->__parent_->__parent_->__left_;
2774684ddb6SLionel Sambuc            if (__y != nullptr && !__y->__is_black_)
2784684ddb6SLionel Sambuc            {
2794684ddb6SLionel Sambuc                __x = __x->__parent_;
2804684ddb6SLionel Sambuc                __x->__is_black_ = true;
2814684ddb6SLionel Sambuc                __x = __x->__parent_;
2824684ddb6SLionel Sambuc                __x->__is_black_ = __x == __root;
2834684ddb6SLionel Sambuc                __y->__is_black_ = true;
2844684ddb6SLionel Sambuc            }
2854684ddb6SLionel Sambuc            else
2864684ddb6SLionel Sambuc            {
2874684ddb6SLionel Sambuc                if (__tree_is_left_child(__x))
2884684ddb6SLionel Sambuc                {
2894684ddb6SLionel Sambuc                    __x = __x->__parent_;
2904684ddb6SLionel Sambuc                    __tree_right_rotate(__x);
2914684ddb6SLionel Sambuc                }
2924684ddb6SLionel Sambuc                __x = __x->__parent_;
2934684ddb6SLionel Sambuc                __x->__is_black_ = true;
2944684ddb6SLionel Sambuc                __x = __x->__parent_;
2954684ddb6SLionel Sambuc                __x->__is_black_ = false;
2964684ddb6SLionel Sambuc                __tree_left_rotate(__x);
2974684ddb6SLionel Sambuc                break;
2984684ddb6SLionel Sambuc            }
2994684ddb6SLionel Sambuc        }
3004684ddb6SLionel Sambuc    }
3014684ddb6SLionel Sambuc}
3024684ddb6SLionel Sambuc
3034684ddb6SLionel Sambuc// Precondition:  __root != nullptr && __z != nullptr.
3044684ddb6SLionel Sambuc//                __tree_invariant(__root) == true.
3054684ddb6SLionel Sambuc//                __z == __root or == a direct or indirect child of __root.
3064684ddb6SLionel Sambuc// Effects:  unlinks __z from the tree rooted at __root, rebalancing as needed.
3074684ddb6SLionel Sambuc// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
3084684ddb6SLionel Sambuc//                nor any of its children refer to __z.  end_node->__left_
3094684ddb6SLionel Sambuc//                may be different than the value passed in as __root.
3104684ddb6SLionel Sambuctemplate <class _NodePtr>
3114684ddb6SLionel Sambucvoid
3124684ddb6SLionel Sambuc__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
3134684ddb6SLionel Sambuc{
3144684ddb6SLionel Sambuc    // __z will be removed from the tree.  Client still needs to destruct/deallocate it
3154684ddb6SLionel Sambuc    // __y is either __z, or if __z has two children, __tree_next(__z).
3164684ddb6SLionel Sambuc    // __y will have at most one child.
3174684ddb6SLionel Sambuc    // __y will be the initial hole in the tree (make the hole at a leaf)
3184684ddb6SLionel Sambuc    _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
3194684ddb6SLionel Sambuc                    __z : __tree_next(__z);
3204684ddb6SLionel Sambuc    // __x is __y's possibly null single child
3214684ddb6SLionel Sambuc    _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
3224684ddb6SLionel Sambuc    // __w is __x's possibly null uncle (will become __x's sibling)
3234684ddb6SLionel Sambuc    _NodePtr __w = nullptr;
3244684ddb6SLionel Sambuc    // link __x to __y's parent, and find __w
3254684ddb6SLionel Sambuc    if (__x != nullptr)
3264684ddb6SLionel Sambuc        __x->__parent_ = __y->__parent_;
3274684ddb6SLionel Sambuc    if (__tree_is_left_child(__y))
3284684ddb6SLionel Sambuc    {
3294684ddb6SLionel Sambuc        __y->__parent_->__left_ = __x;
3304684ddb6SLionel Sambuc        if (__y != __root)
3314684ddb6SLionel Sambuc            __w = __y->__parent_->__right_;
3324684ddb6SLionel Sambuc        else
3334684ddb6SLionel Sambuc            __root = __x;  // __w == nullptr
3344684ddb6SLionel Sambuc    }
3354684ddb6SLionel Sambuc    else
3364684ddb6SLionel Sambuc    {
3374684ddb6SLionel Sambuc        __y->__parent_->__right_ = __x;
3384684ddb6SLionel Sambuc        // __y can't be root if it is a right child
3394684ddb6SLionel Sambuc        __w = __y->__parent_->__left_;
3404684ddb6SLionel Sambuc    }
3414684ddb6SLionel Sambuc    bool __removed_black = __y->__is_black_;
3424684ddb6SLionel Sambuc    // If we didn't remove __z, do so now by splicing in __y for __z,
3434684ddb6SLionel Sambuc    //    but copy __z's color.  This does not impact __x or __w.
3444684ddb6SLionel Sambuc    if (__y != __z)
3454684ddb6SLionel Sambuc    {
3464684ddb6SLionel Sambuc        // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
3474684ddb6SLionel Sambuc        __y->__parent_ = __z->__parent_;
3484684ddb6SLionel Sambuc        if (__tree_is_left_child(__z))
3494684ddb6SLionel Sambuc            __y->__parent_->__left_ = __y;
3504684ddb6SLionel Sambuc        else
3514684ddb6SLionel Sambuc            __y->__parent_->__right_ = __y;
3524684ddb6SLionel Sambuc        __y->__left_ = __z->__left_;
3534684ddb6SLionel Sambuc        __y->__left_->__parent_ = __y;
3544684ddb6SLionel Sambuc        __y->__right_ = __z->__right_;
3554684ddb6SLionel Sambuc        if (__y->__right_ != nullptr)
3564684ddb6SLionel Sambuc            __y->__right_->__parent_ = __y;
3574684ddb6SLionel Sambuc        __y->__is_black_ = __z->__is_black_;
3584684ddb6SLionel Sambuc        if (__root == __z)
3594684ddb6SLionel Sambuc            __root = __y;
3604684ddb6SLionel Sambuc    }
3614684ddb6SLionel Sambuc    // There is no need to rebalance if we removed a red, or if we removed
3624684ddb6SLionel Sambuc    //     the last node.
3634684ddb6SLionel Sambuc    if (__removed_black && __root != nullptr)
3644684ddb6SLionel Sambuc    {
3654684ddb6SLionel Sambuc        // Rebalance:
3664684ddb6SLionel Sambuc        // __x has an implicit black color (transferred from the removed __y)
3674684ddb6SLionel Sambuc        //    associated with it, no matter what its color is.
3684684ddb6SLionel Sambuc        // If __x is __root (in which case it can't be null), it is supposed
3694684ddb6SLionel Sambuc        //    to be black anyway, and if it is doubly black, then the double
3704684ddb6SLionel Sambuc        //    can just be ignored.
3714684ddb6SLionel Sambuc        // If __x is red (in which case it can't be null), then it can absorb
3724684ddb6SLionel Sambuc        //    the implicit black just by setting its color to black.
3734684ddb6SLionel Sambuc        // Since __y was black and only had one child (which __x points to), __x
3744684ddb6SLionel Sambuc        //   is either red with no children, else null, otherwise __y would have
3754684ddb6SLionel Sambuc        //   different black heights under left and right pointers.
3764684ddb6SLionel Sambuc        // if (__x == __root || __x != nullptr && !__x->__is_black_)
3774684ddb6SLionel Sambuc        if (__x != nullptr)
3784684ddb6SLionel Sambuc            __x->__is_black_ = true;
3794684ddb6SLionel Sambuc        else
3804684ddb6SLionel Sambuc        {
3814684ddb6SLionel Sambuc            //  Else __x isn't root, and is "doubly black", even though it may
3824684ddb6SLionel Sambuc            //     be null.  __w can not be null here, else the parent would
3834684ddb6SLionel Sambuc            //     see a black height >= 2 on the __x side and a black height
3844684ddb6SLionel Sambuc            //     of 1 on the __w side (__w must be a non-null black or a red
3854684ddb6SLionel Sambuc            //     with a non-null black child).
3864684ddb6SLionel Sambuc            while (true)
3874684ddb6SLionel Sambuc            {
3884684ddb6SLionel Sambuc                if (!__tree_is_left_child(__w))  // if x is left child
3894684ddb6SLionel Sambuc                {
3904684ddb6SLionel Sambuc                    if (!__w->__is_black_)
3914684ddb6SLionel Sambuc                    {
3924684ddb6SLionel Sambuc                        __w->__is_black_ = true;
3934684ddb6SLionel Sambuc                        __w->__parent_->__is_black_ = false;
3944684ddb6SLionel Sambuc                        __tree_left_rotate(__w->__parent_);
3954684ddb6SLionel Sambuc                        // __x is still valid
3964684ddb6SLionel Sambuc                        // reset __root only if necessary
3974684ddb6SLionel Sambuc                        if (__root == __w->__left_)
3984684ddb6SLionel Sambuc                            __root = __w;
3994684ddb6SLionel Sambuc                        // reset sibling, and it still can't be null
4004684ddb6SLionel Sambuc                        __w = __w->__left_->__right_;
4014684ddb6SLionel Sambuc                    }
4024684ddb6SLionel Sambuc                    // __w->__is_black_ is now true, __w may have null children
4034684ddb6SLionel Sambuc                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
4044684ddb6SLionel Sambuc                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
4054684ddb6SLionel Sambuc                    {
4064684ddb6SLionel Sambuc                        __w->__is_black_ = false;
4074684ddb6SLionel Sambuc                        __x = __w->__parent_;
4084684ddb6SLionel Sambuc                        // __x can no longer be null
4094684ddb6SLionel Sambuc                        if (__x == __root || !__x->__is_black_)
4104684ddb6SLionel Sambuc                        {
4114684ddb6SLionel Sambuc                            __x->__is_black_ = true;
4124684ddb6SLionel Sambuc                            break;
4134684ddb6SLionel Sambuc                        }
4144684ddb6SLionel Sambuc                        // reset sibling, and it still can't be null
4154684ddb6SLionel Sambuc                        __w = __tree_is_left_child(__x) ?
4164684ddb6SLionel Sambuc                                    __x->__parent_->__right_ :
4174684ddb6SLionel Sambuc                                    __x->__parent_->__left_;
4184684ddb6SLionel Sambuc                        // continue;
4194684ddb6SLionel Sambuc                    }
4204684ddb6SLionel Sambuc                    else  // __w has a red child
4214684ddb6SLionel Sambuc                    {
4224684ddb6SLionel Sambuc                        if (__w->__right_ == nullptr || __w->__right_->__is_black_)
4234684ddb6SLionel Sambuc                        {
4244684ddb6SLionel Sambuc                            // __w left child is non-null and red
4254684ddb6SLionel Sambuc                            __w->__left_->__is_black_ = true;
4264684ddb6SLionel Sambuc                            __w->__is_black_ = false;
4274684ddb6SLionel Sambuc                            __tree_right_rotate(__w);
4284684ddb6SLionel Sambuc                            // __w is known not to be root, so root hasn't changed
4294684ddb6SLionel Sambuc                            // reset sibling, and it still can't be null
4304684ddb6SLionel Sambuc                            __w = __w->__parent_;
4314684ddb6SLionel Sambuc                        }
4324684ddb6SLionel Sambuc                        // __w has a right red child, left child may be null
4334684ddb6SLionel Sambuc                        __w->__is_black_ = __w->__parent_->__is_black_;
4344684ddb6SLionel Sambuc                        __w->__parent_->__is_black_ = true;
4354684ddb6SLionel Sambuc                        __w->__right_->__is_black_ = true;
4364684ddb6SLionel Sambuc                        __tree_left_rotate(__w->__parent_);
4374684ddb6SLionel Sambuc                        break;
4384684ddb6SLionel Sambuc                    }
4394684ddb6SLionel Sambuc                }
4404684ddb6SLionel Sambuc                else
4414684ddb6SLionel Sambuc                {
4424684ddb6SLionel Sambuc                    if (!__w->__is_black_)
4434684ddb6SLionel Sambuc                    {
4444684ddb6SLionel Sambuc                        __w->__is_black_ = true;
4454684ddb6SLionel Sambuc                        __w->__parent_->__is_black_ = false;
4464684ddb6SLionel Sambuc                        __tree_right_rotate(__w->__parent_);
4474684ddb6SLionel Sambuc                        // __x is still valid
4484684ddb6SLionel Sambuc                        // reset __root only if necessary
4494684ddb6SLionel Sambuc                        if (__root == __w->__right_)
4504684ddb6SLionel Sambuc                            __root = __w;
4514684ddb6SLionel Sambuc                        // reset sibling, and it still can't be null
4524684ddb6SLionel Sambuc                        __w = __w->__right_->__left_;
4534684ddb6SLionel Sambuc                    }
4544684ddb6SLionel Sambuc                    // __w->__is_black_ is now true, __w may have null children
4554684ddb6SLionel Sambuc                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
4564684ddb6SLionel Sambuc                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
4574684ddb6SLionel Sambuc                    {
4584684ddb6SLionel Sambuc                        __w->__is_black_ = false;
4594684ddb6SLionel Sambuc                        __x = __w->__parent_;
4604684ddb6SLionel Sambuc                        // __x can no longer be null
4614684ddb6SLionel Sambuc                        if (!__x->__is_black_ || __x == __root)
4624684ddb6SLionel Sambuc                        {
4634684ddb6SLionel Sambuc                            __x->__is_black_ = true;
4644684ddb6SLionel Sambuc                            break;
4654684ddb6SLionel Sambuc                        }
4664684ddb6SLionel Sambuc                        // reset sibling, and it still can't be null
4674684ddb6SLionel Sambuc                        __w = __tree_is_left_child(__x) ?
4684684ddb6SLionel Sambuc                                    __x->__parent_->__right_ :
4694684ddb6SLionel Sambuc                                    __x->__parent_->__left_;
4704684ddb6SLionel Sambuc                        // continue;
4714684ddb6SLionel Sambuc                    }
4724684ddb6SLionel Sambuc                    else  // __w has a red child
4734684ddb6SLionel Sambuc                    {
4744684ddb6SLionel Sambuc                        if (__w->__left_ == nullptr || __w->__left_->__is_black_)
4754684ddb6SLionel Sambuc                        {
4764684ddb6SLionel Sambuc                            // __w right child is non-null and red
4774684ddb6SLionel Sambuc                            __w->__right_->__is_black_ = true;
4784684ddb6SLionel Sambuc                            __w->__is_black_ = false;
4794684ddb6SLionel Sambuc                            __tree_left_rotate(__w);
4804684ddb6SLionel Sambuc                            // __w is known not to be root, so root hasn't changed
4814684ddb6SLionel Sambuc                            // reset sibling, and it still can't be null
4824684ddb6SLionel Sambuc                            __w = __w->__parent_;
4834684ddb6SLionel Sambuc                        }
4844684ddb6SLionel Sambuc                        // __w has a left red child, right child may be null
4854684ddb6SLionel Sambuc                        __w->__is_black_ = __w->__parent_->__is_black_;
4864684ddb6SLionel Sambuc                        __w->__parent_->__is_black_ = true;
4874684ddb6SLionel Sambuc                        __w->__left_->__is_black_ = true;
4884684ddb6SLionel Sambuc                        __tree_right_rotate(__w->__parent_);
4894684ddb6SLionel Sambuc                        break;
4904684ddb6SLionel Sambuc                    }
4914684ddb6SLionel Sambuc                }
4924684ddb6SLionel Sambuc            }
4934684ddb6SLionel Sambuc        }
4944684ddb6SLionel Sambuc    }
4954684ddb6SLionel Sambuc}
4964684ddb6SLionel Sambuc
4974684ddb6SLionel Sambuctemplate <class _Allocator> class __map_node_destructor;
4984684ddb6SLionel Sambuc
4994684ddb6SLionel Sambuctemplate <class _Allocator>
5004684ddb6SLionel Sambucclass __tree_node_destructor
5014684ddb6SLionel Sambuc{
5024684ddb6SLionel Sambuc    typedef _Allocator                                      allocator_type;
5034684ddb6SLionel Sambuc    typedef allocator_traits<allocator_type>                __alloc_traits;
5044684ddb6SLionel Sambuc    typedef typename __alloc_traits::value_type::value_type value_type;
5054684ddb6SLionel Sambucpublic:
5064684ddb6SLionel Sambuc    typedef typename __alloc_traits::pointer                pointer;
5074684ddb6SLionel Sambucprivate:
5084684ddb6SLionel Sambuc
5094684ddb6SLionel Sambuc    allocator_type& __na_;
5104684ddb6SLionel Sambuc
5114684ddb6SLionel Sambuc    __tree_node_destructor& operator=(const __tree_node_destructor&);
5124684ddb6SLionel Sambuc
5134684ddb6SLionel Sambucpublic:
5144684ddb6SLionel Sambuc    bool __value_constructed;
5154684ddb6SLionel Sambuc
5164684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
517*0a6a1f1dSLionel Sambuc    explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
5184684ddb6SLionel Sambuc        : __na_(__na),
519*0a6a1f1dSLionel Sambuc          __value_constructed(__val)
5204684ddb6SLionel Sambuc        {}
5214684ddb6SLionel Sambuc
5224684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5234684ddb6SLionel Sambuc    void operator()(pointer __p) _NOEXCEPT
5244684ddb6SLionel Sambuc    {
5254684ddb6SLionel Sambuc        if (__value_constructed)
5264684ddb6SLionel Sambuc            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_));
5274684ddb6SLionel Sambuc        if (__p)
5284684ddb6SLionel Sambuc            __alloc_traits::deallocate(__na_, __p, 1);
5294684ddb6SLionel Sambuc    }
5304684ddb6SLionel Sambuc
5314684ddb6SLionel Sambuc    template <class> friend class __map_node_destructor;
5324684ddb6SLionel Sambuc};
5334684ddb6SLionel Sambuc
5344684ddb6SLionel Sambuc// node
5354684ddb6SLionel Sambuc
5364684ddb6SLionel Sambuctemplate <class _Pointer>
5374684ddb6SLionel Sambucclass __tree_end_node
5384684ddb6SLionel Sambuc{
5394684ddb6SLionel Sambucpublic:
5404684ddb6SLionel Sambuc    typedef _Pointer pointer;
5414684ddb6SLionel Sambuc    pointer __left_;
5424684ddb6SLionel Sambuc
5434684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5444684ddb6SLionel Sambuc    __tree_end_node() _NOEXCEPT : __left_() {}
5454684ddb6SLionel Sambuc};
5464684ddb6SLionel Sambuc
5474684ddb6SLionel Sambuctemplate <class _VoidPtr>
5484684ddb6SLionel Sambucclass __tree_node_base
5494684ddb6SLionel Sambuc    : public __tree_end_node
5504684ddb6SLionel Sambuc             <
5514684ddb6SLionel Sambuc                typename pointer_traits<_VoidPtr>::template
5524684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
5534684ddb6SLionel Sambuc                     rebind<__tree_node_base<_VoidPtr> >
5544684ddb6SLionel Sambuc#else
5554684ddb6SLionel Sambuc                     rebind<__tree_node_base<_VoidPtr> >::other
5564684ddb6SLionel Sambuc#endif
5574684ddb6SLionel Sambuc             >
5584684ddb6SLionel Sambuc{
5594684ddb6SLionel Sambuc    __tree_node_base(const __tree_node_base&);
5604684ddb6SLionel Sambuc    __tree_node_base& operator=(const __tree_node_base&);
5614684ddb6SLionel Sambucpublic:
5624684ddb6SLionel Sambuc    typedef typename pointer_traits<_VoidPtr>::template
5634684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
5644684ddb6SLionel Sambuc            rebind<__tree_node_base>
5654684ddb6SLionel Sambuc#else
5664684ddb6SLionel Sambuc            rebind<__tree_node_base>::other
5674684ddb6SLionel Sambuc#endif
5684684ddb6SLionel Sambuc                                                pointer;
5694684ddb6SLionel Sambuc    typedef typename pointer_traits<_VoidPtr>::template
5704684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
5714684ddb6SLionel Sambuc            rebind<const __tree_node_base>
5724684ddb6SLionel Sambuc#else
5734684ddb6SLionel Sambuc            rebind<const __tree_node_base>::other
5744684ddb6SLionel Sambuc#endif
5754684ddb6SLionel Sambuc                                                const_pointer;
5764684ddb6SLionel Sambuc    typedef __tree_end_node<pointer> base;
5774684ddb6SLionel Sambuc
5784684ddb6SLionel Sambuc    pointer __right_;
5794684ddb6SLionel Sambuc    pointer __parent_;
5804684ddb6SLionel Sambuc    bool __is_black_;
5814684ddb6SLionel Sambuc
5824684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5834684ddb6SLionel Sambuc    __tree_node_base() _NOEXCEPT
5844684ddb6SLionel Sambuc        : __right_(), __parent_(), __is_black_(false) {}
5854684ddb6SLionel Sambuc};
5864684ddb6SLionel Sambuc
5874684ddb6SLionel Sambuctemplate <class _Tp, class _VoidPtr>
5884684ddb6SLionel Sambucclass __tree_node
5894684ddb6SLionel Sambuc    : public __tree_node_base<_VoidPtr>
5904684ddb6SLionel Sambuc{
5914684ddb6SLionel Sambucpublic:
5924684ddb6SLionel Sambuc    typedef __tree_node_base<_VoidPtr> base;
5934684ddb6SLionel Sambuc    typedef _Tp value_type;
5944684ddb6SLionel Sambuc
5954684ddb6SLionel Sambuc    value_type __value_;
5964684ddb6SLionel Sambuc
5974684ddb6SLionel Sambuc#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
5984684ddb6SLionel Sambuc    template <class ..._Args>
5994684ddb6SLionel Sambuc        _LIBCPP_INLINE_VISIBILITY
6004684ddb6SLionel Sambuc        explicit __tree_node(_Args&& ...__args)
6014684ddb6SLionel Sambuc            : __value_(_VSTD::forward<_Args>(__args)...) {}
6024684ddb6SLionel Sambuc#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
6034684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
6044684ddb6SLionel Sambuc    explicit __tree_node(const value_type& __v)
6054684ddb6SLionel Sambuc            : __value_(__v) {}
6064684ddb6SLionel Sambuc#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
6074684ddb6SLionel Sambuc};
6084684ddb6SLionel Sambuc
6094684ddb6SLionel Sambuctemplate <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
6104684ddb6SLionel Sambuctemplate <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
6114684ddb6SLionel Sambuc
6124684ddb6SLionel Sambuctemplate <class _Tp, class _NodePtr, class _DiffType>
6134684ddb6SLionel Sambucclass _LIBCPP_TYPE_VIS_ONLY __tree_iterator
6144684ddb6SLionel Sambuc{
6154684ddb6SLionel Sambuc    typedef _NodePtr                                              __node_pointer;
6164684ddb6SLionel Sambuc    typedef typename pointer_traits<__node_pointer>::element_type __node;
6174684ddb6SLionel Sambuc
6184684ddb6SLionel Sambuc    __node_pointer __ptr_;
6194684ddb6SLionel Sambuc
6204684ddb6SLionel Sambuc    typedef pointer_traits<__node_pointer> __pointer_traits;
6214684ddb6SLionel Sambucpublic:
6224684ddb6SLionel Sambuc    typedef bidirectional_iterator_tag iterator_category;
6234684ddb6SLionel Sambuc    typedef _Tp                        value_type;
6244684ddb6SLionel Sambuc    typedef _DiffType                  difference_type;
6254684ddb6SLionel Sambuc    typedef value_type&                reference;
6264684ddb6SLionel Sambuc    typedef typename pointer_traits<__node_pointer>::template
6274684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
6284684ddb6SLionel Sambuc            rebind<value_type>
6294684ddb6SLionel Sambuc#else
6304684ddb6SLionel Sambuc            rebind<value_type>::other
6314684ddb6SLionel Sambuc#endif
6324684ddb6SLionel Sambuc                                       pointer;
6334684ddb6SLionel Sambuc
6344684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
6354684ddb6SLionel Sambuc#if _LIBCPP_STD_VER > 11
6364684ddb6SLionel Sambuc    : __ptr_(nullptr)
6374684ddb6SLionel Sambuc#endif
6384684ddb6SLionel Sambuc    {}
6394684ddb6SLionel Sambuc
6404684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
6414684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
6424684ddb6SLionel Sambuc        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
6434684ddb6SLionel Sambuc
6444684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
645*0a6a1f1dSLionel Sambuc    __tree_iterator& operator++() {
646*0a6a1f1dSLionel Sambuc      __ptr_ = static_cast<__node_pointer>(
647*0a6a1f1dSLionel Sambuc          __tree_next(static_cast<typename __node::base::pointer>(__ptr_)));
648*0a6a1f1dSLionel Sambuc      return *this;
649*0a6a1f1dSLionel Sambuc    }
6504684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
6514684ddb6SLionel Sambuc    __tree_iterator operator++(int)
6524684ddb6SLionel Sambuc        {__tree_iterator __t(*this); ++(*this); return __t;}
6534684ddb6SLionel Sambuc
6544684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
655*0a6a1f1dSLionel Sambuc    __tree_iterator& operator--() {
656*0a6a1f1dSLionel Sambuc      __ptr_ = static_cast<__node_pointer>(
657*0a6a1f1dSLionel Sambuc          __tree_prev(static_cast<typename __node::base::pointer>(__ptr_)));
658*0a6a1f1dSLionel Sambuc      return *this;
659*0a6a1f1dSLionel Sambuc    }
6604684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
6614684ddb6SLionel Sambuc    __tree_iterator operator--(int)
6624684ddb6SLionel Sambuc        {__tree_iterator __t(*this); --(*this); return __t;}
6634684ddb6SLionel Sambuc
6644684ddb6SLionel Sambuc    friend _LIBCPP_INLINE_VISIBILITY
6654684ddb6SLionel Sambuc        bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
6664684ddb6SLionel Sambuc        {return __x.__ptr_ == __y.__ptr_;}
6674684ddb6SLionel Sambuc    friend _LIBCPP_INLINE_VISIBILITY
6684684ddb6SLionel Sambuc        bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
6694684ddb6SLionel Sambuc        {return !(__x == __y);}
6704684ddb6SLionel Sambuc
6714684ddb6SLionel Sambucprivate:
6724684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
6734684ddb6SLionel Sambuc    explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
6744684ddb6SLionel Sambuc    template <class, class, class> friend class __tree;
6754684ddb6SLionel Sambuc    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
6764684ddb6SLionel Sambuc    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
6774684ddb6SLionel Sambuc    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
6784684ddb6SLionel Sambuc    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
6794684ddb6SLionel Sambuc    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
6804684ddb6SLionel Sambuc    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
6814684ddb6SLionel Sambuc};
6824684ddb6SLionel Sambuc
6834684ddb6SLionel Sambuctemplate <class _Tp, class _ConstNodePtr, class _DiffType>
6844684ddb6SLionel Sambucclass _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator
6854684ddb6SLionel Sambuc{
6864684ddb6SLionel Sambuc    typedef _ConstNodePtr                                         __node_pointer;
6874684ddb6SLionel Sambuc    typedef typename pointer_traits<__node_pointer>::element_type __node;
6884684ddb6SLionel Sambuc
6894684ddb6SLionel Sambuc    __node_pointer __ptr_;
6904684ddb6SLionel Sambuc
6914684ddb6SLionel Sambuc    typedef pointer_traits<__node_pointer> __pointer_traits;
6924684ddb6SLionel Sambucpublic:
6934684ddb6SLionel Sambuc    typedef bidirectional_iterator_tag       iterator_category;
6944684ddb6SLionel Sambuc    typedef _Tp                              value_type;
6954684ddb6SLionel Sambuc    typedef _DiffType                        difference_type;
6964684ddb6SLionel Sambuc    typedef const value_type&                reference;
6974684ddb6SLionel Sambuc    typedef typename pointer_traits<__node_pointer>::template
6984684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
6994684ddb6SLionel Sambuc            rebind<const value_type>
7004684ddb6SLionel Sambuc#else
7014684ddb6SLionel Sambuc            rebind<const value_type>::other
7024684ddb6SLionel Sambuc#endif
7034684ddb6SLionel Sambuc                                       pointer;
7044684ddb6SLionel Sambuc
7054684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
7064684ddb6SLionel Sambuc#if _LIBCPP_STD_VER > 11
7074684ddb6SLionel Sambuc    : __ptr_(nullptr)
7084684ddb6SLionel Sambuc#endif
7094684ddb6SLionel Sambuc    {}
7104684ddb6SLionel Sambuc
7114684ddb6SLionel Sambucprivate:
7124684ddb6SLionel Sambuc    typedef typename remove_const<__node>::type  __non_const_node;
7134684ddb6SLionel Sambuc    typedef typename pointer_traits<__node_pointer>::template
7144684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
7154684ddb6SLionel Sambuc            rebind<__non_const_node>
7164684ddb6SLionel Sambuc#else
7174684ddb6SLionel Sambuc            rebind<__non_const_node>::other
7184684ddb6SLionel Sambuc#endif
7194684ddb6SLionel Sambuc                                                 __non_const_node_pointer;
7204684ddb6SLionel Sambuc    typedef __tree_iterator<value_type, __non_const_node_pointer, difference_type>
7214684ddb6SLionel Sambuc                                                 __non_const_iterator;
7224684ddb6SLionel Sambucpublic:
7234684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
7244684ddb6SLionel Sambuc    __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
7254684ddb6SLionel Sambuc        : __ptr_(__p.__ptr_) {}
7264684ddb6SLionel Sambuc
7274684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
7284684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
7294684ddb6SLionel Sambuc        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
7304684ddb6SLionel Sambuc
7314684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
732*0a6a1f1dSLionel Sambuc    __tree_const_iterator& operator++() {
733*0a6a1f1dSLionel Sambuc      typedef typename pointer_traits<__node_pointer>::template
734*0a6a1f1dSLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
735*0a6a1f1dSLionel Sambuc          rebind<typename __node::base>
736*0a6a1f1dSLionel Sambuc#else
737*0a6a1f1dSLionel Sambuc          rebind<typename __node::base>::other
738*0a6a1f1dSLionel Sambuc#endif
739*0a6a1f1dSLionel Sambuc              __node_base_pointer;
740*0a6a1f1dSLionel Sambuc
741*0a6a1f1dSLionel Sambuc      __ptr_ = static_cast<__node_pointer>(
742*0a6a1f1dSLionel Sambuc          __tree_next(static_cast<__node_base_pointer>(__ptr_)));
743*0a6a1f1dSLionel Sambuc      return *this;
744*0a6a1f1dSLionel Sambuc    }
745*0a6a1f1dSLionel Sambuc
7464684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
7474684ddb6SLionel Sambuc    __tree_const_iterator operator++(int)
7484684ddb6SLionel Sambuc        {__tree_const_iterator __t(*this); ++(*this); return __t;}
7494684ddb6SLionel Sambuc
7504684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
751*0a6a1f1dSLionel Sambuc    __tree_const_iterator& operator--() {
752*0a6a1f1dSLionel Sambuc      typedef typename pointer_traits<__node_pointer>::template
753*0a6a1f1dSLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
754*0a6a1f1dSLionel Sambuc          rebind<typename __node::base>
755*0a6a1f1dSLionel Sambuc#else
756*0a6a1f1dSLionel Sambuc          rebind<typename __node::base>::other
757*0a6a1f1dSLionel Sambuc#endif
758*0a6a1f1dSLionel Sambuc              __node_base_pointer;
759*0a6a1f1dSLionel Sambuc
760*0a6a1f1dSLionel Sambuc      __ptr_ = static_cast<__node_pointer>(
761*0a6a1f1dSLionel Sambuc          __tree_prev(static_cast<__node_base_pointer>(__ptr_)));
762*0a6a1f1dSLionel Sambuc      return *this;
763*0a6a1f1dSLionel Sambuc    }
764*0a6a1f1dSLionel Sambuc
7654684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
7664684ddb6SLionel Sambuc    __tree_const_iterator operator--(int)
7674684ddb6SLionel Sambuc        {__tree_const_iterator __t(*this); --(*this); return __t;}
7684684ddb6SLionel Sambuc
7694684ddb6SLionel Sambuc    friend _LIBCPP_INLINE_VISIBILITY
7704684ddb6SLionel Sambuc        bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
7714684ddb6SLionel Sambuc        {return __x.__ptr_ == __y.__ptr_;}
7724684ddb6SLionel Sambuc    friend _LIBCPP_INLINE_VISIBILITY
7734684ddb6SLionel Sambuc        bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
7744684ddb6SLionel Sambuc        {return !(__x == __y);}
7754684ddb6SLionel Sambuc
7764684ddb6SLionel Sambucprivate:
7774684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
7784684ddb6SLionel Sambuc    explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
7794684ddb6SLionel Sambuc        : __ptr_(__p) {}
7804684ddb6SLionel Sambuc    template <class, class, class> friend class __tree;
7814684ddb6SLionel Sambuc    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
7824684ddb6SLionel Sambuc    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
7834684ddb6SLionel Sambuc    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
7844684ddb6SLionel Sambuc    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
7854684ddb6SLionel Sambuc    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
7864684ddb6SLionel Sambuc};
7874684ddb6SLionel Sambuc
7884684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
7894684ddb6SLionel Sambucclass __tree
7904684ddb6SLionel Sambuc{
7914684ddb6SLionel Sambucpublic:
7924684ddb6SLionel Sambuc    typedef _Tp                                      value_type;
7934684ddb6SLionel Sambuc    typedef _Compare                                 value_compare;
7944684ddb6SLionel Sambuc    typedef _Allocator                               allocator_type;
7954684ddb6SLionel Sambuc    typedef allocator_traits<allocator_type>         __alloc_traits;
7964684ddb6SLionel Sambuc    typedef typename __alloc_traits::pointer         pointer;
7974684ddb6SLionel Sambuc    typedef typename __alloc_traits::const_pointer   const_pointer;
7984684ddb6SLionel Sambuc    typedef typename __alloc_traits::size_type       size_type;
7994684ddb6SLionel Sambuc    typedef typename __alloc_traits::difference_type difference_type;
8004684ddb6SLionel Sambuc
8014684ddb6SLionel Sambuc    typedef typename __alloc_traits::void_pointer  __void_pointer;
8024684ddb6SLionel Sambuc
8034684ddb6SLionel Sambuc    typedef __tree_node<value_type, __void_pointer> __node;
8044684ddb6SLionel Sambuc    typedef __tree_node_base<__void_pointer>        __node_base;
805*0a6a1f1dSLionel Sambuc    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
8064684ddb6SLionel Sambuc    typedef allocator_traits<__node_allocator>       __node_traits;
8074684ddb6SLionel Sambuc    typedef typename __node_traits::pointer          __node_pointer;
8084684ddb6SLionel Sambuc    typedef typename __node_traits::pointer          __node_const_pointer;
8094684ddb6SLionel Sambuc    typedef typename __node_base::pointer            __node_base_pointer;
8104684ddb6SLionel Sambuc    typedef typename __node_base::pointer            __node_base_const_pointer;
8114684ddb6SLionel Sambucprivate:
8124684ddb6SLionel Sambuc    typedef typename __node_base::base __end_node_t;
8134684ddb6SLionel Sambuc    typedef typename pointer_traits<__node_pointer>::template
8144684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
8154684ddb6SLionel Sambuc            rebind<__end_node_t>
8164684ddb6SLionel Sambuc#else
8174684ddb6SLionel Sambuc            rebind<__end_node_t>::other
8184684ddb6SLionel Sambuc#endif
8194684ddb6SLionel Sambuc                                                     __end_node_ptr;
8204684ddb6SLionel Sambuc    typedef typename pointer_traits<__node_pointer>::template
8214684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
8224684ddb6SLionel Sambuc            rebind<__end_node_t>
8234684ddb6SLionel Sambuc#else
8244684ddb6SLionel Sambuc            rebind<__end_node_t>::other
8254684ddb6SLionel Sambuc#endif
8264684ddb6SLionel Sambuc                                                     __end_node_const_ptr;
8274684ddb6SLionel Sambuc
8284684ddb6SLionel Sambuc    __node_pointer                                          __begin_node_;
8294684ddb6SLionel Sambuc    __compressed_pair<__end_node_t, __node_allocator>  __pair1_;
8304684ddb6SLionel Sambuc    __compressed_pair<size_type, value_compare>        __pair3_;
8314684ddb6SLionel Sambuc
8324684ddb6SLionel Sambucpublic:
8334684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8344684ddb6SLionel Sambuc    __node_pointer __end_node() _NOEXCEPT
8354684ddb6SLionel Sambuc    {
8364684ddb6SLionel Sambuc        return static_cast<__node_pointer>
8374684ddb6SLionel Sambuc               (
8384684ddb6SLionel Sambuc                   pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
8394684ddb6SLionel Sambuc               );
8404684ddb6SLionel Sambuc    }
8414684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8424684ddb6SLionel Sambuc    __node_const_pointer __end_node() const _NOEXCEPT
8434684ddb6SLionel Sambuc    {
8444684ddb6SLionel Sambuc        return static_cast<__node_const_pointer>
8454684ddb6SLionel Sambuc               (
8464684ddb6SLionel Sambuc                   pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first()))
8474684ddb6SLionel Sambuc               );
8484684ddb6SLionel Sambuc    }
8494684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8504684ddb6SLionel Sambuc          __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
8514684ddb6SLionel Sambucprivate:
8524684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8534684ddb6SLionel Sambuc    const __node_allocator& __node_alloc() const _NOEXCEPT
8544684ddb6SLionel Sambuc        {return __pair1_.second();}
8554684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8564684ddb6SLionel Sambuc          __node_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
8574684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8584684ddb6SLionel Sambuc    const __node_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
8594684ddb6SLionel Sambucpublic:
8604684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8614684ddb6SLionel Sambuc    allocator_type __alloc() const _NOEXCEPT
8624684ddb6SLionel Sambuc        {return allocator_type(__node_alloc());}
8634684ddb6SLionel Sambucprivate:
8644684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8654684ddb6SLionel Sambuc          size_type& size() _NOEXCEPT {return __pair3_.first();}
8664684ddb6SLionel Sambucpublic:
8674684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8684684ddb6SLionel Sambuc    const size_type& size() const _NOEXCEPT {return __pair3_.first();}
8694684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8704684ddb6SLionel Sambuc          value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
8714684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8724684ddb6SLionel Sambuc    const value_compare& value_comp() const _NOEXCEPT
8734684ddb6SLionel Sambuc        {return __pair3_.second();}
8744684ddb6SLionel Sambucpublic:
8754684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8764684ddb6SLionel Sambuc    __node_pointer __root() _NOEXCEPT
8774684ddb6SLionel Sambuc        {return static_cast<__node_pointer>      (__end_node()->__left_);}
8784684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8794684ddb6SLionel Sambuc    __node_const_pointer __root() const _NOEXCEPT
8804684ddb6SLionel Sambuc        {return static_cast<__node_const_pointer>(__end_node()->__left_);}
8814684ddb6SLionel Sambuc
8824684ddb6SLionel Sambuc    typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
8834684ddb6SLionel Sambuc    typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
8844684ddb6SLionel Sambuc
8854684ddb6SLionel Sambuc    explicit __tree(const value_compare& __comp)
8864684ddb6SLionel Sambuc        _NOEXCEPT_(
8874684ddb6SLionel Sambuc            is_nothrow_default_constructible<__node_allocator>::value &&
8884684ddb6SLionel Sambuc            is_nothrow_copy_constructible<value_compare>::value);
8894684ddb6SLionel Sambuc    explicit __tree(const allocator_type& __a);
8904684ddb6SLionel Sambuc    __tree(const value_compare& __comp, const allocator_type& __a);
8914684ddb6SLionel Sambuc    __tree(const __tree& __t);
8924684ddb6SLionel Sambuc    __tree& operator=(const __tree& __t);
8934684ddb6SLionel Sambuc    template <class _InputIterator>
8944684ddb6SLionel Sambuc        void __assign_unique(_InputIterator __first, _InputIterator __last);
8954684ddb6SLionel Sambuc    template <class _InputIterator>
8964684ddb6SLionel Sambuc        void __assign_multi(_InputIterator __first, _InputIterator __last);
8974684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
8984684ddb6SLionel Sambuc    __tree(__tree&& __t)
8994684ddb6SLionel Sambuc        _NOEXCEPT_(
9004684ddb6SLionel Sambuc            is_nothrow_move_constructible<__node_allocator>::value &&
9014684ddb6SLionel Sambuc            is_nothrow_move_constructible<value_compare>::value);
9024684ddb6SLionel Sambuc    __tree(__tree&& __t, const allocator_type& __a);
9034684ddb6SLionel Sambuc    __tree& operator=(__tree&& __t)
9044684ddb6SLionel Sambuc        _NOEXCEPT_(
9054684ddb6SLionel Sambuc            __node_traits::propagate_on_container_move_assignment::value &&
9064684ddb6SLionel Sambuc            is_nothrow_move_assignable<value_compare>::value &&
9074684ddb6SLionel Sambuc            is_nothrow_move_assignable<__node_allocator>::value);
9084684ddb6SLionel Sambuc#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
9094684ddb6SLionel Sambuc
9104684ddb6SLionel Sambuc    ~__tree();
9114684ddb6SLionel Sambuc
9124684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
9134684ddb6SLionel Sambuc          iterator begin()  _NOEXCEPT {return       iterator(__begin_node());}
9144684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
9154684ddb6SLionel Sambuc    const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
9164684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
9174684ddb6SLionel Sambuc          iterator end() _NOEXCEPT {return       iterator(__end_node());}
9184684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
9194684ddb6SLionel Sambuc    const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
9204684ddb6SLionel Sambuc
9214684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
9224684ddb6SLionel Sambuc    size_type max_size() const _NOEXCEPT
9234684ddb6SLionel Sambuc        {return __node_traits::max_size(__node_alloc());}
9244684ddb6SLionel Sambuc
9254684ddb6SLionel Sambuc    void clear() _NOEXCEPT;
9264684ddb6SLionel Sambuc
9274684ddb6SLionel Sambuc    void swap(__tree& __t)
9284684ddb6SLionel Sambuc        _NOEXCEPT_(
929*0a6a1f1dSLionel Sambuc            __is_nothrow_swappable<value_compare>::value
930*0a6a1f1dSLionel Sambuc#if _LIBCPP_STD_VER <= 11
931*0a6a1f1dSLionel Sambuc            && (!__node_traits::propagate_on_container_swap::value ||
932*0a6a1f1dSLionel Sambuc                 __is_nothrow_swappable<__node_allocator>::value)
933*0a6a1f1dSLionel Sambuc#endif
934*0a6a1f1dSLionel Sambuc            );
9354684ddb6SLionel Sambuc
9364684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9374684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_VARIADICS
9384684ddb6SLionel Sambuc    template <class... _Args>
9394684ddb6SLionel Sambuc        pair<iterator, bool>
9404684ddb6SLionel Sambuc        __emplace_unique(_Args&&... __args);
9414684ddb6SLionel Sambuc    template <class... _Args>
9424684ddb6SLionel Sambuc        iterator
9434684ddb6SLionel Sambuc        __emplace_multi(_Args&&... __args);
9444684ddb6SLionel Sambuc
9454684ddb6SLionel Sambuc    template <class... _Args>
9464684ddb6SLionel Sambuc        iterator
9474684ddb6SLionel Sambuc        __emplace_hint_unique(const_iterator __p, _Args&&... __args);
9484684ddb6SLionel Sambuc    template <class... _Args>
9494684ddb6SLionel Sambuc        iterator
9504684ddb6SLionel Sambuc        __emplace_hint_multi(const_iterator __p, _Args&&... __args);
9514684ddb6SLionel Sambuc#endif  // _LIBCPP_HAS_NO_VARIADICS
9524684ddb6SLionel Sambuc
9534684ddb6SLionel Sambuc    template <class _Vp>
9544684ddb6SLionel Sambuc        pair<iterator, bool> __insert_unique(_Vp&& __v);
9554684ddb6SLionel Sambuc    template <class _Vp>
9564684ddb6SLionel Sambuc        iterator __insert_unique(const_iterator __p, _Vp&& __v);
9574684ddb6SLionel Sambuc    template <class _Vp>
9584684ddb6SLionel Sambuc        iterator __insert_multi(_Vp&& __v);
9594684ddb6SLionel Sambuc    template <class _Vp>
9604684ddb6SLionel Sambuc        iterator __insert_multi(const_iterator __p, _Vp&& __v);
9614684ddb6SLionel Sambuc#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
9624684ddb6SLionel Sambuc
9634684ddb6SLionel Sambuc    pair<iterator, bool> __insert_unique(const value_type& __v);
9644684ddb6SLionel Sambuc    iterator __insert_unique(const_iterator __p, const value_type& __v);
9654684ddb6SLionel Sambuc    iterator __insert_multi(const value_type& __v);
9664684ddb6SLionel Sambuc    iterator __insert_multi(const_iterator __p, const value_type& __v);
9674684ddb6SLionel Sambuc
9684684ddb6SLionel Sambuc    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
9694684ddb6SLionel Sambuc    iterator             __node_insert_unique(const_iterator __p,
9704684ddb6SLionel Sambuc                                              __node_pointer __nd);
9714684ddb6SLionel Sambuc
9724684ddb6SLionel Sambuc    iterator __node_insert_multi(__node_pointer __nd);
9734684ddb6SLionel Sambuc    iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
9744684ddb6SLionel Sambuc
9754684ddb6SLionel Sambuc    iterator erase(const_iterator __p);
9764684ddb6SLionel Sambuc    iterator erase(const_iterator __f, const_iterator __l);
9774684ddb6SLionel Sambuc    template <class _Key>
9784684ddb6SLionel Sambuc        size_type __erase_unique(const _Key& __k);
9794684ddb6SLionel Sambuc    template <class _Key>
9804684ddb6SLionel Sambuc        size_type __erase_multi(const _Key& __k);
9814684ddb6SLionel Sambuc
9824684ddb6SLionel Sambuc    void __insert_node_at(__node_base_pointer __parent,
9834684ddb6SLionel Sambuc                          __node_base_pointer& __child,
9844684ddb6SLionel Sambuc                          __node_base_pointer __new_node);
9854684ddb6SLionel Sambuc
9864684ddb6SLionel Sambuc    template <class _Key>
9874684ddb6SLionel Sambuc        iterator find(const _Key& __v);
9884684ddb6SLionel Sambuc    template <class _Key>
9894684ddb6SLionel Sambuc        const_iterator find(const _Key& __v) const;
9904684ddb6SLionel Sambuc
9914684ddb6SLionel Sambuc    template <class _Key>
9924684ddb6SLionel Sambuc        size_type __count_unique(const _Key& __k) const;
9934684ddb6SLionel Sambuc    template <class _Key>
9944684ddb6SLionel Sambuc        size_type __count_multi(const _Key& __k) const;
9954684ddb6SLionel Sambuc
9964684ddb6SLionel Sambuc    template <class _Key>
9974684ddb6SLionel Sambuc        _LIBCPP_INLINE_VISIBILITY
9984684ddb6SLionel Sambuc        iterator lower_bound(const _Key& __v)
9994684ddb6SLionel Sambuc            {return __lower_bound(__v, __root(), __end_node());}
10004684ddb6SLionel Sambuc    template <class _Key>
10014684ddb6SLionel Sambuc        iterator __lower_bound(const _Key& __v,
10024684ddb6SLionel Sambuc                               __node_pointer __root,
10034684ddb6SLionel Sambuc                               __node_pointer __result);
10044684ddb6SLionel Sambuc    template <class _Key>
10054684ddb6SLionel Sambuc        _LIBCPP_INLINE_VISIBILITY
10064684ddb6SLionel Sambuc        const_iterator lower_bound(const _Key& __v) const
10074684ddb6SLionel Sambuc            {return __lower_bound(__v, __root(), __end_node());}
10084684ddb6SLionel Sambuc    template <class _Key>
10094684ddb6SLionel Sambuc        const_iterator __lower_bound(const _Key& __v,
10104684ddb6SLionel Sambuc                                     __node_const_pointer __root,
10114684ddb6SLionel Sambuc                                     __node_const_pointer __result) const;
10124684ddb6SLionel Sambuc    template <class _Key>
10134684ddb6SLionel Sambuc        _LIBCPP_INLINE_VISIBILITY
10144684ddb6SLionel Sambuc        iterator upper_bound(const _Key& __v)
10154684ddb6SLionel Sambuc            {return __upper_bound(__v, __root(), __end_node());}
10164684ddb6SLionel Sambuc    template <class _Key>
10174684ddb6SLionel Sambuc        iterator __upper_bound(const _Key& __v,
10184684ddb6SLionel Sambuc                               __node_pointer __root,
10194684ddb6SLionel Sambuc                               __node_pointer __result);
10204684ddb6SLionel Sambuc    template <class _Key>
10214684ddb6SLionel Sambuc        _LIBCPP_INLINE_VISIBILITY
10224684ddb6SLionel Sambuc        const_iterator upper_bound(const _Key& __v) const
10234684ddb6SLionel Sambuc            {return __upper_bound(__v, __root(), __end_node());}
10244684ddb6SLionel Sambuc    template <class _Key>
10254684ddb6SLionel Sambuc        const_iterator __upper_bound(const _Key& __v,
10264684ddb6SLionel Sambuc                                     __node_const_pointer __root,
10274684ddb6SLionel Sambuc                                     __node_const_pointer __result) const;
10284684ddb6SLionel Sambuc    template <class _Key>
10294684ddb6SLionel Sambuc        pair<iterator, iterator>
10304684ddb6SLionel Sambuc        __equal_range_unique(const _Key& __k);
10314684ddb6SLionel Sambuc    template <class _Key>
10324684ddb6SLionel Sambuc        pair<const_iterator, const_iterator>
10334684ddb6SLionel Sambuc        __equal_range_unique(const _Key& __k) const;
10344684ddb6SLionel Sambuc
10354684ddb6SLionel Sambuc    template <class _Key>
10364684ddb6SLionel Sambuc        pair<iterator, iterator>
10374684ddb6SLionel Sambuc        __equal_range_multi(const _Key& __k);
10384684ddb6SLionel Sambuc    template <class _Key>
10394684ddb6SLionel Sambuc        pair<const_iterator, const_iterator>
10404684ddb6SLionel Sambuc        __equal_range_multi(const _Key& __k) const;
10414684ddb6SLionel Sambuc
10424684ddb6SLionel Sambuc    typedef __tree_node_destructor<__node_allocator> _Dp;
10434684ddb6SLionel Sambuc    typedef unique_ptr<__node, _Dp> __node_holder;
10444684ddb6SLionel Sambuc
10454684ddb6SLionel Sambuc    __node_holder remove(const_iterator __p) _NOEXCEPT;
10464684ddb6SLionel Sambucprivate:
10474684ddb6SLionel Sambuc    typename __node_base::pointer&
10484684ddb6SLionel Sambuc        __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v);
10494684ddb6SLionel Sambuc    typename __node_base::pointer&
10504684ddb6SLionel Sambuc        __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v);
10514684ddb6SLionel Sambuc    typename __node_base::pointer&
10524684ddb6SLionel Sambuc        __find_leaf(const_iterator __hint,
10534684ddb6SLionel Sambuc                    typename __node_base::pointer& __parent, const value_type& __v);
10544684ddb6SLionel Sambuc    template <class _Key>
10554684ddb6SLionel Sambuc        typename __node_base::pointer&
10564684ddb6SLionel Sambuc        __find_equal(typename __node_base::pointer& __parent, const _Key& __v);
10574684ddb6SLionel Sambuc    template <class _Key>
10584684ddb6SLionel Sambuc        typename __node_base::pointer&
10594684ddb6SLionel Sambuc        __find_equal(const_iterator __hint, typename __node_base::pointer& __parent,
10604684ddb6SLionel Sambuc                     const _Key& __v);
10614684ddb6SLionel Sambuc
10624684ddb6SLionel Sambuc#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
10634684ddb6SLionel Sambuc    template <class ..._Args>
10644684ddb6SLionel Sambuc        __node_holder __construct_node(_Args&& ...__args);
10654684ddb6SLionel Sambuc#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
10664684ddb6SLionel Sambuc        __node_holder __construct_node(const value_type& __v);
10674684ddb6SLionel Sambuc#endif
10684684ddb6SLionel Sambuc
10694684ddb6SLionel Sambuc    void destroy(__node_pointer __nd) _NOEXCEPT;
10704684ddb6SLionel Sambuc
10714684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
10724684ddb6SLionel Sambuc    void __copy_assign_alloc(const __tree& __t)
10734684ddb6SLionel Sambuc        {__copy_assign_alloc(__t, integral_constant<bool,
10744684ddb6SLionel Sambuc             __node_traits::propagate_on_container_copy_assignment::value>());}
10754684ddb6SLionel Sambuc
10764684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
10774684ddb6SLionel Sambuc    void __copy_assign_alloc(const __tree& __t, true_type)
10784684ddb6SLionel Sambuc        {__node_alloc() = __t.__node_alloc();}
10794684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
10804684ddb6SLionel Sambuc    void __copy_assign_alloc(const __tree& __t, false_type) {}
10814684ddb6SLionel Sambuc
10824684ddb6SLionel Sambuc    void __move_assign(__tree& __t, false_type);
10834684ddb6SLionel Sambuc    void __move_assign(__tree& __t, true_type)
10844684ddb6SLionel Sambuc        _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
10854684ddb6SLionel Sambuc                   is_nothrow_move_assignable<__node_allocator>::value);
10864684ddb6SLionel Sambuc
10874684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
10884684ddb6SLionel Sambuc    void __move_assign_alloc(__tree& __t)
10894684ddb6SLionel Sambuc        _NOEXCEPT_(
10904684ddb6SLionel Sambuc            !__node_traits::propagate_on_container_move_assignment::value ||
10914684ddb6SLionel Sambuc            is_nothrow_move_assignable<__node_allocator>::value)
10924684ddb6SLionel Sambuc        {__move_assign_alloc(__t, integral_constant<bool,
10934684ddb6SLionel Sambuc             __node_traits::propagate_on_container_move_assignment::value>());}
10944684ddb6SLionel Sambuc
10954684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
10964684ddb6SLionel Sambuc    void __move_assign_alloc(__tree& __t, true_type)
10974684ddb6SLionel Sambuc        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
10984684ddb6SLionel Sambuc        {__node_alloc() = _VSTD::move(__t.__node_alloc());}
10994684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
11004684ddb6SLionel Sambuc    void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {}
11014684ddb6SLionel Sambuc
11024684ddb6SLionel Sambuc    __node_pointer __detach();
11034684ddb6SLionel Sambuc    static __node_pointer __detach(__node_pointer);
11044684ddb6SLionel Sambuc
11054684ddb6SLionel Sambuc    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
11064684ddb6SLionel Sambuc    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
11074684ddb6SLionel Sambuc};
11084684ddb6SLionel Sambuc
11094684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
11104684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
11114684ddb6SLionel Sambuc        _NOEXCEPT_(
11124684ddb6SLionel Sambuc            is_nothrow_default_constructible<__node_allocator>::value &&
11134684ddb6SLionel Sambuc            is_nothrow_copy_constructible<value_compare>::value)
11144684ddb6SLionel Sambuc    : __pair3_(0, __comp)
11154684ddb6SLionel Sambuc{
11164684ddb6SLionel Sambuc    __begin_node() = __end_node();
11174684ddb6SLionel Sambuc}
11184684ddb6SLionel Sambuc
11194684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
11204684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
1121*0a6a1f1dSLionel Sambuc    : __begin_node_(__node_pointer()),
1122*0a6a1f1dSLionel Sambuc      __pair1_(__node_allocator(__a)),
11234684ddb6SLionel Sambuc      __pair3_(0)
11244684ddb6SLionel Sambuc{
11254684ddb6SLionel Sambuc    __begin_node() = __end_node();
11264684ddb6SLionel Sambuc}
11274684ddb6SLionel Sambuc
11284684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
11294684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
11304684ddb6SLionel Sambuc                                           const allocator_type& __a)
1131*0a6a1f1dSLionel Sambuc    : __begin_node_(__node_pointer()),
1132*0a6a1f1dSLionel Sambuc      __pair1_(__node_allocator(__a)),
11334684ddb6SLionel Sambuc      __pair3_(0, __comp)
11344684ddb6SLionel Sambuc{
11354684ddb6SLionel Sambuc    __begin_node() = __end_node();
11364684ddb6SLionel Sambuc}
11374684ddb6SLionel Sambuc
11384684ddb6SLionel Sambuc// Precondition:  size() != 0
11394684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
11404684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_pointer
11414684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__detach()
11424684ddb6SLionel Sambuc{
11434684ddb6SLionel Sambuc    __node_pointer __cache = __begin_node();
11444684ddb6SLionel Sambuc    __begin_node() = __end_node();
11454684ddb6SLionel Sambuc    __end_node()->__left_->__parent_ = nullptr;
11464684ddb6SLionel Sambuc    __end_node()->__left_ = nullptr;
11474684ddb6SLionel Sambuc    size() = 0;
11484684ddb6SLionel Sambuc    // __cache->__left_ == nullptr
11494684ddb6SLionel Sambuc    if (__cache->__right_ != nullptr)
11504684ddb6SLionel Sambuc        __cache = static_cast<__node_pointer>(__cache->__right_);
11514684ddb6SLionel Sambuc    // __cache->__left_ == nullptr
11524684ddb6SLionel Sambuc    // __cache->__right_ == nullptr
11534684ddb6SLionel Sambuc    return __cache;
11544684ddb6SLionel Sambuc}
11554684ddb6SLionel Sambuc
11564684ddb6SLionel Sambuc// Precondition:  __cache != nullptr
11574684ddb6SLionel Sambuc//    __cache->left_ == nullptr
11584684ddb6SLionel Sambuc//    __cache->right_ == nullptr
11594684ddb6SLionel Sambuc//    This is no longer a red-black tree
11604684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
11614684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_pointer
11624684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
11634684ddb6SLionel Sambuc{
11644684ddb6SLionel Sambuc    if (__cache->__parent_ == nullptr)
11654684ddb6SLionel Sambuc        return nullptr;
11664684ddb6SLionel Sambuc    if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
11674684ddb6SLionel Sambuc    {
11684684ddb6SLionel Sambuc        __cache->__parent_->__left_ = nullptr;
11694684ddb6SLionel Sambuc        __cache = static_cast<__node_pointer>(__cache->__parent_);
11704684ddb6SLionel Sambuc        if (__cache->__right_ == nullptr)
11714684ddb6SLionel Sambuc            return __cache;
11724684ddb6SLionel Sambuc        return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
11734684ddb6SLionel Sambuc    }
11744684ddb6SLionel Sambuc    // __cache is right child
11754684ddb6SLionel Sambuc    __cache->__parent_->__right_ = nullptr;
11764684ddb6SLionel Sambuc    __cache = static_cast<__node_pointer>(__cache->__parent_);
11774684ddb6SLionel Sambuc    if (__cache->__left_ == nullptr)
11784684ddb6SLionel Sambuc        return __cache;
11794684ddb6SLionel Sambuc    return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
11804684ddb6SLionel Sambuc}
11814684ddb6SLionel Sambuc
11824684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
11834684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>&
11844684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
11854684ddb6SLionel Sambuc{
11864684ddb6SLionel Sambuc    if (this != &__t)
11874684ddb6SLionel Sambuc    {
11884684ddb6SLionel Sambuc        value_comp() = __t.value_comp();
11894684ddb6SLionel Sambuc        __copy_assign_alloc(__t);
11904684ddb6SLionel Sambuc        __assign_multi(__t.begin(), __t.end());
11914684ddb6SLionel Sambuc    }
11924684ddb6SLionel Sambuc    return *this;
11934684ddb6SLionel Sambuc}
11944684ddb6SLionel Sambuc
11954684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
11964684ddb6SLionel Sambuctemplate <class _InputIterator>
11974684ddb6SLionel Sambucvoid
11984684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
11994684ddb6SLionel Sambuc{
12004684ddb6SLionel Sambuc    if (size() != 0)
12014684ddb6SLionel Sambuc    {
12024684ddb6SLionel Sambuc        __node_pointer __cache = __detach();
12034684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
12044684ddb6SLionel Sambuc        try
12054684ddb6SLionel Sambuc        {
12064684ddb6SLionel Sambuc#endif  // _LIBCPP_NO_EXCEPTIONS
12074684ddb6SLionel Sambuc            for (; __cache != nullptr && __first != __last; ++__first)
12084684ddb6SLionel Sambuc            {
12094684ddb6SLionel Sambuc                __cache->__value_ = *__first;
12104684ddb6SLionel Sambuc                __node_pointer __next = __detach(__cache);
12114684ddb6SLionel Sambuc                __node_insert_unique(__cache);
12124684ddb6SLionel Sambuc                __cache = __next;
12134684ddb6SLionel Sambuc            }
12144684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
12154684ddb6SLionel Sambuc        }
12164684ddb6SLionel Sambuc        catch (...)
12174684ddb6SLionel Sambuc        {
12184684ddb6SLionel Sambuc            while (__cache->__parent_ != nullptr)
12194684ddb6SLionel Sambuc                __cache = static_cast<__node_pointer>(__cache->__parent_);
12204684ddb6SLionel Sambuc            destroy(__cache);
12214684ddb6SLionel Sambuc            throw;
12224684ddb6SLionel Sambuc        }
12234684ddb6SLionel Sambuc#endif  // _LIBCPP_NO_EXCEPTIONS
12244684ddb6SLionel Sambuc        if (__cache != nullptr)
12254684ddb6SLionel Sambuc        {
12264684ddb6SLionel Sambuc            while (__cache->__parent_ != nullptr)
12274684ddb6SLionel Sambuc                __cache = static_cast<__node_pointer>(__cache->__parent_);
12284684ddb6SLionel Sambuc            destroy(__cache);
12294684ddb6SLionel Sambuc        }
12304684ddb6SLionel Sambuc    }
12314684ddb6SLionel Sambuc    for (; __first != __last; ++__first)
12324684ddb6SLionel Sambuc        __insert_unique(*__first);
12334684ddb6SLionel Sambuc}
12344684ddb6SLionel Sambuc
12354684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
12364684ddb6SLionel Sambuctemplate <class _InputIterator>
12374684ddb6SLionel Sambucvoid
12384684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
12394684ddb6SLionel Sambuc{
12404684ddb6SLionel Sambuc    if (size() != 0)
12414684ddb6SLionel Sambuc    {
12424684ddb6SLionel Sambuc        __node_pointer __cache = __detach();
12434684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
12444684ddb6SLionel Sambuc        try
12454684ddb6SLionel Sambuc        {
12464684ddb6SLionel Sambuc#endif  // _LIBCPP_NO_EXCEPTIONS
12474684ddb6SLionel Sambuc            for (; __cache != nullptr && __first != __last; ++__first)
12484684ddb6SLionel Sambuc            {
12494684ddb6SLionel Sambuc                __cache->__value_ = *__first;
12504684ddb6SLionel Sambuc                __node_pointer __next = __detach(__cache);
12514684ddb6SLionel Sambuc                __node_insert_multi(__cache);
12524684ddb6SLionel Sambuc                __cache = __next;
12534684ddb6SLionel Sambuc            }
12544684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
12554684ddb6SLionel Sambuc        }
12564684ddb6SLionel Sambuc        catch (...)
12574684ddb6SLionel Sambuc        {
12584684ddb6SLionel Sambuc            while (__cache->__parent_ != nullptr)
12594684ddb6SLionel Sambuc                __cache = static_cast<__node_pointer>(__cache->__parent_);
12604684ddb6SLionel Sambuc            destroy(__cache);
12614684ddb6SLionel Sambuc            throw;
12624684ddb6SLionel Sambuc        }
12634684ddb6SLionel Sambuc#endif  // _LIBCPP_NO_EXCEPTIONS
12644684ddb6SLionel Sambuc        if (__cache != nullptr)
12654684ddb6SLionel Sambuc        {
12664684ddb6SLionel Sambuc            while (__cache->__parent_ != nullptr)
12674684ddb6SLionel Sambuc                __cache = static_cast<__node_pointer>(__cache->__parent_);
12684684ddb6SLionel Sambuc            destroy(__cache);
12694684ddb6SLionel Sambuc        }
12704684ddb6SLionel Sambuc    }
12714684ddb6SLionel Sambuc    for (; __first != __last; ++__first)
12724684ddb6SLionel Sambuc        __insert_multi(*__first);
12734684ddb6SLionel Sambuc}
12744684ddb6SLionel Sambuc
12754684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
12764684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
12774684ddb6SLionel Sambuc    : __begin_node_(__node_pointer()),
12784684ddb6SLionel Sambuc      __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
12794684ddb6SLionel Sambuc      __pair3_(0, __t.value_comp())
12804684ddb6SLionel Sambuc{
12814684ddb6SLionel Sambuc    __begin_node() = __end_node();
12824684ddb6SLionel Sambuc}
12834684ddb6SLionel Sambuc
12844684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
12854684ddb6SLionel Sambuc
12864684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
12874684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
12884684ddb6SLionel Sambuc    _NOEXCEPT_(
12894684ddb6SLionel Sambuc        is_nothrow_move_constructible<__node_allocator>::value &&
12904684ddb6SLionel Sambuc        is_nothrow_move_constructible<value_compare>::value)
12914684ddb6SLionel Sambuc    : __begin_node_(_VSTD::move(__t.__begin_node_)),
12924684ddb6SLionel Sambuc      __pair1_(_VSTD::move(__t.__pair1_)),
12934684ddb6SLionel Sambuc      __pair3_(_VSTD::move(__t.__pair3_))
12944684ddb6SLionel Sambuc{
12954684ddb6SLionel Sambuc    if (size() == 0)
12964684ddb6SLionel Sambuc        __begin_node() = __end_node();
12974684ddb6SLionel Sambuc    else
12984684ddb6SLionel Sambuc    {
12994684ddb6SLionel Sambuc        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
13004684ddb6SLionel Sambuc        __t.__begin_node() = __t.__end_node();
13014684ddb6SLionel Sambuc        __t.__end_node()->__left_ = nullptr;
13024684ddb6SLionel Sambuc        __t.size() = 0;
13034684ddb6SLionel Sambuc    }
13044684ddb6SLionel Sambuc}
13054684ddb6SLionel Sambuc
13064684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
13074684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
13084684ddb6SLionel Sambuc    : __pair1_(__node_allocator(__a)),
13094684ddb6SLionel Sambuc      __pair3_(0, _VSTD::move(__t.value_comp()))
13104684ddb6SLionel Sambuc{
13114684ddb6SLionel Sambuc    if (__a == __t.__alloc())
13124684ddb6SLionel Sambuc    {
13134684ddb6SLionel Sambuc        if (__t.size() == 0)
13144684ddb6SLionel Sambuc            __begin_node() = __end_node();
13154684ddb6SLionel Sambuc        else
13164684ddb6SLionel Sambuc        {
13174684ddb6SLionel Sambuc            __begin_node() = __t.__begin_node();
13184684ddb6SLionel Sambuc            __end_node()->__left_ = __t.__end_node()->__left_;
13194684ddb6SLionel Sambuc            __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
13204684ddb6SLionel Sambuc            size() = __t.size();
13214684ddb6SLionel Sambuc            __t.__begin_node() = __t.__end_node();
13224684ddb6SLionel Sambuc            __t.__end_node()->__left_ = nullptr;
13234684ddb6SLionel Sambuc            __t.size() = 0;
13244684ddb6SLionel Sambuc        }
13254684ddb6SLionel Sambuc    }
13264684ddb6SLionel Sambuc    else
13274684ddb6SLionel Sambuc    {
13284684ddb6SLionel Sambuc        __begin_node() = __end_node();
13294684ddb6SLionel Sambuc    }
13304684ddb6SLionel Sambuc}
13314684ddb6SLionel Sambuc
13324684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
13334684ddb6SLionel Sambucvoid
13344684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
13354684ddb6SLionel Sambuc    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
13364684ddb6SLionel Sambuc               is_nothrow_move_assignable<__node_allocator>::value)
13374684ddb6SLionel Sambuc{
13384684ddb6SLionel Sambuc    destroy(static_cast<__node_pointer>(__end_node()->__left_));
13394684ddb6SLionel Sambuc    __begin_node_ = __t.__begin_node_;
13404684ddb6SLionel Sambuc    __pair1_.first() = __t.__pair1_.first();
13414684ddb6SLionel Sambuc    __move_assign_alloc(__t);
13424684ddb6SLionel Sambuc    __pair3_ = _VSTD::move(__t.__pair3_);
13434684ddb6SLionel Sambuc    if (size() == 0)
13444684ddb6SLionel Sambuc        __begin_node() = __end_node();
13454684ddb6SLionel Sambuc    else
13464684ddb6SLionel Sambuc    {
13474684ddb6SLionel Sambuc        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
13484684ddb6SLionel Sambuc        __t.__begin_node() = __t.__end_node();
13494684ddb6SLionel Sambuc        __t.__end_node()->__left_ = nullptr;
13504684ddb6SLionel Sambuc        __t.size() = 0;
13514684ddb6SLionel Sambuc    }
13524684ddb6SLionel Sambuc}
13534684ddb6SLionel Sambuc
13544684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
13554684ddb6SLionel Sambucvoid
13564684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
13574684ddb6SLionel Sambuc{
13584684ddb6SLionel Sambuc    if (__node_alloc() == __t.__node_alloc())
13594684ddb6SLionel Sambuc        __move_assign(__t, true_type());
13604684ddb6SLionel Sambuc    else
13614684ddb6SLionel Sambuc    {
13624684ddb6SLionel Sambuc        value_comp() = _VSTD::move(__t.value_comp());
13634684ddb6SLionel Sambuc        const_iterator __e = end();
13644684ddb6SLionel Sambuc        if (size() != 0)
13654684ddb6SLionel Sambuc        {
13664684ddb6SLionel Sambuc            __node_pointer __cache = __detach();
13674684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
13684684ddb6SLionel Sambuc            try
13694684ddb6SLionel Sambuc            {
13704684ddb6SLionel Sambuc#endif  // _LIBCPP_NO_EXCEPTIONS
13714684ddb6SLionel Sambuc                while (__cache != nullptr && __t.size() != 0)
13724684ddb6SLionel Sambuc                {
13734684ddb6SLionel Sambuc                    __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
13744684ddb6SLionel Sambuc                    __node_pointer __next = __detach(__cache);
13754684ddb6SLionel Sambuc                    __node_insert_multi(__cache);
13764684ddb6SLionel Sambuc                    __cache = __next;
13774684ddb6SLionel Sambuc                }
13784684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
13794684ddb6SLionel Sambuc            }
13804684ddb6SLionel Sambuc            catch (...)
13814684ddb6SLionel Sambuc            {
13824684ddb6SLionel Sambuc                while (__cache->__parent_ != nullptr)
13834684ddb6SLionel Sambuc                    __cache = static_cast<__node_pointer>(__cache->__parent_);
13844684ddb6SLionel Sambuc                destroy(__cache);
13854684ddb6SLionel Sambuc                throw;
13864684ddb6SLionel Sambuc            }
13874684ddb6SLionel Sambuc#endif  // _LIBCPP_NO_EXCEPTIONS
13884684ddb6SLionel Sambuc            if (__cache != nullptr)
13894684ddb6SLionel Sambuc            {
13904684ddb6SLionel Sambuc                while (__cache->__parent_ != nullptr)
13914684ddb6SLionel Sambuc                    __cache = static_cast<__node_pointer>(__cache->__parent_);
13924684ddb6SLionel Sambuc                destroy(__cache);
13934684ddb6SLionel Sambuc            }
13944684ddb6SLionel Sambuc        }
13954684ddb6SLionel Sambuc        while (__t.size() != 0)
13964684ddb6SLionel Sambuc            __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_));
13974684ddb6SLionel Sambuc    }
13984684ddb6SLionel Sambuc}
13994684ddb6SLionel Sambuc
14004684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
14014684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>&
14024684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
14034684ddb6SLionel Sambuc    _NOEXCEPT_(
14044684ddb6SLionel Sambuc        __node_traits::propagate_on_container_move_assignment::value &&
14054684ddb6SLionel Sambuc        is_nothrow_move_assignable<value_compare>::value &&
14064684ddb6SLionel Sambuc        is_nothrow_move_assignable<__node_allocator>::value)
14074684ddb6SLionel Sambuc
14084684ddb6SLionel Sambuc{
14094684ddb6SLionel Sambuc    __move_assign(__t, integral_constant<bool,
14104684ddb6SLionel Sambuc                  __node_traits::propagate_on_container_move_assignment::value>());
14114684ddb6SLionel Sambuc    return *this;
14124684ddb6SLionel Sambuc}
14134684ddb6SLionel Sambuc
14144684ddb6SLionel Sambuc#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
14154684ddb6SLionel Sambuc
14164684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
14174684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::~__tree()
14184684ddb6SLionel Sambuc{
14194684ddb6SLionel Sambuc    destroy(__root());
14204684ddb6SLionel Sambuc}
14214684ddb6SLionel Sambuc
14224684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
14234684ddb6SLionel Sambucvoid
14244684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
14254684ddb6SLionel Sambuc{
14264684ddb6SLionel Sambuc    if (__nd != nullptr)
14274684ddb6SLionel Sambuc    {
14284684ddb6SLionel Sambuc        destroy(static_cast<__node_pointer>(__nd->__left_));
14294684ddb6SLionel Sambuc        destroy(static_cast<__node_pointer>(__nd->__right_));
14304684ddb6SLionel Sambuc        __node_allocator& __na = __node_alloc();
14314684ddb6SLionel Sambuc        __node_traits::destroy(__na, _VSTD::addressof(__nd->__value_));
14324684ddb6SLionel Sambuc        __node_traits::deallocate(__na, __nd, 1);
14334684ddb6SLionel Sambuc    }
14344684ddb6SLionel Sambuc}
14354684ddb6SLionel Sambuc
14364684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
14374684ddb6SLionel Sambucvoid
14384684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
14394684ddb6SLionel Sambuc        _NOEXCEPT_(
1440*0a6a1f1dSLionel Sambuc            __is_nothrow_swappable<value_compare>::value
1441*0a6a1f1dSLionel Sambuc#if _LIBCPP_STD_VER <= 11
1442*0a6a1f1dSLionel Sambuc            && (!__node_traits::propagate_on_container_swap::value ||
1443*0a6a1f1dSLionel Sambuc                 __is_nothrow_swappable<__node_allocator>::value)
1444*0a6a1f1dSLionel Sambuc#endif
1445*0a6a1f1dSLionel Sambuc            )
14464684ddb6SLionel Sambuc{
14474684ddb6SLionel Sambuc    using _VSTD::swap;
14484684ddb6SLionel Sambuc    swap(__begin_node_, __t.__begin_node_);
14494684ddb6SLionel Sambuc    swap(__pair1_.first(), __t.__pair1_.first());
1450*0a6a1f1dSLionel Sambuc    __swap_allocator(__node_alloc(), __t.__node_alloc());
14514684ddb6SLionel Sambuc    __pair3_.swap(__t.__pair3_);
14524684ddb6SLionel Sambuc    if (size() == 0)
14534684ddb6SLionel Sambuc        __begin_node() = __end_node();
14544684ddb6SLionel Sambuc    else
14554684ddb6SLionel Sambuc        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
14564684ddb6SLionel Sambuc    if (__t.size() == 0)
14574684ddb6SLionel Sambuc        __t.__begin_node() = __t.__end_node();
14584684ddb6SLionel Sambuc    else
14594684ddb6SLionel Sambuc        __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node());
14604684ddb6SLionel Sambuc}
14614684ddb6SLionel Sambuc
14624684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
14634684ddb6SLionel Sambucvoid
14644684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
14654684ddb6SLionel Sambuc{
14664684ddb6SLionel Sambuc    destroy(__root());
14674684ddb6SLionel Sambuc    size() = 0;
14684684ddb6SLionel Sambuc    __begin_node() = __end_node();
14694684ddb6SLionel Sambuc    __end_node()->__left_ = nullptr;
14704684ddb6SLionel Sambuc}
14714684ddb6SLionel Sambuc
14724684ddb6SLionel Sambuc// Find lower_bound place to insert
14734684ddb6SLionel Sambuc// Set __parent to parent of null leaf
14744684ddb6SLionel Sambuc// Return reference to null leaf
14754684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
14764684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
14774684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer& __parent,
14784684ddb6SLionel Sambuc                                                   const value_type& __v)
14794684ddb6SLionel Sambuc{
14804684ddb6SLionel Sambuc    __node_pointer __nd = __root();
14814684ddb6SLionel Sambuc    if (__nd != nullptr)
14824684ddb6SLionel Sambuc    {
14834684ddb6SLionel Sambuc        while (true)
14844684ddb6SLionel Sambuc        {
14854684ddb6SLionel Sambuc            if (value_comp()(__nd->__value_, __v))
14864684ddb6SLionel Sambuc            {
14874684ddb6SLionel Sambuc                if (__nd->__right_ != nullptr)
14884684ddb6SLionel Sambuc                    __nd = static_cast<__node_pointer>(__nd->__right_);
14894684ddb6SLionel Sambuc                else
14904684ddb6SLionel Sambuc                {
14914684ddb6SLionel Sambuc                    __parent = static_cast<__node_base_pointer>(__nd);
14924684ddb6SLionel Sambuc                    return __parent->__right_;
14934684ddb6SLionel Sambuc                }
14944684ddb6SLionel Sambuc            }
14954684ddb6SLionel Sambuc            else
14964684ddb6SLionel Sambuc            {
14974684ddb6SLionel Sambuc                if (__nd->__left_ != nullptr)
14984684ddb6SLionel Sambuc                    __nd = static_cast<__node_pointer>(__nd->__left_);
14994684ddb6SLionel Sambuc                else
15004684ddb6SLionel Sambuc                {
15014684ddb6SLionel Sambuc                    __parent = static_cast<__node_base_pointer>(__nd);
15024684ddb6SLionel Sambuc                    return __parent->__left_;
15034684ddb6SLionel Sambuc                }
15044684ddb6SLionel Sambuc            }
15054684ddb6SLionel Sambuc        }
15064684ddb6SLionel Sambuc    }
15074684ddb6SLionel Sambuc    __parent = static_cast<__node_base_pointer>(__end_node());
15084684ddb6SLionel Sambuc    return __parent->__left_;
15094684ddb6SLionel Sambuc}
15104684ddb6SLionel Sambuc
15114684ddb6SLionel Sambuc// Find upper_bound place to insert
15124684ddb6SLionel Sambuc// Set __parent to parent of null leaf
15134684ddb6SLionel Sambuc// Return reference to null leaf
15144684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
15154684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
15164684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointer& __parent,
15174684ddb6SLionel Sambuc                                                    const value_type& __v)
15184684ddb6SLionel Sambuc{
15194684ddb6SLionel Sambuc    __node_pointer __nd = __root();
15204684ddb6SLionel Sambuc    if (__nd != nullptr)
15214684ddb6SLionel Sambuc    {
15224684ddb6SLionel Sambuc        while (true)
15234684ddb6SLionel Sambuc        {
15244684ddb6SLionel Sambuc            if (value_comp()(__v, __nd->__value_))
15254684ddb6SLionel Sambuc            {
15264684ddb6SLionel Sambuc                if (__nd->__left_ != nullptr)
15274684ddb6SLionel Sambuc                    __nd = static_cast<__node_pointer>(__nd->__left_);
15284684ddb6SLionel Sambuc                else
15294684ddb6SLionel Sambuc                {
15304684ddb6SLionel Sambuc                    __parent = static_cast<__node_base_pointer>(__nd);
15314684ddb6SLionel Sambuc                    return __parent->__left_;
15324684ddb6SLionel Sambuc                }
15334684ddb6SLionel Sambuc            }
15344684ddb6SLionel Sambuc            else
15354684ddb6SLionel Sambuc            {
15364684ddb6SLionel Sambuc                if (__nd->__right_ != nullptr)
15374684ddb6SLionel Sambuc                    __nd = static_cast<__node_pointer>(__nd->__right_);
15384684ddb6SLionel Sambuc                else
15394684ddb6SLionel Sambuc                {
15404684ddb6SLionel Sambuc                    __parent = static_cast<__node_base_pointer>(__nd);
15414684ddb6SLionel Sambuc                    return __parent->__right_;
15424684ddb6SLionel Sambuc                }
15434684ddb6SLionel Sambuc            }
15444684ddb6SLionel Sambuc        }
15454684ddb6SLionel Sambuc    }
15464684ddb6SLionel Sambuc    __parent = static_cast<__node_base_pointer>(__end_node());
15474684ddb6SLionel Sambuc    return __parent->__left_;
15484684ddb6SLionel Sambuc}
15494684ddb6SLionel Sambuc
15504684ddb6SLionel Sambuc// Find leaf place to insert closest to __hint
15514684ddb6SLionel Sambuc// First check prior to __hint.
15524684ddb6SLionel Sambuc// Next check after __hint.
15534684ddb6SLionel Sambuc// Next do O(log N) search.
15544684ddb6SLionel Sambuc// Set __parent to parent of null leaf
15554684ddb6SLionel Sambuc// Return reference to null leaf
15564684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
15574684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
15584684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
15594684ddb6SLionel Sambuc                                               typename __node_base::pointer& __parent,
15604684ddb6SLionel Sambuc                                               const value_type& __v)
15614684ddb6SLionel Sambuc{
15624684ddb6SLionel Sambuc    if (__hint == end() || !value_comp()(*__hint, __v))  // check before
15634684ddb6SLionel Sambuc    {
15644684ddb6SLionel Sambuc        // __v <= *__hint
15654684ddb6SLionel Sambuc        const_iterator __prior = __hint;
15664684ddb6SLionel Sambuc        if (__prior == begin() || !value_comp()(__v, *--__prior))
15674684ddb6SLionel Sambuc        {
15684684ddb6SLionel Sambuc            // *prev(__hint) <= __v <= *__hint
15694684ddb6SLionel Sambuc            if (__hint.__ptr_->__left_ == nullptr)
15704684ddb6SLionel Sambuc            {
15714684ddb6SLionel Sambuc                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
15724684ddb6SLionel Sambuc                return __parent->__left_;
15734684ddb6SLionel Sambuc            }
15744684ddb6SLionel Sambuc            else
15754684ddb6SLionel Sambuc            {
15764684ddb6SLionel Sambuc                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
15774684ddb6SLionel Sambuc                return __parent->__right_;
15784684ddb6SLionel Sambuc            }
15794684ddb6SLionel Sambuc        }
15804684ddb6SLionel Sambuc        // __v < *prev(__hint)
15814684ddb6SLionel Sambuc        return __find_leaf_high(__parent, __v);
15824684ddb6SLionel Sambuc    }
15834684ddb6SLionel Sambuc    // else __v > *__hint
15844684ddb6SLionel Sambuc    return __find_leaf_low(__parent, __v);
15854684ddb6SLionel Sambuc}
15864684ddb6SLionel Sambuc
15874684ddb6SLionel Sambuc// Find place to insert if __v doesn't exist
15884684ddb6SLionel Sambuc// Set __parent to parent of null leaf
15894684ddb6SLionel Sambuc// Return reference to null leaf
15904684ddb6SLionel Sambuc// If __v exists, set parent to node of __v and return reference to node of __v
15914684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
15924684ddb6SLionel Sambuctemplate <class _Key>
15934684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
15944684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& __parent,
15954684ddb6SLionel Sambuc                                                const _Key& __v)
15964684ddb6SLionel Sambuc{
15974684ddb6SLionel Sambuc    __node_pointer __nd = __root();
15984684ddb6SLionel Sambuc    if (__nd != nullptr)
15994684ddb6SLionel Sambuc    {
16004684ddb6SLionel Sambuc        while (true)
16014684ddb6SLionel Sambuc        {
16024684ddb6SLionel Sambuc            if (value_comp()(__v, __nd->__value_))
16034684ddb6SLionel Sambuc            {
16044684ddb6SLionel Sambuc                if (__nd->__left_ != nullptr)
16054684ddb6SLionel Sambuc                    __nd = static_cast<__node_pointer>(__nd->__left_);
16064684ddb6SLionel Sambuc                else
16074684ddb6SLionel Sambuc                {
16084684ddb6SLionel Sambuc                    __parent = static_cast<__node_base_pointer>(__nd);
16094684ddb6SLionel Sambuc                    return __parent->__left_;
16104684ddb6SLionel Sambuc                }
16114684ddb6SLionel Sambuc            }
16124684ddb6SLionel Sambuc            else if (value_comp()(__nd->__value_, __v))
16134684ddb6SLionel Sambuc            {
16144684ddb6SLionel Sambuc                if (__nd->__right_ != nullptr)
16154684ddb6SLionel Sambuc                    __nd = static_cast<__node_pointer>(__nd->__right_);
16164684ddb6SLionel Sambuc                else
16174684ddb6SLionel Sambuc                {
16184684ddb6SLionel Sambuc                    __parent = static_cast<__node_base_pointer>(__nd);
16194684ddb6SLionel Sambuc                    return __parent->__right_;
16204684ddb6SLionel Sambuc                }
16214684ddb6SLionel Sambuc            }
16224684ddb6SLionel Sambuc            else
16234684ddb6SLionel Sambuc            {
16244684ddb6SLionel Sambuc                __parent = static_cast<__node_base_pointer>(__nd);
16254684ddb6SLionel Sambuc                return __parent;
16264684ddb6SLionel Sambuc            }
16274684ddb6SLionel Sambuc        }
16284684ddb6SLionel Sambuc    }
16294684ddb6SLionel Sambuc    __parent = static_cast<__node_base_pointer>(__end_node());
16304684ddb6SLionel Sambuc    return __parent->__left_;
16314684ddb6SLionel Sambuc}
16324684ddb6SLionel Sambuc
16334684ddb6SLionel Sambuc// Find place to insert if __v doesn't exist
16344684ddb6SLionel Sambuc// First check prior to __hint.
16354684ddb6SLionel Sambuc// Next check after __hint.
16364684ddb6SLionel Sambuc// Next do O(log N) search.
16374684ddb6SLionel Sambuc// Set __parent to parent of null leaf
16384684ddb6SLionel Sambuc// Return reference to null leaf
16394684ddb6SLionel Sambuc// If __v exists, set parent to node of __v and return reference to node of __v
16404684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
16414684ddb6SLionel Sambuctemplate <class _Key>
16424684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
16434684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
16444684ddb6SLionel Sambuc                                                typename __node_base::pointer& __parent,
16454684ddb6SLionel Sambuc                                                const _Key& __v)
16464684ddb6SLionel Sambuc{
16474684ddb6SLionel Sambuc    if (__hint == end() || value_comp()(__v, *__hint))  // check before
16484684ddb6SLionel Sambuc    {
16494684ddb6SLionel Sambuc        // __v < *__hint
16504684ddb6SLionel Sambuc        const_iterator __prior = __hint;
16514684ddb6SLionel Sambuc        if (__prior == begin() || value_comp()(*--__prior, __v))
16524684ddb6SLionel Sambuc        {
16534684ddb6SLionel Sambuc            // *prev(__hint) < __v < *__hint
16544684ddb6SLionel Sambuc            if (__hint.__ptr_->__left_ == nullptr)
16554684ddb6SLionel Sambuc            {
16564684ddb6SLionel Sambuc                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
16574684ddb6SLionel Sambuc                return __parent->__left_;
16584684ddb6SLionel Sambuc            }
16594684ddb6SLionel Sambuc            else
16604684ddb6SLionel Sambuc            {
16614684ddb6SLionel Sambuc                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
16624684ddb6SLionel Sambuc                return __parent->__right_;
16634684ddb6SLionel Sambuc            }
16644684ddb6SLionel Sambuc        }
16654684ddb6SLionel Sambuc        // __v <= *prev(__hint)
16664684ddb6SLionel Sambuc        return __find_equal(__parent, __v);
16674684ddb6SLionel Sambuc    }
16684684ddb6SLionel Sambuc    else if (value_comp()(*__hint, __v))  // check after
16694684ddb6SLionel Sambuc    {
16704684ddb6SLionel Sambuc        // *__hint < __v
16714684ddb6SLionel Sambuc        const_iterator __next = _VSTD::next(__hint);
16724684ddb6SLionel Sambuc        if (__next == end() || value_comp()(__v, *__next))
16734684ddb6SLionel Sambuc        {
16744684ddb6SLionel Sambuc            // *__hint < __v < *_VSTD::next(__hint)
16754684ddb6SLionel Sambuc            if (__hint.__ptr_->__right_ == nullptr)
16764684ddb6SLionel Sambuc            {
16774684ddb6SLionel Sambuc                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
16784684ddb6SLionel Sambuc                return __parent->__right_;
16794684ddb6SLionel Sambuc            }
16804684ddb6SLionel Sambuc            else
16814684ddb6SLionel Sambuc            {
16824684ddb6SLionel Sambuc                __parent = static_cast<__node_base_pointer>(__next.__ptr_);
16834684ddb6SLionel Sambuc                return __parent->__left_;
16844684ddb6SLionel Sambuc            }
16854684ddb6SLionel Sambuc        }
16864684ddb6SLionel Sambuc        // *next(__hint) <= __v
16874684ddb6SLionel Sambuc        return __find_equal(__parent, __v);
16884684ddb6SLionel Sambuc    }
16894684ddb6SLionel Sambuc    // else __v == *__hint
16904684ddb6SLionel Sambuc    __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
16914684ddb6SLionel Sambuc    return __parent;
16924684ddb6SLionel Sambuc}
16934684ddb6SLionel Sambuc
16944684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
16954684ddb6SLionel Sambucvoid
16964684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent,
16974684ddb6SLionel Sambuc                                                    __node_base_pointer& __child,
16984684ddb6SLionel Sambuc                                                    __node_base_pointer __new_node)
16994684ddb6SLionel Sambuc{
17004684ddb6SLionel Sambuc    __new_node->__left_   = nullptr;
17014684ddb6SLionel Sambuc    __new_node->__right_  = nullptr;
17024684ddb6SLionel Sambuc    __new_node->__parent_ = __parent;
17034684ddb6SLionel Sambuc    __child = __new_node;
17044684ddb6SLionel Sambuc    if (__begin_node()->__left_ != nullptr)
17054684ddb6SLionel Sambuc        __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_);
17064684ddb6SLionel Sambuc    __tree_balance_after_insert(__end_node()->__left_, __child);
17074684ddb6SLionel Sambuc    ++size();
17084684ddb6SLionel Sambuc}
17094684ddb6SLionel Sambuc
17104684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
17114684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_VARIADICS
17124684ddb6SLionel Sambuc
17134684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
17144684ddb6SLionel Sambuctemplate <class ..._Args>
17154684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_holder
17164684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
17174684ddb6SLionel Sambuc{
17184684ddb6SLionel Sambuc    __node_allocator& __na = __node_alloc();
17194684ddb6SLionel Sambuc    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
17204684ddb6SLionel Sambuc    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);
17214684ddb6SLionel Sambuc    __h.get_deleter().__value_constructed = true;
17224684ddb6SLionel Sambuc    return __h;
17234684ddb6SLionel Sambuc}
17244684ddb6SLionel Sambuc
17254684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
17264684ddb6SLionel Sambuctemplate <class... _Args>
17274684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
17284684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args)
17294684ddb6SLionel Sambuc{
17304684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
17314684ddb6SLionel Sambuc    __node_base_pointer __parent;
17324684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
17334684ddb6SLionel Sambuc    __node_pointer __r = static_cast<__node_pointer>(__child);
17344684ddb6SLionel Sambuc    bool __inserted = false;
17354684ddb6SLionel Sambuc    if (__child == nullptr)
17364684ddb6SLionel Sambuc    {
17374684ddb6SLionel Sambuc        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
17384684ddb6SLionel Sambuc        __r = __h.release();
17394684ddb6SLionel Sambuc        __inserted = true;
17404684ddb6SLionel Sambuc    }
17414684ddb6SLionel Sambuc    return pair<iterator, bool>(iterator(__r), __inserted);
17424684ddb6SLionel Sambuc}
17434684ddb6SLionel Sambuc
17444684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
17454684ddb6SLionel Sambuctemplate <class... _Args>
17464684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
17474684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args)
17484684ddb6SLionel Sambuc{
17494684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
17504684ddb6SLionel Sambuc    __node_base_pointer __parent;
17514684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_);
17524684ddb6SLionel Sambuc    __node_pointer __r = static_cast<__node_pointer>(__child);
17534684ddb6SLionel Sambuc    if (__child == nullptr)
17544684ddb6SLionel Sambuc    {
17554684ddb6SLionel Sambuc        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
17564684ddb6SLionel Sambuc        __r = __h.release();
17574684ddb6SLionel Sambuc    }
17584684ddb6SLionel Sambuc    return iterator(__r);
17594684ddb6SLionel Sambuc}
17604684ddb6SLionel Sambuc
17614684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
17624684ddb6SLionel Sambuctemplate <class... _Args>
17634684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
17644684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
17654684ddb6SLionel Sambuc{
17664684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
17674684ddb6SLionel Sambuc    __node_base_pointer __parent;
17684684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
17694684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
17704684ddb6SLionel Sambuc    return iterator(static_cast<__node_pointer>(__h.release()));
17714684ddb6SLionel Sambuc}
17724684ddb6SLionel Sambuc
17734684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
17744684ddb6SLionel Sambuctemplate <class... _Args>
17754684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
17764684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
17774684ddb6SLionel Sambuc                                                        _Args&&... __args)
17784684ddb6SLionel Sambuc{
17794684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
17804684ddb6SLionel Sambuc    __node_base_pointer __parent;
17814684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
17824684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
17834684ddb6SLionel Sambuc    return iterator(static_cast<__node_pointer>(__h.release()));
17844684ddb6SLionel Sambuc}
17854684ddb6SLionel Sambuc
17864684ddb6SLionel Sambuc#endif  // _LIBCPP_HAS_NO_VARIADICS
17874684ddb6SLionel Sambuc
17884684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
17894684ddb6SLionel Sambuctemplate <class _Vp>
17904684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
17914684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_unique(_Vp&& __v)
17924684ddb6SLionel Sambuc{
17934684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
17944684ddb6SLionel Sambuc    pair<iterator, bool> __r = __node_insert_unique(__h.get());
17954684ddb6SLionel Sambuc    if (__r.second)
17964684ddb6SLionel Sambuc        __h.release();
17974684ddb6SLionel Sambuc    return __r;
17984684ddb6SLionel Sambuc}
17994684ddb6SLionel Sambuc
18004684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18014684ddb6SLionel Sambuctemplate <class _Vp>
18024684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
18034684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _Vp&& __v)
18044684ddb6SLionel Sambuc{
18054684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
18064684ddb6SLionel Sambuc    iterator __r = __node_insert_unique(__p, __h.get());
18074684ddb6SLionel Sambuc    if (__r.__ptr_ == __h.get())
18084684ddb6SLionel Sambuc        __h.release();
18094684ddb6SLionel Sambuc    return __r;
18104684ddb6SLionel Sambuc}
18114684ddb6SLionel Sambuc
18124684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18134684ddb6SLionel Sambuctemplate <class _Vp>
18144684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
18154684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_multi(_Vp&& __v)
18164684ddb6SLionel Sambuc{
18174684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
18184684ddb6SLionel Sambuc    __node_base_pointer __parent;
18194684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
18204684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
18214684ddb6SLionel Sambuc    return iterator(__h.release());
18224684ddb6SLionel Sambuc}
18234684ddb6SLionel Sambuc
18244684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18254684ddb6SLionel Sambuctemplate <class _Vp>
18264684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
18274684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _Vp&& __v)
18284684ddb6SLionel Sambuc{
18294684ddb6SLionel Sambuc    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
18304684ddb6SLionel Sambuc    __node_base_pointer __parent;
18314684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
18324684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
18334684ddb6SLionel Sambuc    return iterator(__h.release());
18344684ddb6SLionel Sambuc}
18354684ddb6SLionel Sambuc
18364684ddb6SLionel Sambuc#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
18374684ddb6SLionel Sambuc
18384684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18394684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_holder
18404684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v)
18414684ddb6SLionel Sambuc{
18424684ddb6SLionel Sambuc    __node_allocator& __na = __node_alloc();
18434684ddb6SLionel Sambuc    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
18444684ddb6SLionel Sambuc    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
18454684ddb6SLionel Sambuc    __h.get_deleter().__value_constructed = true;
1846*0a6a1f1dSLionel Sambuc    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
18474684ddb6SLionel Sambuc}
18484684ddb6SLionel Sambuc
18494684ddb6SLionel Sambuc#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
18504684ddb6SLionel Sambuc
18514684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18524684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
18534684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v)
18544684ddb6SLionel Sambuc{
18554684ddb6SLionel Sambuc    __node_base_pointer __parent;
18564684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_equal(__parent, __v);
18574684ddb6SLionel Sambuc    __node_pointer __r = static_cast<__node_pointer>(__child);
18584684ddb6SLionel Sambuc    bool __inserted = false;
18594684ddb6SLionel Sambuc    if (__child == nullptr)
18604684ddb6SLionel Sambuc    {
18614684ddb6SLionel Sambuc        __node_holder __h = __construct_node(__v);
18624684ddb6SLionel Sambuc        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
18634684ddb6SLionel Sambuc        __r = __h.release();
18644684ddb6SLionel Sambuc        __inserted = true;
18654684ddb6SLionel Sambuc    }
18664684ddb6SLionel Sambuc    return pair<iterator, bool>(iterator(__r), __inserted);
18674684ddb6SLionel Sambuc}
18684684ddb6SLionel Sambuc
18694684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18704684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
18714684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v)
18724684ddb6SLionel Sambuc{
18734684ddb6SLionel Sambuc    __node_base_pointer __parent;
18744684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_equal(__p, __parent, __v);
18754684ddb6SLionel Sambuc    __node_pointer __r = static_cast<__node_pointer>(__child);
18764684ddb6SLionel Sambuc    if (__child == nullptr)
18774684ddb6SLionel Sambuc    {
18784684ddb6SLionel Sambuc        __node_holder __h = __construct_node(__v);
18794684ddb6SLionel Sambuc        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
18804684ddb6SLionel Sambuc        __r = __h.release();
18814684ddb6SLionel Sambuc    }
18824684ddb6SLionel Sambuc    return iterator(__r);
18834684ddb6SLionel Sambuc}
18844684ddb6SLionel Sambuc
18854684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18864684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
18874684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v)
18884684ddb6SLionel Sambuc{
18894684ddb6SLionel Sambuc    __node_base_pointer __parent;
18904684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf_high(__parent, __v);
18914684ddb6SLionel Sambuc    __node_holder __h = __construct_node(__v);
18924684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
18934684ddb6SLionel Sambuc    return iterator(__h.release());
18944684ddb6SLionel Sambuc}
18954684ddb6SLionel Sambuc
18964684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
18974684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
18984684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v)
18994684ddb6SLionel Sambuc{
19004684ddb6SLionel Sambuc    __node_base_pointer __parent;
19014684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf(__p, __parent, __v);
19024684ddb6SLionel Sambuc    __node_holder __h = __construct_node(__v);
19034684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
19044684ddb6SLionel Sambuc    return iterator(__h.release());
19054684ddb6SLionel Sambuc}
19064684ddb6SLionel Sambuc
19074684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
19084684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
19094684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
19104684ddb6SLionel Sambuc{
19114684ddb6SLionel Sambuc    __node_base_pointer __parent;
19124684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
19134684ddb6SLionel Sambuc    __node_pointer __r = static_cast<__node_pointer>(__child);
19144684ddb6SLionel Sambuc    bool __inserted = false;
19154684ddb6SLionel Sambuc    if (__child == nullptr)
19164684ddb6SLionel Sambuc    {
19174684ddb6SLionel Sambuc        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
19184684ddb6SLionel Sambuc        __r = __nd;
19194684ddb6SLionel Sambuc        __inserted = true;
19204684ddb6SLionel Sambuc    }
19214684ddb6SLionel Sambuc    return pair<iterator, bool>(iterator(__r), __inserted);
19224684ddb6SLionel Sambuc}
19234684ddb6SLionel Sambuc
19244684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
19254684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
19264684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
19274684ddb6SLionel Sambuc                                                        __node_pointer __nd)
19284684ddb6SLionel Sambuc{
19294684ddb6SLionel Sambuc    __node_base_pointer __parent;
19304684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
19314684ddb6SLionel Sambuc    __node_pointer __r = static_cast<__node_pointer>(__child);
19324684ddb6SLionel Sambuc    if (__child == nullptr)
19334684ddb6SLionel Sambuc    {
19344684ddb6SLionel Sambuc        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
19354684ddb6SLionel Sambuc        __r = __nd;
19364684ddb6SLionel Sambuc    }
19374684ddb6SLionel Sambuc    return iterator(__r);
19384684ddb6SLionel Sambuc}
19394684ddb6SLionel Sambuc
19404684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
19414684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
19424684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
19434684ddb6SLionel Sambuc{
19444684ddb6SLionel Sambuc    __node_base_pointer __parent;
19454684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
19464684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
19474684ddb6SLionel Sambuc    return iterator(__nd);
19484684ddb6SLionel Sambuc}
19494684ddb6SLionel Sambuc
19504684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
19514684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
19524684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
19534684ddb6SLionel Sambuc                                                       __node_pointer __nd)
19544684ddb6SLionel Sambuc{
19554684ddb6SLionel Sambuc    __node_base_pointer __parent;
19564684ddb6SLionel Sambuc    __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
19574684ddb6SLionel Sambuc    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
19584684ddb6SLionel Sambuc    return iterator(__nd);
19594684ddb6SLionel Sambuc}
19604684ddb6SLionel Sambuc
19614684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
19624684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
19634684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
19644684ddb6SLionel Sambuc{
19654684ddb6SLionel Sambuc    __node_pointer __np = __p.__ptr_;
19664684ddb6SLionel Sambuc    iterator __r(__np);
19674684ddb6SLionel Sambuc    ++__r;
19684684ddb6SLionel Sambuc    if (__begin_node() == __np)
19694684ddb6SLionel Sambuc        __begin_node() = __r.__ptr_;
19704684ddb6SLionel Sambuc    --size();
19714684ddb6SLionel Sambuc    __node_allocator& __na = __node_alloc();
19724684ddb6SLionel Sambuc    __tree_remove(__end_node()->__left_,
19734684ddb6SLionel Sambuc                  static_cast<__node_base_pointer>(__np));
1974*0a6a1f1dSLionel Sambuc    __node_traits::destroy(__na, const_cast<value_type*>(_VSTD::addressof(*__p)));
19754684ddb6SLionel Sambuc    __node_traits::deallocate(__na, __np, 1);
19764684ddb6SLionel Sambuc    return __r;
19774684ddb6SLionel Sambuc}
19784684ddb6SLionel Sambuc
19794684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
19804684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
19814684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
19824684ddb6SLionel Sambuc{
19834684ddb6SLionel Sambuc    while (__f != __l)
19844684ddb6SLionel Sambuc        __f = erase(__f);
19854684ddb6SLionel Sambuc    return iterator(__l.__ptr_);
19864684ddb6SLionel Sambuc}
19874684ddb6SLionel Sambuc
19884684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
19894684ddb6SLionel Sambuctemplate <class _Key>
19904684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::size_type
19914684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
19924684ddb6SLionel Sambuc{
19934684ddb6SLionel Sambuc    iterator __i = find(__k);
19944684ddb6SLionel Sambuc    if (__i == end())
19954684ddb6SLionel Sambuc        return 0;
19964684ddb6SLionel Sambuc    erase(__i);
19974684ddb6SLionel Sambuc    return 1;
19984684ddb6SLionel Sambuc}
19994684ddb6SLionel Sambuc
20004684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
20014684ddb6SLionel Sambuctemplate <class _Key>
20024684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::size_type
20034684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
20044684ddb6SLionel Sambuc{
20054684ddb6SLionel Sambuc    pair<iterator, iterator> __p = __equal_range_multi(__k);
20064684ddb6SLionel Sambuc    size_type __r = 0;
20074684ddb6SLionel Sambuc    for (; __p.first != __p.second; ++__r)
20084684ddb6SLionel Sambuc        __p.first = erase(__p.first);
20094684ddb6SLionel Sambuc    return __r;
20104684ddb6SLionel Sambuc}
20114684ddb6SLionel Sambuc
20124684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
20134684ddb6SLionel Sambuctemplate <class _Key>
20144684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
20154684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
20164684ddb6SLionel Sambuc{
20174684ddb6SLionel Sambuc    iterator __p = __lower_bound(__v, __root(), __end_node());
20184684ddb6SLionel Sambuc    if (__p != end() && !value_comp()(__v, *__p))
20194684ddb6SLionel Sambuc        return __p;
20204684ddb6SLionel Sambuc    return end();
20214684ddb6SLionel Sambuc}
20224684ddb6SLionel Sambuc
20234684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
20244684ddb6SLionel Sambuctemplate <class _Key>
20254684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::const_iterator
20264684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
20274684ddb6SLionel Sambuc{
20284684ddb6SLionel Sambuc    const_iterator __p = __lower_bound(__v, __root(), __end_node());
20294684ddb6SLionel Sambuc    if (__p != end() && !value_comp()(__v, *__p))
20304684ddb6SLionel Sambuc        return __p;
20314684ddb6SLionel Sambuc    return end();
20324684ddb6SLionel Sambuc}
20334684ddb6SLionel Sambuc
20344684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
20354684ddb6SLionel Sambuctemplate <class _Key>
20364684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::size_type
20374684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
20384684ddb6SLionel Sambuc{
20394684ddb6SLionel Sambuc    __node_const_pointer __result = __end_node();
20404684ddb6SLionel Sambuc    __node_const_pointer __rt = __root();
20414684ddb6SLionel Sambuc    while (__rt != nullptr)
20424684ddb6SLionel Sambuc    {
20434684ddb6SLionel Sambuc        if (value_comp()(__k, __rt->__value_))
20444684ddb6SLionel Sambuc        {
20454684ddb6SLionel Sambuc            __result = __rt;
20464684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__left_);
20474684ddb6SLionel Sambuc        }
20484684ddb6SLionel Sambuc        else if (value_comp()(__rt->__value_, __k))
20494684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__right_);
20504684ddb6SLionel Sambuc        else
20514684ddb6SLionel Sambuc            return 1;
20524684ddb6SLionel Sambuc    }
20534684ddb6SLionel Sambuc    return 0;
20544684ddb6SLionel Sambuc}
20554684ddb6SLionel Sambuc
20564684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
20574684ddb6SLionel Sambuctemplate <class _Key>
20584684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::size_type
20594684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
20604684ddb6SLionel Sambuc{
20614684ddb6SLionel Sambuc    __node_const_pointer __result = __end_node();
20624684ddb6SLionel Sambuc    __node_const_pointer __rt = __root();
20634684ddb6SLionel Sambuc    while (__rt != nullptr)
20644684ddb6SLionel Sambuc    {
20654684ddb6SLionel Sambuc        if (value_comp()(__k, __rt->__value_))
20664684ddb6SLionel Sambuc        {
20674684ddb6SLionel Sambuc            __result = __rt;
20684684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__left_);
20694684ddb6SLionel Sambuc        }
20704684ddb6SLionel Sambuc        else if (value_comp()(__rt->__value_, __k))
20714684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__right_);
20724684ddb6SLionel Sambuc        else
20734684ddb6SLionel Sambuc            return _VSTD::distance(
20744684ddb6SLionel Sambuc                __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
20754684ddb6SLionel Sambuc                __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)
20764684ddb6SLionel Sambuc            );
20774684ddb6SLionel Sambuc    }
20784684ddb6SLionel Sambuc    return 0;
20794684ddb6SLionel Sambuc}
20804684ddb6SLionel Sambuc
20814684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
20824684ddb6SLionel Sambuctemplate <class _Key>
20834684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
20844684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
20854684ddb6SLionel Sambuc                                                 __node_pointer __root,
20864684ddb6SLionel Sambuc                                                 __node_pointer __result)
20874684ddb6SLionel Sambuc{
20884684ddb6SLionel Sambuc    while (__root != nullptr)
20894684ddb6SLionel Sambuc    {
20904684ddb6SLionel Sambuc        if (!value_comp()(__root->__value_, __v))
20914684ddb6SLionel Sambuc        {
20924684ddb6SLionel Sambuc            __result = __root;
20934684ddb6SLionel Sambuc            __root = static_cast<__node_pointer>(__root->__left_);
20944684ddb6SLionel Sambuc        }
20954684ddb6SLionel Sambuc        else
20964684ddb6SLionel Sambuc            __root = static_cast<__node_pointer>(__root->__right_);
20974684ddb6SLionel Sambuc    }
20984684ddb6SLionel Sambuc    return iterator(__result);
20994684ddb6SLionel Sambuc}
21004684ddb6SLionel Sambuc
21014684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
21024684ddb6SLionel Sambuctemplate <class _Key>
21034684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::const_iterator
21044684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
21054684ddb6SLionel Sambuc                                                 __node_const_pointer __root,
21064684ddb6SLionel Sambuc                                                 __node_const_pointer __result) const
21074684ddb6SLionel Sambuc{
21084684ddb6SLionel Sambuc    while (__root != nullptr)
21094684ddb6SLionel Sambuc    {
21104684ddb6SLionel Sambuc        if (!value_comp()(__root->__value_, __v))
21114684ddb6SLionel Sambuc        {
21124684ddb6SLionel Sambuc            __result = __root;
21134684ddb6SLionel Sambuc            __root = static_cast<__node_const_pointer>(__root->__left_);
21144684ddb6SLionel Sambuc        }
21154684ddb6SLionel Sambuc        else
21164684ddb6SLionel Sambuc            __root = static_cast<__node_const_pointer>(__root->__right_);
21174684ddb6SLionel Sambuc    }
21184684ddb6SLionel Sambuc    return const_iterator(__result);
21194684ddb6SLionel Sambuc}
21204684ddb6SLionel Sambuc
21214684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
21224684ddb6SLionel Sambuctemplate <class _Key>
21234684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::iterator
21244684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
21254684ddb6SLionel Sambuc                                                 __node_pointer __root,
21264684ddb6SLionel Sambuc                                                 __node_pointer __result)
21274684ddb6SLionel Sambuc{
21284684ddb6SLionel Sambuc    while (__root != nullptr)
21294684ddb6SLionel Sambuc    {
21304684ddb6SLionel Sambuc        if (value_comp()(__v, __root->__value_))
21314684ddb6SLionel Sambuc        {
21324684ddb6SLionel Sambuc            __result = __root;
21334684ddb6SLionel Sambuc            __root = static_cast<__node_pointer>(__root->__left_);
21344684ddb6SLionel Sambuc        }
21354684ddb6SLionel Sambuc        else
21364684ddb6SLionel Sambuc            __root = static_cast<__node_pointer>(__root->__right_);
21374684ddb6SLionel Sambuc    }
21384684ddb6SLionel Sambuc    return iterator(__result);
21394684ddb6SLionel Sambuc}
21404684ddb6SLionel Sambuc
21414684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
21424684ddb6SLionel Sambuctemplate <class _Key>
21434684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::const_iterator
21444684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
21454684ddb6SLionel Sambuc                                                 __node_const_pointer __root,
21464684ddb6SLionel Sambuc                                                 __node_const_pointer __result) const
21474684ddb6SLionel Sambuc{
21484684ddb6SLionel Sambuc    while (__root != nullptr)
21494684ddb6SLionel Sambuc    {
21504684ddb6SLionel Sambuc        if (value_comp()(__v, __root->__value_))
21514684ddb6SLionel Sambuc        {
21524684ddb6SLionel Sambuc            __result = __root;
21534684ddb6SLionel Sambuc            __root = static_cast<__node_const_pointer>(__root->__left_);
21544684ddb6SLionel Sambuc        }
21554684ddb6SLionel Sambuc        else
21564684ddb6SLionel Sambuc            __root = static_cast<__node_const_pointer>(__root->__right_);
21574684ddb6SLionel Sambuc    }
21584684ddb6SLionel Sambuc    return const_iterator(__result);
21594684ddb6SLionel Sambuc}
21604684ddb6SLionel Sambuc
21614684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
21624684ddb6SLionel Sambuctemplate <class _Key>
21634684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
21644684ddb6SLionel Sambuc     typename __tree<_Tp, _Compare, _Allocator>::iterator>
21654684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
21664684ddb6SLionel Sambuc{
21674684ddb6SLionel Sambuc    typedef pair<iterator, iterator> _Pp;
21684684ddb6SLionel Sambuc    __node_pointer __result = __end_node();
21694684ddb6SLionel Sambuc    __node_pointer __rt = __root();
21704684ddb6SLionel Sambuc    while (__rt != nullptr)
21714684ddb6SLionel Sambuc    {
21724684ddb6SLionel Sambuc        if (value_comp()(__k, __rt->__value_))
21734684ddb6SLionel Sambuc        {
21744684ddb6SLionel Sambuc            __result = __rt;
21754684ddb6SLionel Sambuc            __rt = static_cast<__node_pointer>(__rt->__left_);
21764684ddb6SLionel Sambuc        }
21774684ddb6SLionel Sambuc        else if (value_comp()(__rt->__value_, __k))
21784684ddb6SLionel Sambuc            __rt = static_cast<__node_pointer>(__rt->__right_);
21794684ddb6SLionel Sambuc        else
21804684ddb6SLionel Sambuc            return _Pp(iterator(__rt),
21814684ddb6SLionel Sambuc                      iterator(
21824684ddb6SLionel Sambuc                          __rt->__right_ != nullptr ?
21834684ddb6SLionel Sambuc                              static_cast<__node_pointer>(__tree_min(__rt->__right_))
21844684ddb6SLionel Sambuc                            : __result));
21854684ddb6SLionel Sambuc    }
21864684ddb6SLionel Sambuc    return _Pp(iterator(__result), iterator(__result));
21874684ddb6SLionel Sambuc}
21884684ddb6SLionel Sambuc
21894684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
21904684ddb6SLionel Sambuctemplate <class _Key>
21914684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
21924684ddb6SLionel Sambuc     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
21934684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
21944684ddb6SLionel Sambuc{
21954684ddb6SLionel Sambuc    typedef pair<const_iterator, const_iterator> _Pp;
21964684ddb6SLionel Sambuc    __node_const_pointer __result = __end_node();
21974684ddb6SLionel Sambuc    __node_const_pointer __rt = __root();
21984684ddb6SLionel Sambuc    while (__rt != nullptr)
21994684ddb6SLionel Sambuc    {
22004684ddb6SLionel Sambuc        if (value_comp()(__k, __rt->__value_))
22014684ddb6SLionel Sambuc        {
22024684ddb6SLionel Sambuc            __result = __rt;
22034684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__left_);
22044684ddb6SLionel Sambuc        }
22054684ddb6SLionel Sambuc        else if (value_comp()(__rt->__value_, __k))
22064684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__right_);
22074684ddb6SLionel Sambuc        else
22084684ddb6SLionel Sambuc            return _Pp(const_iterator(__rt),
22094684ddb6SLionel Sambuc                      const_iterator(
22104684ddb6SLionel Sambuc                          __rt->__right_ != nullptr ?
22114684ddb6SLionel Sambuc                              static_cast<__node_const_pointer>(__tree_min(__rt->__right_))
22124684ddb6SLionel Sambuc                            : __result));
22134684ddb6SLionel Sambuc    }
22144684ddb6SLionel Sambuc    return _Pp(const_iterator(__result), const_iterator(__result));
22154684ddb6SLionel Sambuc}
22164684ddb6SLionel Sambuc
22174684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
22184684ddb6SLionel Sambuctemplate <class _Key>
22194684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
22204684ddb6SLionel Sambuc     typename __tree<_Tp, _Compare, _Allocator>::iterator>
22214684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
22224684ddb6SLionel Sambuc{
22234684ddb6SLionel Sambuc    typedef pair<iterator, iterator> _Pp;
22244684ddb6SLionel Sambuc    __node_pointer __result = __end_node();
22254684ddb6SLionel Sambuc    __node_pointer __rt = __root();
22264684ddb6SLionel Sambuc    while (__rt != nullptr)
22274684ddb6SLionel Sambuc    {
22284684ddb6SLionel Sambuc        if (value_comp()(__k, __rt->__value_))
22294684ddb6SLionel Sambuc        {
22304684ddb6SLionel Sambuc            __result = __rt;
22314684ddb6SLionel Sambuc            __rt = static_cast<__node_pointer>(__rt->__left_);
22324684ddb6SLionel Sambuc        }
22334684ddb6SLionel Sambuc        else if (value_comp()(__rt->__value_, __k))
22344684ddb6SLionel Sambuc            __rt = static_cast<__node_pointer>(__rt->__right_);
22354684ddb6SLionel Sambuc        else
22364684ddb6SLionel Sambuc            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
22374684ddb6SLionel Sambuc                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
22384684ddb6SLionel Sambuc    }
22394684ddb6SLionel Sambuc    return _Pp(iterator(__result), iterator(__result));
22404684ddb6SLionel Sambuc}
22414684ddb6SLionel Sambuc
22424684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
22434684ddb6SLionel Sambuctemplate <class _Key>
22444684ddb6SLionel Sambucpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
22454684ddb6SLionel Sambuc     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
22464684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
22474684ddb6SLionel Sambuc{
22484684ddb6SLionel Sambuc    typedef pair<const_iterator, const_iterator> _Pp;
22494684ddb6SLionel Sambuc    __node_const_pointer __result = __end_node();
22504684ddb6SLionel Sambuc    __node_const_pointer __rt = __root();
22514684ddb6SLionel Sambuc    while (__rt != nullptr)
22524684ddb6SLionel Sambuc    {
22534684ddb6SLionel Sambuc        if (value_comp()(__k, __rt->__value_))
22544684ddb6SLionel Sambuc        {
22554684ddb6SLionel Sambuc            __result = __rt;
22564684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__left_);
22574684ddb6SLionel Sambuc        }
22584684ddb6SLionel Sambuc        else if (value_comp()(__rt->__value_, __k))
22594684ddb6SLionel Sambuc            __rt = static_cast<__node_const_pointer>(__rt->__right_);
22604684ddb6SLionel Sambuc        else
22614684ddb6SLionel Sambuc            return _Pp(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
22624684ddb6SLionel Sambuc                      __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result));
22634684ddb6SLionel Sambuc    }
22644684ddb6SLionel Sambuc    return _Pp(const_iterator(__result), const_iterator(__result));
22654684ddb6SLionel Sambuc}
22664684ddb6SLionel Sambuc
22674684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
22684684ddb6SLionel Sambuctypename __tree<_Tp, _Compare, _Allocator>::__node_holder
22694684ddb6SLionel Sambuc__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
22704684ddb6SLionel Sambuc{
22714684ddb6SLionel Sambuc    __node_pointer __np = __p.__ptr_;
22724684ddb6SLionel Sambuc    if (__begin_node() == __np)
22734684ddb6SLionel Sambuc    {
22744684ddb6SLionel Sambuc        if (__np->__right_ != nullptr)
22754684ddb6SLionel Sambuc            __begin_node() = static_cast<__node_pointer>(__np->__right_);
22764684ddb6SLionel Sambuc        else
22774684ddb6SLionel Sambuc            __begin_node() = static_cast<__node_pointer>(__np->__parent_);
22784684ddb6SLionel Sambuc    }
22794684ddb6SLionel Sambuc    --size();
22804684ddb6SLionel Sambuc    __tree_remove(__end_node()->__left_,
22814684ddb6SLionel Sambuc                  static_cast<__node_base_pointer>(__np));
2282*0a6a1f1dSLionel Sambuc    return __node_holder(__np, _Dp(__node_alloc(), true));
22834684ddb6SLionel Sambuc}
22844684ddb6SLionel Sambuc
22854684ddb6SLionel Sambuctemplate <class _Tp, class _Compare, class _Allocator>
22864684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
22874684ddb6SLionel Sambucvoid
22884684ddb6SLionel Sambucswap(__tree<_Tp, _Compare, _Allocator>& __x,
22894684ddb6SLionel Sambuc     __tree<_Tp, _Compare, _Allocator>& __y)
22904684ddb6SLionel Sambuc    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
22914684ddb6SLionel Sambuc{
22924684ddb6SLionel Sambuc    __x.swap(__y);
22934684ddb6SLionel Sambuc}
22944684ddb6SLionel Sambuc
22954684ddb6SLionel Sambuc_LIBCPP_END_NAMESPACE_STD
22964684ddb6SLionel Sambuc
22974684ddb6SLionel Sambuc#endif  // _LIBCPP___TREE
2298