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