1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP___TREE 11*0b57cec5SDimitry Andric#define _LIBCPP___TREE 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric#include <__config> 14*0b57cec5SDimitry Andric#include <iterator> 15*0b57cec5SDimitry Andric#include <memory> 16*0b57cec5SDimitry Andric#include <stdexcept> 17*0b57cec5SDimitry Andric#include <algorithm> 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20*0b57cec5SDimitry Andric#pragma GCC system_header 21*0b57cec5SDimitry Andric#endif 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 24*0b57cec5SDimitry Andric#include <__undef_macros> 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric#if defined(__GNUC__) && !defined(__clang__) // gcc.gnu.org/PR37804 30*0b57cec5SDimitry Andrictemplate <class, class, class, class> class _LIBCPP_TEMPLATE_VIS map; 31*0b57cec5SDimitry Andrictemplate <class, class, class, class> class _LIBCPP_TEMPLATE_VIS multimap; 32*0b57cec5SDimitry Andrictemplate <class, class, class> class _LIBCPP_TEMPLATE_VIS set; 33*0b57cec5SDimitry Andrictemplate <class, class, class> class _LIBCPP_TEMPLATE_VIS multiset; 34*0b57cec5SDimitry Andric#endif 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> class __tree; 37*0b57cec5SDimitry Andrictemplate <class _Tp, class _NodePtr, class _DiffType> 38*0b57cec5SDimitry Andric class _LIBCPP_TEMPLATE_VIS __tree_iterator; 39*0b57cec5SDimitry Andrictemplate <class _Tp, class _ConstNodePtr, class _DiffType> 40*0b57cec5SDimitry Andric class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andrictemplate <class _Pointer> class __tree_end_node; 43*0b57cec5SDimitry Andrictemplate <class _VoidPtr> class __tree_node_base; 44*0b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr> class __tree_node; 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andrictemplate <class _Key, class _Value> 47*0b57cec5SDimitry Andricstruct __value_type; 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andrictemplate <class _Allocator> class __map_node_destructor; 50*0b57cec5SDimitry Andrictemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator; 51*0b57cec5SDimitry Andrictemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric/* 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric_NodePtr algorithms 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry AndricThe algorithms taking _NodePtr are red black tree algorithms. Those 58*0b57cec5SDimitry Andricalgorithms taking a parameter named __root should assume that __root 59*0b57cec5SDimitry Andricpoints to a proper red black tree (unless otherwise specified). 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry AndricEach algorithm herein assumes that __root->__parent_ points to a non-null 62*0b57cec5SDimitry Andricstructure which has a member __left_ which points back to __root. No other 63*0b57cec5SDimitry Andricmember is read or written to at __root->__parent_. 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric__root->__parent_ will be referred to below (in comments only) as end_node. 66*0b57cec5SDimitry Andricend_node->__left_ is an externably accessible lvalue for __root, and can be 67*0b57cec5SDimitry Andricchanged by node insertion and removal (without explicit reference to end_node). 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry AndricAll nodes (with the exception of end_node), even the node referred to as 70*0b57cec5SDimitry Andric__root, have a non-null __parent_ field. 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric*/ 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric// Returns: true if __x is a left child of its parent, else false 75*0b57cec5SDimitry Andric// Precondition: __x != nullptr. 76*0b57cec5SDimitry Andrictemplate <class _NodePtr> 77*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 78*0b57cec5SDimitry Andricbool 79*0b57cec5SDimitry Andric__tree_is_left_child(_NodePtr __x) _NOEXCEPT 80*0b57cec5SDimitry Andric{ 81*0b57cec5SDimitry Andric return __x == __x->__parent_->__left_; 82*0b57cec5SDimitry Andric} 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric// Determines if the subtree rooted at __x is a proper red black subtree. If 85*0b57cec5SDimitry Andric// __x is a proper subtree, returns the black height (null counts as 1). If 86*0b57cec5SDimitry Andric// __x is an improper subtree, returns 0. 87*0b57cec5SDimitry Andrictemplate <class _NodePtr> 88*0b57cec5SDimitry Andricunsigned 89*0b57cec5SDimitry Andric__tree_sub_invariant(_NodePtr __x) 90*0b57cec5SDimitry Andric{ 91*0b57cec5SDimitry Andric if (__x == nullptr) 92*0b57cec5SDimitry Andric return 1; 93*0b57cec5SDimitry Andric // parent consistency checked by caller 94*0b57cec5SDimitry Andric // check __x->__left_ consistency 95*0b57cec5SDimitry Andric if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x) 96*0b57cec5SDimitry Andric return 0; 97*0b57cec5SDimitry Andric // check __x->__right_ consistency 98*0b57cec5SDimitry Andric if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x) 99*0b57cec5SDimitry Andric return 0; 100*0b57cec5SDimitry Andric // check __x->__left_ != __x->__right_ unless both are nullptr 101*0b57cec5SDimitry Andric if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr) 102*0b57cec5SDimitry Andric return 0; 103*0b57cec5SDimitry Andric // If this is red, neither child can be red 104*0b57cec5SDimitry Andric if (!__x->__is_black_) 105*0b57cec5SDimitry Andric { 106*0b57cec5SDimitry Andric if (__x->__left_ && !__x->__left_->__is_black_) 107*0b57cec5SDimitry Andric return 0; 108*0b57cec5SDimitry Andric if (__x->__right_ && !__x->__right_->__is_black_) 109*0b57cec5SDimitry Andric return 0; 110*0b57cec5SDimitry Andric } 111*0b57cec5SDimitry Andric unsigned __h = __tree_sub_invariant(__x->__left_); 112*0b57cec5SDimitry Andric if (__h == 0) 113*0b57cec5SDimitry Andric return 0; // invalid left subtree 114*0b57cec5SDimitry Andric if (__h != __tree_sub_invariant(__x->__right_)) 115*0b57cec5SDimitry Andric return 0; // invalid or different height right subtree 116*0b57cec5SDimitry Andric return __h + __x->__is_black_; // return black height of this node 117*0b57cec5SDimitry Andric} 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric// Determines if the red black tree rooted at __root is a proper red black tree. 120*0b57cec5SDimitry Andric// __root == nullptr is a proper tree. Returns true is __root is a proper 121*0b57cec5SDimitry Andric// red black tree, else returns false. 122*0b57cec5SDimitry Andrictemplate <class _NodePtr> 123*0b57cec5SDimitry Andricbool 124*0b57cec5SDimitry Andric__tree_invariant(_NodePtr __root) 125*0b57cec5SDimitry Andric{ 126*0b57cec5SDimitry Andric if (__root == nullptr) 127*0b57cec5SDimitry Andric return true; 128*0b57cec5SDimitry Andric // check __x->__parent_ consistency 129*0b57cec5SDimitry Andric if (__root->__parent_ == nullptr) 130*0b57cec5SDimitry Andric return false; 131*0b57cec5SDimitry Andric if (!__tree_is_left_child(__root)) 132*0b57cec5SDimitry Andric return false; 133*0b57cec5SDimitry Andric // root must be black 134*0b57cec5SDimitry Andric if (!__root->__is_black_) 135*0b57cec5SDimitry Andric return false; 136*0b57cec5SDimitry Andric // do normal node checks 137*0b57cec5SDimitry Andric return __tree_sub_invariant(__root) != 0; 138*0b57cec5SDimitry Andric} 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric// Returns: pointer to the left-most node under __x. 141*0b57cec5SDimitry Andric// Precondition: __x != nullptr. 142*0b57cec5SDimitry Andrictemplate <class _NodePtr> 143*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 144*0b57cec5SDimitry Andric_NodePtr 145*0b57cec5SDimitry Andric__tree_min(_NodePtr __x) _NOEXCEPT 146*0b57cec5SDimitry Andric{ 147*0b57cec5SDimitry Andric while (__x->__left_ != nullptr) 148*0b57cec5SDimitry Andric __x = __x->__left_; 149*0b57cec5SDimitry Andric return __x; 150*0b57cec5SDimitry Andric} 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andric// Returns: pointer to the right-most node under __x. 153*0b57cec5SDimitry Andric// Precondition: __x != nullptr. 154*0b57cec5SDimitry Andrictemplate <class _NodePtr> 155*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 156*0b57cec5SDimitry Andric_NodePtr 157*0b57cec5SDimitry Andric__tree_max(_NodePtr __x) _NOEXCEPT 158*0b57cec5SDimitry Andric{ 159*0b57cec5SDimitry Andric while (__x->__right_ != nullptr) 160*0b57cec5SDimitry Andric __x = __x->__right_; 161*0b57cec5SDimitry Andric return __x; 162*0b57cec5SDimitry Andric} 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric// Returns: pointer to the next in-order node after __x. 165*0b57cec5SDimitry Andric// Precondition: __x != nullptr. 166*0b57cec5SDimitry Andrictemplate <class _NodePtr> 167*0b57cec5SDimitry Andric_NodePtr 168*0b57cec5SDimitry Andric__tree_next(_NodePtr __x) _NOEXCEPT 169*0b57cec5SDimitry Andric{ 170*0b57cec5SDimitry Andric if (__x->__right_ != nullptr) 171*0b57cec5SDimitry Andric return __tree_min(__x->__right_); 172*0b57cec5SDimitry Andric while (!__tree_is_left_child(__x)) 173*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 174*0b57cec5SDimitry Andric return __x->__parent_unsafe(); 175*0b57cec5SDimitry Andric} 176*0b57cec5SDimitry Andric 177*0b57cec5SDimitry Andrictemplate <class _EndNodePtr, class _NodePtr> 178*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 179*0b57cec5SDimitry Andric_EndNodePtr 180*0b57cec5SDimitry Andric__tree_next_iter(_NodePtr __x) _NOEXCEPT 181*0b57cec5SDimitry Andric{ 182*0b57cec5SDimitry Andric if (__x->__right_ != nullptr) 183*0b57cec5SDimitry Andric return static_cast<_EndNodePtr>(__tree_min(__x->__right_)); 184*0b57cec5SDimitry Andric while (!__tree_is_left_child(__x)) 185*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 186*0b57cec5SDimitry Andric return static_cast<_EndNodePtr>(__x->__parent_); 187*0b57cec5SDimitry Andric} 188*0b57cec5SDimitry Andric 189*0b57cec5SDimitry Andric// Returns: pointer to the previous in-order node before __x. 190*0b57cec5SDimitry Andric// Precondition: __x != nullptr. 191*0b57cec5SDimitry Andric// Note: __x may be the end node. 192*0b57cec5SDimitry Andrictemplate <class _NodePtr, class _EndNodePtr> 193*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 194*0b57cec5SDimitry Andric_NodePtr 195*0b57cec5SDimitry Andric__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT 196*0b57cec5SDimitry Andric{ 197*0b57cec5SDimitry Andric if (__x->__left_ != nullptr) 198*0b57cec5SDimitry Andric return __tree_max(__x->__left_); 199*0b57cec5SDimitry Andric _NodePtr __xx = static_cast<_NodePtr>(__x); 200*0b57cec5SDimitry Andric while (__tree_is_left_child(__xx)) 201*0b57cec5SDimitry Andric __xx = __xx->__parent_unsafe(); 202*0b57cec5SDimitry Andric return __xx->__parent_unsafe(); 203*0b57cec5SDimitry Andric} 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric// Returns: pointer to a node which has no children 206*0b57cec5SDimitry Andric// Precondition: __x != nullptr. 207*0b57cec5SDimitry Andrictemplate <class _NodePtr> 208*0b57cec5SDimitry Andric_NodePtr 209*0b57cec5SDimitry Andric__tree_leaf(_NodePtr __x) _NOEXCEPT 210*0b57cec5SDimitry Andric{ 211*0b57cec5SDimitry Andric while (true) 212*0b57cec5SDimitry Andric { 213*0b57cec5SDimitry Andric if (__x->__left_ != nullptr) 214*0b57cec5SDimitry Andric { 215*0b57cec5SDimitry Andric __x = __x->__left_; 216*0b57cec5SDimitry Andric continue; 217*0b57cec5SDimitry Andric } 218*0b57cec5SDimitry Andric if (__x->__right_ != nullptr) 219*0b57cec5SDimitry Andric { 220*0b57cec5SDimitry Andric __x = __x->__right_; 221*0b57cec5SDimitry Andric continue; 222*0b57cec5SDimitry Andric } 223*0b57cec5SDimitry Andric break; 224*0b57cec5SDimitry Andric } 225*0b57cec5SDimitry Andric return __x; 226*0b57cec5SDimitry Andric} 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric// Effects: Makes __x->__right_ the subtree root with __x as its left child 229*0b57cec5SDimitry Andric// while preserving in-order order. 230*0b57cec5SDimitry Andric// Precondition: __x->__right_ != nullptr 231*0b57cec5SDimitry Andrictemplate <class _NodePtr> 232*0b57cec5SDimitry Andricvoid 233*0b57cec5SDimitry Andric__tree_left_rotate(_NodePtr __x) _NOEXCEPT 234*0b57cec5SDimitry Andric{ 235*0b57cec5SDimitry Andric _NodePtr __y = __x->__right_; 236*0b57cec5SDimitry Andric __x->__right_ = __y->__left_; 237*0b57cec5SDimitry Andric if (__x->__right_ != nullptr) 238*0b57cec5SDimitry Andric __x->__right_->__set_parent(__x); 239*0b57cec5SDimitry Andric __y->__parent_ = __x->__parent_; 240*0b57cec5SDimitry Andric if (__tree_is_left_child(__x)) 241*0b57cec5SDimitry Andric __x->__parent_->__left_ = __y; 242*0b57cec5SDimitry Andric else 243*0b57cec5SDimitry Andric __x->__parent_unsafe()->__right_ = __y; 244*0b57cec5SDimitry Andric __y->__left_ = __x; 245*0b57cec5SDimitry Andric __x->__set_parent(__y); 246*0b57cec5SDimitry Andric} 247*0b57cec5SDimitry Andric 248*0b57cec5SDimitry Andric// Effects: Makes __x->__left_ the subtree root with __x as its right child 249*0b57cec5SDimitry Andric// while preserving in-order order. 250*0b57cec5SDimitry Andric// Precondition: __x->__left_ != nullptr 251*0b57cec5SDimitry Andrictemplate <class _NodePtr> 252*0b57cec5SDimitry Andricvoid 253*0b57cec5SDimitry Andric__tree_right_rotate(_NodePtr __x) _NOEXCEPT 254*0b57cec5SDimitry Andric{ 255*0b57cec5SDimitry Andric _NodePtr __y = __x->__left_; 256*0b57cec5SDimitry Andric __x->__left_ = __y->__right_; 257*0b57cec5SDimitry Andric if (__x->__left_ != nullptr) 258*0b57cec5SDimitry Andric __x->__left_->__set_parent(__x); 259*0b57cec5SDimitry Andric __y->__parent_ = __x->__parent_; 260*0b57cec5SDimitry Andric if (__tree_is_left_child(__x)) 261*0b57cec5SDimitry Andric __x->__parent_->__left_ = __y; 262*0b57cec5SDimitry Andric else 263*0b57cec5SDimitry Andric __x->__parent_unsafe()->__right_ = __y; 264*0b57cec5SDimitry Andric __y->__right_ = __x; 265*0b57cec5SDimitry Andric __x->__set_parent(__y); 266*0b57cec5SDimitry Andric} 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric// Effects: Rebalances __root after attaching __x to a leaf. 269*0b57cec5SDimitry Andric// Precondition: __root != nulptr && __x != nullptr. 270*0b57cec5SDimitry Andric// __x has no children. 271*0b57cec5SDimitry Andric// __x == __root or == a direct or indirect child of __root. 272*0b57cec5SDimitry Andric// If __x were to be unlinked from __root (setting __root to 273*0b57cec5SDimitry Andric// nullptr if __root == __x), __tree_invariant(__root) == true. 274*0b57cec5SDimitry Andric// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_ 275*0b57cec5SDimitry Andric// may be different than the value passed in as __root. 276*0b57cec5SDimitry Andrictemplate <class _NodePtr> 277*0b57cec5SDimitry Andricvoid 278*0b57cec5SDimitry Andric__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT 279*0b57cec5SDimitry Andric{ 280*0b57cec5SDimitry Andric __x->__is_black_ = __x == __root; 281*0b57cec5SDimitry Andric while (__x != __root && !__x->__parent_unsafe()->__is_black_) 282*0b57cec5SDimitry Andric { 283*0b57cec5SDimitry Andric // __x->__parent_ != __root because __x->__parent_->__is_black == false 284*0b57cec5SDimitry Andric if (__tree_is_left_child(__x->__parent_unsafe())) 285*0b57cec5SDimitry Andric { 286*0b57cec5SDimitry Andric _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_; 287*0b57cec5SDimitry Andric if (__y != nullptr && !__y->__is_black_) 288*0b57cec5SDimitry Andric { 289*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 290*0b57cec5SDimitry Andric __x->__is_black_ = true; 291*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 292*0b57cec5SDimitry Andric __x->__is_black_ = __x == __root; 293*0b57cec5SDimitry Andric __y->__is_black_ = true; 294*0b57cec5SDimitry Andric } 295*0b57cec5SDimitry Andric else 296*0b57cec5SDimitry Andric { 297*0b57cec5SDimitry Andric if (!__tree_is_left_child(__x)) 298*0b57cec5SDimitry Andric { 299*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 300*0b57cec5SDimitry Andric __tree_left_rotate(__x); 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 303*0b57cec5SDimitry Andric __x->__is_black_ = true; 304*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 305*0b57cec5SDimitry Andric __x->__is_black_ = false; 306*0b57cec5SDimitry Andric __tree_right_rotate(__x); 307*0b57cec5SDimitry Andric break; 308*0b57cec5SDimitry Andric } 309*0b57cec5SDimitry Andric } 310*0b57cec5SDimitry Andric else 311*0b57cec5SDimitry Andric { 312*0b57cec5SDimitry Andric _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_; 313*0b57cec5SDimitry Andric if (__y != nullptr && !__y->__is_black_) 314*0b57cec5SDimitry Andric { 315*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 316*0b57cec5SDimitry Andric __x->__is_black_ = true; 317*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 318*0b57cec5SDimitry Andric __x->__is_black_ = __x == __root; 319*0b57cec5SDimitry Andric __y->__is_black_ = true; 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric else 322*0b57cec5SDimitry Andric { 323*0b57cec5SDimitry Andric if (__tree_is_left_child(__x)) 324*0b57cec5SDimitry Andric { 325*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 326*0b57cec5SDimitry Andric __tree_right_rotate(__x); 327*0b57cec5SDimitry Andric } 328*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 329*0b57cec5SDimitry Andric __x->__is_black_ = true; 330*0b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 331*0b57cec5SDimitry Andric __x->__is_black_ = false; 332*0b57cec5SDimitry Andric __tree_left_rotate(__x); 333*0b57cec5SDimitry Andric break; 334*0b57cec5SDimitry Andric } 335*0b57cec5SDimitry Andric } 336*0b57cec5SDimitry Andric } 337*0b57cec5SDimitry Andric} 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric// Precondition: __root != nullptr && __z != nullptr. 340*0b57cec5SDimitry Andric// __tree_invariant(__root) == true. 341*0b57cec5SDimitry Andric// __z == __root or == a direct or indirect child of __root. 342*0b57cec5SDimitry Andric// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed. 343*0b57cec5SDimitry Andric// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_ 344*0b57cec5SDimitry Andric// nor any of its children refer to __z. end_node->__left_ 345*0b57cec5SDimitry Andric// may be different than the value passed in as __root. 346*0b57cec5SDimitry Andrictemplate <class _NodePtr> 347*0b57cec5SDimitry Andricvoid 348*0b57cec5SDimitry Andric__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT 349*0b57cec5SDimitry Andric{ 350*0b57cec5SDimitry Andric // __z will be removed from the tree. Client still needs to destruct/deallocate it 351*0b57cec5SDimitry Andric // __y is either __z, or if __z has two children, __tree_next(__z). 352*0b57cec5SDimitry Andric // __y will have at most one child. 353*0b57cec5SDimitry Andric // __y will be the initial hole in the tree (make the hole at a leaf) 354*0b57cec5SDimitry Andric _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ? 355*0b57cec5SDimitry Andric __z : __tree_next(__z); 356*0b57cec5SDimitry Andric // __x is __y's possibly null single child 357*0b57cec5SDimitry Andric _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_; 358*0b57cec5SDimitry Andric // __w is __x's possibly null uncle (will become __x's sibling) 359*0b57cec5SDimitry Andric _NodePtr __w = nullptr; 360*0b57cec5SDimitry Andric // link __x to __y's parent, and find __w 361*0b57cec5SDimitry Andric if (__x != nullptr) 362*0b57cec5SDimitry Andric __x->__parent_ = __y->__parent_; 363*0b57cec5SDimitry Andric if (__tree_is_left_child(__y)) 364*0b57cec5SDimitry Andric { 365*0b57cec5SDimitry Andric __y->__parent_->__left_ = __x; 366*0b57cec5SDimitry Andric if (__y != __root) 367*0b57cec5SDimitry Andric __w = __y->__parent_unsafe()->__right_; 368*0b57cec5SDimitry Andric else 369*0b57cec5SDimitry Andric __root = __x; // __w == nullptr 370*0b57cec5SDimitry Andric } 371*0b57cec5SDimitry Andric else 372*0b57cec5SDimitry Andric { 373*0b57cec5SDimitry Andric __y->__parent_unsafe()->__right_ = __x; 374*0b57cec5SDimitry Andric // __y can't be root if it is a right child 375*0b57cec5SDimitry Andric __w = __y->__parent_->__left_; 376*0b57cec5SDimitry Andric } 377*0b57cec5SDimitry Andric bool __removed_black = __y->__is_black_; 378*0b57cec5SDimitry Andric // If we didn't remove __z, do so now by splicing in __y for __z, 379*0b57cec5SDimitry Andric // but copy __z's color. This does not impact __x or __w. 380*0b57cec5SDimitry Andric if (__y != __z) 381*0b57cec5SDimitry Andric { 382*0b57cec5SDimitry Andric // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr 383*0b57cec5SDimitry Andric __y->__parent_ = __z->__parent_; 384*0b57cec5SDimitry Andric if (__tree_is_left_child(__z)) 385*0b57cec5SDimitry Andric __y->__parent_->__left_ = __y; 386*0b57cec5SDimitry Andric else 387*0b57cec5SDimitry Andric __y->__parent_unsafe()->__right_ = __y; 388*0b57cec5SDimitry Andric __y->__left_ = __z->__left_; 389*0b57cec5SDimitry Andric __y->__left_->__set_parent(__y); 390*0b57cec5SDimitry Andric __y->__right_ = __z->__right_; 391*0b57cec5SDimitry Andric if (__y->__right_ != nullptr) 392*0b57cec5SDimitry Andric __y->__right_->__set_parent(__y); 393*0b57cec5SDimitry Andric __y->__is_black_ = __z->__is_black_; 394*0b57cec5SDimitry Andric if (__root == __z) 395*0b57cec5SDimitry Andric __root = __y; 396*0b57cec5SDimitry Andric } 397*0b57cec5SDimitry Andric // There is no need to rebalance if we removed a red, or if we removed 398*0b57cec5SDimitry Andric // the last node. 399*0b57cec5SDimitry Andric if (__removed_black && __root != nullptr) 400*0b57cec5SDimitry Andric { 401*0b57cec5SDimitry Andric // Rebalance: 402*0b57cec5SDimitry Andric // __x has an implicit black color (transferred from the removed __y) 403*0b57cec5SDimitry Andric // associated with it, no matter what its color is. 404*0b57cec5SDimitry Andric // If __x is __root (in which case it can't be null), it is supposed 405*0b57cec5SDimitry Andric // to be black anyway, and if it is doubly black, then the double 406*0b57cec5SDimitry Andric // can just be ignored. 407*0b57cec5SDimitry Andric // If __x is red (in which case it can't be null), then it can absorb 408*0b57cec5SDimitry Andric // the implicit black just by setting its color to black. 409*0b57cec5SDimitry Andric // Since __y was black and only had one child (which __x points to), __x 410*0b57cec5SDimitry Andric // is either red with no children, else null, otherwise __y would have 411*0b57cec5SDimitry Andric // different black heights under left and right pointers. 412*0b57cec5SDimitry Andric // if (__x == __root || __x != nullptr && !__x->__is_black_) 413*0b57cec5SDimitry Andric if (__x != nullptr) 414*0b57cec5SDimitry Andric __x->__is_black_ = true; 415*0b57cec5SDimitry Andric else 416*0b57cec5SDimitry Andric { 417*0b57cec5SDimitry Andric // Else __x isn't root, and is "doubly black", even though it may 418*0b57cec5SDimitry Andric // be null. __w can not be null here, else the parent would 419*0b57cec5SDimitry Andric // see a black height >= 2 on the __x side and a black height 420*0b57cec5SDimitry Andric // of 1 on the __w side (__w must be a non-null black or a red 421*0b57cec5SDimitry Andric // with a non-null black child). 422*0b57cec5SDimitry Andric while (true) 423*0b57cec5SDimitry Andric { 424*0b57cec5SDimitry Andric if (!__tree_is_left_child(__w)) // if x is left child 425*0b57cec5SDimitry Andric { 426*0b57cec5SDimitry Andric if (!__w->__is_black_) 427*0b57cec5SDimitry Andric { 428*0b57cec5SDimitry Andric __w->__is_black_ = true; 429*0b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = false; 430*0b57cec5SDimitry Andric __tree_left_rotate(__w->__parent_unsafe()); 431*0b57cec5SDimitry Andric // __x is still valid 432*0b57cec5SDimitry Andric // reset __root only if necessary 433*0b57cec5SDimitry Andric if (__root == __w->__left_) 434*0b57cec5SDimitry Andric __root = __w; 435*0b57cec5SDimitry Andric // reset sibling, and it still can't be null 436*0b57cec5SDimitry Andric __w = __w->__left_->__right_; 437*0b57cec5SDimitry Andric } 438*0b57cec5SDimitry Andric // __w->__is_black_ is now true, __w may have null children 439*0b57cec5SDimitry Andric if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && 440*0b57cec5SDimitry Andric (__w->__right_ == nullptr || __w->__right_->__is_black_)) 441*0b57cec5SDimitry Andric { 442*0b57cec5SDimitry Andric __w->__is_black_ = false; 443*0b57cec5SDimitry Andric __x = __w->__parent_unsafe(); 444*0b57cec5SDimitry Andric // __x can no longer be null 445*0b57cec5SDimitry Andric if (__x == __root || !__x->__is_black_) 446*0b57cec5SDimitry Andric { 447*0b57cec5SDimitry Andric __x->__is_black_ = true; 448*0b57cec5SDimitry Andric break; 449*0b57cec5SDimitry Andric } 450*0b57cec5SDimitry Andric // reset sibling, and it still can't be null 451*0b57cec5SDimitry Andric __w = __tree_is_left_child(__x) ? 452*0b57cec5SDimitry Andric __x->__parent_unsafe()->__right_ : 453*0b57cec5SDimitry Andric __x->__parent_->__left_; 454*0b57cec5SDimitry Andric // continue; 455*0b57cec5SDimitry Andric } 456*0b57cec5SDimitry Andric else // __w has a red child 457*0b57cec5SDimitry Andric { 458*0b57cec5SDimitry Andric if (__w->__right_ == nullptr || __w->__right_->__is_black_) 459*0b57cec5SDimitry Andric { 460*0b57cec5SDimitry Andric // __w left child is non-null and red 461*0b57cec5SDimitry Andric __w->__left_->__is_black_ = true; 462*0b57cec5SDimitry Andric __w->__is_black_ = false; 463*0b57cec5SDimitry Andric __tree_right_rotate(__w); 464*0b57cec5SDimitry Andric // __w is known not to be root, so root hasn't changed 465*0b57cec5SDimitry Andric // reset sibling, and it still can't be null 466*0b57cec5SDimitry Andric __w = __w->__parent_unsafe(); 467*0b57cec5SDimitry Andric } 468*0b57cec5SDimitry Andric // __w has a right red child, left child may be null 469*0b57cec5SDimitry Andric __w->__is_black_ = __w->__parent_unsafe()->__is_black_; 470*0b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = true; 471*0b57cec5SDimitry Andric __w->__right_->__is_black_ = true; 472*0b57cec5SDimitry Andric __tree_left_rotate(__w->__parent_unsafe()); 473*0b57cec5SDimitry Andric break; 474*0b57cec5SDimitry Andric } 475*0b57cec5SDimitry Andric } 476*0b57cec5SDimitry Andric else 477*0b57cec5SDimitry Andric { 478*0b57cec5SDimitry Andric if (!__w->__is_black_) 479*0b57cec5SDimitry Andric { 480*0b57cec5SDimitry Andric __w->__is_black_ = true; 481*0b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = false; 482*0b57cec5SDimitry Andric __tree_right_rotate(__w->__parent_unsafe()); 483*0b57cec5SDimitry Andric // __x is still valid 484*0b57cec5SDimitry Andric // reset __root only if necessary 485*0b57cec5SDimitry Andric if (__root == __w->__right_) 486*0b57cec5SDimitry Andric __root = __w; 487*0b57cec5SDimitry Andric // reset sibling, and it still can't be null 488*0b57cec5SDimitry Andric __w = __w->__right_->__left_; 489*0b57cec5SDimitry Andric } 490*0b57cec5SDimitry Andric // __w->__is_black_ is now true, __w may have null children 491*0b57cec5SDimitry Andric if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && 492*0b57cec5SDimitry Andric (__w->__right_ == nullptr || __w->__right_->__is_black_)) 493*0b57cec5SDimitry Andric { 494*0b57cec5SDimitry Andric __w->__is_black_ = false; 495*0b57cec5SDimitry Andric __x = __w->__parent_unsafe(); 496*0b57cec5SDimitry Andric // __x can no longer be null 497*0b57cec5SDimitry Andric if (!__x->__is_black_ || __x == __root) 498*0b57cec5SDimitry Andric { 499*0b57cec5SDimitry Andric __x->__is_black_ = true; 500*0b57cec5SDimitry Andric break; 501*0b57cec5SDimitry Andric } 502*0b57cec5SDimitry Andric // reset sibling, and it still can't be null 503*0b57cec5SDimitry Andric __w = __tree_is_left_child(__x) ? 504*0b57cec5SDimitry Andric __x->__parent_unsafe()->__right_ : 505*0b57cec5SDimitry Andric __x->__parent_->__left_; 506*0b57cec5SDimitry Andric // continue; 507*0b57cec5SDimitry Andric } 508*0b57cec5SDimitry Andric else // __w has a red child 509*0b57cec5SDimitry Andric { 510*0b57cec5SDimitry Andric if (__w->__left_ == nullptr || __w->__left_->__is_black_) 511*0b57cec5SDimitry Andric { 512*0b57cec5SDimitry Andric // __w right child is non-null and red 513*0b57cec5SDimitry Andric __w->__right_->__is_black_ = true; 514*0b57cec5SDimitry Andric __w->__is_black_ = false; 515*0b57cec5SDimitry Andric __tree_left_rotate(__w); 516*0b57cec5SDimitry Andric // __w is known not to be root, so root hasn't changed 517*0b57cec5SDimitry Andric // reset sibling, and it still can't be null 518*0b57cec5SDimitry Andric __w = __w->__parent_unsafe(); 519*0b57cec5SDimitry Andric } 520*0b57cec5SDimitry Andric // __w has a left red child, right child may be null 521*0b57cec5SDimitry Andric __w->__is_black_ = __w->__parent_unsafe()->__is_black_; 522*0b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = true; 523*0b57cec5SDimitry Andric __w->__left_->__is_black_ = true; 524*0b57cec5SDimitry Andric __tree_right_rotate(__w->__parent_unsafe()); 525*0b57cec5SDimitry Andric break; 526*0b57cec5SDimitry Andric } 527*0b57cec5SDimitry Andric } 528*0b57cec5SDimitry Andric } 529*0b57cec5SDimitry Andric } 530*0b57cec5SDimitry Andric } 531*0b57cec5SDimitry Andric} 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andric// node traits 534*0b57cec5SDimitry Andric 535*0b57cec5SDimitry Andric 536*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 537*0b57cec5SDimitry Andrictemplate <class _Tp> 538*0b57cec5SDimitry Andricstruct __is_tree_value_type_imp : false_type {}; 539*0b57cec5SDimitry Andric 540*0b57cec5SDimitry Andrictemplate <class _Key, class _Value> 541*0b57cec5SDimitry Andricstruct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {}; 542*0b57cec5SDimitry Andric 543*0b57cec5SDimitry Andrictemplate <class ..._Args> 544*0b57cec5SDimitry Andricstruct __is_tree_value_type : false_type {}; 545*0b57cec5SDimitry Andric 546*0b57cec5SDimitry Andrictemplate <class _One> 547*0b57cec5SDimitry Andricstruct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {}; 548*0b57cec5SDimitry Andric#endif 549*0b57cec5SDimitry Andric 550*0b57cec5SDimitry Andrictemplate <class _Tp> 551*0b57cec5SDimitry Andricstruct __tree_key_value_types { 552*0b57cec5SDimitry Andric typedef _Tp key_type; 553*0b57cec5SDimitry Andric typedef _Tp __node_value_type; 554*0b57cec5SDimitry Andric typedef _Tp __container_value_type; 555*0b57cec5SDimitry Andric static const bool __is_map = false; 556*0b57cec5SDimitry Andric 557*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 558*0b57cec5SDimitry Andric static key_type const& __get_key(_Tp const& __v) { 559*0b57cec5SDimitry Andric return __v; 560*0b57cec5SDimitry Andric } 561*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 562*0b57cec5SDimitry Andric static __container_value_type const& __get_value(__node_value_type const& __v) { 563*0b57cec5SDimitry Andric return __v; 564*0b57cec5SDimitry Andric } 565*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 566*0b57cec5SDimitry Andric static __container_value_type* __get_ptr(__node_value_type& __n) { 567*0b57cec5SDimitry Andric return _VSTD::addressof(__n); 568*0b57cec5SDimitry Andric } 569*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 570*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 571*0b57cec5SDimitry Andric static __container_value_type&& __move(__node_value_type& __v) { 572*0b57cec5SDimitry Andric return _VSTD::move(__v); 573*0b57cec5SDimitry Andric } 574*0b57cec5SDimitry Andric#endif 575*0b57cec5SDimitry Andric}; 576*0b57cec5SDimitry Andric 577*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp> 578*0b57cec5SDimitry Andricstruct __tree_key_value_types<__value_type<_Key, _Tp> > { 579*0b57cec5SDimitry Andric typedef _Key key_type; 580*0b57cec5SDimitry Andric typedef _Tp mapped_type; 581*0b57cec5SDimitry Andric typedef __value_type<_Key, _Tp> __node_value_type; 582*0b57cec5SDimitry Andric typedef pair<const _Key, _Tp> __container_value_type; 583*0b57cec5SDimitry Andric typedef __container_value_type __map_value_type; 584*0b57cec5SDimitry Andric static const bool __is_map = true; 585*0b57cec5SDimitry Andric 586*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 587*0b57cec5SDimitry Andric static key_type const& 588*0b57cec5SDimitry Andric __get_key(__node_value_type const& __t) { 589*0b57cec5SDimitry Andric return __t.__get_value().first; 590*0b57cec5SDimitry Andric } 591*0b57cec5SDimitry Andric 592*0b57cec5SDimitry Andric template <class _Up> 593*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 594*0b57cec5SDimitry Andric static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, 595*0b57cec5SDimitry Andric key_type const&>::type 596*0b57cec5SDimitry Andric __get_key(_Up& __t) { 597*0b57cec5SDimitry Andric return __t.first; 598*0b57cec5SDimitry Andric } 599*0b57cec5SDimitry Andric 600*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 601*0b57cec5SDimitry Andric static __container_value_type const& 602*0b57cec5SDimitry Andric __get_value(__node_value_type const& __t) { 603*0b57cec5SDimitry Andric return __t.__get_value(); 604*0b57cec5SDimitry Andric } 605*0b57cec5SDimitry Andric 606*0b57cec5SDimitry Andric template <class _Up> 607*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 608*0b57cec5SDimitry Andric static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, 609*0b57cec5SDimitry Andric __container_value_type const&>::type 610*0b57cec5SDimitry Andric __get_value(_Up& __t) { 611*0b57cec5SDimitry Andric return __t; 612*0b57cec5SDimitry Andric } 613*0b57cec5SDimitry Andric 614*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 615*0b57cec5SDimitry Andric static __container_value_type* __get_ptr(__node_value_type& __n) { 616*0b57cec5SDimitry Andric return _VSTD::addressof(__n.__get_value()); 617*0b57cec5SDimitry Andric } 618*0b57cec5SDimitry Andric 619*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 620*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 621*0b57cec5SDimitry Andric static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { 622*0b57cec5SDimitry Andric return __v.__move(); 623*0b57cec5SDimitry Andric } 624*0b57cec5SDimitry Andric#endif 625*0b57cec5SDimitry Andric}; 626*0b57cec5SDimitry Andric 627*0b57cec5SDimitry Andrictemplate <class _VoidPtr> 628*0b57cec5SDimitry Andricstruct __tree_node_base_types { 629*0b57cec5SDimitry Andric typedef _VoidPtr __void_pointer; 630*0b57cec5SDimitry Andric 631*0b57cec5SDimitry Andric typedef __tree_node_base<__void_pointer> __node_base_type; 632*0b57cec5SDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type 633*0b57cec5SDimitry Andric __node_base_pointer; 634*0b57cec5SDimitry Andric 635*0b57cec5SDimitry Andric typedef __tree_end_node<__node_base_pointer> __end_node_type; 636*0b57cec5SDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type 637*0b57cec5SDimitry Andric __end_node_pointer; 638*0b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) 639*0b57cec5SDimitry Andric typedef __end_node_pointer __parent_pointer; 640*0b57cec5SDimitry Andric#else 641*0b57cec5SDimitry Andric typedef typename conditional< 642*0b57cec5SDimitry Andric is_pointer<__end_node_pointer>::value, 643*0b57cec5SDimitry Andric __end_node_pointer, 644*0b57cec5SDimitry Andric __node_base_pointer>::type __parent_pointer; 645*0b57cec5SDimitry Andric#endif 646*0b57cec5SDimitry Andric 647*0b57cec5SDimitry Andricprivate: 648*0b57cec5SDimitry Andric static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), 649*0b57cec5SDimitry Andric "_VoidPtr does not point to unqualified void type"); 650*0b57cec5SDimitry Andric}; 651*0b57cec5SDimitry Andric 652*0b57cec5SDimitry Andrictemplate <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>, 653*0b57cec5SDimitry Andric bool = _KVTypes::__is_map> 654*0b57cec5SDimitry Andricstruct __tree_map_pointer_types {}; 655*0b57cec5SDimitry Andric 656*0b57cec5SDimitry Andrictemplate <class _Tp, class _AllocPtr, class _KVTypes> 657*0b57cec5SDimitry Andricstruct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { 658*0b57cec5SDimitry Andric typedef typename _KVTypes::__map_value_type _Mv; 659*0b57cec5SDimitry Andric typedef typename __rebind_pointer<_AllocPtr, _Mv>::type 660*0b57cec5SDimitry Andric __map_value_type_pointer; 661*0b57cec5SDimitry Andric typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type 662*0b57cec5SDimitry Andric __const_map_value_type_pointer; 663*0b57cec5SDimitry Andric}; 664*0b57cec5SDimitry Andric 665*0b57cec5SDimitry Andrictemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> 666*0b57cec5SDimitry Andricstruct __tree_node_types; 667*0b57cec5SDimitry Andric 668*0b57cec5SDimitry Andrictemplate <class _NodePtr, class _Tp, class _VoidPtr> 669*0b57cec5SDimitry Andricstruct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > 670*0b57cec5SDimitry Andric : public __tree_node_base_types<_VoidPtr>, 671*0b57cec5SDimitry Andric __tree_key_value_types<_Tp>, 672*0b57cec5SDimitry Andric __tree_map_pointer_types<_Tp, _VoidPtr> 673*0b57cec5SDimitry Andric{ 674*0b57cec5SDimitry Andric typedef __tree_node_base_types<_VoidPtr> __base; 675*0b57cec5SDimitry Andric typedef __tree_key_value_types<_Tp> __key_base; 676*0b57cec5SDimitry Andric typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base; 677*0b57cec5SDimitry Andricpublic: 678*0b57cec5SDimitry Andric 679*0b57cec5SDimitry Andric typedef typename pointer_traits<_NodePtr>::element_type __node_type; 680*0b57cec5SDimitry Andric typedef _NodePtr __node_pointer; 681*0b57cec5SDimitry Andric 682*0b57cec5SDimitry Andric typedef _Tp __node_value_type; 683*0b57cec5SDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type 684*0b57cec5SDimitry Andric __node_value_type_pointer; 685*0b57cec5SDimitry Andric typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type 686*0b57cec5SDimitry Andric __const_node_value_type_pointer; 687*0b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) 688*0b57cec5SDimitry Andric typedef typename __base::__end_node_pointer __iter_pointer; 689*0b57cec5SDimitry Andric#else 690*0b57cec5SDimitry Andric typedef typename conditional< 691*0b57cec5SDimitry Andric is_pointer<__node_pointer>::value, 692*0b57cec5SDimitry Andric typename __base::__end_node_pointer, 693*0b57cec5SDimitry Andric __node_pointer>::type __iter_pointer; 694*0b57cec5SDimitry Andric#endif 695*0b57cec5SDimitry Andricprivate: 696*0b57cec5SDimitry Andric static_assert(!is_const<__node_type>::value, 697*0b57cec5SDimitry Andric "_NodePtr should never be a pointer to const"); 698*0b57cec5SDimitry Andric static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, 699*0b57cec5SDimitry Andric _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); 700*0b57cec5SDimitry Andric}; 701*0b57cec5SDimitry Andric 702*0b57cec5SDimitry Andrictemplate <class _ValueTp, class _VoidPtr> 703*0b57cec5SDimitry Andricstruct __make_tree_node_types { 704*0b57cec5SDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type 705*0b57cec5SDimitry Andric _NodePtr; 706*0b57cec5SDimitry Andric typedef __tree_node_types<_NodePtr> type; 707*0b57cec5SDimitry Andric}; 708*0b57cec5SDimitry Andric 709*0b57cec5SDimitry Andric// node 710*0b57cec5SDimitry Andric 711*0b57cec5SDimitry Andrictemplate <class _Pointer> 712*0b57cec5SDimitry Andricclass __tree_end_node 713*0b57cec5SDimitry Andric{ 714*0b57cec5SDimitry Andricpublic: 715*0b57cec5SDimitry Andric typedef _Pointer pointer; 716*0b57cec5SDimitry Andric pointer __left_; 717*0b57cec5SDimitry Andric 718*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 719*0b57cec5SDimitry Andric __tree_end_node() _NOEXCEPT : __left_() {} 720*0b57cec5SDimitry Andric}; 721*0b57cec5SDimitry Andric 722*0b57cec5SDimitry Andrictemplate <class _VoidPtr> 723*0b57cec5SDimitry Andricclass __tree_node_base 724*0b57cec5SDimitry Andric : public __tree_node_base_types<_VoidPtr>::__end_node_type 725*0b57cec5SDimitry Andric{ 726*0b57cec5SDimitry Andric typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes; 727*0b57cec5SDimitry Andric 728*0b57cec5SDimitry Andricpublic: 729*0b57cec5SDimitry Andric typedef typename _NodeBaseTypes::__node_base_pointer pointer; 730*0b57cec5SDimitry Andric typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer; 731*0b57cec5SDimitry Andric 732*0b57cec5SDimitry Andric pointer __right_; 733*0b57cec5SDimitry Andric __parent_pointer __parent_; 734*0b57cec5SDimitry Andric bool __is_black_; 735*0b57cec5SDimitry Andric 736*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 737*0b57cec5SDimitry Andric pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);} 738*0b57cec5SDimitry Andric 739*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 740*0b57cec5SDimitry Andric void __set_parent(pointer __p) { 741*0b57cec5SDimitry Andric __parent_ = static_cast<__parent_pointer>(__p); 742*0b57cec5SDimitry Andric } 743*0b57cec5SDimitry Andric 744*0b57cec5SDimitry Andricprivate: 745*0b57cec5SDimitry Andric ~__tree_node_base() _LIBCPP_EQUAL_DELETE; 746*0b57cec5SDimitry Andric __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; 747*0b57cec5SDimitry Andric __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; 748*0b57cec5SDimitry Andric}; 749*0b57cec5SDimitry Andric 750*0b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr> 751*0b57cec5SDimitry Andricclass __tree_node 752*0b57cec5SDimitry Andric : public __tree_node_base<_VoidPtr> 753*0b57cec5SDimitry Andric{ 754*0b57cec5SDimitry Andricpublic: 755*0b57cec5SDimitry Andric typedef _Tp __node_value_type; 756*0b57cec5SDimitry Andric 757*0b57cec5SDimitry Andric __node_value_type __value_; 758*0b57cec5SDimitry Andric 759*0b57cec5SDimitry Andricprivate: 760*0b57cec5SDimitry Andric ~__tree_node() _LIBCPP_EQUAL_DELETE; 761*0b57cec5SDimitry Andric __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE; 762*0b57cec5SDimitry Andric __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE; 763*0b57cec5SDimitry Andric}; 764*0b57cec5SDimitry Andric 765*0b57cec5SDimitry Andric 766*0b57cec5SDimitry Andrictemplate <class _Allocator> 767*0b57cec5SDimitry Andricclass __tree_node_destructor 768*0b57cec5SDimitry Andric{ 769*0b57cec5SDimitry Andric typedef _Allocator allocator_type; 770*0b57cec5SDimitry Andric typedef allocator_traits<allocator_type> __alloc_traits; 771*0b57cec5SDimitry Andric 772*0b57cec5SDimitry Andricpublic: 773*0b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 774*0b57cec5SDimitry Andricprivate: 775*0b57cec5SDimitry Andric typedef __tree_node_types<pointer> _NodeTypes; 776*0b57cec5SDimitry Andric allocator_type& __na_; 777*0b57cec5SDimitry Andric 778*0b57cec5SDimitry Andric __tree_node_destructor& operator=(const __tree_node_destructor&); 779*0b57cec5SDimitry Andric 780*0b57cec5SDimitry Andricpublic: 781*0b57cec5SDimitry Andric bool __value_constructed; 782*0b57cec5SDimitry Andric 783*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 784*0b57cec5SDimitry Andric explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT 785*0b57cec5SDimitry Andric : __na_(__na), 786*0b57cec5SDimitry Andric __value_constructed(__val) 787*0b57cec5SDimitry Andric {} 788*0b57cec5SDimitry Andric 789*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 790*0b57cec5SDimitry Andric void operator()(pointer __p) _NOEXCEPT 791*0b57cec5SDimitry Andric { 792*0b57cec5SDimitry Andric if (__value_constructed) 793*0b57cec5SDimitry Andric __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); 794*0b57cec5SDimitry Andric if (__p) 795*0b57cec5SDimitry Andric __alloc_traits::deallocate(__na_, __p, 1); 796*0b57cec5SDimitry Andric } 797*0b57cec5SDimitry Andric 798*0b57cec5SDimitry Andric template <class> friend class __map_node_destructor; 799*0b57cec5SDimitry Andric}; 800*0b57cec5SDimitry Andric 801*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 802*0b57cec5SDimitry Andrictemplate <class _NodeType, class _Alloc> 803*0b57cec5SDimitry Andricstruct __generic_container_node_destructor; 804*0b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr, class _Alloc> 805*0b57cec5SDimitry Andricstruct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> 806*0b57cec5SDimitry Andric : __tree_node_destructor<_Alloc> 807*0b57cec5SDimitry Andric{ 808*0b57cec5SDimitry Andric using __tree_node_destructor<_Alloc>::__tree_node_destructor; 809*0b57cec5SDimitry Andric}; 810*0b57cec5SDimitry Andric#endif 811*0b57cec5SDimitry Andric 812*0b57cec5SDimitry Andrictemplate <class _Tp, class _NodePtr, class _DiffType> 813*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_iterator 814*0b57cec5SDimitry Andric{ 815*0b57cec5SDimitry Andric typedef __tree_node_types<_NodePtr> _NodeTypes; 816*0b57cec5SDimitry Andric typedef _NodePtr __node_pointer; 817*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 818*0b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; 819*0b57cec5SDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 820*0b57cec5SDimitry Andric typedef pointer_traits<__node_pointer> __pointer_traits; 821*0b57cec5SDimitry Andric 822*0b57cec5SDimitry Andric __iter_pointer __ptr_; 823*0b57cec5SDimitry Andric 824*0b57cec5SDimitry Andricpublic: 825*0b57cec5SDimitry Andric typedef bidirectional_iterator_tag iterator_category; 826*0b57cec5SDimitry Andric typedef _Tp value_type; 827*0b57cec5SDimitry Andric typedef _DiffType difference_type; 828*0b57cec5SDimitry Andric typedef value_type& reference; 829*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_value_type_pointer pointer; 830*0b57cec5SDimitry Andric 831*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT 832*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 833*0b57cec5SDimitry Andric : __ptr_(nullptr) 834*0b57cec5SDimitry Andric#endif 835*0b57cec5SDimitry Andric {} 836*0b57cec5SDimitry Andric 837*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY reference operator*() const 838*0b57cec5SDimitry Andric {return __get_np()->__value_;} 839*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY pointer operator->() const 840*0b57cec5SDimitry Andric {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} 841*0b57cec5SDimitry Andric 842*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 843*0b57cec5SDimitry Andric __tree_iterator& operator++() { 844*0b57cec5SDimitry Andric __ptr_ = static_cast<__iter_pointer>( 845*0b57cec5SDimitry Andric __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); 846*0b57cec5SDimitry Andric return *this; 847*0b57cec5SDimitry Andric } 848*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 849*0b57cec5SDimitry Andric __tree_iterator operator++(int) 850*0b57cec5SDimitry Andric {__tree_iterator __t(*this); ++(*this); return __t;} 851*0b57cec5SDimitry Andric 852*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 853*0b57cec5SDimitry Andric __tree_iterator& operator--() { 854*0b57cec5SDimitry Andric __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( 855*0b57cec5SDimitry Andric static_cast<__end_node_pointer>(__ptr_))); 856*0b57cec5SDimitry Andric return *this; 857*0b57cec5SDimitry Andric } 858*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 859*0b57cec5SDimitry Andric __tree_iterator operator--(int) 860*0b57cec5SDimitry Andric {__tree_iterator __t(*this); --(*this); return __t;} 861*0b57cec5SDimitry Andric 862*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 863*0b57cec5SDimitry Andric bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) 864*0b57cec5SDimitry Andric {return __x.__ptr_ == __y.__ptr_;} 865*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 866*0b57cec5SDimitry Andric bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) 867*0b57cec5SDimitry Andric {return !(__x == __y);} 868*0b57cec5SDimitry Andric 869*0b57cec5SDimitry Andricprivate: 870*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 871*0b57cec5SDimitry Andric explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 872*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 873*0b57cec5SDimitry Andric explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 874*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 875*0b57cec5SDimitry Andric __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } 876*0b57cec5SDimitry Andric template <class, class, class> friend class __tree; 877*0b57cec5SDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; 878*0b57cec5SDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator; 879*0b57cec5SDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 880*0b57cec5SDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 881*0b57cec5SDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set; 882*0b57cec5SDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset; 883*0b57cec5SDimitry Andric}; 884*0b57cec5SDimitry Andric 885*0b57cec5SDimitry Andrictemplate <class _Tp, class _NodePtr, class _DiffType> 886*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_const_iterator 887*0b57cec5SDimitry Andric{ 888*0b57cec5SDimitry Andric typedef __tree_node_types<_NodePtr> _NodeTypes; 889*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_pointer __node_pointer; 890*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 891*0b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; 892*0b57cec5SDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 893*0b57cec5SDimitry Andric typedef pointer_traits<__node_pointer> __pointer_traits; 894*0b57cec5SDimitry Andric 895*0b57cec5SDimitry Andric __iter_pointer __ptr_; 896*0b57cec5SDimitry Andric 897*0b57cec5SDimitry Andricpublic: 898*0b57cec5SDimitry Andric typedef bidirectional_iterator_tag iterator_category; 899*0b57cec5SDimitry Andric typedef _Tp value_type; 900*0b57cec5SDimitry Andric typedef _DiffType difference_type; 901*0b57cec5SDimitry Andric typedef const value_type& reference; 902*0b57cec5SDimitry Andric typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 903*0b57cec5SDimitry Andric 904*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT 905*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 906*0b57cec5SDimitry Andric : __ptr_(nullptr) 907*0b57cec5SDimitry Andric#endif 908*0b57cec5SDimitry Andric {} 909*0b57cec5SDimitry Andric 910*0b57cec5SDimitry Andricprivate: 911*0b57cec5SDimitry Andric typedef __tree_iterator<value_type, __node_pointer, difference_type> 912*0b57cec5SDimitry Andric __non_const_iterator; 913*0b57cec5SDimitry Andricpublic: 914*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 915*0b57cec5SDimitry Andric __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT 916*0b57cec5SDimitry Andric : __ptr_(__p.__ptr_) {} 917*0b57cec5SDimitry Andric 918*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY reference operator*() const 919*0b57cec5SDimitry Andric {return __get_np()->__value_;} 920*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY pointer operator->() const 921*0b57cec5SDimitry Andric {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} 922*0b57cec5SDimitry Andric 923*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 924*0b57cec5SDimitry Andric __tree_const_iterator& operator++() { 925*0b57cec5SDimitry Andric __ptr_ = static_cast<__iter_pointer>( 926*0b57cec5SDimitry Andric __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); 927*0b57cec5SDimitry Andric return *this; 928*0b57cec5SDimitry Andric } 929*0b57cec5SDimitry Andric 930*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 931*0b57cec5SDimitry Andric __tree_const_iterator operator++(int) 932*0b57cec5SDimitry Andric {__tree_const_iterator __t(*this); ++(*this); return __t;} 933*0b57cec5SDimitry Andric 934*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 935*0b57cec5SDimitry Andric __tree_const_iterator& operator--() { 936*0b57cec5SDimitry Andric __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( 937*0b57cec5SDimitry Andric static_cast<__end_node_pointer>(__ptr_))); 938*0b57cec5SDimitry Andric return *this; 939*0b57cec5SDimitry Andric } 940*0b57cec5SDimitry Andric 941*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 942*0b57cec5SDimitry Andric __tree_const_iterator operator--(int) 943*0b57cec5SDimitry Andric {__tree_const_iterator __t(*this); --(*this); return __t;} 944*0b57cec5SDimitry Andric 945*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 946*0b57cec5SDimitry Andric bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) 947*0b57cec5SDimitry Andric {return __x.__ptr_ == __y.__ptr_;} 948*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 949*0b57cec5SDimitry Andric bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) 950*0b57cec5SDimitry Andric {return !(__x == __y);} 951*0b57cec5SDimitry Andric 952*0b57cec5SDimitry Andricprivate: 953*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 954*0b57cec5SDimitry Andric explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT 955*0b57cec5SDimitry Andric : __ptr_(__p) {} 956*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 957*0b57cec5SDimitry Andric explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT 958*0b57cec5SDimitry Andric : __ptr_(__p) {} 959*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 960*0b57cec5SDimitry Andric __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } 961*0b57cec5SDimitry Andric 962*0b57cec5SDimitry Andric template <class, class, class> friend class __tree; 963*0b57cec5SDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 964*0b57cec5SDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 965*0b57cec5SDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set; 966*0b57cec5SDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset; 967*0b57cec5SDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator; 968*0b57cec5SDimitry Andric 969*0b57cec5SDimitry Andric}; 970*0b57cec5SDimitry Andric 971*0b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 972*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 973*0b57cec5SDimitry Andric _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value, 974*0b57cec5SDimitry Andric "the specified comparator type does not provide a viable const call operator") 975*0b57cec5SDimitry Andric#endif 976*0b57cec5SDimitry Andricint __diagnose_non_const_comparator(); 977*0b57cec5SDimitry Andric 978*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 979*0b57cec5SDimitry Andricclass __tree 980*0b57cec5SDimitry Andric{ 981*0b57cec5SDimitry Andricpublic: 982*0b57cec5SDimitry Andric typedef _Tp value_type; 983*0b57cec5SDimitry Andric typedef _Compare value_compare; 984*0b57cec5SDimitry Andric typedef _Allocator allocator_type; 985*0b57cec5SDimitry Andric 986*0b57cec5SDimitry Andricprivate: 987*0b57cec5SDimitry Andric typedef allocator_traits<allocator_type> __alloc_traits; 988*0b57cec5SDimitry Andric typedef typename __make_tree_node_types<value_type, 989*0b57cec5SDimitry Andric typename __alloc_traits::void_pointer>::type 990*0b57cec5SDimitry Andric _NodeTypes; 991*0b57cec5SDimitry Andric typedef typename _NodeTypes::key_type key_type; 992*0b57cec5SDimitry Andricpublic: 993*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_value_type __node_value_type; 994*0b57cec5SDimitry Andric typedef typename _NodeTypes::__container_value_type __container_value_type; 995*0b57cec5SDimitry Andric 996*0b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 997*0b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 998*0b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 999*0b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 1000*0b57cec5SDimitry Andric 1001*0b57cec5SDimitry Andricpublic: 1002*0b57cec5SDimitry Andric typedef typename _NodeTypes::__void_pointer __void_pointer; 1003*0b57cec5SDimitry Andric 1004*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_type __node; 1005*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_pointer __node_pointer; 1006*0b57cec5SDimitry Andric 1007*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_type __node_base; 1008*0b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 1009*0b57cec5SDimitry Andric 1010*0b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_type __end_node_t; 1011*0b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_ptr; 1012*0b57cec5SDimitry Andric 1013*0b57cec5SDimitry Andric typedef typename _NodeTypes::__parent_pointer __parent_pointer; 1014*0b57cec5SDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 1015*0b57cec5SDimitry Andric 1016*0b57cec5SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; 1017*0b57cec5SDimitry Andric typedef allocator_traits<__node_allocator> __node_traits; 1018*0b57cec5SDimitry Andric 1019*0b57cec5SDimitry Andricprivate: 1020*0b57cec5SDimitry Andric // check for sane allocator pointer rebinding semantics. Rebinding the 1021*0b57cec5SDimitry Andric // allocator for a new pointer type should be exactly the same as rebinding 1022*0b57cec5SDimitry Andric // the pointer using 'pointer_traits'. 1023*0b57cec5SDimitry Andric static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), 1024*0b57cec5SDimitry Andric "Allocator does not rebind pointers in a sane manner."); 1025*0b57cec5SDimitry Andric typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type 1026*0b57cec5SDimitry Andric __node_base_allocator; 1027*0b57cec5SDimitry Andric typedef allocator_traits<__node_base_allocator> __node_base_traits; 1028*0b57cec5SDimitry Andric static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), 1029*0b57cec5SDimitry Andric "Allocator does not rebind pointers in a sane manner."); 1030*0b57cec5SDimitry Andric 1031*0b57cec5SDimitry Andricprivate: 1032*0b57cec5SDimitry Andric __iter_pointer __begin_node_; 1033*0b57cec5SDimitry Andric __compressed_pair<__end_node_t, __node_allocator> __pair1_; 1034*0b57cec5SDimitry Andric __compressed_pair<size_type, value_compare> __pair3_; 1035*0b57cec5SDimitry Andric 1036*0b57cec5SDimitry Andricpublic: 1037*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1038*0b57cec5SDimitry Andric __iter_pointer __end_node() _NOEXCEPT 1039*0b57cec5SDimitry Andric { 1040*0b57cec5SDimitry Andric return static_cast<__iter_pointer>( 1041*0b57cec5SDimitry Andric pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) 1042*0b57cec5SDimitry Andric ); 1043*0b57cec5SDimitry Andric } 1044*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1045*0b57cec5SDimitry Andric __iter_pointer __end_node() const _NOEXCEPT 1046*0b57cec5SDimitry Andric { 1047*0b57cec5SDimitry Andric return static_cast<__iter_pointer>( 1048*0b57cec5SDimitry Andric pointer_traits<__end_node_ptr>::pointer_to( 1049*0b57cec5SDimitry Andric const_cast<__end_node_t&>(__pair1_.first()) 1050*0b57cec5SDimitry Andric ) 1051*0b57cec5SDimitry Andric ); 1052*0b57cec5SDimitry Andric } 1053*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1054*0b57cec5SDimitry Andric __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();} 1055*0b57cec5SDimitry Andricprivate: 1056*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1057*0b57cec5SDimitry Andric const __node_allocator& __node_alloc() const _NOEXCEPT 1058*0b57cec5SDimitry Andric {return __pair1_.second();} 1059*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1060*0b57cec5SDimitry Andric __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} 1061*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1062*0b57cec5SDimitry Andric const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} 1063*0b57cec5SDimitry Andricpublic: 1064*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1065*0b57cec5SDimitry Andric allocator_type __alloc() const _NOEXCEPT 1066*0b57cec5SDimitry Andric {return allocator_type(__node_alloc());} 1067*0b57cec5SDimitry Andricprivate: 1068*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1069*0b57cec5SDimitry Andric size_type& size() _NOEXCEPT {return __pair3_.first();} 1070*0b57cec5SDimitry Andricpublic: 1071*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1072*0b57cec5SDimitry Andric const size_type& size() const _NOEXCEPT {return __pair3_.first();} 1073*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1074*0b57cec5SDimitry Andric value_compare& value_comp() _NOEXCEPT {return __pair3_.second();} 1075*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1076*0b57cec5SDimitry Andric const value_compare& value_comp() const _NOEXCEPT 1077*0b57cec5SDimitry Andric {return __pair3_.second();} 1078*0b57cec5SDimitry Andricpublic: 1079*0b57cec5SDimitry Andric 1080*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1081*0b57cec5SDimitry Andric __node_pointer __root() const _NOEXCEPT 1082*0b57cec5SDimitry Andric {return static_cast<__node_pointer>(__end_node()->__left_);} 1083*0b57cec5SDimitry Andric 1084*0b57cec5SDimitry Andric __node_base_pointer* __root_ptr() const _NOEXCEPT { 1085*0b57cec5SDimitry Andric return _VSTD::addressof(__end_node()->__left_); 1086*0b57cec5SDimitry Andric } 1087*0b57cec5SDimitry Andric 1088*0b57cec5SDimitry Andric typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator; 1089*0b57cec5SDimitry Andric typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator; 1090*0b57cec5SDimitry Andric 1091*0b57cec5SDimitry Andric explicit __tree(const value_compare& __comp) 1092*0b57cec5SDimitry Andric _NOEXCEPT_( 1093*0b57cec5SDimitry Andric is_nothrow_default_constructible<__node_allocator>::value && 1094*0b57cec5SDimitry Andric is_nothrow_copy_constructible<value_compare>::value); 1095*0b57cec5SDimitry Andric explicit __tree(const allocator_type& __a); 1096*0b57cec5SDimitry Andric __tree(const value_compare& __comp, const allocator_type& __a); 1097*0b57cec5SDimitry Andric __tree(const __tree& __t); 1098*0b57cec5SDimitry Andric __tree& operator=(const __tree& __t); 1099*0b57cec5SDimitry Andric template <class _ForwardIterator> 1100*0b57cec5SDimitry Andric void __assign_unique(_ForwardIterator __first, _ForwardIterator __last); 1101*0b57cec5SDimitry Andric template <class _InputIterator> 1102*0b57cec5SDimitry Andric void __assign_multi(_InputIterator __first, _InputIterator __last); 1103*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1104*0b57cec5SDimitry Andric __tree(__tree&& __t) 1105*0b57cec5SDimitry Andric _NOEXCEPT_( 1106*0b57cec5SDimitry Andric is_nothrow_move_constructible<__node_allocator>::value && 1107*0b57cec5SDimitry Andric is_nothrow_move_constructible<value_compare>::value); 1108*0b57cec5SDimitry Andric __tree(__tree&& __t, const allocator_type& __a); 1109*0b57cec5SDimitry Andric __tree& operator=(__tree&& __t) 1110*0b57cec5SDimitry Andric _NOEXCEPT_( 1111*0b57cec5SDimitry Andric __node_traits::propagate_on_container_move_assignment::value && 1112*0b57cec5SDimitry Andric is_nothrow_move_assignable<value_compare>::value && 1113*0b57cec5SDimitry Andric is_nothrow_move_assignable<__node_allocator>::value); 1114*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 1115*0b57cec5SDimitry Andric 1116*0b57cec5SDimitry Andric ~__tree(); 1117*0b57cec5SDimitry Andric 1118*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1119*0b57cec5SDimitry Andric iterator begin() _NOEXCEPT {return iterator(__begin_node());} 1120*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1121*0b57cec5SDimitry Andric const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());} 1122*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1123*0b57cec5SDimitry Andric iterator end() _NOEXCEPT {return iterator(__end_node());} 1124*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1125*0b57cec5SDimitry Andric const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());} 1126*0b57cec5SDimitry Andric 1127*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1128*0b57cec5SDimitry Andric size_type max_size() const _NOEXCEPT 1129*0b57cec5SDimitry Andric {return std::min<size_type>( 1130*0b57cec5SDimitry Andric __node_traits::max_size(__node_alloc()), 1131*0b57cec5SDimitry Andric numeric_limits<difference_type >::max());} 1132*0b57cec5SDimitry Andric 1133*0b57cec5SDimitry Andric void clear() _NOEXCEPT; 1134*0b57cec5SDimitry Andric 1135*0b57cec5SDimitry Andric void swap(__tree& __t) 1136*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 11 1137*0b57cec5SDimitry Andric _NOEXCEPT_( 1138*0b57cec5SDimitry Andric __is_nothrow_swappable<value_compare>::value 1139*0b57cec5SDimitry Andric && (!__node_traits::propagate_on_container_swap::value || 1140*0b57cec5SDimitry Andric __is_nothrow_swappable<__node_allocator>::value) 1141*0b57cec5SDimitry Andric ); 1142*0b57cec5SDimitry Andric#else 1143*0b57cec5SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value); 1144*0b57cec5SDimitry Andric#endif 1145*0b57cec5SDimitry Andric 1146*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1147*0b57cec5SDimitry Andric template <class _Key, class ..._Args> 1148*0b57cec5SDimitry Andric pair<iterator, bool> 1149*0b57cec5SDimitry Andric __emplace_unique_key_args(_Key const&, _Args&&... __args); 1150*0b57cec5SDimitry Andric template <class _Key, class ..._Args> 1151*0b57cec5SDimitry Andric iterator 1152*0b57cec5SDimitry Andric __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); 1153*0b57cec5SDimitry Andric 1154*0b57cec5SDimitry Andric template <class... _Args> 1155*0b57cec5SDimitry Andric pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); 1156*0b57cec5SDimitry Andric 1157*0b57cec5SDimitry Andric template <class... _Args> 1158*0b57cec5SDimitry Andric iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); 1159*0b57cec5SDimitry Andric 1160*0b57cec5SDimitry Andric template <class... _Args> 1161*0b57cec5SDimitry Andric iterator __emplace_multi(_Args&&... __args); 1162*0b57cec5SDimitry Andric 1163*0b57cec5SDimitry Andric template <class... _Args> 1164*0b57cec5SDimitry Andric iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); 1165*0b57cec5SDimitry Andric 1166*0b57cec5SDimitry Andric template <class _Pp> 1167*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1168*0b57cec5SDimitry Andric pair<iterator, bool> __emplace_unique(_Pp&& __x) { 1169*0b57cec5SDimitry Andric return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), 1170*0b57cec5SDimitry Andric __can_extract_key<_Pp, key_type>()); 1171*0b57cec5SDimitry Andric } 1172*0b57cec5SDimitry Andric 1173*0b57cec5SDimitry Andric template <class _First, class _Second> 1174*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1175*0b57cec5SDimitry Andric typename enable_if< 1176*0b57cec5SDimitry Andric __can_extract_map_key<_First, key_type, __container_value_type>::value, 1177*0b57cec5SDimitry Andric pair<iterator, bool> 1178*0b57cec5SDimitry Andric >::type __emplace_unique(_First&& __f, _Second&& __s) { 1179*0b57cec5SDimitry Andric return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), 1180*0b57cec5SDimitry Andric _VSTD::forward<_Second>(__s)); 1181*0b57cec5SDimitry Andric } 1182*0b57cec5SDimitry Andric 1183*0b57cec5SDimitry Andric template <class... _Args> 1184*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1185*0b57cec5SDimitry Andric pair<iterator, bool> __emplace_unique(_Args&&... __args) { 1186*0b57cec5SDimitry Andric return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); 1187*0b57cec5SDimitry Andric } 1188*0b57cec5SDimitry Andric 1189*0b57cec5SDimitry Andric template <class _Pp> 1190*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1191*0b57cec5SDimitry Andric pair<iterator, bool> 1192*0b57cec5SDimitry Andric __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { 1193*0b57cec5SDimitry Andric return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); 1194*0b57cec5SDimitry Andric } 1195*0b57cec5SDimitry Andric 1196*0b57cec5SDimitry Andric template <class _Pp> 1197*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1198*0b57cec5SDimitry Andric pair<iterator, bool> 1199*0b57cec5SDimitry Andric __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { 1200*0b57cec5SDimitry Andric return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); 1201*0b57cec5SDimitry Andric } 1202*0b57cec5SDimitry Andric 1203*0b57cec5SDimitry Andric template <class _Pp> 1204*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1205*0b57cec5SDimitry Andric pair<iterator, bool> 1206*0b57cec5SDimitry Andric __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { 1207*0b57cec5SDimitry Andric return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); 1208*0b57cec5SDimitry Andric } 1209*0b57cec5SDimitry Andric 1210*0b57cec5SDimitry Andric template <class _Pp> 1211*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1212*0b57cec5SDimitry Andric iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { 1213*0b57cec5SDimitry Andric return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), 1214*0b57cec5SDimitry Andric __can_extract_key<_Pp, key_type>()); 1215*0b57cec5SDimitry Andric } 1216*0b57cec5SDimitry Andric 1217*0b57cec5SDimitry Andric template <class _First, class _Second> 1218*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1219*0b57cec5SDimitry Andric typename enable_if< 1220*0b57cec5SDimitry Andric __can_extract_map_key<_First, key_type, __container_value_type>::value, 1221*0b57cec5SDimitry Andric iterator 1222*0b57cec5SDimitry Andric >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) { 1223*0b57cec5SDimitry Andric return __emplace_hint_unique_key_args(__p, __f, 1224*0b57cec5SDimitry Andric _VSTD::forward<_First>(__f), 1225*0b57cec5SDimitry Andric _VSTD::forward<_Second>(__s)); 1226*0b57cec5SDimitry Andric } 1227*0b57cec5SDimitry Andric 1228*0b57cec5SDimitry Andric template <class... _Args> 1229*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1230*0b57cec5SDimitry Andric iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { 1231*0b57cec5SDimitry Andric return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); 1232*0b57cec5SDimitry Andric } 1233*0b57cec5SDimitry Andric 1234*0b57cec5SDimitry Andric template <class _Pp> 1235*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1236*0b57cec5SDimitry Andric iterator 1237*0b57cec5SDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { 1238*0b57cec5SDimitry Andric return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x)); 1239*0b57cec5SDimitry Andric } 1240*0b57cec5SDimitry Andric 1241*0b57cec5SDimitry Andric template <class _Pp> 1242*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1243*0b57cec5SDimitry Andric iterator 1244*0b57cec5SDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { 1245*0b57cec5SDimitry Andric return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); 1246*0b57cec5SDimitry Andric } 1247*0b57cec5SDimitry Andric 1248*0b57cec5SDimitry Andric template <class _Pp> 1249*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1250*0b57cec5SDimitry Andric iterator 1251*0b57cec5SDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { 1252*0b57cec5SDimitry Andric return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); 1253*0b57cec5SDimitry Andric } 1254*0b57cec5SDimitry Andric 1255*0b57cec5SDimitry Andric#else 1256*0b57cec5SDimitry Andric template <class _Key, class _Args> 1257*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1258*0b57cec5SDimitry Andric pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args); 1259*0b57cec5SDimitry Andric template <class _Key, class _Args> 1260*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1261*0b57cec5SDimitry Andric iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&); 1262*0b57cec5SDimitry Andric#endif 1263*0b57cec5SDimitry Andric 1264*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1265*0b57cec5SDimitry Andric pair<iterator, bool> __insert_unique(const __container_value_type& __v) { 1266*0b57cec5SDimitry Andric return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v); 1267*0b57cec5SDimitry Andric } 1268*0b57cec5SDimitry Andric 1269*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1270*0b57cec5SDimitry Andric iterator __insert_unique(const_iterator __p, const __container_value_type& __v) { 1271*0b57cec5SDimitry Andric return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v); 1272*0b57cec5SDimitry Andric } 1273*0b57cec5SDimitry Andric 1274*0b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 1275*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1276*0b57cec5SDimitry Andric iterator __insert_multi(const __container_value_type& __v); 1277*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1278*0b57cec5SDimitry Andric iterator __insert_multi(const_iterator __p, const __container_value_type& __v); 1279*0b57cec5SDimitry Andric#else 1280*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1281*0b57cec5SDimitry Andric pair<iterator, bool> __insert_unique(__container_value_type&& __v) { 1282*0b57cec5SDimitry Andric return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v)); 1283*0b57cec5SDimitry Andric } 1284*0b57cec5SDimitry Andric 1285*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1286*0b57cec5SDimitry Andric iterator __insert_unique(const_iterator __p, __container_value_type&& __v) { 1287*0b57cec5SDimitry Andric return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)); 1288*0b57cec5SDimitry Andric } 1289*0b57cec5SDimitry Andric 1290*0b57cec5SDimitry Andric template <class _Vp, class = typename enable_if< 1291*0b57cec5SDimitry Andric !is_same<typename __unconstref<_Vp>::type, 1292*0b57cec5SDimitry Andric __container_value_type 1293*0b57cec5SDimitry Andric >::value 1294*0b57cec5SDimitry Andric >::type> 1295*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1296*0b57cec5SDimitry Andric pair<iterator, bool> __insert_unique(_Vp&& __v) { 1297*0b57cec5SDimitry Andric return __emplace_unique(_VSTD::forward<_Vp>(__v)); 1298*0b57cec5SDimitry Andric } 1299*0b57cec5SDimitry Andric 1300*0b57cec5SDimitry Andric template <class _Vp, class = typename enable_if< 1301*0b57cec5SDimitry Andric !is_same<typename __unconstref<_Vp>::type, 1302*0b57cec5SDimitry Andric __container_value_type 1303*0b57cec5SDimitry Andric >::value 1304*0b57cec5SDimitry Andric >::type> 1305*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1306*0b57cec5SDimitry Andric iterator __insert_unique(const_iterator __p, _Vp&& __v) { 1307*0b57cec5SDimitry Andric return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v)); 1308*0b57cec5SDimitry Andric } 1309*0b57cec5SDimitry Andric 1310*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1311*0b57cec5SDimitry Andric iterator __insert_multi(__container_value_type&& __v) { 1312*0b57cec5SDimitry Andric return __emplace_multi(_VSTD::move(__v)); 1313*0b57cec5SDimitry Andric } 1314*0b57cec5SDimitry Andric 1315*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1316*0b57cec5SDimitry Andric iterator __insert_multi(const_iterator __p, __container_value_type&& __v) { 1317*0b57cec5SDimitry Andric return __emplace_hint_multi(__p, _VSTD::move(__v)); 1318*0b57cec5SDimitry Andric } 1319*0b57cec5SDimitry Andric 1320*0b57cec5SDimitry Andric template <class _Vp> 1321*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1322*0b57cec5SDimitry Andric iterator __insert_multi(_Vp&& __v) { 1323*0b57cec5SDimitry Andric return __emplace_multi(_VSTD::forward<_Vp>(__v)); 1324*0b57cec5SDimitry Andric } 1325*0b57cec5SDimitry Andric 1326*0b57cec5SDimitry Andric template <class _Vp> 1327*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1328*0b57cec5SDimitry Andric iterator __insert_multi(const_iterator __p, _Vp&& __v) { 1329*0b57cec5SDimitry Andric return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v)); 1330*0b57cec5SDimitry Andric } 1331*0b57cec5SDimitry Andric 1332*0b57cec5SDimitry Andric#endif // !_LIBCPP_CXX03_LANG 1333*0b57cec5SDimitry Andric 1334*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1335*0b57cec5SDimitry Andric pair<iterator, bool> __node_assign_unique(const __container_value_type& __v, __node_pointer __dest); 1336*0b57cec5SDimitry Andric 1337*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1338*0b57cec5SDimitry Andric iterator __node_insert_multi(__node_pointer __nd); 1339*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1340*0b57cec5SDimitry Andric iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); 1341*0b57cec5SDimitry Andric 1342*0b57cec5SDimitry Andric 1343*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY iterator 1344*0b57cec5SDimitry Andric __remove_node_pointer(__node_pointer) _NOEXCEPT; 1345*0b57cec5SDimitry Andric 1346*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 1347*0b57cec5SDimitry Andric template <class _NodeHandle, class _InsertReturnType> 1348*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1349*0b57cec5SDimitry Andric _InsertReturnType __node_handle_insert_unique(_NodeHandle&&); 1350*0b57cec5SDimitry Andric template <class _NodeHandle> 1351*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1352*0b57cec5SDimitry Andric iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&); 1353*0b57cec5SDimitry Andric template <class _Tree> 1354*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1355*0b57cec5SDimitry Andric void __node_handle_merge_unique(_Tree& __source); 1356*0b57cec5SDimitry Andric 1357*0b57cec5SDimitry Andric template <class _NodeHandle> 1358*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1359*0b57cec5SDimitry Andric iterator __node_handle_insert_multi(_NodeHandle&&); 1360*0b57cec5SDimitry Andric template <class _NodeHandle> 1361*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1362*0b57cec5SDimitry Andric iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&); 1363*0b57cec5SDimitry Andric template <class _Tree> 1364*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1365*0b57cec5SDimitry Andric void __node_handle_merge_multi(_Tree& __source); 1366*0b57cec5SDimitry Andric 1367*0b57cec5SDimitry Andric 1368*0b57cec5SDimitry Andric template <class _NodeHandle> 1369*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1370*0b57cec5SDimitry Andric _NodeHandle __node_handle_extract(key_type const&); 1371*0b57cec5SDimitry Andric template <class _NodeHandle> 1372*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1373*0b57cec5SDimitry Andric _NodeHandle __node_handle_extract(const_iterator); 1374*0b57cec5SDimitry Andric#endif 1375*0b57cec5SDimitry Andric 1376*0b57cec5SDimitry Andric iterator erase(const_iterator __p); 1377*0b57cec5SDimitry Andric iterator erase(const_iterator __f, const_iterator __l); 1378*0b57cec5SDimitry Andric template <class _Key> 1379*0b57cec5SDimitry Andric size_type __erase_unique(const _Key& __k); 1380*0b57cec5SDimitry Andric template <class _Key> 1381*0b57cec5SDimitry Andric size_type __erase_multi(const _Key& __k); 1382*0b57cec5SDimitry Andric 1383*0b57cec5SDimitry Andric void __insert_node_at(__parent_pointer __parent, 1384*0b57cec5SDimitry Andric __node_base_pointer& __child, 1385*0b57cec5SDimitry Andric __node_base_pointer __new_node) _NOEXCEPT; 1386*0b57cec5SDimitry Andric 1387*0b57cec5SDimitry Andric template <class _Key> 1388*0b57cec5SDimitry Andric iterator find(const _Key& __v); 1389*0b57cec5SDimitry Andric template <class _Key> 1390*0b57cec5SDimitry Andric const_iterator find(const _Key& __v) const; 1391*0b57cec5SDimitry Andric 1392*0b57cec5SDimitry Andric template <class _Key> 1393*0b57cec5SDimitry Andric size_type __count_unique(const _Key& __k) const; 1394*0b57cec5SDimitry Andric template <class _Key> 1395*0b57cec5SDimitry Andric size_type __count_multi(const _Key& __k) const; 1396*0b57cec5SDimitry Andric 1397*0b57cec5SDimitry Andric template <class _Key> 1398*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1399*0b57cec5SDimitry Andric iterator lower_bound(const _Key& __v) 1400*0b57cec5SDimitry Andric {return __lower_bound(__v, __root(), __end_node());} 1401*0b57cec5SDimitry Andric template <class _Key> 1402*0b57cec5SDimitry Andric iterator __lower_bound(const _Key& __v, 1403*0b57cec5SDimitry Andric __node_pointer __root, 1404*0b57cec5SDimitry Andric __iter_pointer __result); 1405*0b57cec5SDimitry Andric template <class _Key> 1406*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1407*0b57cec5SDimitry Andric const_iterator lower_bound(const _Key& __v) const 1408*0b57cec5SDimitry Andric {return __lower_bound(__v, __root(), __end_node());} 1409*0b57cec5SDimitry Andric template <class _Key> 1410*0b57cec5SDimitry Andric const_iterator __lower_bound(const _Key& __v, 1411*0b57cec5SDimitry Andric __node_pointer __root, 1412*0b57cec5SDimitry Andric __iter_pointer __result) const; 1413*0b57cec5SDimitry Andric template <class _Key> 1414*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1415*0b57cec5SDimitry Andric iterator upper_bound(const _Key& __v) 1416*0b57cec5SDimitry Andric {return __upper_bound(__v, __root(), __end_node());} 1417*0b57cec5SDimitry Andric template <class _Key> 1418*0b57cec5SDimitry Andric iterator __upper_bound(const _Key& __v, 1419*0b57cec5SDimitry Andric __node_pointer __root, 1420*0b57cec5SDimitry Andric __iter_pointer __result); 1421*0b57cec5SDimitry Andric template <class _Key> 1422*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1423*0b57cec5SDimitry Andric const_iterator upper_bound(const _Key& __v) const 1424*0b57cec5SDimitry Andric {return __upper_bound(__v, __root(), __end_node());} 1425*0b57cec5SDimitry Andric template <class _Key> 1426*0b57cec5SDimitry Andric const_iterator __upper_bound(const _Key& __v, 1427*0b57cec5SDimitry Andric __node_pointer __root, 1428*0b57cec5SDimitry Andric __iter_pointer __result) const; 1429*0b57cec5SDimitry Andric template <class _Key> 1430*0b57cec5SDimitry Andric pair<iterator, iterator> 1431*0b57cec5SDimitry Andric __equal_range_unique(const _Key& __k); 1432*0b57cec5SDimitry Andric template <class _Key> 1433*0b57cec5SDimitry Andric pair<const_iterator, const_iterator> 1434*0b57cec5SDimitry Andric __equal_range_unique(const _Key& __k) const; 1435*0b57cec5SDimitry Andric 1436*0b57cec5SDimitry Andric template <class _Key> 1437*0b57cec5SDimitry Andric pair<iterator, iterator> 1438*0b57cec5SDimitry Andric __equal_range_multi(const _Key& __k); 1439*0b57cec5SDimitry Andric template <class _Key> 1440*0b57cec5SDimitry Andric pair<const_iterator, const_iterator> 1441*0b57cec5SDimitry Andric __equal_range_multi(const _Key& __k) const; 1442*0b57cec5SDimitry Andric 1443*0b57cec5SDimitry Andric typedef __tree_node_destructor<__node_allocator> _Dp; 1444*0b57cec5SDimitry Andric typedef unique_ptr<__node, _Dp> __node_holder; 1445*0b57cec5SDimitry Andric 1446*0b57cec5SDimitry Andric __node_holder remove(const_iterator __p) _NOEXCEPT; 1447*0b57cec5SDimitry Andricprivate: 1448*0b57cec5SDimitry Andric __node_base_pointer& 1449*0b57cec5SDimitry Andric __find_leaf_low(__parent_pointer& __parent, const key_type& __v); 1450*0b57cec5SDimitry Andric __node_base_pointer& 1451*0b57cec5SDimitry Andric __find_leaf_high(__parent_pointer& __parent, const key_type& __v); 1452*0b57cec5SDimitry Andric __node_base_pointer& 1453*0b57cec5SDimitry Andric __find_leaf(const_iterator __hint, 1454*0b57cec5SDimitry Andric __parent_pointer& __parent, const key_type& __v); 1455*0b57cec5SDimitry Andric // FIXME: Make this function const qualified. Unfortunetly doing so 1456*0b57cec5SDimitry Andric // breaks existing code which uses non-const callable comparators. 1457*0b57cec5SDimitry Andric template <class _Key> 1458*0b57cec5SDimitry Andric __node_base_pointer& 1459*0b57cec5SDimitry Andric __find_equal(__parent_pointer& __parent, const _Key& __v); 1460*0b57cec5SDimitry Andric template <class _Key> 1461*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __node_base_pointer& 1462*0b57cec5SDimitry Andric __find_equal(__parent_pointer& __parent, const _Key& __v) const { 1463*0b57cec5SDimitry Andric return const_cast<__tree*>(this)->__find_equal(__parent, __v); 1464*0b57cec5SDimitry Andric } 1465*0b57cec5SDimitry Andric template <class _Key> 1466*0b57cec5SDimitry Andric __node_base_pointer& 1467*0b57cec5SDimitry Andric __find_equal(const_iterator __hint, __parent_pointer& __parent, 1468*0b57cec5SDimitry Andric __node_base_pointer& __dummy, 1469*0b57cec5SDimitry Andric const _Key& __v); 1470*0b57cec5SDimitry Andric 1471*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1472*0b57cec5SDimitry Andric template <class ..._Args> 1473*0b57cec5SDimitry Andric __node_holder __construct_node(_Args&& ...__args); 1474*0b57cec5SDimitry Andric#else 1475*0b57cec5SDimitry Andric __node_holder __construct_node(const __container_value_type& __v); 1476*0b57cec5SDimitry Andric#endif 1477*0b57cec5SDimitry Andric 1478*0b57cec5SDimitry Andric void destroy(__node_pointer __nd) _NOEXCEPT; 1479*0b57cec5SDimitry Andric 1480*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1481*0b57cec5SDimitry Andric void __copy_assign_alloc(const __tree& __t) 1482*0b57cec5SDimitry Andric {__copy_assign_alloc(__t, integral_constant<bool, 1483*0b57cec5SDimitry Andric __node_traits::propagate_on_container_copy_assignment::value>());} 1484*0b57cec5SDimitry Andric 1485*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1486*0b57cec5SDimitry Andric void __copy_assign_alloc(const __tree& __t, true_type) 1487*0b57cec5SDimitry Andric { 1488*0b57cec5SDimitry Andric if (__node_alloc() != __t.__node_alloc()) 1489*0b57cec5SDimitry Andric clear(); 1490*0b57cec5SDimitry Andric __node_alloc() = __t.__node_alloc(); 1491*0b57cec5SDimitry Andric } 1492*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1493*0b57cec5SDimitry Andric void __copy_assign_alloc(const __tree&, false_type) {} 1494*0b57cec5SDimitry Andric 1495*0b57cec5SDimitry Andric void __move_assign(__tree& __t, false_type); 1496*0b57cec5SDimitry Andric void __move_assign(__tree& __t, true_type) 1497*0b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value && 1498*0b57cec5SDimitry Andric is_nothrow_move_assignable<__node_allocator>::value); 1499*0b57cec5SDimitry Andric 1500*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1501*0b57cec5SDimitry Andric void __move_assign_alloc(__tree& __t) 1502*0b57cec5SDimitry Andric _NOEXCEPT_( 1503*0b57cec5SDimitry Andric !__node_traits::propagate_on_container_move_assignment::value || 1504*0b57cec5SDimitry Andric is_nothrow_move_assignable<__node_allocator>::value) 1505*0b57cec5SDimitry Andric {__move_assign_alloc(__t, integral_constant<bool, 1506*0b57cec5SDimitry Andric __node_traits::propagate_on_container_move_assignment::value>());} 1507*0b57cec5SDimitry Andric 1508*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1509*0b57cec5SDimitry Andric void __move_assign_alloc(__tree& __t, true_type) 1510*0b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) 1511*0b57cec5SDimitry Andric {__node_alloc() = _VSTD::move(__t.__node_alloc());} 1512*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1513*0b57cec5SDimitry Andric void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {} 1514*0b57cec5SDimitry Andric 1515*0b57cec5SDimitry Andric struct _DetachedTreeCache { 1516*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1517*0b57cec5SDimitry Andric explicit _DetachedTreeCache(__tree *__t) _NOEXCEPT : __t_(__t), 1518*0b57cec5SDimitry Andric __cache_root_(__detach_from_tree(__t)) { 1519*0b57cec5SDimitry Andric __advance(); 1520*0b57cec5SDimitry Andric } 1521*0b57cec5SDimitry Andric 1522*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1523*0b57cec5SDimitry Andric __node_pointer __get() const _NOEXCEPT { 1524*0b57cec5SDimitry Andric return __cache_elem_; 1525*0b57cec5SDimitry Andric } 1526*0b57cec5SDimitry Andric 1527*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1528*0b57cec5SDimitry Andric void __advance() _NOEXCEPT { 1529*0b57cec5SDimitry Andric __cache_elem_ = __cache_root_; 1530*0b57cec5SDimitry Andric if (__cache_root_) { 1531*0b57cec5SDimitry Andric __cache_root_ = __detach_next(__cache_root_); 1532*0b57cec5SDimitry Andric } 1533*0b57cec5SDimitry Andric } 1534*0b57cec5SDimitry Andric 1535*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1536*0b57cec5SDimitry Andric ~_DetachedTreeCache() { 1537*0b57cec5SDimitry Andric __t_->destroy(__cache_elem_); 1538*0b57cec5SDimitry Andric if (__cache_root_) { 1539*0b57cec5SDimitry Andric while (__cache_root_->__parent_ != nullptr) 1540*0b57cec5SDimitry Andric __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_); 1541*0b57cec5SDimitry Andric __t_->destroy(__cache_root_); 1542*0b57cec5SDimitry Andric } 1543*0b57cec5SDimitry Andric } 1544*0b57cec5SDimitry Andric 1545*0b57cec5SDimitry Andric _DetachedTreeCache(_DetachedTreeCache const&) = delete; 1546*0b57cec5SDimitry Andric _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete; 1547*0b57cec5SDimitry Andric 1548*0b57cec5SDimitry Andric private: 1549*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1550*0b57cec5SDimitry Andric static __node_pointer __detach_from_tree(__tree *__t) _NOEXCEPT; 1551*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1552*0b57cec5SDimitry Andric static __node_pointer __detach_next(__node_pointer) _NOEXCEPT; 1553*0b57cec5SDimitry Andric 1554*0b57cec5SDimitry Andric __tree *__t_; 1555*0b57cec5SDimitry Andric __node_pointer __cache_root_; 1556*0b57cec5SDimitry Andric __node_pointer __cache_elem_; 1557*0b57cec5SDimitry Andric }; 1558*0b57cec5SDimitry Andric 1559*0b57cec5SDimitry Andric 1560*0b57cec5SDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 1561*0b57cec5SDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 1562*0b57cec5SDimitry Andric}; 1563*0b57cec5SDimitry Andric 1564*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1565*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) 1566*0b57cec5SDimitry Andric _NOEXCEPT_( 1567*0b57cec5SDimitry Andric is_nothrow_default_constructible<__node_allocator>::value && 1568*0b57cec5SDimitry Andric is_nothrow_copy_constructible<value_compare>::value) 1569*0b57cec5SDimitry Andric : __pair3_(0, __comp) 1570*0b57cec5SDimitry Andric{ 1571*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1572*0b57cec5SDimitry Andric} 1573*0b57cec5SDimitry Andric 1574*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1575*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) 1576*0b57cec5SDimitry Andric : __begin_node_(__iter_pointer()), 1577*0b57cec5SDimitry Andric __pair1_(__second_tag(), __node_allocator(__a)), 1578*0b57cec5SDimitry Andric __pair3_(0) 1579*0b57cec5SDimitry Andric{ 1580*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1581*0b57cec5SDimitry Andric} 1582*0b57cec5SDimitry Andric 1583*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1584*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, 1585*0b57cec5SDimitry Andric const allocator_type& __a) 1586*0b57cec5SDimitry Andric : __begin_node_(__iter_pointer()), 1587*0b57cec5SDimitry Andric __pair1_(__second_tag(), __node_allocator(__a)), 1588*0b57cec5SDimitry Andric __pair3_(0, __comp) 1589*0b57cec5SDimitry Andric{ 1590*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1591*0b57cec5SDimitry Andric} 1592*0b57cec5SDimitry Andric 1593*0b57cec5SDimitry Andric// Precondition: size() != 0 1594*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1595*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_pointer 1596*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree *__t) _NOEXCEPT 1597*0b57cec5SDimitry Andric{ 1598*0b57cec5SDimitry Andric __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node()); 1599*0b57cec5SDimitry Andric __t->__begin_node() = __t->__end_node(); 1600*0b57cec5SDimitry Andric __t->__end_node()->__left_->__parent_ = nullptr; 1601*0b57cec5SDimitry Andric __t->__end_node()->__left_ = nullptr; 1602*0b57cec5SDimitry Andric __t->size() = 0; 1603*0b57cec5SDimitry Andric // __cache->__left_ == nullptr 1604*0b57cec5SDimitry Andric if (__cache->__right_ != nullptr) 1605*0b57cec5SDimitry Andric __cache = static_cast<__node_pointer>(__cache->__right_); 1606*0b57cec5SDimitry Andric // __cache->__left_ == nullptr 1607*0b57cec5SDimitry Andric // __cache->__right_ == nullptr 1608*0b57cec5SDimitry Andric return __cache; 1609*0b57cec5SDimitry Andric} 1610*0b57cec5SDimitry Andric 1611*0b57cec5SDimitry Andric// Precondition: __cache != nullptr 1612*0b57cec5SDimitry Andric// __cache->left_ == nullptr 1613*0b57cec5SDimitry Andric// __cache->right_ == nullptr 1614*0b57cec5SDimitry Andric// This is no longer a red-black tree 1615*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1616*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_pointer 1617*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT 1618*0b57cec5SDimitry Andric{ 1619*0b57cec5SDimitry Andric if (__cache->__parent_ == nullptr) 1620*0b57cec5SDimitry Andric return nullptr; 1621*0b57cec5SDimitry Andric if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) 1622*0b57cec5SDimitry Andric { 1623*0b57cec5SDimitry Andric __cache->__parent_->__left_ = nullptr; 1624*0b57cec5SDimitry Andric __cache = static_cast<__node_pointer>(__cache->__parent_); 1625*0b57cec5SDimitry Andric if (__cache->__right_ == nullptr) 1626*0b57cec5SDimitry Andric return __cache; 1627*0b57cec5SDimitry Andric return static_cast<__node_pointer>(__tree_leaf(__cache->__right_)); 1628*0b57cec5SDimitry Andric } 1629*0b57cec5SDimitry Andric // __cache is right child 1630*0b57cec5SDimitry Andric __cache->__parent_unsafe()->__right_ = nullptr; 1631*0b57cec5SDimitry Andric __cache = static_cast<__node_pointer>(__cache->__parent_); 1632*0b57cec5SDimitry Andric if (__cache->__left_ == nullptr) 1633*0b57cec5SDimitry Andric return __cache; 1634*0b57cec5SDimitry Andric return static_cast<__node_pointer>(__tree_leaf(__cache->__left_)); 1635*0b57cec5SDimitry Andric} 1636*0b57cec5SDimitry Andric 1637*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1638*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>& 1639*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) 1640*0b57cec5SDimitry Andric{ 1641*0b57cec5SDimitry Andric if (this != &__t) 1642*0b57cec5SDimitry Andric { 1643*0b57cec5SDimitry Andric value_comp() = __t.value_comp(); 1644*0b57cec5SDimitry Andric __copy_assign_alloc(__t); 1645*0b57cec5SDimitry Andric __assign_multi(__t.begin(), __t.end()); 1646*0b57cec5SDimitry Andric } 1647*0b57cec5SDimitry Andric return *this; 1648*0b57cec5SDimitry Andric} 1649*0b57cec5SDimitry Andric 1650*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1651*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 1652*0b57cec5SDimitry Andricvoid 1653*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last) 1654*0b57cec5SDimitry Andric{ 1655*0b57cec5SDimitry Andric typedef iterator_traits<_ForwardIterator> _ITraits; 1656*0b57cec5SDimitry Andric typedef typename _ITraits::value_type _ItValueType; 1657*0b57cec5SDimitry Andric static_assert((is_same<_ItValueType, __container_value_type>::value), 1658*0b57cec5SDimitry Andric "__assign_unique may only be called with the containers value type"); 1659*0b57cec5SDimitry Andric static_assert(__is_forward_iterator<_ForwardIterator>::value, 1660*0b57cec5SDimitry Andric "__assign_unique requires a forward iterator"); 1661*0b57cec5SDimitry Andric if (size() != 0) 1662*0b57cec5SDimitry Andric { 1663*0b57cec5SDimitry Andric _DetachedTreeCache __cache(this); 1664*0b57cec5SDimitry Andric for (; __cache.__get() != nullptr && __first != __last; ++__first) { 1665*0b57cec5SDimitry Andric if (__node_assign_unique(*__first, __cache.__get()).second) 1666*0b57cec5SDimitry Andric __cache.__advance(); 1667*0b57cec5SDimitry Andric } 1668*0b57cec5SDimitry Andric } 1669*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 1670*0b57cec5SDimitry Andric __insert_unique(*__first); 1671*0b57cec5SDimitry Andric} 1672*0b57cec5SDimitry Andric 1673*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1674*0b57cec5SDimitry Andrictemplate <class _InputIterator> 1675*0b57cec5SDimitry Andricvoid 1676*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) 1677*0b57cec5SDimitry Andric{ 1678*0b57cec5SDimitry Andric typedef iterator_traits<_InputIterator> _ITraits; 1679*0b57cec5SDimitry Andric typedef typename _ITraits::value_type _ItValueType; 1680*0b57cec5SDimitry Andric static_assert((is_same<_ItValueType, __container_value_type>::value || 1681*0b57cec5SDimitry Andric is_same<_ItValueType, __node_value_type>::value), 1682*0b57cec5SDimitry Andric "__assign_multi may only be called with the containers value type" 1683*0b57cec5SDimitry Andric " or the nodes value type"); 1684*0b57cec5SDimitry Andric if (size() != 0) 1685*0b57cec5SDimitry Andric { 1686*0b57cec5SDimitry Andric _DetachedTreeCache __cache(this); 1687*0b57cec5SDimitry Andric for (; __cache.__get() && __first != __last; ++__first) { 1688*0b57cec5SDimitry Andric __cache.__get()->__value_ = *__first; 1689*0b57cec5SDimitry Andric __node_insert_multi(__cache.__get()); 1690*0b57cec5SDimitry Andric __cache.__advance(); 1691*0b57cec5SDimitry Andric } 1692*0b57cec5SDimitry Andric } 1693*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 1694*0b57cec5SDimitry Andric __insert_multi(_NodeTypes::__get_value(*__first)); 1695*0b57cec5SDimitry Andric} 1696*0b57cec5SDimitry Andric 1697*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1698*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) 1699*0b57cec5SDimitry Andric : __begin_node_(__iter_pointer()), 1700*0b57cec5SDimitry Andric __pair1_(__second_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())), 1701*0b57cec5SDimitry Andric __pair3_(0, __t.value_comp()) 1702*0b57cec5SDimitry Andric{ 1703*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1704*0b57cec5SDimitry Andric} 1705*0b57cec5SDimitry Andric 1706*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1707*0b57cec5SDimitry Andric 1708*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1709*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) 1710*0b57cec5SDimitry Andric _NOEXCEPT_( 1711*0b57cec5SDimitry Andric is_nothrow_move_constructible<__node_allocator>::value && 1712*0b57cec5SDimitry Andric is_nothrow_move_constructible<value_compare>::value) 1713*0b57cec5SDimitry Andric : __begin_node_(_VSTD::move(__t.__begin_node_)), 1714*0b57cec5SDimitry Andric __pair1_(_VSTD::move(__t.__pair1_)), 1715*0b57cec5SDimitry Andric __pair3_(_VSTD::move(__t.__pair3_)) 1716*0b57cec5SDimitry Andric{ 1717*0b57cec5SDimitry Andric if (size() == 0) 1718*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1719*0b57cec5SDimitry Andric else 1720*0b57cec5SDimitry Andric { 1721*0b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 1722*0b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 1723*0b57cec5SDimitry Andric __t.__end_node()->__left_ = nullptr; 1724*0b57cec5SDimitry Andric __t.size() = 0; 1725*0b57cec5SDimitry Andric } 1726*0b57cec5SDimitry Andric} 1727*0b57cec5SDimitry Andric 1728*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1729*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) 1730*0b57cec5SDimitry Andric : __pair1_(__second_tag(), __node_allocator(__a)), 1731*0b57cec5SDimitry Andric __pair3_(0, _VSTD::move(__t.value_comp())) 1732*0b57cec5SDimitry Andric{ 1733*0b57cec5SDimitry Andric if (__a == __t.__alloc()) 1734*0b57cec5SDimitry Andric { 1735*0b57cec5SDimitry Andric if (__t.size() == 0) 1736*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1737*0b57cec5SDimitry Andric else 1738*0b57cec5SDimitry Andric { 1739*0b57cec5SDimitry Andric __begin_node() = __t.__begin_node(); 1740*0b57cec5SDimitry Andric __end_node()->__left_ = __t.__end_node()->__left_; 1741*0b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 1742*0b57cec5SDimitry Andric size() = __t.size(); 1743*0b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 1744*0b57cec5SDimitry Andric __t.__end_node()->__left_ = nullptr; 1745*0b57cec5SDimitry Andric __t.size() = 0; 1746*0b57cec5SDimitry Andric } 1747*0b57cec5SDimitry Andric } 1748*0b57cec5SDimitry Andric else 1749*0b57cec5SDimitry Andric { 1750*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1751*0b57cec5SDimitry Andric } 1752*0b57cec5SDimitry Andric} 1753*0b57cec5SDimitry Andric 1754*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1755*0b57cec5SDimitry Andricvoid 1756*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) 1757*0b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value && 1758*0b57cec5SDimitry Andric is_nothrow_move_assignable<__node_allocator>::value) 1759*0b57cec5SDimitry Andric{ 1760*0b57cec5SDimitry Andric destroy(static_cast<__node_pointer>(__end_node()->__left_)); 1761*0b57cec5SDimitry Andric __begin_node_ = __t.__begin_node_; 1762*0b57cec5SDimitry Andric __pair1_.first() = __t.__pair1_.first(); 1763*0b57cec5SDimitry Andric __move_assign_alloc(__t); 1764*0b57cec5SDimitry Andric __pair3_ = _VSTD::move(__t.__pair3_); 1765*0b57cec5SDimitry Andric if (size() == 0) 1766*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1767*0b57cec5SDimitry Andric else 1768*0b57cec5SDimitry Andric { 1769*0b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 1770*0b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 1771*0b57cec5SDimitry Andric __t.__end_node()->__left_ = nullptr; 1772*0b57cec5SDimitry Andric __t.size() = 0; 1773*0b57cec5SDimitry Andric } 1774*0b57cec5SDimitry Andric} 1775*0b57cec5SDimitry Andric 1776*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1777*0b57cec5SDimitry Andricvoid 1778*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) 1779*0b57cec5SDimitry Andric{ 1780*0b57cec5SDimitry Andric if (__node_alloc() == __t.__node_alloc()) 1781*0b57cec5SDimitry Andric __move_assign(__t, true_type()); 1782*0b57cec5SDimitry Andric else 1783*0b57cec5SDimitry Andric { 1784*0b57cec5SDimitry Andric value_comp() = _VSTD::move(__t.value_comp()); 1785*0b57cec5SDimitry Andric const_iterator __e = end(); 1786*0b57cec5SDimitry Andric if (size() != 0) 1787*0b57cec5SDimitry Andric { 1788*0b57cec5SDimitry Andric _DetachedTreeCache __cache(this); 1789*0b57cec5SDimitry Andric while (__cache.__get() != nullptr && __t.size() != 0) { 1790*0b57cec5SDimitry Andric __cache.__get()->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_); 1791*0b57cec5SDimitry Andric __node_insert_multi(__cache.__get()); 1792*0b57cec5SDimitry Andric __cache.__advance(); 1793*0b57cec5SDimitry Andric } 1794*0b57cec5SDimitry Andric } 1795*0b57cec5SDimitry Andric while (__t.size() != 0) 1796*0b57cec5SDimitry Andric __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); 1797*0b57cec5SDimitry Andric } 1798*0b57cec5SDimitry Andric} 1799*0b57cec5SDimitry Andric 1800*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1801*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>& 1802*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) 1803*0b57cec5SDimitry Andric _NOEXCEPT_( 1804*0b57cec5SDimitry Andric __node_traits::propagate_on_container_move_assignment::value && 1805*0b57cec5SDimitry Andric is_nothrow_move_assignable<value_compare>::value && 1806*0b57cec5SDimitry Andric is_nothrow_move_assignable<__node_allocator>::value) 1807*0b57cec5SDimitry Andric 1808*0b57cec5SDimitry Andric{ 1809*0b57cec5SDimitry Andric __move_assign(__t, integral_constant<bool, 1810*0b57cec5SDimitry Andric __node_traits::propagate_on_container_move_assignment::value>()); 1811*0b57cec5SDimitry Andric return *this; 1812*0b57cec5SDimitry Andric} 1813*0b57cec5SDimitry Andric 1814*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 1815*0b57cec5SDimitry Andric 1816*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1817*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::~__tree() 1818*0b57cec5SDimitry Andric{ 1819*0b57cec5SDimitry Andric static_assert((is_copy_constructible<value_compare>::value), 1820*0b57cec5SDimitry Andric "Comparator must be copy-constructible."); 1821*0b57cec5SDimitry Andric destroy(__root()); 1822*0b57cec5SDimitry Andric} 1823*0b57cec5SDimitry Andric 1824*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1825*0b57cec5SDimitry Andricvoid 1826*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT 1827*0b57cec5SDimitry Andric{ 1828*0b57cec5SDimitry Andric if (__nd != nullptr) 1829*0b57cec5SDimitry Andric { 1830*0b57cec5SDimitry Andric destroy(static_cast<__node_pointer>(__nd->__left_)); 1831*0b57cec5SDimitry Andric destroy(static_cast<__node_pointer>(__nd->__right_)); 1832*0b57cec5SDimitry Andric __node_allocator& __na = __node_alloc(); 1833*0b57cec5SDimitry Andric __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); 1834*0b57cec5SDimitry Andric __node_traits::deallocate(__na, __nd, 1); 1835*0b57cec5SDimitry Andric } 1836*0b57cec5SDimitry Andric} 1837*0b57cec5SDimitry Andric 1838*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1839*0b57cec5SDimitry Andricvoid 1840*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) 1841*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 11 1842*0b57cec5SDimitry Andric _NOEXCEPT_( 1843*0b57cec5SDimitry Andric __is_nothrow_swappable<value_compare>::value 1844*0b57cec5SDimitry Andric && (!__node_traits::propagate_on_container_swap::value || 1845*0b57cec5SDimitry Andric __is_nothrow_swappable<__node_allocator>::value) 1846*0b57cec5SDimitry Andric ) 1847*0b57cec5SDimitry Andric#else 1848*0b57cec5SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value) 1849*0b57cec5SDimitry Andric#endif 1850*0b57cec5SDimitry Andric{ 1851*0b57cec5SDimitry Andric using _VSTD::swap; 1852*0b57cec5SDimitry Andric swap(__begin_node_, __t.__begin_node_); 1853*0b57cec5SDimitry Andric swap(__pair1_.first(), __t.__pair1_.first()); 1854*0b57cec5SDimitry Andric __swap_allocator(__node_alloc(), __t.__node_alloc()); 1855*0b57cec5SDimitry Andric __pair3_.swap(__t.__pair3_); 1856*0b57cec5SDimitry Andric if (size() == 0) 1857*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1858*0b57cec5SDimitry Andric else 1859*0b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 1860*0b57cec5SDimitry Andric if (__t.size() == 0) 1861*0b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 1862*0b57cec5SDimitry Andric else 1863*0b57cec5SDimitry Andric __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node()); 1864*0b57cec5SDimitry Andric} 1865*0b57cec5SDimitry Andric 1866*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1867*0b57cec5SDimitry Andricvoid 1868*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT 1869*0b57cec5SDimitry Andric{ 1870*0b57cec5SDimitry Andric destroy(__root()); 1871*0b57cec5SDimitry Andric size() = 0; 1872*0b57cec5SDimitry Andric __begin_node() = __end_node(); 1873*0b57cec5SDimitry Andric __end_node()->__left_ = nullptr; 1874*0b57cec5SDimitry Andric} 1875*0b57cec5SDimitry Andric 1876*0b57cec5SDimitry Andric// Find lower_bound place to insert 1877*0b57cec5SDimitry Andric// Set __parent to parent of null leaf 1878*0b57cec5SDimitry Andric// Return reference to null leaf 1879*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1880*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1881*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent, 1882*0b57cec5SDimitry Andric const key_type& __v) 1883*0b57cec5SDimitry Andric{ 1884*0b57cec5SDimitry Andric __node_pointer __nd = __root(); 1885*0b57cec5SDimitry Andric if (__nd != nullptr) 1886*0b57cec5SDimitry Andric { 1887*0b57cec5SDimitry Andric while (true) 1888*0b57cec5SDimitry Andric { 1889*0b57cec5SDimitry Andric if (value_comp()(__nd->__value_, __v)) 1890*0b57cec5SDimitry Andric { 1891*0b57cec5SDimitry Andric if (__nd->__right_ != nullptr) 1892*0b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__right_); 1893*0b57cec5SDimitry Andric else 1894*0b57cec5SDimitry Andric { 1895*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 1896*0b57cec5SDimitry Andric return __nd->__right_; 1897*0b57cec5SDimitry Andric } 1898*0b57cec5SDimitry Andric } 1899*0b57cec5SDimitry Andric else 1900*0b57cec5SDimitry Andric { 1901*0b57cec5SDimitry Andric if (__nd->__left_ != nullptr) 1902*0b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__left_); 1903*0b57cec5SDimitry Andric else 1904*0b57cec5SDimitry Andric { 1905*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 1906*0b57cec5SDimitry Andric return __parent->__left_; 1907*0b57cec5SDimitry Andric } 1908*0b57cec5SDimitry Andric } 1909*0b57cec5SDimitry Andric } 1910*0b57cec5SDimitry Andric } 1911*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 1912*0b57cec5SDimitry Andric return __parent->__left_; 1913*0b57cec5SDimitry Andric} 1914*0b57cec5SDimitry Andric 1915*0b57cec5SDimitry Andric// Find upper_bound place to insert 1916*0b57cec5SDimitry Andric// Set __parent to parent of null leaf 1917*0b57cec5SDimitry Andric// Return reference to null leaf 1918*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1919*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1920*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent, 1921*0b57cec5SDimitry Andric const key_type& __v) 1922*0b57cec5SDimitry Andric{ 1923*0b57cec5SDimitry Andric __node_pointer __nd = __root(); 1924*0b57cec5SDimitry Andric if (__nd != nullptr) 1925*0b57cec5SDimitry Andric { 1926*0b57cec5SDimitry Andric while (true) 1927*0b57cec5SDimitry Andric { 1928*0b57cec5SDimitry Andric if (value_comp()(__v, __nd->__value_)) 1929*0b57cec5SDimitry Andric { 1930*0b57cec5SDimitry Andric if (__nd->__left_ != nullptr) 1931*0b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__left_); 1932*0b57cec5SDimitry Andric else 1933*0b57cec5SDimitry Andric { 1934*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 1935*0b57cec5SDimitry Andric return __parent->__left_; 1936*0b57cec5SDimitry Andric } 1937*0b57cec5SDimitry Andric } 1938*0b57cec5SDimitry Andric else 1939*0b57cec5SDimitry Andric { 1940*0b57cec5SDimitry Andric if (__nd->__right_ != nullptr) 1941*0b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__right_); 1942*0b57cec5SDimitry Andric else 1943*0b57cec5SDimitry Andric { 1944*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 1945*0b57cec5SDimitry Andric return __nd->__right_; 1946*0b57cec5SDimitry Andric } 1947*0b57cec5SDimitry Andric } 1948*0b57cec5SDimitry Andric } 1949*0b57cec5SDimitry Andric } 1950*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 1951*0b57cec5SDimitry Andric return __parent->__left_; 1952*0b57cec5SDimitry Andric} 1953*0b57cec5SDimitry Andric 1954*0b57cec5SDimitry Andric// Find leaf place to insert closest to __hint 1955*0b57cec5SDimitry Andric// First check prior to __hint. 1956*0b57cec5SDimitry Andric// Next check after __hint. 1957*0b57cec5SDimitry Andric// Next do O(log N) search. 1958*0b57cec5SDimitry Andric// Set __parent to parent of null leaf 1959*0b57cec5SDimitry Andric// Return reference to null leaf 1960*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1961*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1962*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, 1963*0b57cec5SDimitry Andric __parent_pointer& __parent, 1964*0b57cec5SDimitry Andric const key_type& __v) 1965*0b57cec5SDimitry Andric{ 1966*0b57cec5SDimitry Andric if (__hint == end() || !value_comp()(*__hint, __v)) // check before 1967*0b57cec5SDimitry Andric { 1968*0b57cec5SDimitry Andric // __v <= *__hint 1969*0b57cec5SDimitry Andric const_iterator __prior = __hint; 1970*0b57cec5SDimitry Andric if (__prior == begin() || !value_comp()(__v, *--__prior)) 1971*0b57cec5SDimitry Andric { 1972*0b57cec5SDimitry Andric // *prev(__hint) <= __v <= *__hint 1973*0b57cec5SDimitry Andric if (__hint.__ptr_->__left_ == nullptr) 1974*0b57cec5SDimitry Andric { 1975*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 1976*0b57cec5SDimitry Andric return __parent->__left_; 1977*0b57cec5SDimitry Andric } 1978*0b57cec5SDimitry Andric else 1979*0b57cec5SDimitry Andric { 1980*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__prior.__ptr_); 1981*0b57cec5SDimitry Andric return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; 1982*0b57cec5SDimitry Andric } 1983*0b57cec5SDimitry Andric } 1984*0b57cec5SDimitry Andric // __v < *prev(__hint) 1985*0b57cec5SDimitry Andric return __find_leaf_high(__parent, __v); 1986*0b57cec5SDimitry Andric } 1987*0b57cec5SDimitry Andric // else __v > *__hint 1988*0b57cec5SDimitry Andric return __find_leaf_low(__parent, __v); 1989*0b57cec5SDimitry Andric} 1990*0b57cec5SDimitry Andric 1991*0b57cec5SDimitry Andric// Find place to insert if __v doesn't exist 1992*0b57cec5SDimitry Andric// Set __parent to parent of null leaf 1993*0b57cec5SDimitry Andric// Return reference to null leaf 1994*0b57cec5SDimitry Andric// If __v exists, set parent to node of __v and return reference to node of __v 1995*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1996*0b57cec5SDimitry Andrictemplate <class _Key> 1997*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1998*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent, 1999*0b57cec5SDimitry Andric const _Key& __v) 2000*0b57cec5SDimitry Andric{ 2001*0b57cec5SDimitry Andric __node_pointer __nd = __root(); 2002*0b57cec5SDimitry Andric __node_base_pointer* __nd_ptr = __root_ptr(); 2003*0b57cec5SDimitry Andric if (__nd != nullptr) 2004*0b57cec5SDimitry Andric { 2005*0b57cec5SDimitry Andric while (true) 2006*0b57cec5SDimitry Andric { 2007*0b57cec5SDimitry Andric if (value_comp()(__v, __nd->__value_)) 2008*0b57cec5SDimitry Andric { 2009*0b57cec5SDimitry Andric if (__nd->__left_ != nullptr) { 2010*0b57cec5SDimitry Andric __nd_ptr = _VSTD::addressof(__nd->__left_); 2011*0b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__left_); 2012*0b57cec5SDimitry Andric } else { 2013*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 2014*0b57cec5SDimitry Andric return __parent->__left_; 2015*0b57cec5SDimitry Andric } 2016*0b57cec5SDimitry Andric } 2017*0b57cec5SDimitry Andric else if (value_comp()(__nd->__value_, __v)) 2018*0b57cec5SDimitry Andric { 2019*0b57cec5SDimitry Andric if (__nd->__right_ != nullptr) { 2020*0b57cec5SDimitry Andric __nd_ptr = _VSTD::addressof(__nd->__right_); 2021*0b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__right_); 2022*0b57cec5SDimitry Andric } else { 2023*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 2024*0b57cec5SDimitry Andric return __nd->__right_; 2025*0b57cec5SDimitry Andric } 2026*0b57cec5SDimitry Andric } 2027*0b57cec5SDimitry Andric else 2028*0b57cec5SDimitry Andric { 2029*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 2030*0b57cec5SDimitry Andric return *__nd_ptr; 2031*0b57cec5SDimitry Andric } 2032*0b57cec5SDimitry Andric } 2033*0b57cec5SDimitry Andric } 2034*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 2035*0b57cec5SDimitry Andric return __parent->__left_; 2036*0b57cec5SDimitry Andric} 2037*0b57cec5SDimitry Andric 2038*0b57cec5SDimitry Andric// Find place to insert if __v doesn't exist 2039*0b57cec5SDimitry Andric// First check prior to __hint. 2040*0b57cec5SDimitry Andric// Next check after __hint. 2041*0b57cec5SDimitry Andric// Next do O(log N) search. 2042*0b57cec5SDimitry Andric// Set __parent to parent of null leaf 2043*0b57cec5SDimitry Andric// Return reference to null leaf 2044*0b57cec5SDimitry Andric// If __v exists, set parent to node of __v and return reference to node of __v 2045*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2046*0b57cec5SDimitry Andrictemplate <class _Key> 2047*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 2048*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, 2049*0b57cec5SDimitry Andric __parent_pointer& __parent, 2050*0b57cec5SDimitry Andric __node_base_pointer& __dummy, 2051*0b57cec5SDimitry Andric const _Key& __v) 2052*0b57cec5SDimitry Andric{ 2053*0b57cec5SDimitry Andric if (__hint == end() || value_comp()(__v, *__hint)) // check before 2054*0b57cec5SDimitry Andric { 2055*0b57cec5SDimitry Andric // __v < *__hint 2056*0b57cec5SDimitry Andric const_iterator __prior = __hint; 2057*0b57cec5SDimitry Andric if (__prior == begin() || value_comp()(*--__prior, __v)) 2058*0b57cec5SDimitry Andric { 2059*0b57cec5SDimitry Andric // *prev(__hint) < __v < *__hint 2060*0b57cec5SDimitry Andric if (__hint.__ptr_->__left_ == nullptr) 2061*0b57cec5SDimitry Andric { 2062*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 2063*0b57cec5SDimitry Andric return __parent->__left_; 2064*0b57cec5SDimitry Andric } 2065*0b57cec5SDimitry Andric else 2066*0b57cec5SDimitry Andric { 2067*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__prior.__ptr_); 2068*0b57cec5SDimitry Andric return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; 2069*0b57cec5SDimitry Andric } 2070*0b57cec5SDimitry Andric } 2071*0b57cec5SDimitry Andric // __v <= *prev(__hint) 2072*0b57cec5SDimitry Andric return __find_equal(__parent, __v); 2073*0b57cec5SDimitry Andric } 2074*0b57cec5SDimitry Andric else if (value_comp()(*__hint, __v)) // check after 2075*0b57cec5SDimitry Andric { 2076*0b57cec5SDimitry Andric // *__hint < __v 2077*0b57cec5SDimitry Andric const_iterator __next = _VSTD::next(__hint); 2078*0b57cec5SDimitry Andric if (__next == end() || value_comp()(__v, *__next)) 2079*0b57cec5SDimitry Andric { 2080*0b57cec5SDimitry Andric // *__hint < __v < *_VSTD::next(__hint) 2081*0b57cec5SDimitry Andric if (__hint.__get_np()->__right_ == nullptr) 2082*0b57cec5SDimitry Andric { 2083*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 2084*0b57cec5SDimitry Andric return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_; 2085*0b57cec5SDimitry Andric } 2086*0b57cec5SDimitry Andric else 2087*0b57cec5SDimitry Andric { 2088*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__next.__ptr_); 2089*0b57cec5SDimitry Andric return __parent->__left_; 2090*0b57cec5SDimitry Andric } 2091*0b57cec5SDimitry Andric } 2092*0b57cec5SDimitry Andric // *next(__hint) <= __v 2093*0b57cec5SDimitry Andric return __find_equal(__parent, __v); 2094*0b57cec5SDimitry Andric } 2095*0b57cec5SDimitry Andric // else __v == *__hint 2096*0b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 2097*0b57cec5SDimitry Andric __dummy = static_cast<__node_base_pointer>(__hint.__ptr_); 2098*0b57cec5SDimitry Andric return __dummy; 2099*0b57cec5SDimitry Andric} 2100*0b57cec5SDimitry Andric 2101*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2102*0b57cec5SDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::__insert_node_at( 2103*0b57cec5SDimitry Andric __parent_pointer __parent, __node_base_pointer& __child, 2104*0b57cec5SDimitry Andric __node_base_pointer __new_node) _NOEXCEPT 2105*0b57cec5SDimitry Andric{ 2106*0b57cec5SDimitry Andric __new_node->__left_ = nullptr; 2107*0b57cec5SDimitry Andric __new_node->__right_ = nullptr; 2108*0b57cec5SDimitry Andric __new_node->__parent_ = __parent; 2109*0b57cec5SDimitry Andric // __new_node->__is_black_ is initialized in __tree_balance_after_insert 2110*0b57cec5SDimitry Andric __child = __new_node; 2111*0b57cec5SDimitry Andric if (__begin_node()->__left_ != nullptr) 2112*0b57cec5SDimitry Andric __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_); 2113*0b57cec5SDimitry Andric __tree_balance_after_insert(__end_node()->__left_, __child); 2114*0b57cec5SDimitry Andric ++size(); 2115*0b57cec5SDimitry Andric} 2116*0b57cec5SDimitry Andric 2117*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2118*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2119*0b57cec5SDimitry Andrictemplate <class _Key, class... _Args> 2120*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 2121*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) 2122*0b57cec5SDimitry Andric#else 2123*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2124*0b57cec5SDimitry Andrictemplate <class _Key, class _Args> 2125*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 2126*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args) 2127*0b57cec5SDimitry Andric#endif 2128*0b57cec5SDimitry Andric{ 2129*0b57cec5SDimitry Andric __parent_pointer __parent; 2130*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, __k); 2131*0b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 2132*0b57cec5SDimitry Andric bool __inserted = false; 2133*0b57cec5SDimitry Andric if (__child == nullptr) 2134*0b57cec5SDimitry Andric { 2135*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2136*0b57cec5SDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2137*0b57cec5SDimitry Andric#else 2138*0b57cec5SDimitry Andric __node_holder __h = __construct_node(__args); 2139*0b57cec5SDimitry Andric#endif 2140*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2141*0b57cec5SDimitry Andric __r = __h.release(); 2142*0b57cec5SDimitry Andric __inserted = true; 2143*0b57cec5SDimitry Andric } 2144*0b57cec5SDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 2145*0b57cec5SDimitry Andric} 2146*0b57cec5SDimitry Andric 2147*0b57cec5SDimitry Andric 2148*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2149*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2150*0b57cec5SDimitry Andrictemplate <class _Key, class... _Args> 2151*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2152*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( 2153*0b57cec5SDimitry Andric const_iterator __p, _Key const& __k, _Args&&... __args) 2154*0b57cec5SDimitry Andric#else 2155*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2156*0b57cec5SDimitry Andrictemplate <class _Key, class _Args> 2157*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2158*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( 2159*0b57cec5SDimitry Andric const_iterator __p, _Key const& __k, _Args& __args) 2160*0b57cec5SDimitry Andric#endif 2161*0b57cec5SDimitry Andric{ 2162*0b57cec5SDimitry Andric __parent_pointer __parent; 2163*0b57cec5SDimitry Andric __node_base_pointer __dummy; 2164*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k); 2165*0b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 2166*0b57cec5SDimitry Andric if (__child == nullptr) 2167*0b57cec5SDimitry Andric { 2168*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2169*0b57cec5SDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2170*0b57cec5SDimitry Andric#else 2171*0b57cec5SDimitry Andric __node_holder __h = __construct_node(__args); 2172*0b57cec5SDimitry Andric#endif 2173*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2174*0b57cec5SDimitry Andric __r = __h.release(); 2175*0b57cec5SDimitry Andric } 2176*0b57cec5SDimitry Andric return iterator(__r); 2177*0b57cec5SDimitry Andric} 2178*0b57cec5SDimitry Andric 2179*0b57cec5SDimitry Andric 2180*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2181*0b57cec5SDimitry Andric 2182*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2183*0b57cec5SDimitry Andrictemplate <class ..._Args> 2184*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_holder 2185*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) 2186*0b57cec5SDimitry Andric{ 2187*0b57cec5SDimitry Andric static_assert(!__is_tree_value_type<_Args...>::value, 2188*0b57cec5SDimitry Andric "Cannot construct from __value_type"); 2189*0b57cec5SDimitry Andric __node_allocator& __na = __node_alloc(); 2190*0b57cec5SDimitry Andric __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 2191*0b57cec5SDimitry Andric __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); 2192*0b57cec5SDimitry Andric __h.get_deleter().__value_constructed = true; 2193*0b57cec5SDimitry Andric return __h; 2194*0b57cec5SDimitry Andric} 2195*0b57cec5SDimitry Andric 2196*0b57cec5SDimitry Andric 2197*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2198*0b57cec5SDimitry Andrictemplate <class... _Args> 2199*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 2200*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) 2201*0b57cec5SDimitry Andric{ 2202*0b57cec5SDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2203*0b57cec5SDimitry Andric __parent_pointer __parent; 2204*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, __h->__value_); 2205*0b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 2206*0b57cec5SDimitry Andric bool __inserted = false; 2207*0b57cec5SDimitry Andric if (__child == nullptr) 2208*0b57cec5SDimitry Andric { 2209*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2210*0b57cec5SDimitry Andric __r = __h.release(); 2211*0b57cec5SDimitry Andric __inserted = true; 2212*0b57cec5SDimitry Andric } 2213*0b57cec5SDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 2214*0b57cec5SDimitry Andric} 2215*0b57cec5SDimitry Andric 2216*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2217*0b57cec5SDimitry Andrictemplate <class... _Args> 2218*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2219*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) 2220*0b57cec5SDimitry Andric{ 2221*0b57cec5SDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2222*0b57cec5SDimitry Andric __parent_pointer __parent; 2223*0b57cec5SDimitry Andric __node_base_pointer __dummy; 2224*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_); 2225*0b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 2226*0b57cec5SDimitry Andric if (__child == nullptr) 2227*0b57cec5SDimitry Andric { 2228*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2229*0b57cec5SDimitry Andric __r = __h.release(); 2230*0b57cec5SDimitry Andric } 2231*0b57cec5SDimitry Andric return iterator(__r); 2232*0b57cec5SDimitry Andric} 2233*0b57cec5SDimitry Andric 2234*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2235*0b57cec5SDimitry Andrictemplate <class... _Args> 2236*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2237*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) 2238*0b57cec5SDimitry Andric{ 2239*0b57cec5SDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2240*0b57cec5SDimitry Andric __parent_pointer __parent; 2241*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_)); 2242*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2243*0b57cec5SDimitry Andric return iterator(static_cast<__node_pointer>(__h.release())); 2244*0b57cec5SDimitry Andric} 2245*0b57cec5SDimitry Andric 2246*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2247*0b57cec5SDimitry Andrictemplate <class... _Args> 2248*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2249*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, 2250*0b57cec5SDimitry Andric _Args&&... __args) 2251*0b57cec5SDimitry Andric{ 2252*0b57cec5SDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2253*0b57cec5SDimitry Andric __parent_pointer __parent; 2254*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_)); 2255*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2256*0b57cec5SDimitry Andric return iterator(static_cast<__node_pointer>(__h.release())); 2257*0b57cec5SDimitry Andric} 2258*0b57cec5SDimitry Andric 2259*0b57cec5SDimitry Andric 2260*0b57cec5SDimitry Andric#else // _LIBCPP_CXX03_LANG 2261*0b57cec5SDimitry Andric 2262*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2263*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_holder 2264*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v) 2265*0b57cec5SDimitry Andric{ 2266*0b57cec5SDimitry Andric __node_allocator& __na = __node_alloc(); 2267*0b57cec5SDimitry Andric __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 2268*0b57cec5SDimitry Andric __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); 2269*0b57cec5SDimitry Andric __h.get_deleter().__value_constructed = true; 2270*0b57cec5SDimitry Andric return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 2271*0b57cec5SDimitry Andric} 2272*0b57cec5SDimitry Andric 2273*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 2274*0b57cec5SDimitry Andric 2275*0b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 2276*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2277*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2278*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v) 2279*0b57cec5SDimitry Andric{ 2280*0b57cec5SDimitry Andric __parent_pointer __parent; 2281*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v)); 2282*0b57cec5SDimitry Andric __node_holder __h = __construct_node(__v); 2283*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2284*0b57cec5SDimitry Andric return iterator(__h.release()); 2285*0b57cec5SDimitry Andric} 2286*0b57cec5SDimitry Andric 2287*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2288*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2289*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v) 2290*0b57cec5SDimitry Andric{ 2291*0b57cec5SDimitry Andric __parent_pointer __parent; 2292*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v)); 2293*0b57cec5SDimitry Andric __node_holder __h = __construct_node(__v); 2294*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 2295*0b57cec5SDimitry Andric return iterator(__h.release()); 2296*0b57cec5SDimitry Andric} 2297*0b57cec5SDimitry Andric#endif 2298*0b57cec5SDimitry Andric 2299*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2300*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 2301*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_type& __v, __node_pointer __nd) 2302*0b57cec5SDimitry Andric{ 2303*0b57cec5SDimitry Andric __parent_pointer __parent; 2304*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__v)); 2305*0b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 2306*0b57cec5SDimitry Andric bool __inserted = false; 2307*0b57cec5SDimitry Andric if (__child == nullptr) 2308*0b57cec5SDimitry Andric { 2309*0b57cec5SDimitry Andric __nd->__value_ = __v; 2310*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 2311*0b57cec5SDimitry Andric __r = __nd; 2312*0b57cec5SDimitry Andric __inserted = true; 2313*0b57cec5SDimitry Andric } 2314*0b57cec5SDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 2315*0b57cec5SDimitry Andric} 2316*0b57cec5SDimitry Andric 2317*0b57cec5SDimitry Andric 2318*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2319*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2320*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) 2321*0b57cec5SDimitry Andric{ 2322*0b57cec5SDimitry Andric __parent_pointer __parent; 2323*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_)); 2324*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 2325*0b57cec5SDimitry Andric return iterator(__nd); 2326*0b57cec5SDimitry Andric} 2327*0b57cec5SDimitry Andric 2328*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2329*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2330*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, 2331*0b57cec5SDimitry Andric __node_pointer __nd) 2332*0b57cec5SDimitry Andric{ 2333*0b57cec5SDimitry Andric __parent_pointer __parent; 2334*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_)); 2335*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 2336*0b57cec5SDimitry Andric return iterator(__nd); 2337*0b57cec5SDimitry Andric} 2338*0b57cec5SDimitry Andric 2339*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2340*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2341*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT 2342*0b57cec5SDimitry Andric{ 2343*0b57cec5SDimitry Andric iterator __r(__ptr); 2344*0b57cec5SDimitry Andric ++__r; 2345*0b57cec5SDimitry Andric if (__begin_node() == __ptr) 2346*0b57cec5SDimitry Andric __begin_node() = __r.__ptr_; 2347*0b57cec5SDimitry Andric --size(); 2348*0b57cec5SDimitry Andric __tree_remove(__end_node()->__left_, 2349*0b57cec5SDimitry Andric static_cast<__node_base_pointer>(__ptr)); 2350*0b57cec5SDimitry Andric return __r; 2351*0b57cec5SDimitry Andric} 2352*0b57cec5SDimitry Andric 2353*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 2354*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2355*0b57cec5SDimitry Andrictemplate <class _NodeHandle, class _InsertReturnType> 2356*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2357*0b57cec5SDimitry Andric_InsertReturnType 2358*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( 2359*0b57cec5SDimitry Andric _NodeHandle&& __nh) 2360*0b57cec5SDimitry Andric{ 2361*0b57cec5SDimitry Andric if (__nh.empty()) 2362*0b57cec5SDimitry Andric return _InsertReturnType{end(), false, _NodeHandle()}; 2363*0b57cec5SDimitry Andric 2364*0b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 2365*0b57cec5SDimitry Andric __parent_pointer __parent; 2366*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, 2367*0b57cec5SDimitry Andric __ptr->__value_); 2368*0b57cec5SDimitry Andric if (__child != nullptr) 2369*0b57cec5SDimitry Andric return _InsertReturnType{ 2370*0b57cec5SDimitry Andric iterator(static_cast<__node_pointer>(__child)), 2371*0b57cec5SDimitry Andric false, _VSTD::move(__nh)}; 2372*0b57cec5SDimitry Andric 2373*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, 2374*0b57cec5SDimitry Andric static_cast<__node_base_pointer>(__ptr)); 2375*0b57cec5SDimitry Andric __nh.__release_ptr(); 2376*0b57cec5SDimitry Andric return _InsertReturnType{iterator(__ptr), true, _NodeHandle()}; 2377*0b57cec5SDimitry Andric} 2378*0b57cec5SDimitry Andric 2379*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2380*0b57cec5SDimitry Andrictemplate <class _NodeHandle> 2381*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2382*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2383*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( 2384*0b57cec5SDimitry Andric const_iterator __hint, _NodeHandle&& __nh) 2385*0b57cec5SDimitry Andric{ 2386*0b57cec5SDimitry Andric if (__nh.empty()) 2387*0b57cec5SDimitry Andric return end(); 2388*0b57cec5SDimitry Andric 2389*0b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 2390*0b57cec5SDimitry Andric __parent_pointer __parent; 2391*0b57cec5SDimitry Andric __node_base_pointer __dummy; 2392*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, 2393*0b57cec5SDimitry Andric __ptr->__value_); 2394*0b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 2395*0b57cec5SDimitry Andric if (__child == nullptr) 2396*0b57cec5SDimitry Andric { 2397*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, 2398*0b57cec5SDimitry Andric static_cast<__node_base_pointer>(__ptr)); 2399*0b57cec5SDimitry Andric __r = __ptr; 2400*0b57cec5SDimitry Andric __nh.__release_ptr(); 2401*0b57cec5SDimitry Andric } 2402*0b57cec5SDimitry Andric return iterator(__r); 2403*0b57cec5SDimitry Andric} 2404*0b57cec5SDimitry Andric 2405*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2406*0b57cec5SDimitry Andrictemplate <class _NodeHandle> 2407*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2408*0b57cec5SDimitry Andric_NodeHandle 2409*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) 2410*0b57cec5SDimitry Andric{ 2411*0b57cec5SDimitry Andric iterator __it = find(__key); 2412*0b57cec5SDimitry Andric if (__it == end()) 2413*0b57cec5SDimitry Andric return _NodeHandle(); 2414*0b57cec5SDimitry Andric return __node_handle_extract<_NodeHandle>(__it); 2415*0b57cec5SDimitry Andric} 2416*0b57cec5SDimitry Andric 2417*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2418*0b57cec5SDimitry Andrictemplate <class _NodeHandle> 2419*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2420*0b57cec5SDimitry Andric_NodeHandle 2421*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) 2422*0b57cec5SDimitry Andric{ 2423*0b57cec5SDimitry Andric __node_pointer __np = __p.__get_np(); 2424*0b57cec5SDimitry Andric __remove_node_pointer(__np); 2425*0b57cec5SDimitry Andric return _NodeHandle(__np, __alloc()); 2426*0b57cec5SDimitry Andric} 2427*0b57cec5SDimitry Andric 2428*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2429*0b57cec5SDimitry Andrictemplate <class _Tree> 2430*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2431*0b57cec5SDimitry Andricvoid 2432*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) 2433*0b57cec5SDimitry Andric{ 2434*0b57cec5SDimitry Andric static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); 2435*0b57cec5SDimitry Andric 2436*0b57cec5SDimitry Andric for (typename _Tree::iterator __i = __source.begin(); 2437*0b57cec5SDimitry Andric __i != __source.end();) 2438*0b57cec5SDimitry Andric { 2439*0b57cec5SDimitry Andric __node_pointer __src_ptr = __i.__get_np(); 2440*0b57cec5SDimitry Andric __parent_pointer __parent; 2441*0b57cec5SDimitry Andric __node_base_pointer& __child = 2442*0b57cec5SDimitry Andric __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_)); 2443*0b57cec5SDimitry Andric ++__i; 2444*0b57cec5SDimitry Andric if (__child != nullptr) 2445*0b57cec5SDimitry Andric continue; 2446*0b57cec5SDimitry Andric __source.__remove_node_pointer(__src_ptr); 2447*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, 2448*0b57cec5SDimitry Andric static_cast<__node_base_pointer>(__src_ptr)); 2449*0b57cec5SDimitry Andric } 2450*0b57cec5SDimitry Andric} 2451*0b57cec5SDimitry Andric 2452*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2453*0b57cec5SDimitry Andrictemplate <class _NodeHandle> 2454*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2455*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2456*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh) 2457*0b57cec5SDimitry Andric{ 2458*0b57cec5SDimitry Andric if (__nh.empty()) 2459*0b57cec5SDimitry Andric return end(); 2460*0b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 2461*0b57cec5SDimitry Andric __parent_pointer __parent; 2462*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf_high( 2463*0b57cec5SDimitry Andric __parent, _NodeTypes::__get_key(__ptr->__value_)); 2464*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 2465*0b57cec5SDimitry Andric __nh.__release_ptr(); 2466*0b57cec5SDimitry Andric return iterator(__ptr); 2467*0b57cec5SDimitry Andric} 2468*0b57cec5SDimitry Andric 2469*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2470*0b57cec5SDimitry Andrictemplate <class _NodeHandle> 2471*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2472*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2473*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi( 2474*0b57cec5SDimitry Andric const_iterator __hint, _NodeHandle&& __nh) 2475*0b57cec5SDimitry Andric{ 2476*0b57cec5SDimitry Andric if (__nh.empty()) 2477*0b57cec5SDimitry Andric return end(); 2478*0b57cec5SDimitry Andric 2479*0b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 2480*0b57cec5SDimitry Andric __parent_pointer __parent; 2481*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf(__hint, __parent, 2482*0b57cec5SDimitry Andric _NodeTypes::__get_key(__ptr->__value_)); 2483*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 2484*0b57cec5SDimitry Andric __nh.__release_ptr(); 2485*0b57cec5SDimitry Andric return iterator(__ptr); 2486*0b57cec5SDimitry Andric} 2487*0b57cec5SDimitry Andric 2488*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2489*0b57cec5SDimitry Andrictemplate <class _Tree> 2490*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2491*0b57cec5SDimitry Andricvoid 2492*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) 2493*0b57cec5SDimitry Andric{ 2494*0b57cec5SDimitry Andric static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); 2495*0b57cec5SDimitry Andric 2496*0b57cec5SDimitry Andric for (typename _Tree::iterator __i = __source.begin(); 2497*0b57cec5SDimitry Andric __i != __source.end();) 2498*0b57cec5SDimitry Andric { 2499*0b57cec5SDimitry Andric __node_pointer __src_ptr = __i.__get_np(); 2500*0b57cec5SDimitry Andric __parent_pointer __parent; 2501*0b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf_high( 2502*0b57cec5SDimitry Andric __parent, _NodeTypes::__get_key(__src_ptr->__value_)); 2503*0b57cec5SDimitry Andric ++__i; 2504*0b57cec5SDimitry Andric __source.__remove_node_pointer(__src_ptr); 2505*0b57cec5SDimitry Andric __insert_node_at(__parent, __child, 2506*0b57cec5SDimitry Andric static_cast<__node_base_pointer>(__src_ptr)); 2507*0b57cec5SDimitry Andric } 2508*0b57cec5SDimitry Andric} 2509*0b57cec5SDimitry Andric 2510*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14 2511*0b57cec5SDimitry Andric 2512*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2513*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2514*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) 2515*0b57cec5SDimitry Andric{ 2516*0b57cec5SDimitry Andric __node_pointer __np = __p.__get_np(); 2517*0b57cec5SDimitry Andric iterator __r = __remove_node_pointer(__np); 2518*0b57cec5SDimitry Andric __node_allocator& __na = __node_alloc(); 2519*0b57cec5SDimitry Andric __node_traits::destroy(__na, _NodeTypes::__get_ptr( 2520*0b57cec5SDimitry Andric const_cast<__node_value_type&>(*__p))); 2521*0b57cec5SDimitry Andric __node_traits::deallocate(__na, __np, 1); 2522*0b57cec5SDimitry Andric return __r; 2523*0b57cec5SDimitry Andric} 2524*0b57cec5SDimitry Andric 2525*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2526*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2527*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) 2528*0b57cec5SDimitry Andric{ 2529*0b57cec5SDimitry Andric while (__f != __l) 2530*0b57cec5SDimitry Andric __f = erase(__f); 2531*0b57cec5SDimitry Andric return iterator(__l.__ptr_); 2532*0b57cec5SDimitry Andric} 2533*0b57cec5SDimitry Andric 2534*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2535*0b57cec5SDimitry Andrictemplate <class _Key> 2536*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2537*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) 2538*0b57cec5SDimitry Andric{ 2539*0b57cec5SDimitry Andric iterator __i = find(__k); 2540*0b57cec5SDimitry Andric if (__i == end()) 2541*0b57cec5SDimitry Andric return 0; 2542*0b57cec5SDimitry Andric erase(__i); 2543*0b57cec5SDimitry Andric return 1; 2544*0b57cec5SDimitry Andric} 2545*0b57cec5SDimitry Andric 2546*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2547*0b57cec5SDimitry Andrictemplate <class _Key> 2548*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2549*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) 2550*0b57cec5SDimitry Andric{ 2551*0b57cec5SDimitry Andric pair<iterator, iterator> __p = __equal_range_multi(__k); 2552*0b57cec5SDimitry Andric size_type __r = 0; 2553*0b57cec5SDimitry Andric for (; __p.first != __p.second; ++__r) 2554*0b57cec5SDimitry Andric __p.first = erase(__p.first); 2555*0b57cec5SDimitry Andric return __r; 2556*0b57cec5SDimitry Andric} 2557*0b57cec5SDimitry Andric 2558*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2559*0b57cec5SDimitry Andrictemplate <class _Key> 2560*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2561*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) 2562*0b57cec5SDimitry Andric{ 2563*0b57cec5SDimitry Andric iterator __p = __lower_bound(__v, __root(), __end_node()); 2564*0b57cec5SDimitry Andric if (__p != end() && !value_comp()(__v, *__p)) 2565*0b57cec5SDimitry Andric return __p; 2566*0b57cec5SDimitry Andric return end(); 2567*0b57cec5SDimitry Andric} 2568*0b57cec5SDimitry Andric 2569*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2570*0b57cec5SDimitry Andrictemplate <class _Key> 2571*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::const_iterator 2572*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const 2573*0b57cec5SDimitry Andric{ 2574*0b57cec5SDimitry Andric const_iterator __p = __lower_bound(__v, __root(), __end_node()); 2575*0b57cec5SDimitry Andric if (__p != end() && !value_comp()(__v, *__p)) 2576*0b57cec5SDimitry Andric return __p; 2577*0b57cec5SDimitry Andric return end(); 2578*0b57cec5SDimitry Andric} 2579*0b57cec5SDimitry Andric 2580*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2581*0b57cec5SDimitry Andrictemplate <class _Key> 2582*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2583*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const 2584*0b57cec5SDimitry Andric{ 2585*0b57cec5SDimitry Andric __node_pointer __rt = __root(); 2586*0b57cec5SDimitry Andric while (__rt != nullptr) 2587*0b57cec5SDimitry Andric { 2588*0b57cec5SDimitry Andric if (value_comp()(__k, __rt->__value_)) 2589*0b57cec5SDimitry Andric { 2590*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2591*0b57cec5SDimitry Andric } 2592*0b57cec5SDimitry Andric else if (value_comp()(__rt->__value_, __k)) 2593*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 2594*0b57cec5SDimitry Andric else 2595*0b57cec5SDimitry Andric return 1; 2596*0b57cec5SDimitry Andric } 2597*0b57cec5SDimitry Andric return 0; 2598*0b57cec5SDimitry Andric} 2599*0b57cec5SDimitry Andric 2600*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2601*0b57cec5SDimitry Andrictemplate <class _Key> 2602*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2603*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const 2604*0b57cec5SDimitry Andric{ 2605*0b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 2606*0b57cec5SDimitry Andric __node_pointer __rt = __root(); 2607*0b57cec5SDimitry Andric while (__rt != nullptr) 2608*0b57cec5SDimitry Andric { 2609*0b57cec5SDimitry Andric if (value_comp()(__k, __rt->__value_)) 2610*0b57cec5SDimitry Andric { 2611*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 2612*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2613*0b57cec5SDimitry Andric } 2614*0b57cec5SDimitry Andric else if (value_comp()(__rt->__value_, __k)) 2615*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 2616*0b57cec5SDimitry Andric else 2617*0b57cec5SDimitry Andric return _VSTD::distance( 2618*0b57cec5SDimitry Andric __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 2619*0b57cec5SDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result) 2620*0b57cec5SDimitry Andric ); 2621*0b57cec5SDimitry Andric } 2622*0b57cec5SDimitry Andric return 0; 2623*0b57cec5SDimitry Andric} 2624*0b57cec5SDimitry Andric 2625*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2626*0b57cec5SDimitry Andrictemplate <class _Key> 2627*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2628*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, 2629*0b57cec5SDimitry Andric __node_pointer __root, 2630*0b57cec5SDimitry Andric __iter_pointer __result) 2631*0b57cec5SDimitry Andric{ 2632*0b57cec5SDimitry Andric while (__root != nullptr) 2633*0b57cec5SDimitry Andric { 2634*0b57cec5SDimitry Andric if (!value_comp()(__root->__value_, __v)) 2635*0b57cec5SDimitry Andric { 2636*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 2637*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2638*0b57cec5SDimitry Andric } 2639*0b57cec5SDimitry Andric else 2640*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 2641*0b57cec5SDimitry Andric } 2642*0b57cec5SDimitry Andric return iterator(__result); 2643*0b57cec5SDimitry Andric} 2644*0b57cec5SDimitry Andric 2645*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2646*0b57cec5SDimitry Andrictemplate <class _Key> 2647*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::const_iterator 2648*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, 2649*0b57cec5SDimitry Andric __node_pointer __root, 2650*0b57cec5SDimitry Andric __iter_pointer __result) const 2651*0b57cec5SDimitry Andric{ 2652*0b57cec5SDimitry Andric while (__root != nullptr) 2653*0b57cec5SDimitry Andric { 2654*0b57cec5SDimitry Andric if (!value_comp()(__root->__value_, __v)) 2655*0b57cec5SDimitry Andric { 2656*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 2657*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2658*0b57cec5SDimitry Andric } 2659*0b57cec5SDimitry Andric else 2660*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 2661*0b57cec5SDimitry Andric } 2662*0b57cec5SDimitry Andric return const_iterator(__result); 2663*0b57cec5SDimitry Andric} 2664*0b57cec5SDimitry Andric 2665*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2666*0b57cec5SDimitry Andrictemplate <class _Key> 2667*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2668*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, 2669*0b57cec5SDimitry Andric __node_pointer __root, 2670*0b57cec5SDimitry Andric __iter_pointer __result) 2671*0b57cec5SDimitry Andric{ 2672*0b57cec5SDimitry Andric while (__root != nullptr) 2673*0b57cec5SDimitry Andric { 2674*0b57cec5SDimitry Andric if (value_comp()(__v, __root->__value_)) 2675*0b57cec5SDimitry Andric { 2676*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 2677*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2678*0b57cec5SDimitry Andric } 2679*0b57cec5SDimitry Andric else 2680*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 2681*0b57cec5SDimitry Andric } 2682*0b57cec5SDimitry Andric return iterator(__result); 2683*0b57cec5SDimitry Andric} 2684*0b57cec5SDimitry Andric 2685*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2686*0b57cec5SDimitry Andrictemplate <class _Key> 2687*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::const_iterator 2688*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, 2689*0b57cec5SDimitry Andric __node_pointer __root, 2690*0b57cec5SDimitry Andric __iter_pointer __result) const 2691*0b57cec5SDimitry Andric{ 2692*0b57cec5SDimitry Andric while (__root != nullptr) 2693*0b57cec5SDimitry Andric { 2694*0b57cec5SDimitry Andric if (value_comp()(__v, __root->__value_)) 2695*0b57cec5SDimitry Andric { 2696*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 2697*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2698*0b57cec5SDimitry Andric } 2699*0b57cec5SDimitry Andric else 2700*0b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 2701*0b57cec5SDimitry Andric } 2702*0b57cec5SDimitry Andric return const_iterator(__result); 2703*0b57cec5SDimitry Andric} 2704*0b57cec5SDimitry Andric 2705*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2706*0b57cec5SDimitry Andrictemplate <class _Key> 2707*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, 2708*0b57cec5SDimitry Andric typename __tree<_Tp, _Compare, _Allocator>::iterator> 2709*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) 2710*0b57cec5SDimitry Andric{ 2711*0b57cec5SDimitry Andric typedef pair<iterator, iterator> _Pp; 2712*0b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 2713*0b57cec5SDimitry Andric __node_pointer __rt = __root(); 2714*0b57cec5SDimitry Andric while (__rt != nullptr) 2715*0b57cec5SDimitry Andric { 2716*0b57cec5SDimitry Andric if (value_comp()(__k, __rt->__value_)) 2717*0b57cec5SDimitry Andric { 2718*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 2719*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2720*0b57cec5SDimitry Andric } 2721*0b57cec5SDimitry Andric else if (value_comp()(__rt->__value_, __k)) 2722*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 2723*0b57cec5SDimitry Andric else 2724*0b57cec5SDimitry Andric return _Pp(iterator(__rt), 2725*0b57cec5SDimitry Andric iterator( 2726*0b57cec5SDimitry Andric __rt->__right_ != nullptr ? 2727*0b57cec5SDimitry Andric static_cast<__iter_pointer>(__tree_min(__rt->__right_)) 2728*0b57cec5SDimitry Andric : __result)); 2729*0b57cec5SDimitry Andric } 2730*0b57cec5SDimitry Andric return _Pp(iterator(__result), iterator(__result)); 2731*0b57cec5SDimitry Andric} 2732*0b57cec5SDimitry Andric 2733*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2734*0b57cec5SDimitry Andrictemplate <class _Key> 2735*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, 2736*0b57cec5SDimitry Andric typename __tree<_Tp, _Compare, _Allocator>::const_iterator> 2737*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const 2738*0b57cec5SDimitry Andric{ 2739*0b57cec5SDimitry Andric typedef pair<const_iterator, const_iterator> _Pp; 2740*0b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 2741*0b57cec5SDimitry Andric __node_pointer __rt = __root(); 2742*0b57cec5SDimitry Andric while (__rt != nullptr) 2743*0b57cec5SDimitry Andric { 2744*0b57cec5SDimitry Andric if (value_comp()(__k, __rt->__value_)) 2745*0b57cec5SDimitry Andric { 2746*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 2747*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2748*0b57cec5SDimitry Andric } 2749*0b57cec5SDimitry Andric else if (value_comp()(__rt->__value_, __k)) 2750*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 2751*0b57cec5SDimitry Andric else 2752*0b57cec5SDimitry Andric return _Pp(const_iterator(__rt), 2753*0b57cec5SDimitry Andric const_iterator( 2754*0b57cec5SDimitry Andric __rt->__right_ != nullptr ? 2755*0b57cec5SDimitry Andric static_cast<__iter_pointer>(__tree_min(__rt->__right_)) 2756*0b57cec5SDimitry Andric : __result)); 2757*0b57cec5SDimitry Andric } 2758*0b57cec5SDimitry Andric return _Pp(const_iterator(__result), const_iterator(__result)); 2759*0b57cec5SDimitry Andric} 2760*0b57cec5SDimitry Andric 2761*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2762*0b57cec5SDimitry Andrictemplate <class _Key> 2763*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, 2764*0b57cec5SDimitry Andric typename __tree<_Tp, _Compare, _Allocator>::iterator> 2765*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) 2766*0b57cec5SDimitry Andric{ 2767*0b57cec5SDimitry Andric typedef pair<iterator, iterator> _Pp; 2768*0b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 2769*0b57cec5SDimitry Andric __node_pointer __rt = __root(); 2770*0b57cec5SDimitry Andric while (__rt != nullptr) 2771*0b57cec5SDimitry Andric { 2772*0b57cec5SDimitry Andric if (value_comp()(__k, __rt->__value_)) 2773*0b57cec5SDimitry Andric { 2774*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 2775*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2776*0b57cec5SDimitry Andric } 2777*0b57cec5SDimitry Andric else if (value_comp()(__rt->__value_, __k)) 2778*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 2779*0b57cec5SDimitry Andric else 2780*0b57cec5SDimitry Andric return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 2781*0b57cec5SDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); 2782*0b57cec5SDimitry Andric } 2783*0b57cec5SDimitry Andric return _Pp(iterator(__result), iterator(__result)); 2784*0b57cec5SDimitry Andric} 2785*0b57cec5SDimitry Andric 2786*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2787*0b57cec5SDimitry Andrictemplate <class _Key> 2788*0b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, 2789*0b57cec5SDimitry Andric typename __tree<_Tp, _Compare, _Allocator>::const_iterator> 2790*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const 2791*0b57cec5SDimitry Andric{ 2792*0b57cec5SDimitry Andric typedef pair<const_iterator, const_iterator> _Pp; 2793*0b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 2794*0b57cec5SDimitry Andric __node_pointer __rt = __root(); 2795*0b57cec5SDimitry Andric while (__rt != nullptr) 2796*0b57cec5SDimitry Andric { 2797*0b57cec5SDimitry Andric if (value_comp()(__k, __rt->__value_)) 2798*0b57cec5SDimitry Andric { 2799*0b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 2800*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2801*0b57cec5SDimitry Andric } 2802*0b57cec5SDimitry Andric else if (value_comp()(__rt->__value_, __k)) 2803*0b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 2804*0b57cec5SDimitry Andric else 2805*0b57cec5SDimitry Andric return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 2806*0b57cec5SDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); 2807*0b57cec5SDimitry Andric } 2808*0b57cec5SDimitry Andric return _Pp(const_iterator(__result), const_iterator(__result)); 2809*0b57cec5SDimitry Andric} 2810*0b57cec5SDimitry Andric 2811*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2812*0b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_holder 2813*0b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT 2814*0b57cec5SDimitry Andric{ 2815*0b57cec5SDimitry Andric __node_pointer __np = __p.__get_np(); 2816*0b57cec5SDimitry Andric if (__begin_node() == __p.__ptr_) 2817*0b57cec5SDimitry Andric { 2818*0b57cec5SDimitry Andric if (__np->__right_ != nullptr) 2819*0b57cec5SDimitry Andric __begin_node() = static_cast<__iter_pointer>(__np->__right_); 2820*0b57cec5SDimitry Andric else 2821*0b57cec5SDimitry Andric __begin_node() = static_cast<__iter_pointer>(__np->__parent_); 2822*0b57cec5SDimitry Andric } 2823*0b57cec5SDimitry Andric --size(); 2824*0b57cec5SDimitry Andric __tree_remove(__end_node()->__left_, 2825*0b57cec5SDimitry Andric static_cast<__node_base_pointer>(__np)); 2826*0b57cec5SDimitry Andric return __node_holder(__np, _Dp(__node_alloc(), true)); 2827*0b57cec5SDimitry Andric} 2828*0b57cec5SDimitry Andric 2829*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2830*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2831*0b57cec5SDimitry Andricvoid 2832*0b57cec5SDimitry Andricswap(__tree<_Tp, _Compare, _Allocator>& __x, 2833*0b57cec5SDimitry Andric __tree<_Tp, _Compare, _Allocator>& __y) 2834*0b57cec5SDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 2835*0b57cec5SDimitry Andric{ 2836*0b57cec5SDimitry Andric __x.swap(__y); 2837*0b57cec5SDimitry Andric} 2838*0b57cec5SDimitry Andric 2839*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 2840*0b57cec5SDimitry Andric 2841*0b57cec5SDimitry Andric_LIBCPP_POP_MACROS 2842*0b57cec5SDimitry Andric 2843*0b57cec5SDimitry Andric#endif // _LIBCPP___TREE 2844