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