17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===----------------------------------------------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP___TREE 127a984708SDavid Chisnall#define _LIBCPP___TREE 137a984708SDavid Chisnall 147a984708SDavid Chisnall#include <__config> 157a984708SDavid Chisnall#include <iterator> 167a984708SDavid Chisnall#include <memory> 177a984708SDavid Chisnall#include <stdexcept> 187a984708SDavid Chisnall#include <algorithm> 197a984708SDavid Chisnall 207a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 217a984708SDavid Chisnall#pragma GCC system_header 227a984708SDavid Chisnall#endif 237a984708SDavid Chisnall 24f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS 25f9448bf3SDimitry Andric#include <__undef_macros> 26f9448bf3SDimitry Andric 27f9448bf3SDimitry Andric 287a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 297a984708SDavid Chisnall 307a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> class __tree; 317a984708SDavid Chisnalltemplate <class _Tp, class _NodePtr, class _DiffType> 32aed8d94eSDimitry Andric class _LIBCPP_TEMPLATE_VIS __tree_iterator; 337a984708SDavid Chisnalltemplate <class _Tp, class _ConstNodePtr, class _DiffType> 34aed8d94eSDimitry Andric class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; 357a984708SDavid Chisnall 367c82a1ecSDimitry Andrictemplate <class _Pointer> class __tree_end_node; 377c82a1ecSDimitry Andrictemplate <class _VoidPtr> class __tree_node_base; 387c82a1ecSDimitry Andrictemplate <class _Tp, class _VoidPtr> class __tree_node; 397c82a1ecSDimitry Andric 407c82a1ecSDimitry Andrictemplate <class _Key, class _Value> 417c82a1ecSDimitry Andricstruct __value_type; 427c82a1ecSDimitry Andric 437c82a1ecSDimitry Andrictemplate <class _Allocator> class __map_node_destructor; 44aed8d94eSDimitry Andrictemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator; 45aed8d94eSDimitry Andrictemplate <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator; 467c82a1ecSDimitry Andric 477a984708SDavid Chisnall/* 487a984708SDavid Chisnall 497a984708SDavid Chisnall_NodePtr algorithms 507a984708SDavid Chisnall 517a984708SDavid ChisnallThe algorithms taking _NodePtr are red black tree algorithms. Those 527a984708SDavid Chisnallalgorithms taking a parameter named __root should assume that __root 537a984708SDavid Chisnallpoints to a proper red black tree (unless otherwise specified). 547a984708SDavid Chisnall 557a984708SDavid ChisnallEach algorithm herein assumes that __root->__parent_ points to a non-null 567a984708SDavid Chisnallstructure which has a member __left_ which points back to __root. No other 577a984708SDavid Chisnallmember is read or written to at __root->__parent_. 587a984708SDavid Chisnall 597a984708SDavid Chisnall__root->__parent_ will be referred to below (in comments only) as end_node. 607a984708SDavid Chisnallend_node->__left_ is an externably accessible lvalue for __root, and can be 617a984708SDavid Chisnallchanged by node insertion and removal (without explicit reference to end_node). 627a984708SDavid Chisnall 637a984708SDavid ChisnallAll nodes (with the exception of end_node), even the node referred to as 647a984708SDavid Chisnall__root, have a non-null __parent_ field. 657a984708SDavid Chisnall 667a984708SDavid Chisnall*/ 677a984708SDavid Chisnall 687a984708SDavid Chisnall// Returns: true if __x is a left child of its parent, else false 697a984708SDavid Chisnall// Precondition: __x != nullptr. 707a984708SDavid Chisnalltemplate <class _NodePtr> 717a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 727a984708SDavid Chisnallbool 737a984708SDavid Chisnall__tree_is_left_child(_NodePtr __x) _NOEXCEPT 747a984708SDavid Chisnall{ 757a984708SDavid Chisnall return __x == __x->__parent_->__left_; 767a984708SDavid Chisnall} 777a984708SDavid Chisnall 78b2c7081bSDimitry Andric// Determines if the subtree rooted at __x is a proper red black subtree. If 797a984708SDavid Chisnall// __x is a proper subtree, returns the black height (null counts as 1). If 807a984708SDavid Chisnall// __x is an improper subtree, returns 0. 817a984708SDavid Chisnalltemplate <class _NodePtr> 827a984708SDavid Chisnallunsigned 837a984708SDavid Chisnall__tree_sub_invariant(_NodePtr __x) 847a984708SDavid Chisnall{ 857a984708SDavid Chisnall if (__x == nullptr) 867a984708SDavid Chisnall return 1; 877a984708SDavid Chisnall // parent consistency checked by caller 887a984708SDavid Chisnall // check __x->__left_ consistency 897a984708SDavid Chisnall if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x) 907a984708SDavid Chisnall return 0; 917a984708SDavid Chisnall // check __x->__right_ consistency 927a984708SDavid Chisnall if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x) 937a984708SDavid Chisnall return 0; 947a984708SDavid Chisnall // check __x->__left_ != __x->__right_ unless both are nullptr 957a984708SDavid Chisnall if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr) 967a984708SDavid Chisnall return 0; 977a984708SDavid Chisnall // If this is red, neither child can be red 987a984708SDavid Chisnall if (!__x->__is_black_) 997a984708SDavid Chisnall { 1007a984708SDavid Chisnall if (__x->__left_ && !__x->__left_->__is_black_) 1017a984708SDavid Chisnall return 0; 1027a984708SDavid Chisnall if (__x->__right_ && !__x->__right_->__is_black_) 1037a984708SDavid Chisnall return 0; 1047a984708SDavid Chisnall } 1057a984708SDavid Chisnall unsigned __h = __tree_sub_invariant(__x->__left_); 1067a984708SDavid Chisnall if (__h == 0) 1077a984708SDavid Chisnall return 0; // invalid left subtree 1087a984708SDavid Chisnall if (__h != __tree_sub_invariant(__x->__right_)) 1097a984708SDavid Chisnall return 0; // invalid or different height right subtree 1107a984708SDavid Chisnall return __h + __x->__is_black_; // return black height of this node 1117a984708SDavid Chisnall} 1127a984708SDavid Chisnall 113b2c7081bSDimitry Andric// Determines if the red black tree rooted at __root is a proper red black tree. 1147a984708SDavid Chisnall// __root == nullptr is a proper tree. Returns true is __root is a proper 1157a984708SDavid Chisnall// red black tree, else returns false. 1167a984708SDavid Chisnalltemplate <class _NodePtr> 1177a984708SDavid Chisnallbool 1187a984708SDavid Chisnall__tree_invariant(_NodePtr __root) 1197a984708SDavid Chisnall{ 1207a984708SDavid Chisnall if (__root == nullptr) 1217a984708SDavid Chisnall return true; 1227a984708SDavid Chisnall // check __x->__parent_ consistency 1237a984708SDavid Chisnall if (__root->__parent_ == nullptr) 1247a984708SDavid Chisnall return false; 1257a984708SDavid Chisnall if (!__tree_is_left_child(__root)) 1267a984708SDavid Chisnall return false; 1277a984708SDavid Chisnall // root must be black 1287a984708SDavid Chisnall if (!__root->__is_black_) 1297a984708SDavid Chisnall return false; 1307a984708SDavid Chisnall // do normal node checks 1317a984708SDavid Chisnall return __tree_sub_invariant(__root) != 0; 1327a984708SDavid Chisnall} 1337a984708SDavid Chisnall 1347a984708SDavid Chisnall// Returns: pointer to the left-most node under __x. 1357a984708SDavid Chisnall// Precondition: __x != nullptr. 1367a984708SDavid Chisnalltemplate <class _NodePtr> 1377a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 1387a984708SDavid Chisnall_NodePtr 1397a984708SDavid Chisnall__tree_min(_NodePtr __x) _NOEXCEPT 1407a984708SDavid Chisnall{ 1417a984708SDavid Chisnall while (__x->__left_ != nullptr) 1427a984708SDavid Chisnall __x = __x->__left_; 1437a984708SDavid Chisnall return __x; 1447a984708SDavid Chisnall} 1457a984708SDavid Chisnall 1467a984708SDavid Chisnall// Returns: pointer to the right-most node under __x. 1477a984708SDavid Chisnall// Precondition: __x != nullptr. 1487a984708SDavid Chisnalltemplate <class _NodePtr> 1497a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 1507a984708SDavid Chisnall_NodePtr 1517a984708SDavid Chisnall__tree_max(_NodePtr __x) _NOEXCEPT 1527a984708SDavid Chisnall{ 1537a984708SDavid Chisnall while (__x->__right_ != nullptr) 1547a984708SDavid Chisnall __x = __x->__right_; 1557a984708SDavid Chisnall return __x; 1567a984708SDavid Chisnall} 1577a984708SDavid Chisnall 1587a984708SDavid Chisnall// Returns: pointer to the next in-order node after __x. 1597a984708SDavid Chisnall// Precondition: __x != nullptr. 1607a984708SDavid Chisnalltemplate <class _NodePtr> 1617a984708SDavid Chisnall_NodePtr 1627a984708SDavid Chisnall__tree_next(_NodePtr __x) _NOEXCEPT 1637a984708SDavid Chisnall{ 1647a984708SDavid Chisnall if (__x->__right_ != nullptr) 1657a984708SDavid Chisnall return __tree_min(__x->__right_); 1667a984708SDavid Chisnall while (!__tree_is_left_child(__x)) 1677c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 1687c82a1ecSDimitry Andric return __x->__parent_unsafe(); 1697c82a1ecSDimitry Andric} 1707c82a1ecSDimitry Andric 1717c82a1ecSDimitry Andrictemplate <class _EndNodePtr, class _NodePtr> 1727c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1737c82a1ecSDimitry Andric_EndNodePtr 1747c82a1ecSDimitry Andric__tree_next_iter(_NodePtr __x) _NOEXCEPT 1757c82a1ecSDimitry Andric{ 1767c82a1ecSDimitry Andric if (__x->__right_ != nullptr) 1777c82a1ecSDimitry Andric return static_cast<_EndNodePtr>(__tree_min(__x->__right_)); 1787c82a1ecSDimitry Andric while (!__tree_is_left_child(__x)) 1797c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 1807c82a1ecSDimitry Andric return static_cast<_EndNodePtr>(__x->__parent_); 1817a984708SDavid Chisnall} 1827a984708SDavid Chisnall 1837a984708SDavid Chisnall// Returns: pointer to the previous in-order node before __x. 1847a984708SDavid Chisnall// Precondition: __x != nullptr. 1857c82a1ecSDimitry Andric// Note: __x may be the end node. 1867c82a1ecSDimitry Andrictemplate <class _NodePtr, class _EndNodePtr> 1877c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1887a984708SDavid Chisnall_NodePtr 1897c82a1ecSDimitry Andric__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT 1907a984708SDavid Chisnall{ 1917a984708SDavid Chisnall if (__x->__left_ != nullptr) 1927a984708SDavid Chisnall return __tree_max(__x->__left_); 1937c82a1ecSDimitry Andric _NodePtr __xx = static_cast<_NodePtr>(__x); 1947c82a1ecSDimitry Andric while (__tree_is_left_child(__xx)) 1957c82a1ecSDimitry Andric __xx = __xx->__parent_unsafe(); 1967c82a1ecSDimitry Andric return __xx->__parent_unsafe(); 1977a984708SDavid Chisnall} 1987a984708SDavid Chisnall 1997a984708SDavid Chisnall// Returns: pointer to a node which has no children 2007a984708SDavid Chisnall// Precondition: __x != nullptr. 2017a984708SDavid Chisnalltemplate <class _NodePtr> 2027a984708SDavid Chisnall_NodePtr 2037a984708SDavid Chisnall__tree_leaf(_NodePtr __x) _NOEXCEPT 2047a984708SDavid Chisnall{ 2057a984708SDavid Chisnall while (true) 2067a984708SDavid Chisnall { 2077a984708SDavid Chisnall if (__x->__left_ != nullptr) 2087a984708SDavid Chisnall { 2097a984708SDavid Chisnall __x = __x->__left_; 2107a984708SDavid Chisnall continue; 2117a984708SDavid Chisnall } 2127a984708SDavid Chisnall if (__x->__right_ != nullptr) 2137a984708SDavid Chisnall { 2147a984708SDavid Chisnall __x = __x->__right_; 2157a984708SDavid Chisnall continue; 2167a984708SDavid Chisnall } 2177a984708SDavid Chisnall break; 2187a984708SDavid Chisnall } 2197a984708SDavid Chisnall return __x; 2207a984708SDavid Chisnall} 2217a984708SDavid Chisnall 2227a984708SDavid Chisnall// Effects: Makes __x->__right_ the subtree root with __x as its left child 2237a984708SDavid Chisnall// while preserving in-order order. 2247a984708SDavid Chisnall// Precondition: __x->__right_ != nullptr 2257a984708SDavid Chisnalltemplate <class _NodePtr> 2267a984708SDavid Chisnallvoid 2277a984708SDavid Chisnall__tree_left_rotate(_NodePtr __x) _NOEXCEPT 2287a984708SDavid Chisnall{ 2297a984708SDavid Chisnall _NodePtr __y = __x->__right_; 2307a984708SDavid Chisnall __x->__right_ = __y->__left_; 2317a984708SDavid Chisnall if (__x->__right_ != nullptr) 2327c82a1ecSDimitry Andric __x->__right_->__set_parent(__x); 2337a984708SDavid Chisnall __y->__parent_ = __x->__parent_; 2347a984708SDavid Chisnall if (__tree_is_left_child(__x)) 2357a984708SDavid Chisnall __x->__parent_->__left_ = __y; 2367a984708SDavid Chisnall else 2377c82a1ecSDimitry Andric __x->__parent_unsafe()->__right_ = __y; 2387a984708SDavid Chisnall __y->__left_ = __x; 2397c82a1ecSDimitry Andric __x->__set_parent(__y); 2407a984708SDavid Chisnall} 2417a984708SDavid Chisnall 2427a984708SDavid Chisnall// Effects: Makes __x->__left_ the subtree root with __x as its right child 2437a984708SDavid Chisnall// while preserving in-order order. 2447a984708SDavid Chisnall// Precondition: __x->__left_ != nullptr 2457a984708SDavid Chisnalltemplate <class _NodePtr> 2467a984708SDavid Chisnallvoid 2477a984708SDavid Chisnall__tree_right_rotate(_NodePtr __x) _NOEXCEPT 2487a984708SDavid Chisnall{ 2497a984708SDavid Chisnall _NodePtr __y = __x->__left_; 2507a984708SDavid Chisnall __x->__left_ = __y->__right_; 2517a984708SDavid Chisnall if (__x->__left_ != nullptr) 2527c82a1ecSDimitry Andric __x->__left_->__set_parent(__x); 2537a984708SDavid Chisnall __y->__parent_ = __x->__parent_; 2547a984708SDavid Chisnall if (__tree_is_left_child(__x)) 2557a984708SDavid Chisnall __x->__parent_->__left_ = __y; 2567a984708SDavid Chisnall else 2577c82a1ecSDimitry Andric __x->__parent_unsafe()->__right_ = __y; 2587a984708SDavid Chisnall __y->__right_ = __x; 2597c82a1ecSDimitry Andric __x->__set_parent(__y); 2607a984708SDavid Chisnall} 2617a984708SDavid Chisnall 2627a984708SDavid Chisnall// Effects: Rebalances __root after attaching __x to a leaf. 2637a984708SDavid Chisnall// Precondition: __root != nulptr && __x != nullptr. 2647a984708SDavid Chisnall// __x has no children. 2657a984708SDavid Chisnall// __x == __root or == a direct or indirect child of __root. 2667a984708SDavid Chisnall// If __x were to be unlinked from __root (setting __root to 2677a984708SDavid Chisnall// nullptr if __root == __x), __tree_invariant(__root) == true. 2687a984708SDavid Chisnall// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_ 2697a984708SDavid Chisnall// may be different than the value passed in as __root. 2707a984708SDavid Chisnalltemplate <class _NodePtr> 2717a984708SDavid Chisnallvoid 2727a984708SDavid Chisnall__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT 2737a984708SDavid Chisnall{ 2747a984708SDavid Chisnall __x->__is_black_ = __x == __root; 2757c82a1ecSDimitry Andric while (__x != __root && !__x->__parent_unsafe()->__is_black_) 2767a984708SDavid Chisnall { 2777a984708SDavid Chisnall // __x->__parent_ != __root because __x->__parent_->__is_black == false 2787c82a1ecSDimitry Andric if (__tree_is_left_child(__x->__parent_unsafe())) 2797a984708SDavid Chisnall { 2807c82a1ecSDimitry Andric _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_; 2817a984708SDavid Chisnall if (__y != nullptr && !__y->__is_black_) 2827a984708SDavid Chisnall { 2837c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 2847a984708SDavid Chisnall __x->__is_black_ = true; 2857c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 2867a984708SDavid Chisnall __x->__is_black_ = __x == __root; 2877a984708SDavid Chisnall __y->__is_black_ = true; 2887a984708SDavid Chisnall } 2897a984708SDavid Chisnall else 2907a984708SDavid Chisnall { 2917a984708SDavid Chisnall if (!__tree_is_left_child(__x)) 2927a984708SDavid Chisnall { 2937c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 2947a984708SDavid Chisnall __tree_left_rotate(__x); 2957a984708SDavid Chisnall } 2967c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 2977a984708SDavid Chisnall __x->__is_black_ = true; 2987c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 2997a984708SDavid Chisnall __x->__is_black_ = false; 3007a984708SDavid Chisnall __tree_right_rotate(__x); 3017a984708SDavid Chisnall break; 3027a984708SDavid Chisnall } 3037a984708SDavid Chisnall } 3047a984708SDavid Chisnall else 3057a984708SDavid Chisnall { 3067c82a1ecSDimitry Andric _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_; 3077a984708SDavid Chisnall if (__y != nullptr && !__y->__is_black_) 3087a984708SDavid Chisnall { 3097c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 3107a984708SDavid Chisnall __x->__is_black_ = true; 3117c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 3127a984708SDavid Chisnall __x->__is_black_ = __x == __root; 3137a984708SDavid Chisnall __y->__is_black_ = true; 3147a984708SDavid Chisnall } 3157a984708SDavid Chisnall else 3167a984708SDavid Chisnall { 3177a984708SDavid Chisnall if (__tree_is_left_child(__x)) 3187a984708SDavid Chisnall { 3197c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 3207a984708SDavid Chisnall __tree_right_rotate(__x); 3217a984708SDavid Chisnall } 3227c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 3237a984708SDavid Chisnall __x->__is_black_ = true; 3247c82a1ecSDimitry Andric __x = __x->__parent_unsafe(); 3257a984708SDavid Chisnall __x->__is_black_ = false; 3267a984708SDavid Chisnall __tree_left_rotate(__x); 3277a984708SDavid Chisnall break; 3287a984708SDavid Chisnall } 3297a984708SDavid Chisnall } 3307a984708SDavid Chisnall } 3317a984708SDavid Chisnall} 3327a984708SDavid Chisnall 3337a984708SDavid Chisnall// Precondition: __root != nullptr && __z != nullptr. 3347a984708SDavid Chisnall// __tree_invariant(__root) == true. 3357a984708SDavid Chisnall// __z == __root or == a direct or indirect child of __root. 3367a984708SDavid Chisnall// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed. 3377a984708SDavid Chisnall// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_ 3387a984708SDavid Chisnall// nor any of its children refer to __z. end_node->__left_ 3397a984708SDavid Chisnall// may be different than the value passed in as __root. 3407a984708SDavid Chisnalltemplate <class _NodePtr> 3417a984708SDavid Chisnallvoid 3427a984708SDavid Chisnall__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT 3437a984708SDavid Chisnall{ 3447a984708SDavid Chisnall // __z will be removed from the tree. Client still needs to destruct/deallocate it 3457a984708SDavid Chisnall // __y is either __z, or if __z has two children, __tree_next(__z). 3467a984708SDavid Chisnall // __y will have at most one child. 3477a984708SDavid Chisnall // __y will be the initial hole in the tree (make the hole at a leaf) 3487a984708SDavid Chisnall _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ? 3497a984708SDavid Chisnall __z : __tree_next(__z); 3507a984708SDavid Chisnall // __x is __y's possibly null single child 3517a984708SDavid Chisnall _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_; 3527a984708SDavid Chisnall // __w is __x's possibly null uncle (will become __x's sibling) 3537a984708SDavid Chisnall _NodePtr __w = nullptr; 3547a984708SDavid Chisnall // link __x to __y's parent, and find __w 3557a984708SDavid Chisnall if (__x != nullptr) 3567a984708SDavid Chisnall __x->__parent_ = __y->__parent_; 3577a984708SDavid Chisnall if (__tree_is_left_child(__y)) 3587a984708SDavid Chisnall { 3597a984708SDavid Chisnall __y->__parent_->__left_ = __x; 3607a984708SDavid Chisnall if (__y != __root) 3617c82a1ecSDimitry Andric __w = __y->__parent_unsafe()->__right_; 3627a984708SDavid Chisnall else 3637a984708SDavid Chisnall __root = __x; // __w == nullptr 3647a984708SDavid Chisnall } 3657a984708SDavid Chisnall else 3667a984708SDavid Chisnall { 3677c82a1ecSDimitry Andric __y->__parent_unsafe()->__right_ = __x; 3687a984708SDavid Chisnall // __y can't be root if it is a right child 3697a984708SDavid Chisnall __w = __y->__parent_->__left_; 3707a984708SDavid Chisnall } 3717a984708SDavid Chisnall bool __removed_black = __y->__is_black_; 3727a984708SDavid Chisnall // If we didn't remove __z, do so now by splicing in __y for __z, 3737a984708SDavid Chisnall // but copy __z's color. This does not impact __x or __w. 3747a984708SDavid Chisnall if (__y != __z) 3757a984708SDavid Chisnall { 3767a984708SDavid Chisnall // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr 3777a984708SDavid Chisnall __y->__parent_ = __z->__parent_; 3787a984708SDavid Chisnall if (__tree_is_left_child(__z)) 3797a984708SDavid Chisnall __y->__parent_->__left_ = __y; 3807a984708SDavid Chisnall else 3817c82a1ecSDimitry Andric __y->__parent_unsafe()->__right_ = __y; 3827a984708SDavid Chisnall __y->__left_ = __z->__left_; 3837c82a1ecSDimitry Andric __y->__left_->__set_parent(__y); 3847a984708SDavid Chisnall __y->__right_ = __z->__right_; 3857a984708SDavid Chisnall if (__y->__right_ != nullptr) 3867c82a1ecSDimitry Andric __y->__right_->__set_parent(__y); 3877a984708SDavid Chisnall __y->__is_black_ = __z->__is_black_; 3887a984708SDavid Chisnall if (__root == __z) 3897a984708SDavid Chisnall __root = __y; 3907a984708SDavid Chisnall } 3917a984708SDavid Chisnall // There is no need to rebalance if we removed a red, or if we removed 3927a984708SDavid Chisnall // the last node. 3937a984708SDavid Chisnall if (__removed_black && __root != nullptr) 3947a984708SDavid Chisnall { 3957a984708SDavid Chisnall // Rebalance: 3967a984708SDavid Chisnall // __x has an implicit black color (transferred from the removed __y) 3977a984708SDavid Chisnall // associated with it, no matter what its color is. 3987a984708SDavid Chisnall // If __x is __root (in which case it can't be null), it is supposed 3997a984708SDavid Chisnall // to be black anyway, and if it is doubly black, then the double 4007a984708SDavid Chisnall // can just be ignored. 4017a984708SDavid Chisnall // If __x is red (in which case it can't be null), then it can absorb 4027a984708SDavid Chisnall // the implicit black just by setting its color to black. 4037a984708SDavid Chisnall // Since __y was black and only had one child (which __x points to), __x 4047a984708SDavid Chisnall // is either red with no children, else null, otherwise __y would have 4057a984708SDavid Chisnall // different black heights under left and right pointers. 4067a984708SDavid Chisnall // if (__x == __root || __x != nullptr && !__x->__is_black_) 4077a984708SDavid Chisnall if (__x != nullptr) 4087a984708SDavid Chisnall __x->__is_black_ = true; 4097a984708SDavid Chisnall else 4107a984708SDavid Chisnall { 4117a984708SDavid Chisnall // Else __x isn't root, and is "doubly black", even though it may 4127a984708SDavid Chisnall // be null. __w can not be null here, else the parent would 4137a984708SDavid Chisnall // see a black height >= 2 on the __x side and a black height 4147a984708SDavid Chisnall // of 1 on the __w side (__w must be a non-null black or a red 4157a984708SDavid Chisnall // with a non-null black child). 4167a984708SDavid Chisnall while (true) 4177a984708SDavid Chisnall { 4187a984708SDavid Chisnall if (!__tree_is_left_child(__w)) // if x is left child 4197a984708SDavid Chisnall { 4207a984708SDavid Chisnall if (!__w->__is_black_) 4217a984708SDavid Chisnall { 4227a984708SDavid Chisnall __w->__is_black_ = true; 4237c82a1ecSDimitry Andric __w->__parent_unsafe()->__is_black_ = false; 4247c82a1ecSDimitry Andric __tree_left_rotate(__w->__parent_unsafe()); 4257a984708SDavid Chisnall // __x is still valid 4267a984708SDavid Chisnall // reset __root only if necessary 4277a984708SDavid Chisnall if (__root == __w->__left_) 4287a984708SDavid Chisnall __root = __w; 4297a984708SDavid Chisnall // reset sibling, and it still can't be null 4307a984708SDavid Chisnall __w = __w->__left_->__right_; 4317a984708SDavid Chisnall } 4327a984708SDavid Chisnall // __w->__is_black_ is now true, __w may have null children 4337a984708SDavid Chisnall if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && 4347a984708SDavid Chisnall (__w->__right_ == nullptr || __w->__right_->__is_black_)) 4357a984708SDavid Chisnall { 4367a984708SDavid Chisnall __w->__is_black_ = false; 4377c82a1ecSDimitry Andric __x = __w->__parent_unsafe(); 4387a984708SDavid Chisnall // __x can no longer be null 4397a984708SDavid Chisnall if (__x == __root || !__x->__is_black_) 4407a984708SDavid Chisnall { 4417a984708SDavid Chisnall __x->__is_black_ = true; 4427a984708SDavid Chisnall break; 4437a984708SDavid Chisnall } 4447a984708SDavid Chisnall // reset sibling, and it still can't be null 4457a984708SDavid Chisnall __w = __tree_is_left_child(__x) ? 4467c82a1ecSDimitry Andric __x->__parent_unsafe()->__right_ : 4477a984708SDavid Chisnall __x->__parent_->__left_; 4487a984708SDavid Chisnall // continue; 4497a984708SDavid Chisnall } 4507a984708SDavid Chisnall else // __w has a red child 4517a984708SDavid Chisnall { 4527a984708SDavid Chisnall if (__w->__right_ == nullptr || __w->__right_->__is_black_) 4537a984708SDavid Chisnall { 4547a984708SDavid Chisnall // __w left child is non-null and red 4557a984708SDavid Chisnall __w->__left_->__is_black_ = true; 4567a984708SDavid Chisnall __w->__is_black_ = false; 4577a984708SDavid Chisnall __tree_right_rotate(__w); 4587a984708SDavid Chisnall // __w is known not to be root, so root hasn't changed 4597a984708SDavid Chisnall // reset sibling, and it still can't be null 4607c82a1ecSDimitry Andric __w = __w->__parent_unsafe(); 4617a984708SDavid Chisnall } 4627a984708SDavid Chisnall // __w has a right red child, left child may be null 4637c82a1ecSDimitry Andric __w->__is_black_ = __w->__parent_unsafe()->__is_black_; 4647c82a1ecSDimitry Andric __w->__parent_unsafe()->__is_black_ = true; 4657a984708SDavid Chisnall __w->__right_->__is_black_ = true; 4667c82a1ecSDimitry Andric __tree_left_rotate(__w->__parent_unsafe()); 4677a984708SDavid Chisnall break; 4687a984708SDavid Chisnall } 4697a984708SDavid Chisnall } 4707a984708SDavid Chisnall else 4717a984708SDavid Chisnall { 4727a984708SDavid Chisnall if (!__w->__is_black_) 4737a984708SDavid Chisnall { 4747a984708SDavid Chisnall __w->__is_black_ = true; 4757c82a1ecSDimitry Andric __w->__parent_unsafe()->__is_black_ = false; 4767c82a1ecSDimitry Andric __tree_right_rotate(__w->__parent_unsafe()); 4777a984708SDavid Chisnall // __x is still valid 4787a984708SDavid Chisnall // reset __root only if necessary 4797a984708SDavid Chisnall if (__root == __w->__right_) 4807a984708SDavid Chisnall __root = __w; 4817a984708SDavid Chisnall // reset sibling, and it still can't be null 4827a984708SDavid Chisnall __w = __w->__right_->__left_; 4837a984708SDavid Chisnall } 4847a984708SDavid Chisnall // __w->__is_black_ is now true, __w may have null children 4857a984708SDavid Chisnall if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && 4867a984708SDavid Chisnall (__w->__right_ == nullptr || __w->__right_->__is_black_)) 4877a984708SDavid Chisnall { 4887a984708SDavid Chisnall __w->__is_black_ = false; 4897c82a1ecSDimitry Andric __x = __w->__parent_unsafe(); 4907a984708SDavid Chisnall // __x can no longer be null 4917a984708SDavid Chisnall if (!__x->__is_black_ || __x == __root) 4927a984708SDavid Chisnall { 4937a984708SDavid Chisnall __x->__is_black_ = true; 4947a984708SDavid Chisnall break; 4957a984708SDavid Chisnall } 4967a984708SDavid Chisnall // reset sibling, and it still can't be null 4977a984708SDavid Chisnall __w = __tree_is_left_child(__x) ? 4987c82a1ecSDimitry Andric __x->__parent_unsafe()->__right_ : 4997a984708SDavid Chisnall __x->__parent_->__left_; 5007a984708SDavid Chisnall // continue; 5017a984708SDavid Chisnall } 5027a984708SDavid Chisnall else // __w has a red child 5037a984708SDavid Chisnall { 5047a984708SDavid Chisnall if (__w->__left_ == nullptr || __w->__left_->__is_black_) 5057a984708SDavid Chisnall { 5067a984708SDavid Chisnall // __w right child is non-null and red 5077a984708SDavid Chisnall __w->__right_->__is_black_ = true; 5087a984708SDavid Chisnall __w->__is_black_ = false; 5097a984708SDavid Chisnall __tree_left_rotate(__w); 5107a984708SDavid Chisnall // __w is known not to be root, so root hasn't changed 5117a984708SDavid Chisnall // reset sibling, and it still can't be null 5127c82a1ecSDimitry Andric __w = __w->__parent_unsafe(); 5137a984708SDavid Chisnall } 5147a984708SDavid Chisnall // __w has a left red child, right child may be null 5157c82a1ecSDimitry Andric __w->__is_black_ = __w->__parent_unsafe()->__is_black_; 5167c82a1ecSDimitry Andric __w->__parent_unsafe()->__is_black_ = true; 5177a984708SDavid Chisnall __w->__left_->__is_black_ = true; 5187c82a1ecSDimitry Andric __tree_right_rotate(__w->__parent_unsafe()); 5197a984708SDavid Chisnall break; 5207a984708SDavid Chisnall } 5217a984708SDavid Chisnall } 5227a984708SDavid Chisnall } 5237a984708SDavid Chisnall } 5247a984708SDavid Chisnall } 5257a984708SDavid Chisnall} 5267a984708SDavid Chisnall 5277c82a1ecSDimitry Andric// node traits 5287a984708SDavid Chisnall 5297a984708SDavid Chisnall 5307c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 5317c82a1ecSDimitry Andrictemplate <class _Tp> 5327c82a1ecSDimitry Andricstruct __is_tree_value_type_imp : false_type {}; 5337a984708SDavid Chisnall 5347c82a1ecSDimitry Andrictemplate <class _Key, class _Value> 5357c82a1ecSDimitry Andricstruct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {}; 5367a984708SDavid Chisnall 5377c82a1ecSDimitry Andrictemplate <class ..._Args> 5387c82a1ecSDimitry Andricstruct __is_tree_value_type : false_type {}; 5397c82a1ecSDimitry Andric 5407c82a1ecSDimitry Andrictemplate <class _One> 5417c82a1ecSDimitry Andricstruct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {}; 5427c82a1ecSDimitry Andric#endif 5437c82a1ecSDimitry Andric 5447c82a1ecSDimitry Andrictemplate <class _Tp> 5457c82a1ecSDimitry Andricstruct __tree_key_value_types { 5467c82a1ecSDimitry Andric typedef _Tp key_type; 5477c82a1ecSDimitry Andric typedef _Tp __node_value_type; 5487c82a1ecSDimitry Andric typedef _Tp __container_value_type; 5497c82a1ecSDimitry Andric static const bool __is_map = false; 5507a984708SDavid Chisnall 5517a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5527c82a1ecSDimitry Andric static key_type const& __get_key(_Tp const& __v) { 5537c82a1ecSDimitry Andric return __v; 5547c82a1ecSDimitry Andric } 5557a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5567c82a1ecSDimitry Andric static __container_value_type const& __get_value(__node_value_type const& __v) { 5577c82a1ecSDimitry Andric return __v; 5587c82a1ecSDimitry Andric } 5597c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 5607c82a1ecSDimitry Andric static __container_value_type* __get_ptr(__node_value_type& __n) { 5617c82a1ecSDimitry Andric return _VSTD::addressof(__n); 5627a984708SDavid Chisnall } 5637c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 5647c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 5657c82a1ecSDimitry Andric static __container_value_type&& __move(__node_value_type& __v) { 5667c82a1ecSDimitry Andric return _VSTD::move(__v); 5677c82a1ecSDimitry Andric } 5687c82a1ecSDimitry Andric#endif 5697c82a1ecSDimitry Andric}; 5707c82a1ecSDimitry Andric 5717c82a1ecSDimitry Andrictemplate <class _Key, class _Tp> 5727c82a1ecSDimitry Andricstruct __tree_key_value_types<__value_type<_Key, _Tp> > { 5737c82a1ecSDimitry Andric typedef _Key key_type; 5747c82a1ecSDimitry Andric typedef _Tp mapped_type; 5757c82a1ecSDimitry Andric typedef __value_type<_Key, _Tp> __node_value_type; 5767c82a1ecSDimitry Andric typedef pair<const _Key, _Tp> __container_value_type; 5777c82a1ecSDimitry Andric typedef __container_value_type __map_value_type; 5787c82a1ecSDimitry Andric static const bool __is_map = true; 5797c82a1ecSDimitry Andric 5807c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 5817c82a1ecSDimitry Andric static key_type const& 5827c82a1ecSDimitry Andric __get_key(__node_value_type const& __t) { 5834ba319b5SDimitry Andric return __t.__get_value().first; 5847c82a1ecSDimitry Andric } 5857c82a1ecSDimitry Andric 5867c82a1ecSDimitry Andric template <class _Up> 5877c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 5887c82a1ecSDimitry Andric static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, 5897c82a1ecSDimitry Andric key_type const&>::type 5907c82a1ecSDimitry Andric __get_key(_Up& __t) { 5917c82a1ecSDimitry Andric return __t.first; 5927c82a1ecSDimitry Andric } 5937c82a1ecSDimitry Andric 5947c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 5957c82a1ecSDimitry Andric static __container_value_type const& 5967c82a1ecSDimitry Andric __get_value(__node_value_type const& __t) { 5974ba319b5SDimitry Andric return __t.__get_value(); 5987c82a1ecSDimitry Andric } 5997c82a1ecSDimitry Andric 6007c82a1ecSDimitry Andric template <class _Up> 6017c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 6027c82a1ecSDimitry Andric static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, 6037c82a1ecSDimitry Andric __container_value_type const&>::type 6047c82a1ecSDimitry Andric __get_value(_Up& __t) { 6057c82a1ecSDimitry Andric return __t; 6067c82a1ecSDimitry Andric } 6077c82a1ecSDimitry Andric 6087c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 6097c82a1ecSDimitry Andric static __container_value_type* __get_ptr(__node_value_type& __n) { 6104ba319b5SDimitry Andric return _VSTD::addressof(__n.__get_value()); 6117c82a1ecSDimitry Andric } 6127c82a1ecSDimitry Andric 6137c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 6147c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 6154ba319b5SDimitry Andric static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { 6164ba319b5SDimitry Andric return __v.__move(); 6177c82a1ecSDimitry Andric } 6187c82a1ecSDimitry Andric#endif 6197c82a1ecSDimitry Andric}; 6207c82a1ecSDimitry Andric 6217c82a1ecSDimitry Andrictemplate <class _VoidPtr> 6227c82a1ecSDimitry Andricstruct __tree_node_base_types { 6237c82a1ecSDimitry Andric typedef _VoidPtr __void_pointer; 6247c82a1ecSDimitry Andric 6257c82a1ecSDimitry Andric typedef __tree_node_base<__void_pointer> __node_base_type; 6267c82a1ecSDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type 6277c82a1ecSDimitry Andric __node_base_pointer; 6287c82a1ecSDimitry Andric 6297c82a1ecSDimitry Andric typedef __tree_end_node<__node_base_pointer> __end_node_type; 6307c82a1ecSDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type 6317c82a1ecSDimitry Andric __end_node_pointer; 6327c82a1ecSDimitry Andric#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) 6337c82a1ecSDimitry Andric typedef __end_node_pointer __parent_pointer; 6347c82a1ecSDimitry Andric#else 6357c82a1ecSDimitry Andric typedef typename conditional< 6367c82a1ecSDimitry Andric is_pointer<__end_node_pointer>::value, 6377c82a1ecSDimitry Andric __end_node_pointer, 6387c82a1ecSDimitry Andric __node_base_pointer>::type __parent_pointer; 6397c82a1ecSDimitry Andric#endif 6407c82a1ecSDimitry Andric 6417c82a1ecSDimitry Andricprivate: 6427c82a1ecSDimitry Andric static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), 6437c82a1ecSDimitry Andric "_VoidPtr does not point to unqualified void type"); 6447c82a1ecSDimitry Andric}; 6457c82a1ecSDimitry Andric 6467c82a1ecSDimitry Andrictemplate <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>, 6477c82a1ecSDimitry Andric bool = _KVTypes::__is_map> 6487c82a1ecSDimitry Andricstruct __tree_map_pointer_types {}; 6497c82a1ecSDimitry Andric 6507c82a1ecSDimitry Andrictemplate <class _Tp, class _AllocPtr, class _KVTypes> 6517c82a1ecSDimitry Andricstruct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { 6527c82a1ecSDimitry Andric typedef typename _KVTypes::__map_value_type _Mv; 6537c82a1ecSDimitry Andric typedef typename __rebind_pointer<_AllocPtr, _Mv>::type 6547c82a1ecSDimitry Andric __map_value_type_pointer; 6557c82a1ecSDimitry Andric typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type 6567c82a1ecSDimitry Andric __const_map_value_type_pointer; 6577c82a1ecSDimitry Andric}; 6587c82a1ecSDimitry Andric 6597c82a1ecSDimitry Andrictemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> 6607c82a1ecSDimitry Andricstruct __tree_node_types; 6617c82a1ecSDimitry Andric 6627c82a1ecSDimitry Andrictemplate <class _NodePtr, class _Tp, class _VoidPtr> 6637c82a1ecSDimitry Andricstruct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > 6647c82a1ecSDimitry Andric : public __tree_node_base_types<_VoidPtr>, 6657c82a1ecSDimitry Andric __tree_key_value_types<_Tp>, 6667c82a1ecSDimitry Andric __tree_map_pointer_types<_Tp, _VoidPtr> 6677c82a1ecSDimitry Andric{ 6687c82a1ecSDimitry Andric typedef __tree_node_base_types<_VoidPtr> __base; 6697c82a1ecSDimitry Andric typedef __tree_key_value_types<_Tp> __key_base; 6707c82a1ecSDimitry Andric typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base; 6717c82a1ecSDimitry Andricpublic: 6727c82a1ecSDimitry Andric 6737c82a1ecSDimitry Andric typedef typename pointer_traits<_NodePtr>::element_type __node_type; 6747c82a1ecSDimitry Andric typedef _NodePtr __node_pointer; 6757c82a1ecSDimitry Andric 6767c82a1ecSDimitry Andric typedef _Tp __node_value_type; 6777c82a1ecSDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type 6787c82a1ecSDimitry Andric __node_value_type_pointer; 6797c82a1ecSDimitry Andric typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type 6807c82a1ecSDimitry Andric __const_node_value_type_pointer; 6817c82a1ecSDimitry Andric#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) 6827c82a1ecSDimitry Andric typedef typename __base::__end_node_pointer __iter_pointer; 6837c82a1ecSDimitry Andric#else 6847c82a1ecSDimitry Andric typedef typename conditional< 6857c82a1ecSDimitry Andric is_pointer<__node_pointer>::value, 6867c82a1ecSDimitry Andric typename __base::__end_node_pointer, 6877c82a1ecSDimitry Andric __node_pointer>::type __iter_pointer; 6887c82a1ecSDimitry Andric#endif 6897c82a1ecSDimitry Andricprivate: 6907c82a1ecSDimitry Andric static_assert(!is_const<__node_type>::value, 6917c82a1ecSDimitry Andric "_NodePtr should never be a pointer to const"); 6927c82a1ecSDimitry Andric static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, 6937c82a1ecSDimitry Andric _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); 6947c82a1ecSDimitry Andric}; 6957c82a1ecSDimitry Andric 6967c82a1ecSDimitry Andrictemplate <class _ValueTp, class _VoidPtr> 6977c82a1ecSDimitry Andricstruct __make_tree_node_types { 6987c82a1ecSDimitry Andric typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type 6997c82a1ecSDimitry Andric _NodePtr; 7007c82a1ecSDimitry Andric typedef __tree_node_types<_NodePtr> type; 7017a984708SDavid Chisnall}; 7027a984708SDavid Chisnall 7037a984708SDavid Chisnall// node 7047a984708SDavid Chisnall 7057a984708SDavid Chisnalltemplate <class _Pointer> 7067a984708SDavid Chisnallclass __tree_end_node 7077a984708SDavid Chisnall{ 7087a984708SDavid Chisnallpublic: 7097a984708SDavid Chisnall typedef _Pointer pointer; 7107a984708SDavid Chisnall pointer __left_; 7117a984708SDavid Chisnall 7127a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 7137a984708SDavid Chisnall __tree_end_node() _NOEXCEPT : __left_() {} 7147a984708SDavid Chisnall}; 7157a984708SDavid Chisnall 7167a984708SDavid Chisnalltemplate <class _VoidPtr> 7177a984708SDavid Chisnallclass __tree_node_base 7187c82a1ecSDimitry Andric : public __tree_node_base_types<_VoidPtr>::__end_node_type 7197a984708SDavid Chisnall{ 7207c82a1ecSDimitry Andric typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes; 7219729cf09SDimitry Andric 7227c82a1ecSDimitry Andricpublic: 7237c82a1ecSDimitry Andric typedef typename _NodeBaseTypes::__node_base_pointer pointer; 7247c82a1ecSDimitry Andric typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer; 7257a984708SDavid Chisnall 7267a984708SDavid Chisnall pointer __right_; 7277c82a1ecSDimitry Andric __parent_pointer __parent_; 7287a984708SDavid Chisnall bool __is_black_; 7297a984708SDavid Chisnall 7307a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 7317c82a1ecSDimitry Andric pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);} 7327c82a1ecSDimitry Andric 7337c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 7347c82a1ecSDimitry Andric void __set_parent(pointer __p) { 7357c82a1ecSDimitry Andric __parent_ = static_cast<__parent_pointer>(__p); 7367c82a1ecSDimitry Andric } 7377c82a1ecSDimitry Andric 7387c82a1ecSDimitry Andricprivate: 7397c82a1ecSDimitry Andric ~__tree_node_base() _LIBCPP_EQUAL_DELETE; 7407c82a1ecSDimitry Andric __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; 7417c82a1ecSDimitry Andric __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; 7427a984708SDavid Chisnall}; 7437a984708SDavid Chisnall 7447a984708SDavid Chisnalltemplate <class _Tp, class _VoidPtr> 7457a984708SDavid Chisnallclass __tree_node 7467a984708SDavid Chisnall : public __tree_node_base<_VoidPtr> 7477a984708SDavid Chisnall{ 7487a984708SDavid Chisnallpublic: 7497c82a1ecSDimitry Andric typedef _Tp __node_value_type; 7507a984708SDavid Chisnall 7517c82a1ecSDimitry Andric __node_value_type __value_; 7527a984708SDavid Chisnall 7537c82a1ecSDimitry Andricprivate: 7547c82a1ecSDimitry Andric ~__tree_node() _LIBCPP_EQUAL_DELETE; 7557c82a1ecSDimitry Andric __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE; 7567c82a1ecSDimitry Andric __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE; 7577a984708SDavid Chisnall}; 7587a984708SDavid Chisnall 7597c82a1ecSDimitry Andric 7607c82a1ecSDimitry Andrictemplate <class _Allocator> 7617c82a1ecSDimitry Andricclass __tree_node_destructor 7627c82a1ecSDimitry Andric{ 7637c82a1ecSDimitry Andric typedef _Allocator allocator_type; 7647c82a1ecSDimitry Andric typedef allocator_traits<allocator_type> __alloc_traits; 7657c82a1ecSDimitry Andric 7667c82a1ecSDimitry Andricpublic: 7677c82a1ecSDimitry Andric typedef typename __alloc_traits::pointer pointer; 7687c82a1ecSDimitry Andricprivate: 7697c82a1ecSDimitry Andric typedef __tree_node_types<pointer> _NodeTypes; 7707c82a1ecSDimitry Andric allocator_type& __na_; 7717c82a1ecSDimitry Andric 7727c82a1ecSDimitry Andric __tree_node_destructor& operator=(const __tree_node_destructor&); 7737c82a1ecSDimitry Andric 7747c82a1ecSDimitry Andricpublic: 7757c82a1ecSDimitry Andric bool __value_constructed; 7767c82a1ecSDimitry Andric 7777c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 7787c82a1ecSDimitry Andric explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT 7797c82a1ecSDimitry Andric : __na_(__na), 7807c82a1ecSDimitry Andric __value_constructed(__val) 7817c82a1ecSDimitry Andric {} 7827c82a1ecSDimitry Andric 7837c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 7847c82a1ecSDimitry Andric void operator()(pointer __p) _NOEXCEPT 7857c82a1ecSDimitry Andric { 7867c82a1ecSDimitry Andric if (__value_constructed) 7877c82a1ecSDimitry Andric __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); 7887c82a1ecSDimitry Andric if (__p) 7897c82a1ecSDimitry Andric __alloc_traits::deallocate(__na_, __p, 1); 7907c82a1ecSDimitry Andric } 7917c82a1ecSDimitry Andric 7927c82a1ecSDimitry Andric template <class> friend class __map_node_destructor; 7937c82a1ecSDimitry Andric}; 7947c82a1ecSDimitry Andric 7954ba319b5SDimitry Andric#if _LIBCPP_STD_VER > 14 7964ba319b5SDimitry Andrictemplate <class _NodeType, class _Alloc> 7974ba319b5SDimitry Andricstruct __generic_container_node_destructor; 7984ba319b5SDimitry Andrictemplate <class _Tp, class _VoidPtr, class _Alloc> 7994ba319b5SDimitry Andricstruct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> 8004ba319b5SDimitry Andric : __tree_node_destructor<_Alloc> 8014ba319b5SDimitry Andric{ 8024ba319b5SDimitry Andric using __tree_node_destructor<_Alloc>::__tree_node_destructor; 8034ba319b5SDimitry Andric}; 8044ba319b5SDimitry Andric#endif 8057a984708SDavid Chisnall 8067a984708SDavid Chisnalltemplate <class _Tp, class _NodePtr, class _DiffType> 807aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_iterator 8087a984708SDavid Chisnall{ 8097c82a1ecSDimitry Andric typedef __tree_node_types<_NodePtr> _NodeTypes; 8107a984708SDavid Chisnall typedef _NodePtr __node_pointer; 8117c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 8127c82a1ecSDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; 8137c82a1ecSDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 8147a984708SDavid Chisnall typedef pointer_traits<__node_pointer> __pointer_traits; 8157c82a1ecSDimitry Andric 8167c82a1ecSDimitry Andric __iter_pointer __ptr_; 8177c82a1ecSDimitry Andric 8187a984708SDavid Chisnallpublic: 8197a984708SDavid Chisnall typedef bidirectional_iterator_tag iterator_category; 8207a984708SDavid Chisnall typedef _Tp value_type; 8217a984708SDavid Chisnall typedef _DiffType difference_type; 8227a984708SDavid Chisnall typedef value_type& reference; 8237c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_value_type_pointer pointer; 8247a984708SDavid Chisnall 8254f7ab58eSDimitry Andric _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT 8264f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11 8274f7ab58eSDimitry Andric : __ptr_(nullptr) 8284f7ab58eSDimitry Andric#endif 8294f7ab58eSDimitry Andric {} 8307a984708SDavid Chisnall 8317c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY reference operator*() const 8327c82a1ecSDimitry Andric {return __get_np()->__value_;} 8334bab9fd9SDavid Chisnall _LIBCPP_INLINE_VISIBILITY pointer operator->() const 8347c82a1ecSDimitry Andric {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} 8357a984708SDavid Chisnall 8367a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 837854fa44bSDimitry Andric __tree_iterator& operator++() { 8387c82a1ecSDimitry Andric __ptr_ = static_cast<__iter_pointer>( 8397c82a1ecSDimitry Andric __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); 840854fa44bSDimitry Andric return *this; 841854fa44bSDimitry Andric } 8427a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 8437a984708SDavid Chisnall __tree_iterator operator++(int) 8447a984708SDavid Chisnall {__tree_iterator __t(*this); ++(*this); return __t;} 8457a984708SDavid Chisnall 8467a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 847854fa44bSDimitry Andric __tree_iterator& operator--() { 8487c82a1ecSDimitry Andric __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( 8497c82a1ecSDimitry Andric static_cast<__end_node_pointer>(__ptr_))); 850854fa44bSDimitry Andric return *this; 851854fa44bSDimitry Andric } 8527a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 8537a984708SDavid Chisnall __tree_iterator operator--(int) 8547a984708SDavid Chisnall {__tree_iterator __t(*this); --(*this); return __t;} 8557a984708SDavid Chisnall 8567a984708SDavid Chisnall friend _LIBCPP_INLINE_VISIBILITY 8577a984708SDavid Chisnall bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) 8587a984708SDavid Chisnall {return __x.__ptr_ == __y.__ptr_;} 8597a984708SDavid Chisnall friend _LIBCPP_INLINE_VISIBILITY 8607a984708SDavid Chisnall bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) 8617a984708SDavid Chisnall {return !(__x == __y);} 8627a984708SDavid Chisnall 8637a984708SDavid Chisnallprivate: 8647a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 8657a984708SDavid Chisnall explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 8667c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 8677c82a1ecSDimitry Andric explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 8687c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 8697c82a1ecSDimitry Andric __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } 8707a984708SDavid Chisnall template <class, class, class> friend class __tree; 871aed8d94eSDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; 872aed8d94eSDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator; 873aed8d94eSDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 874aed8d94eSDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 875aed8d94eSDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set; 876aed8d94eSDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset; 8777a984708SDavid Chisnall}; 8787a984708SDavid Chisnall 8797c82a1ecSDimitry Andrictemplate <class _Tp, class _NodePtr, class _DiffType> 880aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_const_iterator 8817a984708SDavid Chisnall{ 8827c82a1ecSDimitry Andric typedef __tree_node_types<_NodePtr> _NodeTypes; 8837c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_pointer __node_pointer; 8847c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 8857c82a1ecSDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; 8867c82a1ecSDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 8877a984708SDavid Chisnall typedef pointer_traits<__node_pointer> __pointer_traits; 8887c82a1ecSDimitry Andric 8897c82a1ecSDimitry Andric __iter_pointer __ptr_; 8907c82a1ecSDimitry Andric 8917a984708SDavid Chisnallpublic: 8927a984708SDavid Chisnall typedef bidirectional_iterator_tag iterator_category; 8937a984708SDavid Chisnall typedef _Tp value_type; 8947a984708SDavid Chisnall typedef _DiffType difference_type; 8957a984708SDavid Chisnall typedef const value_type& reference; 8967c82a1ecSDimitry Andric typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 8977a984708SDavid Chisnall 8984f7ab58eSDimitry Andric _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT 8994f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11 9004f7ab58eSDimitry Andric : __ptr_(nullptr) 9014f7ab58eSDimitry Andric#endif 9024f7ab58eSDimitry Andric {} 9034f7ab58eSDimitry Andric 9047a984708SDavid Chisnallprivate: 9057c82a1ecSDimitry Andric typedef __tree_iterator<value_type, __node_pointer, difference_type> 9067a984708SDavid Chisnall __non_const_iterator; 9077a984708SDavid Chisnallpublic: 9087a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 9097a984708SDavid Chisnall __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT 9107a984708SDavid Chisnall : __ptr_(__p.__ptr_) {} 9117a984708SDavid Chisnall 9127c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY reference operator*() const 9137c82a1ecSDimitry Andric {return __get_np()->__value_;} 9144bab9fd9SDavid Chisnall _LIBCPP_INLINE_VISIBILITY pointer operator->() const 9157c82a1ecSDimitry Andric {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} 9167a984708SDavid Chisnall 9177a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 918854fa44bSDimitry Andric __tree_const_iterator& operator++() { 9197c82a1ecSDimitry Andric __ptr_ = static_cast<__iter_pointer>( 9207c82a1ecSDimitry Andric __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); 921854fa44bSDimitry Andric return *this; 922854fa44bSDimitry Andric } 923854fa44bSDimitry Andric 9247a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 9257a984708SDavid Chisnall __tree_const_iterator operator++(int) 9267a984708SDavid Chisnall {__tree_const_iterator __t(*this); ++(*this); return __t;} 9277a984708SDavid Chisnall 9287a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 929854fa44bSDimitry Andric __tree_const_iterator& operator--() { 9307c82a1ecSDimitry Andric __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( 9317c82a1ecSDimitry Andric static_cast<__end_node_pointer>(__ptr_))); 932854fa44bSDimitry Andric return *this; 933854fa44bSDimitry Andric } 934854fa44bSDimitry Andric 9357a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 9367a984708SDavid Chisnall __tree_const_iterator operator--(int) 9377a984708SDavid Chisnall {__tree_const_iterator __t(*this); --(*this); return __t;} 9387a984708SDavid Chisnall 9397a984708SDavid Chisnall friend _LIBCPP_INLINE_VISIBILITY 9407a984708SDavid Chisnall bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) 9417a984708SDavid Chisnall {return __x.__ptr_ == __y.__ptr_;} 9427a984708SDavid Chisnall friend _LIBCPP_INLINE_VISIBILITY 9437a984708SDavid Chisnall bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) 9447a984708SDavid Chisnall {return !(__x == __y);} 9457a984708SDavid Chisnall 9467a984708SDavid Chisnallprivate: 9477a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 9487a984708SDavid Chisnall explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT 9497a984708SDavid Chisnall : __ptr_(__p) {} 9507c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 9517c82a1ecSDimitry Andric explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT 9527c82a1ecSDimitry Andric : __ptr_(__p) {} 9537c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 9547c82a1ecSDimitry Andric __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } 9557c82a1ecSDimitry Andric 9567a984708SDavid Chisnall template <class, class, class> friend class __tree; 957aed8d94eSDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 958aed8d94eSDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 959aed8d94eSDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set; 960aed8d94eSDimitry Andric template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset; 961aed8d94eSDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator; 9627c82a1ecSDimitry Andric 9637a984708SDavid Chisnall}; 9647a984708SDavid Chisnall 965*b5893f02SDimitry Andrictemplate<class _Tp, class _Compare> 966540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 967*b5893f02SDimitry Andric _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value, 968540d2a8bSDimitry Andric "the specified comparator type does not provide a const call operator") 969*b5893f02SDimitry Andric#endif 970*b5893f02SDimitry Andricint __diagnose_non_const_comparator(); 971540d2a8bSDimitry Andric 9727a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 9737a984708SDavid Chisnallclass __tree 9747a984708SDavid Chisnall{ 9757a984708SDavid Chisnallpublic: 9767a984708SDavid Chisnall typedef _Tp value_type; 9777a984708SDavid Chisnall typedef _Compare value_compare; 9787a984708SDavid Chisnall typedef _Allocator allocator_type; 9797c82a1ecSDimitry Andric 9807c82a1ecSDimitry Andricprivate: 9817a984708SDavid Chisnall typedef allocator_traits<allocator_type> __alloc_traits; 9827c82a1ecSDimitry Andric typedef typename __make_tree_node_types<value_type, 9837c82a1ecSDimitry Andric typename __alloc_traits::void_pointer>::type 9847c82a1ecSDimitry Andric _NodeTypes; 9857c82a1ecSDimitry Andric typedef typename _NodeTypes::key_type key_type; 9867c82a1ecSDimitry Andricpublic: 9877c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_value_type __node_value_type; 9887c82a1ecSDimitry Andric typedef typename _NodeTypes::__container_value_type __container_value_type; 9897c82a1ecSDimitry Andric 9907a984708SDavid Chisnall typedef typename __alloc_traits::pointer pointer; 9917a984708SDavid Chisnall typedef typename __alloc_traits::const_pointer const_pointer; 9927a984708SDavid Chisnall typedef typename __alloc_traits::size_type size_type; 9937a984708SDavid Chisnall typedef typename __alloc_traits::difference_type difference_type; 9947a984708SDavid Chisnall 9957c82a1ecSDimitry Andricpublic: 9967c82a1ecSDimitry Andric typedef typename _NodeTypes::__void_pointer __void_pointer; 9974bab9fd9SDavid Chisnall 9987c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_type __node; 9997c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_pointer __node_pointer; 10007c82a1ecSDimitry Andric 10017c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_base_type __node_base; 10027c82a1ecSDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 10037c82a1ecSDimitry Andric 10047c82a1ecSDimitry Andric typedef typename _NodeTypes::__end_node_type __end_node_t; 10057c82a1ecSDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_ptr; 10067c82a1ecSDimitry Andric 10077c82a1ecSDimitry Andric typedef typename _NodeTypes::__parent_pointer __parent_pointer; 10087c82a1ecSDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 10097c82a1ecSDimitry Andric 1010854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; 10117a984708SDavid Chisnall typedef allocator_traits<__node_allocator> __node_traits; 10127a984708SDavid Chisnall 10137c82a1ecSDimitry Andricprivate: 10147c82a1ecSDimitry Andric // check for sane allocator pointer rebinding semantics. Rebinding the 10157c82a1ecSDimitry Andric // allocator for a new pointer type should be exactly the same as rebinding 10167c82a1ecSDimitry Andric // the pointer using 'pointer_traits'. 10177c82a1ecSDimitry Andric static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), 10187c82a1ecSDimitry Andric "Allocator does not rebind pointers in a sane manner."); 10197c82a1ecSDimitry Andric typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type 10207c82a1ecSDimitry Andric __node_base_allocator; 10217c82a1ecSDimitry Andric typedef allocator_traits<__node_base_allocator> __node_base_traits; 10227c82a1ecSDimitry Andric static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), 10237c82a1ecSDimitry Andric "Allocator does not rebind pointers in a sane manner."); 10247c82a1ecSDimitry Andric 10257c82a1ecSDimitry Andricprivate: 10267c82a1ecSDimitry Andric __iter_pointer __begin_node_; 10277a984708SDavid Chisnall __compressed_pair<__end_node_t, __node_allocator> __pair1_; 10287a984708SDavid Chisnall __compressed_pair<size_type, value_compare> __pair3_; 10297a984708SDavid Chisnall 10307a984708SDavid Chisnallpublic: 10317a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10327c82a1ecSDimitry Andric __iter_pointer __end_node() _NOEXCEPT 10337a984708SDavid Chisnall { 10347c82a1ecSDimitry Andric return static_cast<__iter_pointer>( 10357a984708SDavid Chisnall pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) 10367a984708SDavid Chisnall ); 10377a984708SDavid Chisnall } 10387a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10397c82a1ecSDimitry Andric __iter_pointer __end_node() const _NOEXCEPT 10407a984708SDavid Chisnall { 10417c82a1ecSDimitry Andric return static_cast<__iter_pointer>( 10427c82a1ecSDimitry Andric pointer_traits<__end_node_ptr>::pointer_to( 10437c82a1ecSDimitry Andric const_cast<__end_node_t&>(__pair1_.first()) 10447c82a1ecSDimitry Andric ) 10457a984708SDavid Chisnall ); 10467a984708SDavid Chisnall } 10477a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10487a984708SDavid Chisnall __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();} 10497a984708SDavid Chisnallprivate: 10507a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10517a984708SDavid Chisnall const __node_allocator& __node_alloc() const _NOEXCEPT 10527a984708SDavid Chisnall {return __pair1_.second();} 10537a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10547c82a1ecSDimitry Andric __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} 10557a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10567c82a1ecSDimitry Andric const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} 10577a984708SDavid Chisnallpublic: 10587a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10597a984708SDavid Chisnall allocator_type __alloc() const _NOEXCEPT 10607a984708SDavid Chisnall {return allocator_type(__node_alloc());} 10617a984708SDavid Chisnallprivate: 10627a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10637a984708SDavid Chisnall size_type& size() _NOEXCEPT {return __pair3_.first();} 10647a984708SDavid Chisnallpublic: 10657a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10667a984708SDavid Chisnall const size_type& size() const _NOEXCEPT {return __pair3_.first();} 10677a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10687a984708SDavid Chisnall value_compare& value_comp() _NOEXCEPT {return __pair3_.second();} 10697a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10707a984708SDavid Chisnall const value_compare& value_comp() const _NOEXCEPT 10717a984708SDavid Chisnall {return __pair3_.second();} 10727a984708SDavid Chisnallpublic: 10737c82a1ecSDimitry Andric 10747a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10757c82a1ecSDimitry Andric __node_pointer __root() const _NOEXCEPT 10767a984708SDavid Chisnall {return static_cast<__node_pointer>(__end_node()->__left_);} 10777c82a1ecSDimitry Andric 10787c82a1ecSDimitry Andric __node_base_pointer* __root_ptr() const _NOEXCEPT { 10797c82a1ecSDimitry Andric return _VSTD::addressof(__end_node()->__left_); 10807c82a1ecSDimitry Andric } 10817a984708SDavid Chisnall 10827a984708SDavid Chisnall typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator; 10834bab9fd9SDavid Chisnall typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator; 10847a984708SDavid Chisnall 10857a984708SDavid Chisnall explicit __tree(const value_compare& __comp) 10867a984708SDavid Chisnall _NOEXCEPT_( 10877a984708SDavid Chisnall is_nothrow_default_constructible<__node_allocator>::value && 10887a984708SDavid Chisnall is_nothrow_copy_constructible<value_compare>::value); 10897a984708SDavid Chisnall explicit __tree(const allocator_type& __a); 10907a984708SDavid Chisnall __tree(const value_compare& __comp, const allocator_type& __a); 10917a984708SDavid Chisnall __tree(const __tree& __t); 10927a984708SDavid Chisnall __tree& operator=(const __tree& __t); 10937a984708SDavid Chisnall template <class _InputIterator> 10947a984708SDavid Chisnall void __assign_unique(_InputIterator __first, _InputIterator __last); 10957a984708SDavid Chisnall template <class _InputIterator> 10967a984708SDavid Chisnall void __assign_multi(_InputIterator __first, _InputIterator __last); 1097540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 10987a984708SDavid Chisnall __tree(__tree&& __t) 10997a984708SDavid Chisnall _NOEXCEPT_( 11007a984708SDavid Chisnall is_nothrow_move_constructible<__node_allocator>::value && 11017a984708SDavid Chisnall is_nothrow_move_constructible<value_compare>::value); 11027a984708SDavid Chisnall __tree(__tree&& __t, const allocator_type& __a); 11037a984708SDavid Chisnall __tree& operator=(__tree&& __t) 11047a984708SDavid Chisnall _NOEXCEPT_( 11057a984708SDavid Chisnall __node_traits::propagate_on_container_move_assignment::value && 11067a984708SDavid Chisnall is_nothrow_move_assignable<value_compare>::value && 11077a984708SDavid Chisnall is_nothrow_move_assignable<__node_allocator>::value); 1108540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 11097a984708SDavid Chisnall 11107a984708SDavid Chisnall ~__tree(); 11117a984708SDavid Chisnall 11127a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11137a984708SDavid Chisnall iterator begin() _NOEXCEPT {return iterator(__begin_node());} 11147a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11157a984708SDavid Chisnall const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());} 11167a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11177a984708SDavid Chisnall iterator end() _NOEXCEPT {return iterator(__end_node());} 11187a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11197a984708SDavid Chisnall const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());} 11207a984708SDavid Chisnall 11217a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 11227a984708SDavid Chisnall size_type max_size() const _NOEXCEPT 1123aed8d94eSDimitry Andric {return std::min<size_type>( 1124aed8d94eSDimitry Andric __node_traits::max_size(__node_alloc()), 1125aed8d94eSDimitry Andric numeric_limits<difference_type >::max());} 11267a984708SDavid Chisnall 11277a984708SDavid Chisnall void clear() _NOEXCEPT; 11287a984708SDavid Chisnall 11297a984708SDavid Chisnall void swap(__tree& __t) 1130aed8d94eSDimitry Andric#if _LIBCPP_STD_VER <= 11 11317a984708SDavid Chisnall _NOEXCEPT_( 1132854fa44bSDimitry Andric __is_nothrow_swappable<value_compare>::value 1133854fa44bSDimitry Andric && (!__node_traits::propagate_on_container_swap::value || 1134854fa44bSDimitry Andric __is_nothrow_swappable<__node_allocator>::value) 1135854fa44bSDimitry Andric ); 1136aed8d94eSDimitry Andric#else 1137aed8d94eSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value); 1138aed8d94eSDimitry Andric#endif 11397c82a1ecSDimitry Andric 11407c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 11417c82a1ecSDimitry Andric template <class _Key, class ..._Args> 11427a984708SDavid Chisnall pair<iterator, bool> 11437c82a1ecSDimitry Andric __emplace_unique_key_args(_Key const&, _Args&&... __args); 11447c82a1ecSDimitry Andric template <class _Key, class ..._Args> 11457a984708SDavid Chisnall iterator 11467c82a1ecSDimitry Andric __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); 11477a984708SDavid Chisnall 11487a984708SDavid Chisnall template <class... _Args> 11497c82a1ecSDimitry Andric pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); 11507c82a1ecSDimitry Andric 11517a984708SDavid Chisnall template <class... _Args> 11527c82a1ecSDimitry Andric iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); 11537c82a1ecSDimitry Andric 11547c82a1ecSDimitry Andric template <class... _Args> 11557c82a1ecSDimitry Andric iterator __emplace_multi(_Args&&... __args); 11567c82a1ecSDimitry Andric 11577c82a1ecSDimitry Andric template <class... _Args> 11587c82a1ecSDimitry Andric iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); 11597c82a1ecSDimitry Andric 11607c82a1ecSDimitry Andric template <class _Pp> 11617c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 11627c82a1ecSDimitry Andric pair<iterator, bool> __emplace_unique(_Pp&& __x) { 11637c82a1ecSDimitry Andric return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), 11647c82a1ecSDimitry Andric __can_extract_key<_Pp, key_type>()); 11657c82a1ecSDimitry Andric } 11667c82a1ecSDimitry Andric 11677c82a1ecSDimitry Andric template <class _First, class _Second> 11687c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 11697c82a1ecSDimitry Andric typename enable_if< 11707c82a1ecSDimitry Andric __can_extract_map_key<_First, key_type, __container_value_type>::value, 11717c82a1ecSDimitry Andric pair<iterator, bool> 11727c82a1ecSDimitry Andric >::type __emplace_unique(_First&& __f, _Second&& __s) { 11737c82a1ecSDimitry Andric return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), 11747c82a1ecSDimitry Andric _VSTD::forward<_Second>(__s)); 11757c82a1ecSDimitry Andric } 11767c82a1ecSDimitry Andric 11777c82a1ecSDimitry Andric template <class... _Args> 11787c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 11797c82a1ecSDimitry Andric pair<iterator, bool> __emplace_unique(_Args&&... __args) { 11807c82a1ecSDimitry Andric return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); 11817c82a1ecSDimitry Andric } 11827c82a1ecSDimitry Andric 11837c82a1ecSDimitry Andric template <class _Pp> 11847c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 11857c82a1ecSDimitry Andric pair<iterator, bool> 11867c82a1ecSDimitry Andric __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { 11877c82a1ecSDimitry Andric return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); 11887c82a1ecSDimitry Andric } 11897c82a1ecSDimitry Andric 11907c82a1ecSDimitry Andric template <class _Pp> 11917c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 11927c82a1ecSDimitry Andric pair<iterator, bool> 11937c82a1ecSDimitry Andric __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { 11947c82a1ecSDimitry Andric return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); 11957c82a1ecSDimitry Andric } 11967c82a1ecSDimitry Andric 11977c82a1ecSDimitry Andric template <class _Pp> 11987c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 11997c82a1ecSDimitry Andric pair<iterator, bool> 12007c82a1ecSDimitry Andric __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { 12017c82a1ecSDimitry Andric return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); 12027c82a1ecSDimitry Andric } 12037c82a1ecSDimitry Andric 12047c82a1ecSDimitry Andric template <class _Pp> 12057c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12067c82a1ecSDimitry Andric iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { 12077c82a1ecSDimitry Andric return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), 12087c82a1ecSDimitry Andric __can_extract_key<_Pp, key_type>()); 12097c82a1ecSDimitry Andric } 12107c82a1ecSDimitry Andric 12117c82a1ecSDimitry Andric template <class _First, class _Second> 12127c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12137c82a1ecSDimitry Andric typename enable_if< 12147c82a1ecSDimitry Andric __can_extract_map_key<_First, key_type, __container_value_type>::value, 12157a984708SDavid Chisnall iterator 12167c82a1ecSDimitry Andric >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) { 12177c82a1ecSDimitry Andric return __emplace_hint_unique_key_args(__p, __f, 12187c82a1ecSDimitry Andric _VSTD::forward<_First>(__f), 12197c82a1ecSDimitry Andric _VSTD::forward<_Second>(__s)); 12207c82a1ecSDimitry Andric } 12217a984708SDavid Chisnall 12227c82a1ecSDimitry Andric template <class... _Args> 12237c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12247c82a1ecSDimitry Andric iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { 12257c82a1ecSDimitry Andric return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); 12267c82a1ecSDimitry Andric } 12277a984708SDavid Chisnall 12287c82a1ecSDimitry Andric template <class _Pp> 12297c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12307c82a1ecSDimitry Andric iterator 12317c82a1ecSDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { 12327c82a1ecSDimitry Andric return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x)); 12337c82a1ecSDimitry Andric } 12347a984708SDavid Chisnall 12357c82a1ecSDimitry Andric template <class _Pp> 12367c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12377c82a1ecSDimitry Andric iterator 12387c82a1ecSDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { 12397c82a1ecSDimitry Andric return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); 12407c82a1ecSDimitry Andric } 12417c82a1ecSDimitry Andric 12427c82a1ecSDimitry Andric template <class _Pp> 12437c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12447c82a1ecSDimitry Andric iterator 12457c82a1ecSDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { 12467c82a1ecSDimitry Andric return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); 12477c82a1ecSDimitry Andric } 12487c82a1ecSDimitry Andric 12497c82a1ecSDimitry Andric#else 12507c82a1ecSDimitry Andric template <class _Key, class _Args> 12517c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12527c82a1ecSDimitry Andric pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args); 12537c82a1ecSDimitry Andric template <class _Key, class _Args> 12547c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12557c82a1ecSDimitry Andric iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&); 12569729cf09SDimitry Andric#endif 12579729cf09SDimitry Andric 12587c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12597c82a1ecSDimitry Andric pair<iterator, bool> __insert_unique(const __container_value_type& __v) { 12607c82a1ecSDimitry Andric return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v); 12617c82a1ecSDimitry Andric } 12627c82a1ecSDimitry Andric 12637c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12647c82a1ecSDimitry Andric iterator __insert_unique(const_iterator __p, const __container_value_type& __v) { 12657c82a1ecSDimitry Andric return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v); 12667c82a1ecSDimitry Andric } 12677c82a1ecSDimitry Andric 12687c82a1ecSDimitry Andric#ifdef _LIBCPP_CXX03_LANG 12697c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12707c82a1ecSDimitry Andric iterator __insert_multi(const __container_value_type& __v); 12717c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12727c82a1ecSDimitry Andric iterator __insert_multi(const_iterator __p, const __container_value_type& __v); 12737c82a1ecSDimitry Andric#else 12747c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12757c82a1ecSDimitry Andric pair<iterator, bool> __insert_unique(__container_value_type&& __v) { 12767c82a1ecSDimitry Andric return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v)); 12777c82a1ecSDimitry Andric } 12787c82a1ecSDimitry Andric 12797c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12807c82a1ecSDimitry Andric iterator __insert_unique(const_iterator __p, __container_value_type&& __v) { 12817c82a1ecSDimitry Andric return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)); 12827c82a1ecSDimitry Andric } 12837c82a1ecSDimitry Andric 12847c82a1ecSDimitry Andric template <class _Vp, class = typename enable_if< 12857c82a1ecSDimitry Andric !is_same<typename __unconstref<_Vp>::type, 12867c82a1ecSDimitry Andric __container_value_type 12877c82a1ecSDimitry Andric >::value 12887c82a1ecSDimitry Andric >::type> 12897c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 12907c82a1ecSDimitry Andric pair<iterator, bool> __insert_unique(_Vp&& __v) { 12917c82a1ecSDimitry Andric return __emplace_unique(_VSTD::forward<_Vp>(__v)); 12927c82a1ecSDimitry Andric } 12937c82a1ecSDimitry Andric 12947c82a1ecSDimitry Andric template <class _Vp, class = typename enable_if< 12957c82a1ecSDimitry Andric !is_same<typename __unconstref<_Vp>::type, 12967c82a1ecSDimitry Andric __container_value_type 12977c82a1ecSDimitry Andric >::value 12987c82a1ecSDimitry Andric >::type> 12997c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 13007c82a1ecSDimitry Andric iterator __insert_unique(const_iterator __p, _Vp&& __v) { 13017c82a1ecSDimitry Andric return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v)); 13027c82a1ecSDimitry Andric } 13037c82a1ecSDimitry Andric 13047c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 13057c82a1ecSDimitry Andric iterator __insert_multi(__container_value_type&& __v) { 13067c82a1ecSDimitry Andric return __emplace_multi(_VSTD::move(__v)); 13077c82a1ecSDimitry Andric } 13087c82a1ecSDimitry Andric 13097c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 13107c82a1ecSDimitry Andric iterator __insert_multi(const_iterator __p, __container_value_type&& __v) { 13117c82a1ecSDimitry Andric return __emplace_hint_multi(__p, _VSTD::move(__v)); 13127c82a1ecSDimitry Andric } 13137c82a1ecSDimitry Andric 13147c82a1ecSDimitry Andric template <class _Vp> 13157c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 13167c82a1ecSDimitry Andric iterator __insert_multi(_Vp&& __v) { 13177c82a1ecSDimitry Andric return __emplace_multi(_VSTD::forward<_Vp>(__v)); 13187c82a1ecSDimitry Andric } 13197c82a1ecSDimitry Andric 13207c82a1ecSDimitry Andric template <class _Vp> 13217c82a1ecSDimitry Andric _LIBCPP_INLINE_VISIBILITY 13227c82a1ecSDimitry Andric iterator __insert_multi(const_iterator __p, _Vp&& __v) { 13237c82a1ecSDimitry Andric return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v)); 13247c82a1ecSDimitry Andric } 13257c82a1ecSDimitry Andric 13267c82a1ecSDimitry Andric#endif // !_LIBCPP_CXX03_LANG 13277c82a1ecSDimitry Andric 1328*b5893f02SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13297a984708SDavid Chisnall pair<iterator, bool> __node_insert_unique(__node_pointer __nd); 1330*b5893f02SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13317a984708SDavid Chisnall iterator __node_insert_unique(const_iterator __p, 13327a984708SDavid Chisnall __node_pointer __nd); 13337a984708SDavid Chisnall 1334*b5893f02SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13357a984708SDavid Chisnall iterator __node_insert_multi(__node_pointer __nd); 1336*b5893f02SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13377a984708SDavid Chisnall iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); 13387a984708SDavid Chisnall 13394ba319b5SDimitry Andric 1340*b5893f02SDimitry Andric _LIBCPP_INLINE_VISIBILITY iterator 1341*b5893f02SDimitry Andric __remove_node_pointer(__node_pointer) _NOEXCEPT; 13424ba319b5SDimitry Andric 13434ba319b5SDimitry Andric#if _LIBCPP_STD_VER > 14 13444ba319b5SDimitry Andric template <class _NodeHandle, class _InsertReturnType> 13454ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13464ba319b5SDimitry Andric _InsertReturnType __node_handle_insert_unique(_NodeHandle&&); 13474ba319b5SDimitry Andric template <class _NodeHandle> 13484ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13494ba319b5SDimitry Andric iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&); 1350*b5893f02SDimitry Andric template <class _Tree> 1351*b5893f02SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1352*b5893f02SDimitry Andric void __node_handle_merge_unique(_Tree& __source); 13534ba319b5SDimitry Andric 13544ba319b5SDimitry Andric template <class _NodeHandle> 13554ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13564ba319b5SDimitry Andric iterator __node_handle_insert_multi(_NodeHandle&&); 13574ba319b5SDimitry Andric template <class _NodeHandle> 13584ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13594ba319b5SDimitry Andric iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&); 1360*b5893f02SDimitry Andric template <class _Tree> 1361*b5893f02SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1362*b5893f02SDimitry Andric void __node_handle_merge_multi(_Tree& __source); 13634ba319b5SDimitry Andric 13644ba319b5SDimitry Andric 13654ba319b5SDimitry Andric template <class _NodeHandle> 13664ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13674ba319b5SDimitry Andric _NodeHandle __node_handle_extract(key_type const&); 13684ba319b5SDimitry Andric template <class _NodeHandle> 13694ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 13704ba319b5SDimitry Andric _NodeHandle __node_handle_extract(const_iterator); 13714ba319b5SDimitry Andric#endif 13724ba319b5SDimitry Andric 13737a984708SDavid Chisnall iterator erase(const_iterator __p); 13747a984708SDavid Chisnall iterator erase(const_iterator __f, const_iterator __l); 13757a984708SDavid Chisnall template <class _Key> 13767a984708SDavid Chisnall size_type __erase_unique(const _Key& __k); 13777a984708SDavid Chisnall template <class _Key> 13787a984708SDavid Chisnall size_type __erase_multi(const _Key& __k); 13797a984708SDavid Chisnall 13807c82a1ecSDimitry Andric void __insert_node_at(__parent_pointer __parent, 13817a984708SDavid Chisnall __node_base_pointer& __child, 1382*b5893f02SDimitry Andric __node_base_pointer __new_node) _NOEXCEPT; 13837a984708SDavid Chisnall 13847a984708SDavid Chisnall template <class _Key> 13857a984708SDavid Chisnall iterator find(const _Key& __v); 13867a984708SDavid Chisnall template <class _Key> 13877a984708SDavid Chisnall const_iterator find(const _Key& __v) const; 13887a984708SDavid Chisnall 13897a984708SDavid Chisnall template <class _Key> 13907a984708SDavid Chisnall size_type __count_unique(const _Key& __k) const; 13917a984708SDavid Chisnall template <class _Key> 13927a984708SDavid Chisnall size_type __count_multi(const _Key& __k) const; 13937a984708SDavid Chisnall 13947a984708SDavid Chisnall template <class _Key> 13957a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 13967a984708SDavid Chisnall iterator lower_bound(const _Key& __v) 13977a984708SDavid Chisnall {return __lower_bound(__v, __root(), __end_node());} 13987a984708SDavid Chisnall template <class _Key> 13997a984708SDavid Chisnall iterator __lower_bound(const _Key& __v, 14007a984708SDavid Chisnall __node_pointer __root, 14017c82a1ecSDimitry Andric __iter_pointer __result); 14027a984708SDavid Chisnall template <class _Key> 14037a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 14047a984708SDavid Chisnall const_iterator lower_bound(const _Key& __v) const 14057a984708SDavid Chisnall {return __lower_bound(__v, __root(), __end_node());} 14067a984708SDavid Chisnall template <class _Key> 14077a984708SDavid Chisnall const_iterator __lower_bound(const _Key& __v, 14087c82a1ecSDimitry Andric __node_pointer __root, 14097c82a1ecSDimitry Andric __iter_pointer __result) const; 14107a984708SDavid Chisnall template <class _Key> 14117a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 14127a984708SDavid Chisnall iterator upper_bound(const _Key& __v) 14137a984708SDavid Chisnall {return __upper_bound(__v, __root(), __end_node());} 14147a984708SDavid Chisnall template <class _Key> 14157a984708SDavid Chisnall iterator __upper_bound(const _Key& __v, 14167a984708SDavid Chisnall __node_pointer __root, 14177c82a1ecSDimitry Andric __iter_pointer __result); 14187a984708SDavid Chisnall template <class _Key> 14197a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 14207a984708SDavid Chisnall const_iterator upper_bound(const _Key& __v) const 14217a984708SDavid Chisnall {return __upper_bound(__v, __root(), __end_node());} 14227a984708SDavid Chisnall template <class _Key> 14237a984708SDavid Chisnall const_iterator __upper_bound(const _Key& __v, 14247c82a1ecSDimitry Andric __node_pointer __root, 14257c82a1ecSDimitry Andric __iter_pointer __result) const; 14267a984708SDavid Chisnall template <class _Key> 14277a984708SDavid Chisnall pair<iterator, iterator> 14287a984708SDavid Chisnall __equal_range_unique(const _Key& __k); 14297a984708SDavid Chisnall template <class _Key> 14307a984708SDavid Chisnall pair<const_iterator, const_iterator> 14317a984708SDavid Chisnall __equal_range_unique(const _Key& __k) const; 14327a984708SDavid Chisnall 14337a984708SDavid Chisnall template <class _Key> 14347a984708SDavid Chisnall pair<iterator, iterator> 14357a984708SDavid Chisnall __equal_range_multi(const _Key& __k); 14367a984708SDavid Chisnall template <class _Key> 14377a984708SDavid Chisnall pair<const_iterator, const_iterator> 14387a984708SDavid Chisnall __equal_range_multi(const _Key& __k) const; 14397a984708SDavid Chisnall 144094e3ee44SDavid Chisnall typedef __tree_node_destructor<__node_allocator> _Dp; 144194e3ee44SDavid Chisnall typedef unique_ptr<__node, _Dp> __node_holder; 14427a984708SDavid Chisnall 14437a984708SDavid Chisnall __node_holder remove(const_iterator __p) _NOEXCEPT; 14447a984708SDavid Chisnallprivate: 14457c82a1ecSDimitry Andric __node_base_pointer& 14467c82a1ecSDimitry Andric __find_leaf_low(__parent_pointer& __parent, const key_type& __v); 14477c82a1ecSDimitry Andric __node_base_pointer& 14487c82a1ecSDimitry Andric __find_leaf_high(__parent_pointer& __parent, const key_type& __v); 14497c82a1ecSDimitry Andric __node_base_pointer& 14507a984708SDavid Chisnall __find_leaf(const_iterator __hint, 14517c82a1ecSDimitry Andric __parent_pointer& __parent, const key_type& __v); 1452aed8d94eSDimitry Andric // FIXME: Make this function const qualified. Unfortunetly doing so 1453aed8d94eSDimitry Andric // breaks existing code which uses non-const callable comparators. 14547a984708SDavid Chisnall template <class _Key> 14557c82a1ecSDimitry Andric __node_base_pointer& 14567c82a1ecSDimitry Andric __find_equal(__parent_pointer& __parent, const _Key& __v); 14577a984708SDavid Chisnall template <class _Key> 1458aed8d94eSDimitry Andric _LIBCPP_INLINE_VISIBILITY __node_base_pointer& 1459aed8d94eSDimitry Andric __find_equal(__parent_pointer& __parent, const _Key& __v) const { 1460aed8d94eSDimitry Andric return const_cast<__tree*>(this)->__find_equal(__parent, __v); 1461aed8d94eSDimitry Andric } 1462aed8d94eSDimitry Andric template <class _Key> 14637c82a1ecSDimitry Andric __node_base_pointer& 14647c82a1ecSDimitry Andric __find_equal(const_iterator __hint, __parent_pointer& __parent, 14657c82a1ecSDimitry Andric __node_base_pointer& __dummy, 14667a984708SDavid Chisnall const _Key& __v); 14677a984708SDavid Chisnall 14687c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 14697a984708SDavid Chisnall template <class ..._Args> 14707a984708SDavid Chisnall __node_holder __construct_node(_Args&& ...__args); 14717c82a1ecSDimitry Andric#else 14727c82a1ecSDimitry Andric __node_holder __construct_node(const __container_value_type& __v); 14737a984708SDavid Chisnall#endif 14747a984708SDavid Chisnall 14757a984708SDavid Chisnall void destroy(__node_pointer __nd) _NOEXCEPT; 14767a984708SDavid Chisnall 14777a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 14787a984708SDavid Chisnall void __copy_assign_alloc(const __tree& __t) 14797a984708SDavid Chisnall {__copy_assign_alloc(__t, integral_constant<bool, 14807a984708SDavid Chisnall __node_traits::propagate_on_container_copy_assignment::value>());} 14817a984708SDavid Chisnall 14827a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 14837a984708SDavid Chisnall void __copy_assign_alloc(const __tree& __t, true_type) 14847c82a1ecSDimitry Andric { 14857c82a1ecSDimitry Andric if (__node_alloc() != __t.__node_alloc()) 14867c82a1ecSDimitry Andric clear(); 14877c82a1ecSDimitry Andric __node_alloc() = __t.__node_alloc(); 14887c82a1ecSDimitry Andric } 14897a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1490aed8d94eSDimitry Andric void __copy_assign_alloc(const __tree&, false_type) {} 14917a984708SDavid Chisnall 14927a984708SDavid Chisnall void __move_assign(__tree& __t, false_type); 14937a984708SDavid Chisnall void __move_assign(__tree& __t, true_type) 14947a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value && 14957a984708SDavid Chisnall is_nothrow_move_assignable<__node_allocator>::value); 14967a984708SDavid Chisnall 14977a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 14987a984708SDavid Chisnall void __move_assign_alloc(__tree& __t) 14997a984708SDavid Chisnall _NOEXCEPT_( 15007a984708SDavid Chisnall !__node_traits::propagate_on_container_move_assignment::value || 15017a984708SDavid Chisnall is_nothrow_move_assignable<__node_allocator>::value) 15027a984708SDavid Chisnall {__move_assign_alloc(__t, integral_constant<bool, 15037a984708SDavid Chisnall __node_traits::propagate_on_container_move_assignment::value>());} 15047a984708SDavid Chisnall 15057a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 15067a984708SDavid Chisnall void __move_assign_alloc(__tree& __t, true_type) 15077a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) 15087a984708SDavid Chisnall {__node_alloc() = _VSTD::move(__t.__node_alloc());} 15097a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1510aed8d94eSDimitry Andric void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {} 15117a984708SDavid Chisnall 15127a984708SDavid Chisnall __node_pointer __detach(); 15137a984708SDavid Chisnall static __node_pointer __detach(__node_pointer); 15144bab9fd9SDavid Chisnall 1515aed8d94eSDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 1516aed8d94eSDimitry Andric template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 15177a984708SDavid Chisnall}; 15187a984708SDavid Chisnall 15197a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 15207a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) 15217a984708SDavid Chisnall _NOEXCEPT_( 15227a984708SDavid Chisnall is_nothrow_default_constructible<__node_allocator>::value && 15237a984708SDavid Chisnall is_nothrow_copy_constructible<value_compare>::value) 15247a984708SDavid Chisnall : __pair3_(0, __comp) 15257a984708SDavid Chisnall{ 15267a984708SDavid Chisnall __begin_node() = __end_node(); 15277a984708SDavid Chisnall} 15287a984708SDavid Chisnall 15297a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 15307a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) 15317c82a1ecSDimitry Andric : __begin_node_(__iter_pointer()), 1532540d2a8bSDimitry Andric __pair1_(__second_tag(), __node_allocator(__a)), 15337a984708SDavid Chisnall __pair3_(0) 15347a984708SDavid Chisnall{ 15357a984708SDavid Chisnall __begin_node() = __end_node(); 15367a984708SDavid Chisnall} 15377a984708SDavid Chisnall 15387a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 15397a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, 15407a984708SDavid Chisnall const allocator_type& __a) 15417c82a1ecSDimitry Andric : __begin_node_(__iter_pointer()), 1542540d2a8bSDimitry Andric __pair1_(__second_tag(), __node_allocator(__a)), 15437a984708SDavid Chisnall __pair3_(0, __comp) 15447a984708SDavid Chisnall{ 15457a984708SDavid Chisnall __begin_node() = __end_node(); 15467a984708SDavid Chisnall} 15477a984708SDavid Chisnall 15487a984708SDavid Chisnall// Precondition: size() != 0 15497a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 15507a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::__node_pointer 15517a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__detach() 15527a984708SDavid Chisnall{ 15537c82a1ecSDimitry Andric __node_pointer __cache = static_cast<__node_pointer>(__begin_node()); 15547a984708SDavid Chisnall __begin_node() = __end_node(); 15557a984708SDavid Chisnall __end_node()->__left_->__parent_ = nullptr; 15567a984708SDavid Chisnall __end_node()->__left_ = nullptr; 15577a984708SDavid Chisnall size() = 0; 15587a984708SDavid Chisnall // __cache->__left_ == nullptr 15597a984708SDavid Chisnall if (__cache->__right_ != nullptr) 15607a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__right_); 15617a984708SDavid Chisnall // __cache->__left_ == nullptr 15627a984708SDavid Chisnall // __cache->__right_ == nullptr 15637a984708SDavid Chisnall return __cache; 15647a984708SDavid Chisnall} 15657a984708SDavid Chisnall 15667a984708SDavid Chisnall// Precondition: __cache != nullptr 15677a984708SDavid Chisnall// __cache->left_ == nullptr 15687a984708SDavid Chisnall// __cache->right_ == nullptr 15697a984708SDavid Chisnall// This is no longer a red-black tree 15707a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 15717a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::__node_pointer 15727a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache) 15737a984708SDavid Chisnall{ 15747a984708SDavid Chisnall if (__cache->__parent_ == nullptr) 15757a984708SDavid Chisnall return nullptr; 15764bab9fd9SDavid Chisnall if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) 15777a984708SDavid Chisnall { 15787a984708SDavid Chisnall __cache->__parent_->__left_ = nullptr; 15797a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 15807a984708SDavid Chisnall if (__cache->__right_ == nullptr) 15817a984708SDavid Chisnall return __cache; 15827a984708SDavid Chisnall return static_cast<__node_pointer>(__tree_leaf(__cache->__right_)); 15837a984708SDavid Chisnall } 15847a984708SDavid Chisnall // __cache is right child 15857c82a1ecSDimitry Andric __cache->__parent_unsafe()->__right_ = nullptr; 15867a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 15877a984708SDavid Chisnall if (__cache->__left_ == nullptr) 15887a984708SDavid Chisnall return __cache; 15897a984708SDavid Chisnall return static_cast<__node_pointer>(__tree_leaf(__cache->__left_)); 15907a984708SDavid Chisnall} 15917a984708SDavid Chisnall 15927a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 15937a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>& 15947a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) 15957a984708SDavid Chisnall{ 15967a984708SDavid Chisnall if (this != &__t) 15977a984708SDavid Chisnall { 15987a984708SDavid Chisnall value_comp() = __t.value_comp(); 15997a984708SDavid Chisnall __copy_assign_alloc(__t); 16007a984708SDavid Chisnall __assign_multi(__t.begin(), __t.end()); 16017a984708SDavid Chisnall } 16027a984708SDavid Chisnall return *this; 16037a984708SDavid Chisnall} 16047a984708SDavid Chisnall 16057a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 16067a984708SDavid Chisnalltemplate <class _InputIterator> 16077a984708SDavid Chisnallvoid 16087a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last) 16097a984708SDavid Chisnall{ 16107c82a1ecSDimitry Andric typedef iterator_traits<_InputIterator> _ITraits; 16117c82a1ecSDimitry Andric typedef typename _ITraits::value_type _ItValueType; 16127c82a1ecSDimitry Andric static_assert((is_same<_ItValueType, __container_value_type>::value), 16137c82a1ecSDimitry Andric "__assign_unique may only be called with the containers value type"); 16147c82a1ecSDimitry Andric 16157a984708SDavid Chisnall if (size() != 0) 16167a984708SDavid Chisnall { 16177a984708SDavid Chisnall __node_pointer __cache = __detach(); 16187a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 16197a984708SDavid Chisnall try 16207a984708SDavid Chisnall { 16217a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 16227a984708SDavid Chisnall for (; __cache != nullptr && __first != __last; ++__first) 16237a984708SDavid Chisnall { 16247a984708SDavid Chisnall __cache->__value_ = *__first; 16257a984708SDavid Chisnall __node_pointer __next = __detach(__cache); 16267a984708SDavid Chisnall __node_insert_unique(__cache); 16277a984708SDavid Chisnall __cache = __next; 16287a984708SDavid Chisnall } 16297a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 16307a984708SDavid Chisnall } 16317a984708SDavid Chisnall catch (...) 16327a984708SDavid Chisnall { 16337a984708SDavid Chisnall while (__cache->__parent_ != nullptr) 16347a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 16357a984708SDavid Chisnall destroy(__cache); 16367a984708SDavid Chisnall throw; 16377a984708SDavid Chisnall } 16387a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 16397a984708SDavid Chisnall if (__cache != nullptr) 16407a984708SDavid Chisnall { 16417a984708SDavid Chisnall while (__cache->__parent_ != nullptr) 16427a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 16437a984708SDavid Chisnall destroy(__cache); 16447a984708SDavid Chisnall } 16457a984708SDavid Chisnall } 16467a984708SDavid Chisnall for (; __first != __last; ++__first) 16477a984708SDavid Chisnall __insert_unique(*__first); 16487a984708SDavid Chisnall} 16497a984708SDavid Chisnall 16507a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 16517a984708SDavid Chisnalltemplate <class _InputIterator> 16527a984708SDavid Chisnallvoid 16537a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) 16547a984708SDavid Chisnall{ 16557c82a1ecSDimitry Andric typedef iterator_traits<_InputIterator> _ITraits; 16567c82a1ecSDimitry Andric typedef typename _ITraits::value_type _ItValueType; 16577c82a1ecSDimitry Andric static_assert((is_same<_ItValueType, __container_value_type>::value || 16587c82a1ecSDimitry Andric is_same<_ItValueType, __node_value_type>::value), 16597c82a1ecSDimitry Andric "__assign_multi may only be called with the containers value type" 16607c82a1ecSDimitry Andric " or the nodes value type"); 16617a984708SDavid Chisnall if (size() != 0) 16627a984708SDavid Chisnall { 16637a984708SDavid Chisnall __node_pointer __cache = __detach(); 16647a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 16657a984708SDavid Chisnall try 16667a984708SDavid Chisnall { 16677a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 16687a984708SDavid Chisnall for (; __cache != nullptr && __first != __last; ++__first) 16697a984708SDavid Chisnall { 16707a984708SDavid Chisnall __cache->__value_ = *__first; 16717a984708SDavid Chisnall __node_pointer __next = __detach(__cache); 16727a984708SDavid Chisnall __node_insert_multi(__cache); 16737a984708SDavid Chisnall __cache = __next; 16747a984708SDavid Chisnall } 16757a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 16767a984708SDavid Chisnall } 16777a984708SDavid Chisnall catch (...) 16787a984708SDavid Chisnall { 16797a984708SDavid Chisnall while (__cache->__parent_ != nullptr) 16807a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 16817a984708SDavid Chisnall destroy(__cache); 16827a984708SDavid Chisnall throw; 16837a984708SDavid Chisnall } 16847a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 16857a984708SDavid Chisnall if (__cache != nullptr) 16867a984708SDavid Chisnall { 16877a984708SDavid Chisnall while (__cache->__parent_ != nullptr) 16887a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 16897a984708SDavid Chisnall destroy(__cache); 16907a984708SDavid Chisnall } 16917a984708SDavid Chisnall } 16927a984708SDavid Chisnall for (; __first != __last; ++__first) 16937c82a1ecSDimitry Andric __insert_multi(_NodeTypes::__get_value(*__first)); 16947a984708SDavid Chisnall} 16957a984708SDavid Chisnall 16967a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 16977a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) 16987c82a1ecSDimitry Andric : __begin_node_(__iter_pointer()), 1699540d2a8bSDimitry Andric __pair1_(__second_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())), 17007a984708SDavid Chisnall __pair3_(0, __t.value_comp()) 17017a984708SDavid Chisnall{ 17027a984708SDavid Chisnall __begin_node() = __end_node(); 17037a984708SDavid Chisnall} 17047a984708SDavid Chisnall 1705540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 17067a984708SDavid Chisnall 17077a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 17087a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) 17097a984708SDavid Chisnall _NOEXCEPT_( 17107a984708SDavid Chisnall is_nothrow_move_constructible<__node_allocator>::value && 17117a984708SDavid Chisnall is_nothrow_move_constructible<value_compare>::value) 17127a984708SDavid Chisnall : __begin_node_(_VSTD::move(__t.__begin_node_)), 17137a984708SDavid Chisnall __pair1_(_VSTD::move(__t.__pair1_)), 17147a984708SDavid Chisnall __pair3_(_VSTD::move(__t.__pair3_)) 17157a984708SDavid Chisnall{ 17167a984708SDavid Chisnall if (size() == 0) 17177a984708SDavid Chisnall __begin_node() = __end_node(); 17187a984708SDavid Chisnall else 17197a984708SDavid Chisnall { 17207c82a1ecSDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 17217a984708SDavid Chisnall __t.__begin_node() = __t.__end_node(); 17227a984708SDavid Chisnall __t.__end_node()->__left_ = nullptr; 17237a984708SDavid Chisnall __t.size() = 0; 17247a984708SDavid Chisnall } 17257a984708SDavid Chisnall} 17267a984708SDavid Chisnall 17277a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 17287a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) 1729540d2a8bSDimitry Andric : __pair1_(__second_tag(), __node_allocator(__a)), 17307a984708SDavid Chisnall __pair3_(0, _VSTD::move(__t.value_comp())) 17317a984708SDavid Chisnall{ 17327a984708SDavid Chisnall if (__a == __t.__alloc()) 17337a984708SDavid Chisnall { 17347a984708SDavid Chisnall if (__t.size() == 0) 17357a984708SDavid Chisnall __begin_node() = __end_node(); 17367a984708SDavid Chisnall else 17377a984708SDavid Chisnall { 17387a984708SDavid Chisnall __begin_node() = __t.__begin_node(); 17397a984708SDavid Chisnall __end_node()->__left_ = __t.__end_node()->__left_; 17407c82a1ecSDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 17417a984708SDavid Chisnall size() = __t.size(); 17427a984708SDavid Chisnall __t.__begin_node() = __t.__end_node(); 17437a984708SDavid Chisnall __t.__end_node()->__left_ = nullptr; 17447a984708SDavid Chisnall __t.size() = 0; 17457a984708SDavid Chisnall } 17467a984708SDavid Chisnall } 17477a984708SDavid Chisnall else 17487a984708SDavid Chisnall { 17497a984708SDavid Chisnall __begin_node() = __end_node(); 17507a984708SDavid Chisnall } 17517a984708SDavid Chisnall} 17527a984708SDavid Chisnall 17537a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 17547a984708SDavid Chisnallvoid 17557a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) 17567a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value && 17577a984708SDavid Chisnall is_nothrow_move_assignable<__node_allocator>::value) 17587a984708SDavid Chisnall{ 17597a984708SDavid Chisnall destroy(static_cast<__node_pointer>(__end_node()->__left_)); 17607a984708SDavid Chisnall __begin_node_ = __t.__begin_node_; 17617a984708SDavid Chisnall __pair1_.first() = __t.__pair1_.first(); 17627a984708SDavid Chisnall __move_assign_alloc(__t); 17637a984708SDavid Chisnall __pair3_ = _VSTD::move(__t.__pair3_); 17647a984708SDavid Chisnall if (size() == 0) 17657a984708SDavid Chisnall __begin_node() = __end_node(); 17667a984708SDavid Chisnall else 17677a984708SDavid Chisnall { 17687c82a1ecSDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 17697a984708SDavid Chisnall __t.__begin_node() = __t.__end_node(); 17707a984708SDavid Chisnall __t.__end_node()->__left_ = nullptr; 17717a984708SDavid Chisnall __t.size() = 0; 17727a984708SDavid Chisnall } 17737a984708SDavid Chisnall} 17747a984708SDavid Chisnall 17757a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 17767a984708SDavid Chisnallvoid 17777a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) 17787a984708SDavid Chisnall{ 17797a984708SDavid Chisnall if (__node_alloc() == __t.__node_alloc()) 17807a984708SDavid Chisnall __move_assign(__t, true_type()); 17817a984708SDavid Chisnall else 17827a984708SDavid Chisnall { 17837a984708SDavid Chisnall value_comp() = _VSTD::move(__t.value_comp()); 17847a984708SDavid Chisnall const_iterator __e = end(); 17857a984708SDavid Chisnall if (size() != 0) 17867a984708SDavid Chisnall { 17877a984708SDavid Chisnall __node_pointer __cache = __detach(); 17887a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 17897a984708SDavid Chisnall try 17907a984708SDavid Chisnall { 17917a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 17927a984708SDavid Chisnall while (__cache != nullptr && __t.size() != 0) 17937a984708SDavid Chisnall { 17947a984708SDavid Chisnall __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_); 17957a984708SDavid Chisnall __node_pointer __next = __detach(__cache); 17967a984708SDavid Chisnall __node_insert_multi(__cache); 17977a984708SDavid Chisnall __cache = __next; 17987a984708SDavid Chisnall } 17997a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 18007a984708SDavid Chisnall } 18017a984708SDavid Chisnall catch (...) 18027a984708SDavid Chisnall { 18037a984708SDavid Chisnall while (__cache->__parent_ != nullptr) 18047a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 18057a984708SDavid Chisnall destroy(__cache); 18067a984708SDavid Chisnall throw; 18077a984708SDavid Chisnall } 18087a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 18097a984708SDavid Chisnall if (__cache != nullptr) 18107a984708SDavid Chisnall { 18117a984708SDavid Chisnall while (__cache->__parent_ != nullptr) 18127a984708SDavid Chisnall __cache = static_cast<__node_pointer>(__cache->__parent_); 18137a984708SDavid Chisnall destroy(__cache); 18147a984708SDavid Chisnall } 18157a984708SDavid Chisnall } 18167a984708SDavid Chisnall while (__t.size() != 0) 18177c82a1ecSDimitry Andric __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); 18187a984708SDavid Chisnall } 18197a984708SDavid Chisnall} 18207a984708SDavid Chisnall 18217a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 18227a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>& 18237a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) 18247a984708SDavid Chisnall _NOEXCEPT_( 18257a984708SDavid Chisnall __node_traits::propagate_on_container_move_assignment::value && 18267a984708SDavid Chisnall is_nothrow_move_assignable<value_compare>::value && 18277a984708SDavid Chisnall is_nothrow_move_assignable<__node_allocator>::value) 18287a984708SDavid Chisnall 18297a984708SDavid Chisnall{ 18307a984708SDavid Chisnall __move_assign(__t, integral_constant<bool, 18317a984708SDavid Chisnall __node_traits::propagate_on_container_move_assignment::value>()); 18327a984708SDavid Chisnall return *this; 18337a984708SDavid Chisnall} 18347a984708SDavid Chisnall 1835540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 18367a984708SDavid Chisnall 18377a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 18387a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::~__tree() 18397a984708SDavid Chisnall{ 18407c82a1ecSDimitry Andric static_assert((is_copy_constructible<value_compare>::value), 18417c82a1ecSDimitry Andric "Comparator must be copy-constructible."); 18427a984708SDavid Chisnall destroy(__root()); 18437a984708SDavid Chisnall} 18447a984708SDavid Chisnall 18457a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 18467a984708SDavid Chisnallvoid 18477a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT 18487a984708SDavid Chisnall{ 18497a984708SDavid Chisnall if (__nd != nullptr) 18507a984708SDavid Chisnall { 18517a984708SDavid Chisnall destroy(static_cast<__node_pointer>(__nd->__left_)); 18527a984708SDavid Chisnall destroy(static_cast<__node_pointer>(__nd->__right_)); 18537a984708SDavid Chisnall __node_allocator& __na = __node_alloc(); 18547c82a1ecSDimitry Andric __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); 18557a984708SDavid Chisnall __node_traits::deallocate(__na, __nd, 1); 18567a984708SDavid Chisnall } 18577a984708SDavid Chisnall} 18587a984708SDavid Chisnall 18597a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 18607a984708SDavid Chisnallvoid 18617a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) 1862aed8d94eSDimitry Andric#if _LIBCPP_STD_VER <= 11 18637a984708SDavid Chisnall _NOEXCEPT_( 1864854fa44bSDimitry Andric __is_nothrow_swappable<value_compare>::value 1865854fa44bSDimitry Andric && (!__node_traits::propagate_on_container_swap::value || 1866854fa44bSDimitry Andric __is_nothrow_swappable<__node_allocator>::value) 1867854fa44bSDimitry Andric ) 1868aed8d94eSDimitry Andric#else 1869aed8d94eSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value) 1870aed8d94eSDimitry Andric#endif 18717a984708SDavid Chisnall{ 18727a984708SDavid Chisnall using _VSTD::swap; 18737a984708SDavid Chisnall swap(__begin_node_, __t.__begin_node_); 18747a984708SDavid Chisnall swap(__pair1_.first(), __t.__pair1_.first()); 1875854fa44bSDimitry Andric __swap_allocator(__node_alloc(), __t.__node_alloc()); 18767a984708SDavid Chisnall __pair3_.swap(__t.__pair3_); 18777a984708SDavid Chisnall if (size() == 0) 18787a984708SDavid Chisnall __begin_node() = __end_node(); 18797a984708SDavid Chisnall else 18807c82a1ecSDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 18817a984708SDavid Chisnall if (__t.size() == 0) 18827a984708SDavid Chisnall __t.__begin_node() = __t.__end_node(); 18837a984708SDavid Chisnall else 18847c82a1ecSDimitry Andric __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node()); 18857a984708SDavid Chisnall} 18867a984708SDavid Chisnall 18877a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 18887a984708SDavid Chisnallvoid 18897a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT 18907a984708SDavid Chisnall{ 18917a984708SDavid Chisnall destroy(__root()); 18927a984708SDavid Chisnall size() = 0; 18937a984708SDavid Chisnall __begin_node() = __end_node(); 18947a984708SDavid Chisnall __end_node()->__left_ = nullptr; 18957a984708SDavid Chisnall} 18967a984708SDavid Chisnall 18977a984708SDavid Chisnall// Find lower_bound place to insert 18987a984708SDavid Chisnall// Set __parent to parent of null leaf 18997a984708SDavid Chisnall// Return reference to null leaf 19007a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 19017c82a1ecSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 19027c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent, 19037c82a1ecSDimitry Andric const key_type& __v) 19047a984708SDavid Chisnall{ 19057a984708SDavid Chisnall __node_pointer __nd = __root(); 19067a984708SDavid Chisnall if (__nd != nullptr) 19077a984708SDavid Chisnall { 19087a984708SDavid Chisnall while (true) 19097a984708SDavid Chisnall { 19107a984708SDavid Chisnall if (value_comp()(__nd->__value_, __v)) 19117a984708SDavid Chisnall { 19127a984708SDavid Chisnall if (__nd->__right_ != nullptr) 19137a984708SDavid Chisnall __nd = static_cast<__node_pointer>(__nd->__right_); 19147a984708SDavid Chisnall else 19157a984708SDavid Chisnall { 19167c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 19177c82a1ecSDimitry Andric return __nd->__right_; 19187a984708SDavid Chisnall } 19197a984708SDavid Chisnall } 19207a984708SDavid Chisnall else 19217a984708SDavid Chisnall { 19227a984708SDavid Chisnall if (__nd->__left_ != nullptr) 19237a984708SDavid Chisnall __nd = static_cast<__node_pointer>(__nd->__left_); 19247a984708SDavid Chisnall else 19257a984708SDavid Chisnall { 19267c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 19277a984708SDavid Chisnall return __parent->__left_; 19287a984708SDavid Chisnall } 19297a984708SDavid Chisnall } 19307a984708SDavid Chisnall } 19317a984708SDavid Chisnall } 19327c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 19337a984708SDavid Chisnall return __parent->__left_; 19347a984708SDavid Chisnall} 19357a984708SDavid Chisnall 19367a984708SDavid Chisnall// Find upper_bound place to insert 19377a984708SDavid Chisnall// Set __parent to parent of null leaf 19387a984708SDavid Chisnall// Return reference to null leaf 19397a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 19407c82a1ecSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 19417c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent, 19427c82a1ecSDimitry Andric const key_type& __v) 19437a984708SDavid Chisnall{ 19447a984708SDavid Chisnall __node_pointer __nd = __root(); 19457a984708SDavid Chisnall if (__nd != nullptr) 19467a984708SDavid Chisnall { 19477a984708SDavid Chisnall while (true) 19487a984708SDavid Chisnall { 19497a984708SDavid Chisnall if (value_comp()(__v, __nd->__value_)) 19507a984708SDavid Chisnall { 19517a984708SDavid Chisnall if (__nd->__left_ != nullptr) 19527a984708SDavid Chisnall __nd = static_cast<__node_pointer>(__nd->__left_); 19537a984708SDavid Chisnall else 19547a984708SDavid Chisnall { 19557c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 19567a984708SDavid Chisnall return __parent->__left_; 19577a984708SDavid Chisnall } 19587a984708SDavid Chisnall } 19597a984708SDavid Chisnall else 19607a984708SDavid Chisnall { 19617a984708SDavid Chisnall if (__nd->__right_ != nullptr) 19627a984708SDavid Chisnall __nd = static_cast<__node_pointer>(__nd->__right_); 19637a984708SDavid Chisnall else 19647a984708SDavid Chisnall { 19657c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 19667c82a1ecSDimitry Andric return __nd->__right_; 19677a984708SDavid Chisnall } 19687a984708SDavid Chisnall } 19697a984708SDavid Chisnall } 19707a984708SDavid Chisnall } 19717c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 19727a984708SDavid Chisnall return __parent->__left_; 19737a984708SDavid Chisnall} 19747a984708SDavid Chisnall 19757a984708SDavid Chisnall// Find leaf place to insert closest to __hint 19767a984708SDavid Chisnall// First check prior to __hint. 19777a984708SDavid Chisnall// Next check after __hint. 19787a984708SDavid Chisnall// Next do O(log N) search. 19797a984708SDavid Chisnall// Set __parent to parent of null leaf 19807a984708SDavid Chisnall// Return reference to null leaf 19817a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 19827c82a1ecSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 19837a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, 19847c82a1ecSDimitry Andric __parent_pointer& __parent, 19857c82a1ecSDimitry Andric const key_type& __v) 19867a984708SDavid Chisnall{ 19877a984708SDavid Chisnall if (__hint == end() || !value_comp()(*__hint, __v)) // check before 19887a984708SDavid Chisnall { 19897a984708SDavid Chisnall // __v <= *__hint 19907a984708SDavid Chisnall const_iterator __prior = __hint; 19917a984708SDavid Chisnall if (__prior == begin() || !value_comp()(__v, *--__prior)) 19927a984708SDavid Chisnall { 19937a984708SDavid Chisnall // *prev(__hint) <= __v <= *__hint 19947a984708SDavid Chisnall if (__hint.__ptr_->__left_ == nullptr) 19957a984708SDavid Chisnall { 19967c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 19977a984708SDavid Chisnall return __parent->__left_; 19987a984708SDavid Chisnall } 19997a984708SDavid Chisnall else 20007a984708SDavid Chisnall { 20017c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__prior.__ptr_); 20027c82a1ecSDimitry Andric return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; 20037a984708SDavid Chisnall } 20047a984708SDavid Chisnall } 20057a984708SDavid Chisnall // __v < *prev(__hint) 20067a984708SDavid Chisnall return __find_leaf_high(__parent, __v); 20077a984708SDavid Chisnall } 20087a984708SDavid Chisnall // else __v > *__hint 20097a984708SDavid Chisnall return __find_leaf_low(__parent, __v); 20107a984708SDavid Chisnall} 20117a984708SDavid Chisnall 20127a984708SDavid Chisnall// Find place to insert if __v doesn't exist 20137a984708SDavid Chisnall// Set __parent to parent of null leaf 20147a984708SDavid Chisnall// Return reference to null leaf 20157a984708SDavid Chisnall// If __v exists, set parent to node of __v and return reference to node of __v 20167a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 20177a984708SDavid Chisnalltemplate <class _Key> 20187c82a1ecSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 20197c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent, 20207a984708SDavid Chisnall const _Key& __v) 20217a984708SDavid Chisnall{ 20227a984708SDavid Chisnall __node_pointer __nd = __root(); 20237c82a1ecSDimitry Andric __node_base_pointer* __nd_ptr = __root_ptr(); 20247a984708SDavid Chisnall if (__nd != nullptr) 20257a984708SDavid Chisnall { 20267a984708SDavid Chisnall while (true) 20277a984708SDavid Chisnall { 20287a984708SDavid Chisnall if (value_comp()(__v, __nd->__value_)) 20297a984708SDavid Chisnall { 20307c82a1ecSDimitry Andric if (__nd->__left_ != nullptr) { 20317c82a1ecSDimitry Andric __nd_ptr = _VSTD::addressof(__nd->__left_); 20327a984708SDavid Chisnall __nd = static_cast<__node_pointer>(__nd->__left_); 20337c82a1ecSDimitry Andric } else { 20347c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 20357a984708SDavid Chisnall return __parent->__left_; 20367a984708SDavid Chisnall } 20377a984708SDavid Chisnall } 20387a984708SDavid Chisnall else if (value_comp()(__nd->__value_, __v)) 20397a984708SDavid Chisnall { 20407c82a1ecSDimitry Andric if (__nd->__right_ != nullptr) { 20417c82a1ecSDimitry Andric __nd_ptr = _VSTD::addressof(__nd->__right_); 20427a984708SDavid Chisnall __nd = static_cast<__node_pointer>(__nd->__right_); 20437c82a1ecSDimitry Andric } else { 20447c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 20457c82a1ecSDimitry Andric return __nd->__right_; 20467a984708SDavid Chisnall } 20477a984708SDavid Chisnall } 20487a984708SDavid Chisnall else 20497a984708SDavid Chisnall { 20507c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 20517c82a1ecSDimitry Andric return *__nd_ptr; 20527a984708SDavid Chisnall } 20537a984708SDavid Chisnall } 20547a984708SDavid Chisnall } 20557c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 20567a984708SDavid Chisnall return __parent->__left_; 20577a984708SDavid Chisnall} 20587a984708SDavid Chisnall 20597a984708SDavid Chisnall// Find place to insert if __v doesn't exist 20607a984708SDavid Chisnall// First check prior to __hint. 20617a984708SDavid Chisnall// Next check after __hint. 20627a984708SDavid Chisnall// Next do O(log N) search. 20637a984708SDavid Chisnall// Set __parent to parent of null leaf 20647a984708SDavid Chisnall// Return reference to null leaf 20657a984708SDavid Chisnall// If __v exists, set parent to node of __v and return reference to node of __v 20667a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 20677a984708SDavid Chisnalltemplate <class _Key> 20687c82a1ecSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 20697a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, 20707c82a1ecSDimitry Andric __parent_pointer& __parent, 20717c82a1ecSDimitry Andric __node_base_pointer& __dummy, 20727a984708SDavid Chisnall const _Key& __v) 20737a984708SDavid Chisnall{ 20747a984708SDavid Chisnall if (__hint == end() || value_comp()(__v, *__hint)) // check before 20757a984708SDavid Chisnall { 20767a984708SDavid Chisnall // __v < *__hint 20777a984708SDavid Chisnall const_iterator __prior = __hint; 20787a984708SDavid Chisnall if (__prior == begin() || value_comp()(*--__prior, __v)) 20797a984708SDavid Chisnall { 20807a984708SDavid Chisnall // *prev(__hint) < __v < *__hint 20817a984708SDavid Chisnall if (__hint.__ptr_->__left_ == nullptr) 20827a984708SDavid Chisnall { 20837c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 20847a984708SDavid Chisnall return __parent->__left_; 20857a984708SDavid Chisnall } 20867a984708SDavid Chisnall else 20877a984708SDavid Chisnall { 20887c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__prior.__ptr_); 20897c82a1ecSDimitry Andric return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; 20907a984708SDavid Chisnall } 20917a984708SDavid Chisnall } 20927a984708SDavid Chisnall // __v <= *prev(__hint) 20937a984708SDavid Chisnall return __find_equal(__parent, __v); 20947a984708SDavid Chisnall } 20957a984708SDavid Chisnall else if (value_comp()(*__hint, __v)) // check after 20967a984708SDavid Chisnall { 20977a984708SDavid Chisnall // *__hint < __v 20987a984708SDavid Chisnall const_iterator __next = _VSTD::next(__hint); 20997a984708SDavid Chisnall if (__next == end() || value_comp()(__v, *__next)) 21007a984708SDavid Chisnall { 21017a984708SDavid Chisnall // *__hint < __v < *_VSTD::next(__hint) 21027c82a1ecSDimitry Andric if (__hint.__get_np()->__right_ == nullptr) 21037a984708SDavid Chisnall { 21047c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 21057c82a1ecSDimitry Andric return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_; 21067a984708SDavid Chisnall } 21077a984708SDavid Chisnall else 21087a984708SDavid Chisnall { 21097c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__next.__ptr_); 21107a984708SDavid Chisnall return __parent->__left_; 21117a984708SDavid Chisnall } 21127a984708SDavid Chisnall } 21137a984708SDavid Chisnall // *next(__hint) <= __v 21147a984708SDavid Chisnall return __find_equal(__parent, __v); 21157a984708SDavid Chisnall } 21167a984708SDavid Chisnall // else __v == *__hint 21177c82a1ecSDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 21187c82a1ecSDimitry Andric __dummy = static_cast<__node_base_pointer>(__hint.__ptr_); 21197c82a1ecSDimitry Andric return __dummy; 21207a984708SDavid Chisnall} 21217a984708SDavid Chisnall 21227a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 2123*b5893f02SDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::__insert_node_at( 2124*b5893f02SDimitry Andric __parent_pointer __parent, __node_base_pointer& __child, 2125*b5893f02SDimitry Andric __node_base_pointer __new_node) _NOEXCEPT 21267a984708SDavid Chisnall{ 21277a984708SDavid Chisnall __new_node->__left_ = nullptr; 21287a984708SDavid Chisnall __new_node->__right_ = nullptr; 21297a984708SDavid Chisnall __new_node->__parent_ = __parent; 21307c82a1ecSDimitry Andric // __new_node->__is_black_ is initialized in __tree_balance_after_insert 21317a984708SDavid Chisnall __child = __new_node; 21327a984708SDavid Chisnall if (__begin_node()->__left_ != nullptr) 21337c82a1ecSDimitry Andric __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_); 21347a984708SDavid Chisnall __tree_balance_after_insert(__end_node()->__left_, __child); 21357a984708SDavid Chisnall ++size(); 21367a984708SDavid Chisnall} 21377a984708SDavid Chisnall 21387c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 21397c82a1ecSDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21407c82a1ecSDimitry Andrictemplate <class _Key, class... _Args> 21417c82a1ecSDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 21427c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) 21437c82a1ecSDimitry Andric#else 21447c82a1ecSDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21457c82a1ecSDimitry Andrictemplate <class _Key, class _Args> 21467c82a1ecSDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 21477c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args) 21487c82a1ecSDimitry Andric#endif 21497c82a1ecSDimitry Andric{ 21507c82a1ecSDimitry Andric __parent_pointer __parent; 21517c82a1ecSDimitry Andric __node_base_pointer& __child = __find_equal(__parent, __k); 21527c82a1ecSDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 21537c82a1ecSDimitry Andric bool __inserted = false; 21547c82a1ecSDimitry Andric if (__child == nullptr) 21557c82a1ecSDimitry Andric { 21567c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 21577c82a1ecSDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 21587c82a1ecSDimitry Andric#else 21597c82a1ecSDimitry Andric __node_holder __h = __construct_node(__args); 21607c82a1ecSDimitry Andric#endif 21617c82a1ecSDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 21627c82a1ecSDimitry Andric __r = __h.release(); 21637c82a1ecSDimitry Andric __inserted = true; 21647c82a1ecSDimitry Andric } 21657c82a1ecSDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 21667c82a1ecSDimitry Andric} 21677c82a1ecSDimitry Andric 21687c82a1ecSDimitry Andric 21697c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 21707c82a1ecSDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21717c82a1ecSDimitry Andrictemplate <class _Key, class... _Args> 21727c82a1ecSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 21737c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( 21747c82a1ecSDimitry Andric const_iterator __p, _Key const& __k, _Args&&... __args) 21757c82a1ecSDimitry Andric#else 21767c82a1ecSDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21777c82a1ecSDimitry Andrictemplate <class _Key, class _Args> 21787c82a1ecSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 21797c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( 21807c82a1ecSDimitry Andric const_iterator __p, _Key const& __k, _Args& __args) 21817c82a1ecSDimitry Andric#endif 21827c82a1ecSDimitry Andric{ 21837c82a1ecSDimitry Andric __parent_pointer __parent; 21847c82a1ecSDimitry Andric __node_base_pointer __dummy; 21857c82a1ecSDimitry Andric __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k); 21867c82a1ecSDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 21877c82a1ecSDimitry Andric if (__child == nullptr) 21887c82a1ecSDimitry Andric { 21897c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 21907c82a1ecSDimitry Andric __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 21917c82a1ecSDimitry Andric#else 21927c82a1ecSDimitry Andric __node_holder __h = __construct_node(__args); 21937c82a1ecSDimitry Andric#endif 21947c82a1ecSDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 21957c82a1ecSDimitry Andric __r = __h.release(); 21967c82a1ecSDimitry Andric } 21977c82a1ecSDimitry Andric return iterator(__r); 21987c82a1ecSDimitry Andric} 21997c82a1ecSDimitry Andric 22007c82a1ecSDimitry Andric 22017c82a1ecSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 22027a984708SDavid Chisnall 22037a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 22047a984708SDavid Chisnalltemplate <class ..._Args> 22057a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::__node_holder 22067a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) 22077a984708SDavid Chisnall{ 22087c82a1ecSDimitry Andric static_assert(!__is_tree_value_type<_Args...>::value, 22097c82a1ecSDimitry Andric "Cannot construct from __value_type"); 22107a984708SDavid Chisnall __node_allocator& __na = __node_alloc(); 221194e3ee44SDavid Chisnall __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 22127c82a1ecSDimitry Andric __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); 22137a984708SDavid Chisnall __h.get_deleter().__value_constructed = true; 22147a984708SDavid Chisnall return __h; 22157a984708SDavid Chisnall} 22167a984708SDavid Chisnall 22177c82a1ecSDimitry Andric 22187a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 22197a984708SDavid Chisnalltemplate <class... _Args> 22207a984708SDavid Chisnallpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 22217c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) 22227a984708SDavid Chisnall{ 22237a984708SDavid Chisnall __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 22247c82a1ecSDimitry Andric __parent_pointer __parent; 22257a984708SDavid Chisnall __node_base_pointer& __child = __find_equal(__parent, __h->__value_); 22267a984708SDavid Chisnall __node_pointer __r = static_cast<__node_pointer>(__child); 22277a984708SDavid Chisnall bool __inserted = false; 22287a984708SDavid Chisnall if (__child == nullptr) 22297a984708SDavid Chisnall { 22304bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 22317a984708SDavid Chisnall __r = __h.release(); 22327a984708SDavid Chisnall __inserted = true; 22337a984708SDavid Chisnall } 22347a984708SDavid Chisnall return pair<iterator, bool>(iterator(__r), __inserted); 22357a984708SDavid Chisnall} 22367a984708SDavid Chisnall 22377a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 22387a984708SDavid Chisnalltemplate <class... _Args> 22397a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 22407c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) 22417a984708SDavid Chisnall{ 22427a984708SDavid Chisnall __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 22437c82a1ecSDimitry Andric __parent_pointer __parent; 22447c82a1ecSDimitry Andric __node_base_pointer __dummy; 22457c82a1ecSDimitry Andric __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_); 22467a984708SDavid Chisnall __node_pointer __r = static_cast<__node_pointer>(__child); 22477a984708SDavid Chisnall if (__child == nullptr) 22487a984708SDavid Chisnall { 22494bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 22507a984708SDavid Chisnall __r = __h.release(); 22517a984708SDavid Chisnall } 22527a984708SDavid Chisnall return iterator(__r); 22537a984708SDavid Chisnall} 22547a984708SDavid Chisnall 22557a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 22567a984708SDavid Chisnalltemplate <class... _Args> 22577a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 22587a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) 22597a984708SDavid Chisnall{ 22607a984708SDavid Chisnall __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 22617c82a1ecSDimitry Andric __parent_pointer __parent; 22627c82a1ecSDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_)); 22634bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 22647a984708SDavid Chisnall return iterator(static_cast<__node_pointer>(__h.release())); 22657a984708SDavid Chisnall} 22667a984708SDavid Chisnall 22677a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 22687a984708SDavid Chisnalltemplate <class... _Args> 22697a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 22707a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, 22717a984708SDavid Chisnall _Args&&... __args) 22727a984708SDavid Chisnall{ 22737a984708SDavid Chisnall __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 22747c82a1ecSDimitry Andric __parent_pointer __parent; 22757c82a1ecSDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_)); 22764bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 22777a984708SDavid Chisnall return iterator(static_cast<__node_pointer>(__h.release())); 22787a984708SDavid Chisnall} 22797a984708SDavid Chisnall 22807a984708SDavid Chisnall 22817c82a1ecSDimitry Andric#else // _LIBCPP_CXX03_LANG 22827a984708SDavid Chisnall 22837a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 22847a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::__node_holder 22857c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v) 22867a984708SDavid Chisnall{ 22877a984708SDavid Chisnall __node_allocator& __na = __node_alloc(); 228894e3ee44SDavid Chisnall __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 22897c82a1ecSDimitry Andric __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); 22907a984708SDavid Chisnall __h.get_deleter().__value_constructed = true; 22919729cf09SDimitry Andric return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 22927a984708SDavid Chisnall} 22937a984708SDavid Chisnall 22947c82a1ecSDimitry Andric#endif // _LIBCPP_CXX03_LANG 22957a984708SDavid Chisnall 22967c82a1ecSDimitry Andric#ifdef _LIBCPP_CXX03_LANG 22977a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 22987a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 22997c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v) 23007a984708SDavid Chisnall{ 23017c82a1ecSDimitry Andric __parent_pointer __parent; 23027c82a1ecSDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v)); 23037a984708SDavid Chisnall __node_holder __h = __construct_node(__v); 23044bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 23057a984708SDavid Chisnall return iterator(__h.release()); 23067a984708SDavid Chisnall} 23077a984708SDavid Chisnall 23087a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 23097a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 23107c82a1ecSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v) 23117a984708SDavid Chisnall{ 23127c82a1ecSDimitry Andric __parent_pointer __parent; 23137c82a1ecSDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v)); 23147a984708SDavid Chisnall __node_holder __h = __construct_node(__v); 23154bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 23167a984708SDavid Chisnall return iterator(__h.release()); 23177a984708SDavid Chisnall} 23187c82a1ecSDimitry Andric#endif 23197a984708SDavid Chisnall 23207a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 23217a984708SDavid Chisnallpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 23227a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd) 23237a984708SDavid Chisnall{ 23247c82a1ecSDimitry Andric __parent_pointer __parent; 23257a984708SDavid Chisnall __node_base_pointer& __child = __find_equal(__parent, __nd->__value_); 23267a984708SDavid Chisnall __node_pointer __r = static_cast<__node_pointer>(__child); 23277a984708SDavid Chisnall bool __inserted = false; 23287a984708SDavid Chisnall if (__child == nullptr) 23297a984708SDavid Chisnall { 23304bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 23317a984708SDavid Chisnall __r = __nd; 23327a984708SDavid Chisnall __inserted = true; 23337a984708SDavid Chisnall } 23347a984708SDavid Chisnall return pair<iterator, bool>(iterator(__r), __inserted); 23357a984708SDavid Chisnall} 23367a984708SDavid Chisnall 23377a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 23387a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 23397a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p, 23407a984708SDavid Chisnall __node_pointer __nd) 23417a984708SDavid Chisnall{ 23427c82a1ecSDimitry Andric __parent_pointer __parent; 23437c82a1ecSDimitry Andric __node_base_pointer __dummy; 23447a984708SDavid Chisnall __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_); 23457a984708SDavid Chisnall __node_pointer __r = static_cast<__node_pointer>(__child); 23467a984708SDavid Chisnall if (__child == nullptr) 23477a984708SDavid Chisnall { 23484bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 23497a984708SDavid Chisnall __r = __nd; 23507a984708SDavid Chisnall } 23517a984708SDavid Chisnall return iterator(__r); 23527a984708SDavid Chisnall} 23537a984708SDavid Chisnall 23547a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 23557a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 23567a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) 23577a984708SDavid Chisnall{ 23587c82a1ecSDimitry Andric __parent_pointer __parent; 23597c82a1ecSDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_)); 23604bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 23617a984708SDavid Chisnall return iterator(__nd); 23627a984708SDavid Chisnall} 23637a984708SDavid Chisnall 23647a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 23657a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 23667a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, 23677a984708SDavid Chisnall __node_pointer __nd) 23687a984708SDavid Chisnall{ 23697c82a1ecSDimitry Andric __parent_pointer __parent; 23707c82a1ecSDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_)); 23714bab9fd9SDavid Chisnall __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 23727a984708SDavid Chisnall return iterator(__nd); 23737a984708SDavid Chisnall} 23747a984708SDavid Chisnall 23757a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 23767a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 2377*b5893f02SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT 23784ba319b5SDimitry Andric{ 23794ba319b5SDimitry Andric iterator __r(__ptr); 23804ba319b5SDimitry Andric ++__r; 23814ba319b5SDimitry Andric if (__begin_node() == __ptr) 23824ba319b5SDimitry Andric __begin_node() = __r.__ptr_; 23834ba319b5SDimitry Andric --size(); 23844ba319b5SDimitry Andric __tree_remove(__end_node()->__left_, 23854ba319b5SDimitry Andric static_cast<__node_base_pointer>(__ptr)); 23864ba319b5SDimitry Andric return __r; 23874ba319b5SDimitry Andric} 23884ba319b5SDimitry Andric 23894ba319b5SDimitry Andric#if _LIBCPP_STD_VER > 14 23904ba319b5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 23914ba319b5SDimitry Andrictemplate <class _NodeHandle, class _InsertReturnType> 23924ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 23934ba319b5SDimitry Andric_InsertReturnType 23944ba319b5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( 23954ba319b5SDimitry Andric _NodeHandle&& __nh) 23964ba319b5SDimitry Andric{ 23974ba319b5SDimitry Andric if (__nh.empty()) 23984ba319b5SDimitry Andric return _InsertReturnType{end(), false, _NodeHandle()}; 23994ba319b5SDimitry Andric 24004ba319b5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 24014ba319b5SDimitry Andric __parent_pointer __parent; 24024ba319b5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, 24034ba319b5SDimitry Andric __ptr->__value_); 24044ba319b5SDimitry Andric if (__child != nullptr) 24054ba319b5SDimitry Andric return _InsertReturnType{ 24064ba319b5SDimitry Andric iterator(static_cast<__node_pointer>(__child)), 24074ba319b5SDimitry Andric false, _VSTD::move(__nh)}; 24084ba319b5SDimitry Andric 24094ba319b5SDimitry Andric __insert_node_at(__parent, __child, 24104ba319b5SDimitry Andric static_cast<__node_base_pointer>(__ptr)); 24114ba319b5SDimitry Andric __nh.__release(); 24124ba319b5SDimitry Andric return _InsertReturnType{iterator(__ptr), true, _NodeHandle()}; 24134ba319b5SDimitry Andric} 24144ba319b5SDimitry Andric 24154ba319b5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 24164ba319b5SDimitry Andrictemplate <class _NodeHandle> 24174ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 24184ba319b5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 24194ba319b5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( 24204ba319b5SDimitry Andric const_iterator __hint, _NodeHandle&& __nh) 24214ba319b5SDimitry Andric{ 24224ba319b5SDimitry Andric if (__nh.empty()) 24234ba319b5SDimitry Andric return end(); 24244ba319b5SDimitry Andric 24254ba319b5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 24264ba319b5SDimitry Andric __parent_pointer __parent; 24274ba319b5SDimitry Andric __node_base_pointer __dummy; 24284ba319b5SDimitry Andric __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, 24294ba319b5SDimitry Andric __ptr->__value_); 24304ba319b5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 24314ba319b5SDimitry Andric if (__child == nullptr) 24324ba319b5SDimitry Andric { 24334ba319b5SDimitry Andric __insert_node_at(__parent, __child, 24344ba319b5SDimitry Andric static_cast<__node_base_pointer>(__ptr)); 24354ba319b5SDimitry Andric __r = __ptr; 24364ba319b5SDimitry Andric __nh.__release(); 24374ba319b5SDimitry Andric } 24384ba319b5SDimitry Andric return iterator(__r); 24394ba319b5SDimitry Andric} 24404ba319b5SDimitry Andric 24414ba319b5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 24424ba319b5SDimitry Andrictemplate <class _NodeHandle> 24434ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 24444ba319b5SDimitry Andric_NodeHandle 24454ba319b5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) 24464ba319b5SDimitry Andric{ 24474ba319b5SDimitry Andric iterator __it = find(__key); 24484ba319b5SDimitry Andric if (__it == end()) 24494ba319b5SDimitry Andric return _NodeHandle(); 24504ba319b5SDimitry Andric return __node_handle_extract<_NodeHandle>(__it); 24514ba319b5SDimitry Andric} 24524ba319b5SDimitry Andric 24534ba319b5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 24544ba319b5SDimitry Andrictemplate <class _NodeHandle> 24554ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 24564ba319b5SDimitry Andric_NodeHandle 24574ba319b5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) 24584ba319b5SDimitry Andric{ 24594ba319b5SDimitry Andric __node_pointer __np = __p.__get_np(); 24604ba319b5SDimitry Andric __remove_node_pointer(__np); 24614ba319b5SDimitry Andric return _NodeHandle(__np, __alloc()); 24624ba319b5SDimitry Andric} 24634ba319b5SDimitry Andric 24644ba319b5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2465*b5893f02SDimitry Andrictemplate <class _Tree> 2466*b5893f02SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2467*b5893f02SDimitry Andricvoid 2468*b5893f02SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) 2469*b5893f02SDimitry Andric{ 2470*b5893f02SDimitry Andric static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); 2471*b5893f02SDimitry Andric 2472*b5893f02SDimitry Andric for (typename _Tree::iterator __i = __source.begin(); 2473*b5893f02SDimitry Andric __i != __source.end();) 2474*b5893f02SDimitry Andric { 2475*b5893f02SDimitry Andric __node_pointer __src_ptr = __i.__get_np(); 2476*b5893f02SDimitry Andric __parent_pointer __parent; 2477*b5893f02SDimitry Andric __node_base_pointer& __child = 2478*b5893f02SDimitry Andric __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_)); 2479*b5893f02SDimitry Andric ++__i; 2480*b5893f02SDimitry Andric if (__child != nullptr) 2481*b5893f02SDimitry Andric continue; 2482*b5893f02SDimitry Andric __source.__remove_node_pointer(__src_ptr); 2483*b5893f02SDimitry Andric __insert_node_at(__parent, __child, 2484*b5893f02SDimitry Andric static_cast<__node_base_pointer>(__src_ptr)); 2485*b5893f02SDimitry Andric } 2486*b5893f02SDimitry Andric} 2487*b5893f02SDimitry Andric 2488*b5893f02SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 24894ba319b5SDimitry Andrictemplate <class _NodeHandle> 24904ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 24914ba319b5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 24924ba319b5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh) 24934ba319b5SDimitry Andric{ 24944ba319b5SDimitry Andric if (__nh.empty()) 24954ba319b5SDimitry Andric return end(); 24964ba319b5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 24974ba319b5SDimitry Andric __parent_pointer __parent; 24984ba319b5SDimitry Andric __node_base_pointer& __child = __find_leaf_high( 24994ba319b5SDimitry Andric __parent, _NodeTypes::__get_key(__ptr->__value_)); 25004ba319b5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 25014ba319b5SDimitry Andric __nh.__release(); 25024ba319b5SDimitry Andric return iterator(__ptr); 25034ba319b5SDimitry Andric} 25044ba319b5SDimitry Andric 25054ba319b5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 25064ba319b5SDimitry Andrictemplate <class _NodeHandle> 25074ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 25084ba319b5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 25094ba319b5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi( 25104ba319b5SDimitry Andric const_iterator __hint, _NodeHandle&& __nh) 25114ba319b5SDimitry Andric{ 25124ba319b5SDimitry Andric if (__nh.empty()) 25134ba319b5SDimitry Andric return end(); 25144ba319b5SDimitry Andric 25154ba319b5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 25164ba319b5SDimitry Andric __parent_pointer __parent; 25174ba319b5SDimitry Andric __node_base_pointer& __child = __find_leaf(__hint, __parent, 25184ba319b5SDimitry Andric _NodeTypes::__get_key(__ptr->__value_)); 25194ba319b5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 25204ba319b5SDimitry Andric __nh.__release(); 25214ba319b5SDimitry Andric return iterator(__ptr); 25224ba319b5SDimitry Andric} 25234ba319b5SDimitry Andric 2524*b5893f02SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2525*b5893f02SDimitry Andrictemplate <class _Tree> 2526*b5893f02SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2527*b5893f02SDimitry Andricvoid 2528*b5893f02SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) 2529*b5893f02SDimitry Andric{ 2530*b5893f02SDimitry Andric static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); 2531*b5893f02SDimitry Andric 2532*b5893f02SDimitry Andric for (typename _Tree::iterator __i = __source.begin(); 2533*b5893f02SDimitry Andric __i != __source.end();) 2534*b5893f02SDimitry Andric { 2535*b5893f02SDimitry Andric __node_pointer __src_ptr = __i.__get_np(); 2536*b5893f02SDimitry Andric __parent_pointer __parent; 2537*b5893f02SDimitry Andric __node_base_pointer& __child = __find_leaf_high( 2538*b5893f02SDimitry Andric __parent, _NodeTypes::__get_key(__src_ptr->__value_)); 2539*b5893f02SDimitry Andric ++__i; 2540*b5893f02SDimitry Andric __source.__remove_node_pointer(__src_ptr); 2541*b5893f02SDimitry Andric __insert_node_at(__parent, __child, 2542*b5893f02SDimitry Andric static_cast<__node_base_pointer>(__src_ptr)); 2543*b5893f02SDimitry Andric } 2544*b5893f02SDimitry Andric} 2545*b5893f02SDimitry Andric 25464ba319b5SDimitry Andric#endif // _LIBCPP_STD_VER > 14 25474ba319b5SDimitry Andric 25484ba319b5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 25494ba319b5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 25507a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) 25517a984708SDavid Chisnall{ 25527c82a1ecSDimitry Andric __node_pointer __np = __p.__get_np(); 25534ba319b5SDimitry Andric iterator __r = __remove_node_pointer(__np); 25547a984708SDavid Chisnall __node_allocator& __na = __node_alloc(); 25557c82a1ecSDimitry Andric __node_traits::destroy(__na, _NodeTypes::__get_ptr( 25567c82a1ecSDimitry Andric const_cast<__node_value_type&>(*__p))); 25577a984708SDavid Chisnall __node_traits::deallocate(__na, __np, 1); 25587a984708SDavid Chisnall return __r; 25597a984708SDavid Chisnall} 25607a984708SDavid Chisnall 25617a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 25627a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 25637a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) 25647a984708SDavid Chisnall{ 25657a984708SDavid Chisnall while (__f != __l) 25667a984708SDavid Chisnall __f = erase(__f); 25674bab9fd9SDavid Chisnall return iterator(__l.__ptr_); 25687a984708SDavid Chisnall} 25697a984708SDavid Chisnall 25707a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 25717a984708SDavid Chisnalltemplate <class _Key> 25727a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::size_type 25737a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) 25747a984708SDavid Chisnall{ 25757a984708SDavid Chisnall iterator __i = find(__k); 25767a984708SDavid Chisnall if (__i == end()) 25777a984708SDavid Chisnall return 0; 25787a984708SDavid Chisnall erase(__i); 25797a984708SDavid Chisnall return 1; 25807a984708SDavid Chisnall} 25817a984708SDavid Chisnall 25827a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 25837a984708SDavid Chisnalltemplate <class _Key> 25847a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::size_type 25857a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) 25867a984708SDavid Chisnall{ 25877a984708SDavid Chisnall pair<iterator, iterator> __p = __equal_range_multi(__k); 25887a984708SDavid Chisnall size_type __r = 0; 25897a984708SDavid Chisnall for (; __p.first != __p.second; ++__r) 25907a984708SDavid Chisnall __p.first = erase(__p.first); 25917a984708SDavid Chisnall return __r; 25927a984708SDavid Chisnall} 25937a984708SDavid Chisnall 25947a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 25957a984708SDavid Chisnalltemplate <class _Key> 25967a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 25977a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) 25987a984708SDavid Chisnall{ 25997a984708SDavid Chisnall iterator __p = __lower_bound(__v, __root(), __end_node()); 26007a984708SDavid Chisnall if (__p != end() && !value_comp()(__v, *__p)) 26017a984708SDavid Chisnall return __p; 26027a984708SDavid Chisnall return end(); 26037a984708SDavid Chisnall} 26047a984708SDavid Chisnall 26057a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 26067a984708SDavid Chisnalltemplate <class _Key> 26077a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::const_iterator 26087a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const 26097a984708SDavid Chisnall{ 26107a984708SDavid Chisnall const_iterator __p = __lower_bound(__v, __root(), __end_node()); 26117a984708SDavid Chisnall if (__p != end() && !value_comp()(__v, *__p)) 26127a984708SDavid Chisnall return __p; 26137a984708SDavid Chisnall return end(); 26147a984708SDavid Chisnall} 26157a984708SDavid Chisnall 26167a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 26177a984708SDavid Chisnalltemplate <class _Key> 26187a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::size_type 26197a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const 26207a984708SDavid Chisnall{ 26217c82a1ecSDimitry Andric __node_pointer __rt = __root(); 26227a984708SDavid Chisnall while (__rt != nullptr) 26237a984708SDavid Chisnall { 26247a984708SDavid Chisnall if (value_comp()(__k, __rt->__value_)) 26257a984708SDavid Chisnall { 26267c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 26277a984708SDavid Chisnall } 26287a984708SDavid Chisnall else if (value_comp()(__rt->__value_, __k)) 26297c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 26307a984708SDavid Chisnall else 26317a984708SDavid Chisnall return 1; 26327a984708SDavid Chisnall } 26337a984708SDavid Chisnall return 0; 26347a984708SDavid Chisnall} 26357a984708SDavid Chisnall 26367a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 26377a984708SDavid Chisnalltemplate <class _Key> 26387a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::size_type 26397a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const 26407a984708SDavid Chisnall{ 26417c82a1ecSDimitry Andric __iter_pointer __result = __end_node(); 26427c82a1ecSDimitry Andric __node_pointer __rt = __root(); 26437a984708SDavid Chisnall while (__rt != nullptr) 26447a984708SDavid Chisnall { 26457a984708SDavid Chisnall if (value_comp()(__k, __rt->__value_)) 26467a984708SDavid Chisnall { 26477c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__rt); 26487c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 26497a984708SDavid Chisnall } 26507a984708SDavid Chisnall else if (value_comp()(__rt->__value_, __k)) 26517c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 26527a984708SDavid Chisnall else 26537a984708SDavid Chisnall return _VSTD::distance( 26547c82a1ecSDimitry Andric __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 26557c82a1ecSDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result) 26567a984708SDavid Chisnall ); 26577a984708SDavid Chisnall } 26587a984708SDavid Chisnall return 0; 26597a984708SDavid Chisnall} 26607a984708SDavid Chisnall 26617a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 26627a984708SDavid Chisnalltemplate <class _Key> 26637a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 26647a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, 26657a984708SDavid Chisnall __node_pointer __root, 26667c82a1ecSDimitry Andric __iter_pointer __result) 26677a984708SDavid Chisnall{ 26687a984708SDavid Chisnall while (__root != nullptr) 26697a984708SDavid Chisnall { 26707a984708SDavid Chisnall if (!value_comp()(__root->__value_, __v)) 26717a984708SDavid Chisnall { 26727c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__root); 26737a984708SDavid Chisnall __root = static_cast<__node_pointer>(__root->__left_); 26747a984708SDavid Chisnall } 26757a984708SDavid Chisnall else 26767a984708SDavid Chisnall __root = static_cast<__node_pointer>(__root->__right_); 26777a984708SDavid Chisnall } 26787a984708SDavid Chisnall return iterator(__result); 26797a984708SDavid Chisnall} 26807a984708SDavid Chisnall 26817a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 26827a984708SDavid Chisnalltemplate <class _Key> 26837a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::const_iterator 26847a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, 26857c82a1ecSDimitry Andric __node_pointer __root, 26867c82a1ecSDimitry Andric __iter_pointer __result) const 26877a984708SDavid Chisnall{ 26887a984708SDavid Chisnall while (__root != nullptr) 26897a984708SDavid Chisnall { 26907a984708SDavid Chisnall if (!value_comp()(__root->__value_, __v)) 26917a984708SDavid Chisnall { 26927c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__root); 26937c82a1ecSDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 26947a984708SDavid Chisnall } 26957a984708SDavid Chisnall else 26967c82a1ecSDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 26977a984708SDavid Chisnall } 26987a984708SDavid Chisnall return const_iterator(__result); 26997a984708SDavid Chisnall} 27007a984708SDavid Chisnall 27017a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 27027a984708SDavid Chisnalltemplate <class _Key> 27037a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::iterator 27047a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, 27057a984708SDavid Chisnall __node_pointer __root, 27067c82a1ecSDimitry Andric __iter_pointer __result) 27077a984708SDavid Chisnall{ 27087a984708SDavid Chisnall while (__root != nullptr) 27097a984708SDavid Chisnall { 27107a984708SDavid Chisnall if (value_comp()(__v, __root->__value_)) 27117a984708SDavid Chisnall { 27127c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__root); 27137a984708SDavid Chisnall __root = static_cast<__node_pointer>(__root->__left_); 27147a984708SDavid Chisnall } 27157a984708SDavid Chisnall else 27167a984708SDavid Chisnall __root = static_cast<__node_pointer>(__root->__right_); 27177a984708SDavid Chisnall } 27187a984708SDavid Chisnall return iterator(__result); 27197a984708SDavid Chisnall} 27207a984708SDavid Chisnall 27217a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 27227a984708SDavid Chisnalltemplate <class _Key> 27237a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::const_iterator 27247a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, 27257c82a1ecSDimitry Andric __node_pointer __root, 27267c82a1ecSDimitry Andric __iter_pointer __result) const 27277a984708SDavid Chisnall{ 27287a984708SDavid Chisnall while (__root != nullptr) 27297a984708SDavid Chisnall { 27307a984708SDavid Chisnall if (value_comp()(__v, __root->__value_)) 27317a984708SDavid Chisnall { 27327c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__root); 27337c82a1ecSDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 27347a984708SDavid Chisnall } 27357a984708SDavid Chisnall else 27367c82a1ecSDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 27377a984708SDavid Chisnall } 27387a984708SDavid Chisnall return const_iterator(__result); 27397a984708SDavid Chisnall} 27407a984708SDavid Chisnall 27417a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 27427a984708SDavid Chisnalltemplate <class _Key> 27437a984708SDavid Chisnallpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, 27447a984708SDavid Chisnall typename __tree<_Tp, _Compare, _Allocator>::iterator> 27457a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) 27467a984708SDavid Chisnall{ 274794e3ee44SDavid Chisnall typedef pair<iterator, iterator> _Pp; 27487c82a1ecSDimitry Andric __iter_pointer __result = __end_node(); 27497a984708SDavid Chisnall __node_pointer __rt = __root(); 27507a984708SDavid Chisnall while (__rt != nullptr) 27517a984708SDavid Chisnall { 27527a984708SDavid Chisnall if (value_comp()(__k, __rt->__value_)) 27537a984708SDavid Chisnall { 27547c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__rt); 27557a984708SDavid Chisnall __rt = static_cast<__node_pointer>(__rt->__left_); 27567a984708SDavid Chisnall } 27577a984708SDavid Chisnall else if (value_comp()(__rt->__value_, __k)) 27587a984708SDavid Chisnall __rt = static_cast<__node_pointer>(__rt->__right_); 27597a984708SDavid Chisnall else 276094e3ee44SDavid Chisnall return _Pp(iterator(__rt), 27617a984708SDavid Chisnall iterator( 27627a984708SDavid Chisnall __rt->__right_ != nullptr ? 27637c82a1ecSDimitry Andric static_cast<__iter_pointer>(__tree_min(__rt->__right_)) 27647a984708SDavid Chisnall : __result)); 27657a984708SDavid Chisnall } 276694e3ee44SDavid Chisnall return _Pp(iterator(__result), iterator(__result)); 27677a984708SDavid Chisnall} 27687a984708SDavid Chisnall 27697a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 27707a984708SDavid Chisnalltemplate <class _Key> 27717a984708SDavid Chisnallpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, 27727a984708SDavid Chisnall typename __tree<_Tp, _Compare, _Allocator>::const_iterator> 27737a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const 27747a984708SDavid Chisnall{ 277594e3ee44SDavid Chisnall typedef pair<const_iterator, const_iterator> _Pp; 27767c82a1ecSDimitry Andric __iter_pointer __result = __end_node(); 27777c82a1ecSDimitry Andric __node_pointer __rt = __root(); 27787a984708SDavid Chisnall while (__rt != nullptr) 27797a984708SDavid Chisnall { 27807a984708SDavid Chisnall if (value_comp()(__k, __rt->__value_)) 27817a984708SDavid Chisnall { 27827c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__rt); 27837c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 27847a984708SDavid Chisnall } 27857a984708SDavid Chisnall else if (value_comp()(__rt->__value_, __k)) 27867c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 27877a984708SDavid Chisnall else 278894e3ee44SDavid Chisnall return _Pp(const_iterator(__rt), 27897a984708SDavid Chisnall const_iterator( 27907a984708SDavid Chisnall __rt->__right_ != nullptr ? 27917c82a1ecSDimitry Andric static_cast<__iter_pointer>(__tree_min(__rt->__right_)) 27927a984708SDavid Chisnall : __result)); 27937a984708SDavid Chisnall } 279494e3ee44SDavid Chisnall return _Pp(const_iterator(__result), const_iterator(__result)); 27957a984708SDavid Chisnall} 27967a984708SDavid Chisnall 27977a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 27987a984708SDavid Chisnalltemplate <class _Key> 27997a984708SDavid Chisnallpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, 28007a984708SDavid Chisnall typename __tree<_Tp, _Compare, _Allocator>::iterator> 28017a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) 28027a984708SDavid Chisnall{ 280394e3ee44SDavid Chisnall typedef pair<iterator, iterator> _Pp; 28047c82a1ecSDimitry Andric __iter_pointer __result = __end_node(); 28057a984708SDavid Chisnall __node_pointer __rt = __root(); 28067a984708SDavid Chisnall while (__rt != nullptr) 28077a984708SDavid Chisnall { 28087a984708SDavid Chisnall if (value_comp()(__k, __rt->__value_)) 28097a984708SDavid Chisnall { 28107c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__rt); 28117a984708SDavid Chisnall __rt = static_cast<__node_pointer>(__rt->__left_); 28127a984708SDavid Chisnall } 28137a984708SDavid Chisnall else if (value_comp()(__rt->__value_, __k)) 28147a984708SDavid Chisnall __rt = static_cast<__node_pointer>(__rt->__right_); 28157a984708SDavid Chisnall else 28167c82a1ecSDimitry Andric return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 28177a984708SDavid Chisnall __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); 28187a984708SDavid Chisnall } 281994e3ee44SDavid Chisnall return _Pp(iterator(__result), iterator(__result)); 28207a984708SDavid Chisnall} 28217a984708SDavid Chisnall 28227a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 28237a984708SDavid Chisnalltemplate <class _Key> 28247a984708SDavid Chisnallpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, 28257a984708SDavid Chisnall typename __tree<_Tp, _Compare, _Allocator>::const_iterator> 28267a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const 28277a984708SDavid Chisnall{ 282894e3ee44SDavid Chisnall typedef pair<const_iterator, const_iterator> _Pp; 28297c82a1ecSDimitry Andric __iter_pointer __result = __end_node(); 28307c82a1ecSDimitry Andric __node_pointer __rt = __root(); 28317a984708SDavid Chisnall while (__rt != nullptr) 28327a984708SDavid Chisnall { 28337a984708SDavid Chisnall if (value_comp()(__k, __rt->__value_)) 28347a984708SDavid Chisnall { 28357c82a1ecSDimitry Andric __result = static_cast<__iter_pointer>(__rt); 28367c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 28377a984708SDavid Chisnall } 28387a984708SDavid Chisnall else if (value_comp()(__rt->__value_, __k)) 28397c82a1ecSDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 28407a984708SDavid Chisnall else 28417c82a1ecSDimitry Andric return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 28427c82a1ecSDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); 28437a984708SDavid Chisnall } 284494e3ee44SDavid Chisnall return _Pp(const_iterator(__result), const_iterator(__result)); 28457a984708SDavid Chisnall} 28467a984708SDavid Chisnall 28477a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 28487a984708SDavid Chisnalltypename __tree<_Tp, _Compare, _Allocator>::__node_holder 28497a984708SDavid Chisnall__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT 28507a984708SDavid Chisnall{ 28517c82a1ecSDimitry Andric __node_pointer __np = __p.__get_np(); 28527c82a1ecSDimitry Andric if (__begin_node() == __p.__ptr_) 28537a984708SDavid Chisnall { 28547a984708SDavid Chisnall if (__np->__right_ != nullptr) 28557c82a1ecSDimitry Andric __begin_node() = static_cast<__iter_pointer>(__np->__right_); 28567a984708SDavid Chisnall else 28577c82a1ecSDimitry Andric __begin_node() = static_cast<__iter_pointer>(__np->__parent_); 28587a984708SDavid Chisnall } 28597a984708SDavid Chisnall --size(); 28607a984708SDavid Chisnall __tree_remove(__end_node()->__left_, 28617a984708SDavid Chisnall static_cast<__node_base_pointer>(__np)); 2862854fa44bSDimitry Andric return __node_holder(__np, _Dp(__node_alloc(), true)); 28637a984708SDavid Chisnall} 28647a984708SDavid Chisnall 28657a984708SDavid Chisnalltemplate <class _Tp, class _Compare, class _Allocator> 28667a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 28677a984708SDavid Chisnallvoid 28687a984708SDavid Chisnallswap(__tree<_Tp, _Compare, _Allocator>& __x, 28697a984708SDavid Chisnall __tree<_Tp, _Compare, _Allocator>& __y) 28707a984708SDavid Chisnall _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 28717a984708SDavid Chisnall{ 28727a984708SDavid Chisnall __x.swap(__y); 28737a984708SDavid Chisnall} 28747a984708SDavid Chisnall 28757a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 28767a984708SDavid Chisnall 2877f9448bf3SDimitry Andric_LIBCPP_POP_MACROS 2878f9448bf3SDimitry Andric 28797a984708SDavid Chisnall#endif // _LIBCPP___TREE 2880