10b57cec5SDimitry Andric// -*- C++ -*- 20b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP___TREE 110b57cec5SDimitry Andric#define _LIBCPP___TREE 120b57cec5SDimitry Andric 1381ad6265SDimitry Andric#include <__algorithm/min.h> 1481ad6265SDimitry Andric#include <__assert> 150b57cec5SDimitry Andric#include <__config> 16bdd1243dSDimitry Andric#include <__functional/invoke.h> 1781ad6265SDimitry Andric#include <__iterator/distance.h> 1881ad6265SDimitry Andric#include <__iterator/iterator_traits.h> 1981ad6265SDimitry Andric#include <__iterator/next.h> 2006c3fb27SDimitry Andric#include <__memory/addressof.h> 21bdd1243dSDimitry Andric#include <__memory/allocator_traits.h> 22bdd1243dSDimitry Andric#include <__memory/compressed_pair.h> 23bdd1243dSDimitry Andric#include <__memory/pointer_traits.h> 24972a253aSDimitry Andric#include <__memory/swap_allocator.h> 25bdd1243dSDimitry Andric#include <__memory/unique_ptr.h> 26bdd1243dSDimitry Andric#include <__type_traits/can_extract_key.h> 27bdd1243dSDimitry Andric#include <__type_traits/conditional.h> 28bdd1243dSDimitry Andric#include <__type_traits/is_const.h> 29*0fca6ea1SDimitry Andric#include <__type_traits/is_constructible.h> 30*0fca6ea1SDimitry Andric#include <__type_traits/is_nothrow_assignable.h> 31*0fca6ea1SDimitry Andric#include <__type_traits/is_nothrow_constructible.h> 32bdd1243dSDimitry Andric#include <__type_traits/is_pointer.h> 33bdd1243dSDimitry Andric#include <__type_traits/is_same.h> 34bdd1243dSDimitry Andric#include <__type_traits/is_swappable.h> 35bdd1243dSDimitry Andric#include <__type_traits/remove_const_ref.h> 36bdd1243dSDimitry Andric#include <__type_traits/remove_cvref.h> 37fe6060f1SDimitry Andric#include <__utility/forward.h> 38bdd1243dSDimitry Andric#include <__utility/move.h> 39bdd1243dSDimitry Andric#include <__utility/pair.h> 4081ad6265SDimitry Andric#include <__utility/swap.h> 41fe6060f1SDimitry Andric#include <limits> 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 440b57cec5SDimitry Andric# pragma GCC system_header 450b57cec5SDimitry Andric#endif 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 480b57cec5SDimitry Andric#include <__undef_macros> 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 510b57cec5SDimitry Andric 52cb14a3feSDimitry Andrictemplate <class, class, class, class> 53cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS map; 54cb14a3feSDimitry Andrictemplate <class, class, class, class> 55cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS multimap; 56cb14a3feSDimitry Andrictemplate <class, class, class> 57cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS set; 58cb14a3feSDimitry Andrictemplate <class, class, class> 59cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS multiset; 600b57cec5SDimitry Andric 61cb14a3feSDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 62cb14a3feSDimitry Andricclass __tree; 630b57cec5SDimitry Andrictemplate <class _Tp, class _NodePtr, class _DiffType> 640b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_iterator; 650b57cec5SDimitry Andrictemplate <class _Tp, class _ConstNodePtr, class _DiffType> 660b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_const_iterator; 670b57cec5SDimitry Andric 68cb14a3feSDimitry Andrictemplate <class _Pointer> 69cb14a3feSDimitry Andricclass __tree_end_node; 70cb14a3feSDimitry Andrictemplate <class _VoidPtr> 71cb14a3feSDimitry Andricclass __tree_node_base; 72cb14a3feSDimitry Andrictemplate <class _Tp, class _VoidPtr> 73cb14a3feSDimitry Andricclass __tree_node; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andrictemplate <class _Key, class _Value> 760b57cec5SDimitry Andricstruct __value_type; 770b57cec5SDimitry Andric 78cb14a3feSDimitry Andrictemplate <class _Allocator> 79cb14a3feSDimitry Andricclass __map_node_destructor; 80cb14a3feSDimitry Andrictemplate <class _TreeIterator> 81cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __map_iterator; 82cb14a3feSDimitry Andrictemplate <class _TreeIterator> 83cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __map_const_iterator; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric/* 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric_NodePtr algorithms 880b57cec5SDimitry Andric 890b57cec5SDimitry AndricThe algorithms taking _NodePtr are red black tree algorithms. Those 900b57cec5SDimitry Andricalgorithms taking a parameter named __root should assume that __root 910b57cec5SDimitry Andricpoints to a proper red black tree (unless otherwise specified). 920b57cec5SDimitry Andric 930b57cec5SDimitry AndricEach algorithm herein assumes that __root->__parent_ points to a non-null 940b57cec5SDimitry Andricstructure which has a member __left_ which points back to __root. No other 950b57cec5SDimitry Andricmember is read or written to at __root->__parent_. 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric__root->__parent_ will be referred to below (in comments only) as end_node. 980b57cec5SDimitry Andricend_node->__left_ is an externably accessible lvalue for __root, and can be 990b57cec5SDimitry Andricchanged by node insertion and removal (without explicit reference to end_node). 1000b57cec5SDimitry Andric 1010b57cec5SDimitry AndricAll nodes (with the exception of end_node), even the node referred to as 1020b57cec5SDimitry Andric__root, have a non-null __parent_ field. 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric*/ 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric// Returns: true if __x is a left child of its parent, else false 1070b57cec5SDimitry Andric// Precondition: __x != nullptr. 1080b57cec5SDimitry Andrictemplate <class _NodePtr> 109cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __tree_is_left_child(_NodePtr __x) _NOEXCEPT { 1100b57cec5SDimitry Andric return __x == __x->__parent_->__left_; 1110b57cec5SDimitry Andric} 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric// Determines if the subtree rooted at __x is a proper red black subtree. If 1140b57cec5SDimitry Andric// __x is a proper subtree, returns the black height (null counts as 1). If 1150b57cec5SDimitry Andric// __x is an improper subtree, returns 0. 1160b57cec5SDimitry Andrictemplate <class _NodePtr> 117cb14a3feSDimitry Andricunsigned __tree_sub_invariant(_NodePtr __x) { 1180b57cec5SDimitry Andric if (__x == nullptr) 1190b57cec5SDimitry Andric return 1; 1200b57cec5SDimitry Andric // parent consistency checked by caller 1210b57cec5SDimitry Andric // check __x->__left_ consistency 1220b57cec5SDimitry Andric if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x) 1230b57cec5SDimitry Andric return 0; 1240b57cec5SDimitry Andric // check __x->__right_ consistency 1250b57cec5SDimitry Andric if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x) 1260b57cec5SDimitry Andric return 0; 1270b57cec5SDimitry Andric // check __x->__left_ != __x->__right_ unless both are nullptr 1280b57cec5SDimitry Andric if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr) 1290b57cec5SDimitry Andric return 0; 1300b57cec5SDimitry Andric // If this is red, neither child can be red 131cb14a3feSDimitry Andric if (!__x->__is_black_) { 1320b57cec5SDimitry Andric if (__x->__left_ && !__x->__left_->__is_black_) 1330b57cec5SDimitry Andric return 0; 1340b57cec5SDimitry Andric if (__x->__right_ && !__x->__right_->__is_black_) 1350b57cec5SDimitry Andric return 0; 1360b57cec5SDimitry Andric } 1375f757f3fSDimitry Andric unsigned __h = std::__tree_sub_invariant(__x->__left_); 1380b57cec5SDimitry Andric if (__h == 0) 1390b57cec5SDimitry Andric return 0; // invalid left subtree 1405f757f3fSDimitry Andric if (__h != std::__tree_sub_invariant(__x->__right_)) 1410b57cec5SDimitry Andric return 0; // invalid or different height right subtree 1420b57cec5SDimitry Andric return __h + __x->__is_black_; // return black height of this node 1430b57cec5SDimitry Andric} 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric// Determines if the red black tree rooted at __root is a proper red black tree. 1460b57cec5SDimitry Andric// __root == nullptr is a proper tree. Returns true is __root is a proper 1470b57cec5SDimitry Andric// red black tree, else returns false. 1480b57cec5SDimitry Andrictemplate <class _NodePtr> 149cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool __tree_invariant(_NodePtr __root) { 1500b57cec5SDimitry Andric if (__root == nullptr) 1510b57cec5SDimitry Andric return true; 1520b57cec5SDimitry Andric // check __x->__parent_ consistency 1530b57cec5SDimitry Andric if (__root->__parent_ == nullptr) 1540b57cec5SDimitry Andric return false; 1555f757f3fSDimitry Andric if (!std::__tree_is_left_child(__root)) 1560b57cec5SDimitry Andric return false; 1570b57cec5SDimitry Andric // root must be black 1580b57cec5SDimitry Andric if (!__root->__is_black_) 1590b57cec5SDimitry Andric return false; 1600b57cec5SDimitry Andric // do normal node checks 1615f757f3fSDimitry Andric return std::__tree_sub_invariant(__root) != 0; 1620b57cec5SDimitry Andric} 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric// Returns: pointer to the left-most node under __x. 1650b57cec5SDimitry Andrictemplate <class _NodePtr> 166cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_min(_NodePtr __x) _NOEXCEPT { 16706c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null"); 1680b57cec5SDimitry Andric while (__x->__left_ != nullptr) 1690b57cec5SDimitry Andric __x = __x->__left_; 1700b57cec5SDimitry Andric return __x; 1710b57cec5SDimitry Andric} 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric// Returns: pointer to the right-most node under __x. 1740b57cec5SDimitry Andrictemplate <class _NodePtr> 175cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_max(_NodePtr __x) _NOEXCEPT { 17606c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null"); 1770b57cec5SDimitry Andric while (__x->__right_ != nullptr) 1780b57cec5SDimitry Andric __x = __x->__right_; 1790b57cec5SDimitry Andric return __x; 1800b57cec5SDimitry Andric} 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric// Returns: pointer to the next in-order node after __x. 1830b57cec5SDimitry Andrictemplate <class _NodePtr> 184cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT { 18506c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); 1860b57cec5SDimitry Andric if (__x->__right_ != nullptr) 1875f757f3fSDimitry Andric return std::__tree_min(__x->__right_); 1885f757f3fSDimitry Andric while (!std::__tree_is_left_child(__x)) 1890b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 1900b57cec5SDimitry Andric return __x->__parent_unsafe(); 1910b57cec5SDimitry Andric} 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andrictemplate <class _EndNodePtr, class _NodePtr> 194cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT { 19506c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); 1960b57cec5SDimitry Andric if (__x->__right_ != nullptr) 1975f757f3fSDimitry Andric return static_cast<_EndNodePtr>(std::__tree_min(__x->__right_)); 1985f757f3fSDimitry Andric while (!std::__tree_is_left_child(__x)) 1990b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 2000b57cec5SDimitry Andric return static_cast<_EndNodePtr>(__x->__parent_); 2010b57cec5SDimitry Andric} 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric// Returns: pointer to the previous in-order node before __x. 2040b57cec5SDimitry Andric// Note: __x may be the end node. 2050b57cec5SDimitry Andrictemplate <class _NodePtr, class _EndNodePtr> 206cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT { 20706c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); 2080b57cec5SDimitry Andric if (__x->__left_ != nullptr) 2095f757f3fSDimitry Andric return std::__tree_max(__x->__left_); 2100b57cec5SDimitry Andric _NodePtr __xx = static_cast<_NodePtr>(__x); 2115f757f3fSDimitry Andric while (std::__tree_is_left_child(__xx)) 2120b57cec5SDimitry Andric __xx = __xx->__parent_unsafe(); 2130b57cec5SDimitry Andric return __xx->__parent_unsafe(); 2140b57cec5SDimitry Andric} 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric// Returns: pointer to a node which has no children 2170b57cec5SDimitry Andrictemplate <class _NodePtr> 218cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _NodePtr __tree_leaf(_NodePtr __x) _NOEXCEPT { 21906c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); 220cb14a3feSDimitry Andric while (true) { 221cb14a3feSDimitry Andric if (__x->__left_ != nullptr) { 2220b57cec5SDimitry Andric __x = __x->__left_; 2230b57cec5SDimitry Andric continue; 2240b57cec5SDimitry Andric } 225cb14a3feSDimitry Andric if (__x->__right_ != nullptr) { 2260b57cec5SDimitry Andric __x = __x->__right_; 2270b57cec5SDimitry Andric continue; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric break; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric return __x; 2320b57cec5SDimitry Andric} 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric// Effects: Makes __x->__right_ the subtree root with __x as its left child 2350b57cec5SDimitry Andric// while preserving in-order order. 2360b57cec5SDimitry Andrictemplate <class _NodePtr> 237cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void __tree_left_rotate(_NodePtr __x) _NOEXCEPT { 23806c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); 23906c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x->__right_ != nullptr, "node should have a right child"); 2400b57cec5SDimitry Andric _NodePtr __y = __x->__right_; 2410b57cec5SDimitry Andric __x->__right_ = __y->__left_; 2420b57cec5SDimitry Andric if (__x->__right_ != nullptr) 2430b57cec5SDimitry Andric __x->__right_->__set_parent(__x); 2440b57cec5SDimitry Andric __y->__parent_ = __x->__parent_; 2455f757f3fSDimitry Andric if (std::__tree_is_left_child(__x)) 2460b57cec5SDimitry Andric __x->__parent_->__left_ = __y; 2470b57cec5SDimitry Andric else 2480b57cec5SDimitry Andric __x->__parent_unsafe()->__right_ = __y; 2490b57cec5SDimitry Andric __y->__left_ = __x; 2500b57cec5SDimitry Andric __x->__set_parent(__y); 2510b57cec5SDimitry Andric} 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric// Effects: Makes __x->__left_ the subtree root with __x as its right child 2540b57cec5SDimitry Andric// while preserving in-order order. 2550b57cec5SDimitry Andrictemplate <class _NodePtr> 256cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void __tree_right_rotate(_NodePtr __x) _NOEXCEPT { 25706c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); 25806c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x->__left_ != nullptr, "node should have a left child"); 2590b57cec5SDimitry Andric _NodePtr __y = __x->__left_; 2600b57cec5SDimitry Andric __x->__left_ = __y->__right_; 2610b57cec5SDimitry Andric if (__x->__left_ != nullptr) 2620b57cec5SDimitry Andric __x->__left_->__set_parent(__x); 2630b57cec5SDimitry Andric __y->__parent_ = __x->__parent_; 2645f757f3fSDimitry Andric if (std::__tree_is_left_child(__x)) 2650b57cec5SDimitry Andric __x->__parent_->__left_ = __y; 2660b57cec5SDimitry Andric else 2670b57cec5SDimitry Andric __x->__parent_unsafe()->__right_ = __y; 2680b57cec5SDimitry Andric __y->__right_ = __x; 2690b57cec5SDimitry Andric __x->__set_parent(__y); 2700b57cec5SDimitry Andric} 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric// Effects: Rebalances __root after attaching __x to a leaf. 27381ad6265SDimitry Andric// Precondition: __x has no children. 2740b57cec5SDimitry Andric// __x == __root or == a direct or indirect child of __root. 2750b57cec5SDimitry Andric// If __x were to be unlinked from __root (setting __root to 2760b57cec5SDimitry Andric// nullptr if __root == __x), __tree_invariant(__root) == true. 2770b57cec5SDimitry Andric// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_ 2780b57cec5SDimitry Andric// may be different than the value passed in as __root. 2790b57cec5SDimitry Andrictemplate <class _NodePtr> 280cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { 28106c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root of the tree shouldn't be null"); 28206c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Can't attach null node to a leaf"); 2830b57cec5SDimitry Andric __x->__is_black_ = __x == __root; 284cb14a3feSDimitry Andric while (__x != __root && !__x->__parent_unsafe()->__is_black_) { 2850b57cec5SDimitry Andric // __x->__parent_ != __root because __x->__parent_->__is_black == false 286cb14a3feSDimitry Andric if (std::__tree_is_left_child(__x->__parent_unsafe())) { 2870b57cec5SDimitry Andric _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_; 288cb14a3feSDimitry Andric if (__y != nullptr && !__y->__is_black_) { 2890b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 2900b57cec5SDimitry Andric __x->__is_black_ = true; 2910b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 2920b57cec5SDimitry Andric __x->__is_black_ = __x == __root; 2930b57cec5SDimitry Andric __y->__is_black_ = true; 294cb14a3feSDimitry Andric } else { 295cb14a3feSDimitry Andric if (!std::__tree_is_left_child(__x)) { 2960b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 2975f757f3fSDimitry Andric std::__tree_left_rotate(__x); 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 3000b57cec5SDimitry Andric __x->__is_black_ = true; 3010b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 3020b57cec5SDimitry Andric __x->__is_black_ = false; 3035f757f3fSDimitry Andric std::__tree_right_rotate(__x); 3040b57cec5SDimitry Andric break; 3050b57cec5SDimitry Andric } 306cb14a3feSDimitry Andric } else { 3070b57cec5SDimitry Andric _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_; 308cb14a3feSDimitry Andric if (__y != nullptr && !__y->__is_black_) { 3090b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 3100b57cec5SDimitry Andric __x->__is_black_ = true; 3110b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 3120b57cec5SDimitry Andric __x->__is_black_ = __x == __root; 3130b57cec5SDimitry Andric __y->__is_black_ = true; 314cb14a3feSDimitry Andric } else { 315cb14a3feSDimitry Andric if (std::__tree_is_left_child(__x)) { 3160b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 3175f757f3fSDimitry Andric std::__tree_right_rotate(__x); 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 3200b57cec5SDimitry Andric __x->__is_black_ = true; 3210b57cec5SDimitry Andric __x = __x->__parent_unsafe(); 3220b57cec5SDimitry Andric __x->__is_black_ = false; 3235f757f3fSDimitry Andric std::__tree_left_rotate(__x); 3240b57cec5SDimitry Andric break; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric} 3290b57cec5SDimitry Andric 33081ad6265SDimitry Andric// Precondition: __z == __root or == a direct or indirect child of __root. 3310b57cec5SDimitry Andric// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed. 3320b57cec5SDimitry Andric// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_ 3330b57cec5SDimitry Andric// nor any of its children refer to __z. end_node->__left_ 3340b57cec5SDimitry Andric// may be different than the value passed in as __root. 3350b57cec5SDimitry Andrictemplate <class _NodePtr> 336cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT { 33706c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root node should not be null"); 33806c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__z != nullptr, "The node to remove should not be null"); 33906c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(std::__tree_invariant(__root), "The tree invariants should hold"); 3400b57cec5SDimitry Andric // __z will be removed from the tree. Client still needs to destruct/deallocate it 3410b57cec5SDimitry Andric // __y is either __z, or if __z has two children, __tree_next(__z). 3420b57cec5SDimitry Andric // __y will have at most one child. 3430b57cec5SDimitry Andric // __y will be the initial hole in the tree (make the hole at a leaf) 344cb14a3feSDimitry Andric _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ? __z : std::__tree_next(__z); 3450b57cec5SDimitry Andric // __x is __y's possibly null single child 3460b57cec5SDimitry Andric _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_; 3470b57cec5SDimitry Andric // __w is __x's possibly null uncle (will become __x's sibling) 3480b57cec5SDimitry Andric _NodePtr __w = nullptr; 3490b57cec5SDimitry Andric // link __x to __y's parent, and find __w 3500b57cec5SDimitry Andric if (__x != nullptr) 3510b57cec5SDimitry Andric __x->__parent_ = __y->__parent_; 352cb14a3feSDimitry Andric if (std::__tree_is_left_child(__y)) { 3530b57cec5SDimitry Andric __y->__parent_->__left_ = __x; 3540b57cec5SDimitry Andric if (__y != __root) 3550b57cec5SDimitry Andric __w = __y->__parent_unsafe()->__right_; 3560b57cec5SDimitry Andric else 3570b57cec5SDimitry Andric __root = __x; // __w == nullptr 358cb14a3feSDimitry Andric } else { 3590b57cec5SDimitry Andric __y->__parent_unsafe()->__right_ = __x; 3600b57cec5SDimitry Andric // __y can't be root if it is a right child 3610b57cec5SDimitry Andric __w = __y->__parent_->__left_; 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric bool __removed_black = __y->__is_black_; 3640b57cec5SDimitry Andric // If we didn't remove __z, do so now by splicing in __y for __z, 3650b57cec5SDimitry Andric // but copy __z's color. This does not impact __x or __w. 366cb14a3feSDimitry Andric if (__y != __z) { 3670b57cec5SDimitry Andric // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr 3680b57cec5SDimitry Andric __y->__parent_ = __z->__parent_; 3695f757f3fSDimitry Andric if (std::__tree_is_left_child(__z)) 3700b57cec5SDimitry Andric __y->__parent_->__left_ = __y; 3710b57cec5SDimitry Andric else 3720b57cec5SDimitry Andric __y->__parent_unsafe()->__right_ = __y; 3730b57cec5SDimitry Andric __y->__left_ = __z->__left_; 3740b57cec5SDimitry Andric __y->__left_->__set_parent(__y); 3750b57cec5SDimitry Andric __y->__right_ = __z->__right_; 3760b57cec5SDimitry Andric if (__y->__right_ != nullptr) 3770b57cec5SDimitry Andric __y->__right_->__set_parent(__y); 3780b57cec5SDimitry Andric __y->__is_black_ = __z->__is_black_; 3790b57cec5SDimitry Andric if (__root == __z) 3800b57cec5SDimitry Andric __root = __y; 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric // There is no need to rebalance if we removed a red, or if we removed 3830b57cec5SDimitry Andric // the last node. 384cb14a3feSDimitry Andric if (__removed_black && __root != nullptr) { 3850b57cec5SDimitry Andric // Rebalance: 3860b57cec5SDimitry Andric // __x has an implicit black color (transferred from the removed __y) 3870b57cec5SDimitry Andric // associated with it, no matter what its color is. 3880b57cec5SDimitry Andric // If __x is __root (in which case it can't be null), it is supposed 3890b57cec5SDimitry Andric // to be black anyway, and if it is doubly black, then the double 3900b57cec5SDimitry Andric // can just be ignored. 3910b57cec5SDimitry Andric // If __x is red (in which case it can't be null), then it can absorb 3920b57cec5SDimitry Andric // the implicit black just by setting its color to black. 3930b57cec5SDimitry Andric // Since __y was black and only had one child (which __x points to), __x 3940b57cec5SDimitry Andric // is either red with no children, else null, otherwise __y would have 3950b57cec5SDimitry Andric // different black heights under left and right pointers. 3960b57cec5SDimitry Andric // if (__x == __root || __x != nullptr && !__x->__is_black_) 3970b57cec5SDimitry Andric if (__x != nullptr) 3980b57cec5SDimitry Andric __x->__is_black_ = true; 399cb14a3feSDimitry Andric else { 4000b57cec5SDimitry Andric // Else __x isn't root, and is "doubly black", even though it may 4010b57cec5SDimitry Andric // be null. __w can not be null here, else the parent would 4020b57cec5SDimitry Andric // see a black height >= 2 on the __x side and a black height 4030b57cec5SDimitry Andric // of 1 on the __w side (__w must be a non-null black or a red 4040b57cec5SDimitry Andric // with a non-null black child). 405cb14a3feSDimitry Andric while (true) { 4065f757f3fSDimitry Andric if (!std::__tree_is_left_child(__w)) // if x is left child 4070b57cec5SDimitry Andric { 408cb14a3feSDimitry Andric if (!__w->__is_black_) { 4090b57cec5SDimitry Andric __w->__is_black_ = true; 4100b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = false; 4115f757f3fSDimitry Andric std::__tree_left_rotate(__w->__parent_unsafe()); 4120b57cec5SDimitry Andric // __x is still valid 4130b57cec5SDimitry Andric // reset __root only if necessary 4140b57cec5SDimitry Andric if (__root == __w->__left_) 4150b57cec5SDimitry Andric __root = __w; 4160b57cec5SDimitry Andric // reset sibling, and it still can't be null 4170b57cec5SDimitry Andric __w = __w->__left_->__right_; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric // __w->__is_black_ is now true, __w may have null children 4200b57cec5SDimitry Andric if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && 421cb14a3feSDimitry Andric (__w->__right_ == nullptr || __w->__right_->__is_black_)) { 4220b57cec5SDimitry Andric __w->__is_black_ = false; 4230b57cec5SDimitry Andric __x = __w->__parent_unsafe(); 4240b57cec5SDimitry Andric // __x can no longer be null 425cb14a3feSDimitry Andric if (__x == __root || !__x->__is_black_) { 4260b57cec5SDimitry Andric __x->__is_black_ = true; 4270b57cec5SDimitry Andric break; 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric // reset sibling, and it still can't be null 430cb14a3feSDimitry Andric __w = std::__tree_is_left_child(__x) ? __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; 4310b57cec5SDimitry Andric // continue; 432cb14a3feSDimitry Andric } else // __w has a red child 4330b57cec5SDimitry Andric { 434cb14a3feSDimitry Andric if (__w->__right_ == nullptr || __w->__right_->__is_black_) { 4350b57cec5SDimitry Andric // __w left child is non-null and red 4360b57cec5SDimitry Andric __w->__left_->__is_black_ = true; 4370b57cec5SDimitry Andric __w->__is_black_ = false; 4385f757f3fSDimitry Andric std::__tree_right_rotate(__w); 4390b57cec5SDimitry Andric // __w is known not to be root, so root hasn't changed 4400b57cec5SDimitry Andric // reset sibling, and it still can't be null 4410b57cec5SDimitry Andric __w = __w->__parent_unsafe(); 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric // __w has a right red child, left child may be null 4440b57cec5SDimitry Andric __w->__is_black_ = __w->__parent_unsafe()->__is_black_; 4450b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = true; 4460b57cec5SDimitry Andric __w->__right_->__is_black_ = true; 4475f757f3fSDimitry Andric std::__tree_left_rotate(__w->__parent_unsafe()); 4480b57cec5SDimitry Andric break; 4490b57cec5SDimitry Andric } 450cb14a3feSDimitry Andric } else { 451cb14a3feSDimitry Andric if (!__w->__is_black_) { 4520b57cec5SDimitry Andric __w->__is_black_ = true; 4530b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = false; 4545f757f3fSDimitry Andric std::__tree_right_rotate(__w->__parent_unsafe()); 4550b57cec5SDimitry Andric // __x is still valid 4560b57cec5SDimitry Andric // reset __root only if necessary 4570b57cec5SDimitry Andric if (__root == __w->__right_) 4580b57cec5SDimitry Andric __root = __w; 4590b57cec5SDimitry Andric // reset sibling, and it still can't be null 4600b57cec5SDimitry Andric __w = __w->__right_->__left_; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric // __w->__is_black_ is now true, __w may have null children 4630b57cec5SDimitry Andric if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && 464cb14a3feSDimitry Andric (__w->__right_ == nullptr || __w->__right_->__is_black_)) { 4650b57cec5SDimitry Andric __w->__is_black_ = false; 4660b57cec5SDimitry Andric __x = __w->__parent_unsafe(); 4670b57cec5SDimitry Andric // __x can no longer be null 468cb14a3feSDimitry Andric if (!__x->__is_black_ || __x == __root) { 4690b57cec5SDimitry Andric __x->__is_black_ = true; 4700b57cec5SDimitry Andric break; 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric // reset sibling, and it still can't be null 473cb14a3feSDimitry Andric __w = std::__tree_is_left_child(__x) ? __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; 4740b57cec5SDimitry Andric // continue; 475cb14a3feSDimitry Andric } else // __w has a red child 4760b57cec5SDimitry Andric { 477cb14a3feSDimitry Andric if (__w->__left_ == nullptr || __w->__left_->__is_black_) { 4780b57cec5SDimitry Andric // __w right child is non-null and red 4790b57cec5SDimitry Andric __w->__right_->__is_black_ = true; 4800b57cec5SDimitry Andric __w->__is_black_ = false; 4815f757f3fSDimitry Andric std::__tree_left_rotate(__w); 4820b57cec5SDimitry Andric // __w is known not to be root, so root hasn't changed 4830b57cec5SDimitry Andric // reset sibling, and it still can't be null 4840b57cec5SDimitry Andric __w = __w->__parent_unsafe(); 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric // __w has a left red child, right child may be null 4870b57cec5SDimitry Andric __w->__is_black_ = __w->__parent_unsafe()->__is_black_; 4880b57cec5SDimitry Andric __w->__parent_unsafe()->__is_black_ = true; 4890b57cec5SDimitry Andric __w->__left_->__is_black_ = true; 4905f757f3fSDimitry Andric std::__tree_right_rotate(__w->__parent_unsafe()); 4910b57cec5SDimitry Andric break; 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric} 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric// node traits 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andrictemplate <class _Tp> 5020b57cec5SDimitry Andricstruct __is_tree_value_type_imp : false_type {}; 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andrictemplate <class _Key, class _Value> 5050b57cec5SDimitry Andricstruct __is_tree_value_type_imp<__value_type<_Key, _Value> > : true_type {}; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andrictemplate <class... _Args> 5080b57cec5SDimitry Andricstruct __is_tree_value_type : false_type {}; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andrictemplate <class _One> 511bdd1243dSDimitry Andricstruct __is_tree_value_type<_One> : __is_tree_value_type_imp<__remove_cvref_t<_One> > {}; 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andrictemplate <class _Tp> 5140b57cec5SDimitry Andricstruct __tree_key_value_types { 5150b57cec5SDimitry Andric typedef _Tp key_type; 5160b57cec5SDimitry Andric typedef _Tp __node_value_type; 5170b57cec5SDimitry Andric typedef _Tp __container_value_type; 5180b57cec5SDimitry Andric static const bool __is_map = false; 5190b57cec5SDimitry Andric 520cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Tp const& __v) { return __v; } 521cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; } 522cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n); } 523cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move(__v); } 5240b57cec5SDimitry Andric}; 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andrictemplate <class _Key, class _Tp> 5270b57cec5SDimitry Andricstruct __tree_key_value_types<__value_type<_Key, _Tp> > { 5280b57cec5SDimitry Andric typedef _Key key_type; 5290b57cec5SDimitry Andric typedef _Tp mapped_type; 5300b57cec5SDimitry Andric typedef __value_type<_Key, _Tp> __node_value_type; 5310b57cec5SDimitry Andric typedef pair<const _Key, _Tp> __container_value_type; 5320b57cec5SDimitry Andric typedef __container_value_type __map_value_type; 5330b57cec5SDimitry Andric static const bool __is_map = true; 5340b57cec5SDimitry Andric 535cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__node_value_type const& __t) { 5360b57cec5SDimitry Andric return __t.__get_value().first; 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric 5395f757f3fSDimitry Andric template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0> 540cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Up& __t) { 5410b57cec5SDimitry Andric return __t.first; 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric 544cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __t) { 5450b57cec5SDimitry Andric return __t.__get_value(); 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 548*0fca6ea1SDimitry Andric template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0> 549*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) { 5500b57cec5SDimitry Andric return __t; 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 553cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { 5545f757f3fSDimitry Andric return std::addressof(__n.__get_value()); 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 557cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); } 5580b57cec5SDimitry Andric}; 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andrictemplate <class _VoidPtr> 5610b57cec5SDimitry Andricstruct __tree_node_base_types { 5620b57cec5SDimitry Andric typedef _VoidPtr __void_pointer; 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric typedef __tree_node_base<__void_pointer> __node_base_type; 565cb14a3feSDimitry Andric typedef __rebind_pointer_t<_VoidPtr, __node_base_type> __node_base_pointer; 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric typedef __tree_end_node<__node_base_pointer> __end_node_type; 568cb14a3feSDimitry Andric typedef __rebind_pointer_t<_VoidPtr, __end_node_type> __end_node_pointer; 5690b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) 5700b57cec5SDimitry Andric typedef __end_node_pointer __parent_pointer; 5710b57cec5SDimitry Andric#else 572bdd1243dSDimitry Andric typedef __conditional_t< is_pointer<__end_node_pointer>::value, __end_node_pointer, __node_base_pointer> 573bdd1243dSDimitry Andric __parent_pointer; 5740b57cec5SDimitry Andric#endif 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andricprivate: 577*0fca6ea1SDimitry Andric static_assert(is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value, 5780b57cec5SDimitry Andric "_VoidPtr does not point to unqualified void type"); 5790b57cec5SDimitry Andric}; 5800b57cec5SDimitry Andric 581cb14a3feSDimitry Andrictemplate <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>, bool = _KVTypes::__is_map> 5820b57cec5SDimitry Andricstruct __tree_map_pointer_types {}; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andrictemplate <class _Tp, class _AllocPtr, class _KVTypes> 5850b57cec5SDimitry Andricstruct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { 5860b57cec5SDimitry Andric typedef typename _KVTypes::__map_value_type _Mv; 587cb14a3feSDimitry Andric typedef __rebind_pointer_t<_AllocPtr, _Mv> __map_value_type_pointer; 588cb14a3feSDimitry Andric typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer; 5890b57cec5SDimitry Andric}; 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andrictemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> 5920b57cec5SDimitry Andricstruct __tree_node_types; 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andrictemplate <class _NodePtr, class _Tp, class _VoidPtr> 5950b57cec5SDimitry Andricstruct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > 596cb14a3feSDimitry Andric : public __tree_node_base_types<_VoidPtr>, __tree_key_value_types<_Tp>, __tree_map_pointer_types<_Tp, _VoidPtr> { 5970b57cec5SDimitry Andric typedef __tree_node_base_types<_VoidPtr> __base; 5980b57cec5SDimitry Andric typedef __tree_key_value_types<_Tp> __key_base; 5990b57cec5SDimitry Andric typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base; 6000b57cec5SDimitry Andric 601cb14a3feSDimitry Andricpublic: 6020b57cec5SDimitry Andric typedef typename pointer_traits<_NodePtr>::element_type __node_type; 6030b57cec5SDimitry Andric typedef _NodePtr __node_pointer; 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andric typedef _Tp __node_value_type; 606cb14a3feSDimitry Andric typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer; 607cb14a3feSDimitry Andric typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer; 6080b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) 6090b57cec5SDimitry Andric typedef typename __base::__end_node_pointer __iter_pointer; 6100b57cec5SDimitry Andric#else 611bdd1243dSDimitry Andric typedef __conditional_t< is_pointer<__node_pointer>::value, typename __base::__end_node_pointer, __node_pointer> 612bdd1243dSDimitry Andric __iter_pointer; 6130b57cec5SDimitry Andric#endif 614cb14a3feSDimitry Andric 6150b57cec5SDimitry Andricprivate: 616cb14a3feSDimitry Andric static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const"); 617*0fca6ea1SDimitry Andric static_assert(is_same<__rebind_pointer_t<_VoidPtr, __node_type>, _NodePtr>::value, 618cb14a3feSDimitry Andric "_VoidPtr does not rebind to _NodePtr."); 6190b57cec5SDimitry Andric}; 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andrictemplate <class _ValueTp, class _VoidPtr> 6220b57cec5SDimitry Andricstruct __make_tree_node_types { 623cb14a3feSDimitry Andric typedef __rebind_pointer_t<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> > _NodePtr; 6240b57cec5SDimitry Andric typedef __tree_node_types<_NodePtr> type; 6250b57cec5SDimitry Andric}; 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric// node 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andrictemplate <class _Pointer> 630cb14a3feSDimitry Andricclass __tree_end_node { 6310b57cec5SDimitry Andricpublic: 6320b57cec5SDimitry Andric typedef _Pointer pointer; 6330b57cec5SDimitry Andric pointer __left_; 6340b57cec5SDimitry Andric 635cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_end_node() _NOEXCEPT : __left_() {} 6360b57cec5SDimitry Andric}; 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andrictemplate <class _VoidPtr> 639cb14a3feSDimitry Andricclass _LIBCPP_STANDALONE_DEBUG __tree_node_base : public __tree_node_base_types<_VoidPtr>::__end_node_type { 6400b57cec5SDimitry Andric typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes; 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andricpublic: 6430b57cec5SDimitry Andric typedef typename _NodeBaseTypes::__node_base_pointer pointer; 6440b57cec5SDimitry Andric typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer; 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric pointer __right_; 6470b57cec5SDimitry Andric __parent_pointer __parent_; 6480b57cec5SDimitry Andric bool __is_black_; 6490b57cec5SDimitry Andric 650cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer __parent_unsafe() const { return static_cast<pointer>(__parent_); } 6510b57cec5SDimitry Andric 652cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = static_cast<__parent_pointer>(__p); } 6530b57cec5SDimitry Andric 654349cc55cSDimitry Andric ~__tree_node_base() = delete; 655349cc55cSDimitry Andric __tree_node_base(__tree_node_base const&) = delete; 656349cc55cSDimitry Andric __tree_node_base& operator=(__tree_node_base const&) = delete; 6570b57cec5SDimitry Andric}; 6580b57cec5SDimitry Andric 6590b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr> 660cb14a3feSDimitry Andricclass _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> { 6610b57cec5SDimitry Andricpublic: 6620b57cec5SDimitry Andric typedef _Tp __node_value_type; 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric __node_value_type __value_; 6650b57cec5SDimitry Andric 6665f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; } 6675f757f3fSDimitry Andric 668349cc55cSDimitry Andric ~__tree_node() = delete; 669349cc55cSDimitry Andric __tree_node(__tree_node const&) = delete; 670349cc55cSDimitry Andric __tree_node& operator=(__tree_node const&) = delete; 6710b57cec5SDimitry Andric}; 6720b57cec5SDimitry Andric 6730b57cec5SDimitry Andrictemplate <class _Allocator> 674cb14a3feSDimitry Andricclass __tree_node_destructor { 6750b57cec5SDimitry Andric typedef _Allocator allocator_type; 6760b57cec5SDimitry Andric typedef allocator_traits<allocator_type> __alloc_traits; 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andricpublic: 6790b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 680cb14a3feSDimitry Andric 6810b57cec5SDimitry Andricprivate: 6820b57cec5SDimitry Andric typedef __tree_node_types<pointer> _NodeTypes; 6830b57cec5SDimitry Andric allocator_type& __na_; 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andricpublic: 6860b57cec5SDimitry Andric bool __value_constructed; 6870b57cec5SDimitry Andric 68806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_node_destructor(const __tree_node_destructor&) = default; 689cd0c3137SDimitry Andric __tree_node_destructor& operator=(const __tree_node_destructor&) = delete; 690cd0c3137SDimitry Andric 691cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT 6920b57cec5SDimitry Andric : __na_(__na), 693cb14a3feSDimitry Andric __value_constructed(__val) {} 6940b57cec5SDimitry Andric 695cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { 6960b57cec5SDimitry Andric if (__value_constructed) 6970b57cec5SDimitry Andric __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); 6980b57cec5SDimitry Andric if (__p) 6990b57cec5SDimitry Andric __alloc_traits::deallocate(__na_, __p, 1); 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric 702cb14a3feSDimitry Andric template <class> 703cb14a3feSDimitry Andric friend class __map_node_destructor; 7040b57cec5SDimitry Andric}; 7050b57cec5SDimitry Andric 70606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 7070b57cec5SDimitry Andrictemplate <class _NodeType, class _Alloc> 7080b57cec5SDimitry Andricstruct __generic_container_node_destructor; 7090b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr, class _Alloc> 710cb14a3feSDimitry Andricstruct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> : __tree_node_destructor<_Alloc> { 7110b57cec5SDimitry Andric using __tree_node_destructor<_Alloc>::__tree_node_destructor; 7120b57cec5SDimitry Andric}; 7130b57cec5SDimitry Andric#endif 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andrictemplate <class _Tp, class _NodePtr, class _DiffType> 716cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_iterator { 7170b57cec5SDimitry Andric typedef __tree_node_types<_NodePtr> _NodeTypes; 7180b57cec5SDimitry Andric typedef _NodePtr __node_pointer; 7190b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 7200b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; 7210b57cec5SDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 7220b57cec5SDimitry Andric typedef pointer_traits<__node_pointer> __pointer_traits; 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric __iter_pointer __ptr_; 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andricpublic: 7270b57cec5SDimitry Andric typedef bidirectional_iterator_tag iterator_category; 7280b57cec5SDimitry Andric typedef _Tp value_type; 7290b57cec5SDimitry Andric typedef _DiffType difference_type; 7300b57cec5SDimitry Andric typedef value_type& reference; 7310b57cec5SDimitry Andric typedef typename _NodeTypes::__node_value_type_pointer pointer; 7320b57cec5SDimitry Andric 7335f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT 73406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 7350b57cec5SDimitry Andric : __ptr_(nullptr) 7360b57cec5SDimitry Andric#endif 737cb14a3feSDimitry Andric { 738cb14a3feSDimitry Andric } 7390b57cec5SDimitry Andric 740cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; } 741cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); } 7420b57cec5SDimitry Andric 743cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator++() { 7440b57cec5SDimitry Andric __ptr_ = static_cast<__iter_pointer>( 7455f757f3fSDimitry Andric std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); 7460b57cec5SDimitry Andric return *this; 7470b57cec5SDimitry Andric } 748cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_iterator operator++(int) { 749cb14a3feSDimitry Andric __tree_iterator __t(*this); 750cb14a3feSDimitry Andric ++(*this); 751cb14a3feSDimitry Andric return __t; 752cb14a3feSDimitry Andric } 7530b57cec5SDimitry Andric 754cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator--() { 755cb14a3feSDimitry Andric __ptr_ = static_cast<__iter_pointer>( 756cb14a3feSDimitry Andric std::__tree_prev_iter<__node_base_pointer>(static_cast<__end_node_pointer>(__ptr_))); 7570b57cec5SDimitry Andric return *this; 7580b57cec5SDimitry Andric } 759cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_iterator operator--(int) { 760cb14a3feSDimitry Andric __tree_iterator __t(*this); 761cb14a3feSDimitry Andric --(*this); 762cb14a3feSDimitry Andric return __t; 763cb14a3feSDimitry Andric } 7640b57cec5SDimitry Andric 765cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) { 766cb14a3feSDimitry Andric return __x.__ptr_ == __y.__ptr_; 767cb14a3feSDimitry Andric } 768cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) { 769cb14a3feSDimitry Andric return !(__x == __y); 770cb14a3feSDimitry Andric } 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andricprivate: 773cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 774cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 775cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } 776cb14a3feSDimitry Andric template <class, class, class> 777cb14a3feSDimitry Andric friend class __tree; 778cb14a3feSDimitry Andric template <class, class, class> 779cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; 780cb14a3feSDimitry Andric template <class> 781cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __map_iterator; 782cb14a3feSDimitry Andric template <class, class, class, class> 783cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS map; 784cb14a3feSDimitry Andric template <class, class, class, class> 785cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS multimap; 786cb14a3feSDimitry Andric template <class, class, class> 787cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS set; 788cb14a3feSDimitry Andric template <class, class, class> 789cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS multiset; 7900b57cec5SDimitry Andric}; 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andrictemplate <class _Tp, class _NodePtr, class _DiffType> 793cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __tree_const_iterator { 7940b57cec5SDimitry Andric typedef __tree_node_types<_NodePtr> _NodeTypes; 7950b57cec5SDimitry Andric typedef typename _NodeTypes::__node_pointer __node_pointer; 7960b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 7970b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; 7980b57cec5SDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 7990b57cec5SDimitry Andric typedef pointer_traits<__node_pointer> __pointer_traits; 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric __iter_pointer __ptr_; 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andricpublic: 8040b57cec5SDimitry Andric typedef bidirectional_iterator_tag iterator_category; 8050b57cec5SDimitry Andric typedef _Tp value_type; 8060b57cec5SDimitry Andric typedef _DiffType difference_type; 8070b57cec5SDimitry Andric typedef const value_type& reference; 8080b57cec5SDimitry Andric typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 8090b57cec5SDimitry Andric 8105f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT 81106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 8120b57cec5SDimitry Andric : __ptr_(nullptr) 8130b57cec5SDimitry Andric#endif 814cb14a3feSDimitry Andric { 815cb14a3feSDimitry Andric } 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andricprivate: 818cb14a3feSDimitry Andric typedef __tree_iterator<value_type, __node_pointer, difference_type> __non_const_iterator; 819cb14a3feSDimitry Andric 8200b57cec5SDimitry Andricpublic: 821cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} 8220b57cec5SDimitry Andric 823cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; } 824cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); } 8250b57cec5SDimitry Andric 826cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator++() { 8270b57cec5SDimitry Andric __ptr_ = static_cast<__iter_pointer>( 8285f757f3fSDimitry Andric std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); 8290b57cec5SDimitry Andric return *this; 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 832cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_const_iterator operator++(int) { 833cb14a3feSDimitry Andric __tree_const_iterator __t(*this); 834cb14a3feSDimitry Andric ++(*this); 835cb14a3feSDimitry Andric return __t; 836cb14a3feSDimitry Andric } 8370b57cec5SDimitry Andric 838cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator--() { 839cb14a3feSDimitry Andric __ptr_ = static_cast<__iter_pointer>( 840cb14a3feSDimitry Andric std::__tree_prev_iter<__node_base_pointer>(static_cast<__end_node_pointer>(__ptr_))); 8410b57cec5SDimitry Andric return *this; 8420b57cec5SDimitry Andric } 8430b57cec5SDimitry Andric 844cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree_const_iterator operator--(int) { 845cb14a3feSDimitry Andric __tree_const_iterator __t(*this); 846cb14a3feSDimitry Andric --(*this); 847cb14a3feSDimitry Andric return __t; 848cb14a3feSDimitry Andric } 8490b57cec5SDimitry Andric 850cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) { 851cb14a3feSDimitry Andric return __x.__ptr_ == __y.__ptr_; 852cb14a3feSDimitry Andric } 853cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) { 854cb14a3feSDimitry Andric return !(__x == __y); 855cb14a3feSDimitry Andric } 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andricprivate: 858cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 859cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} 860cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } 8610b57cec5SDimitry Andric 862cb14a3feSDimitry Andric template <class, class, class> 863cb14a3feSDimitry Andric friend class __tree; 864cb14a3feSDimitry Andric template <class, class, class, class> 865cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS map; 866cb14a3feSDimitry Andric template <class, class, class, class> 867cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS multimap; 868cb14a3feSDimitry Andric template <class, class, class> 869cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS set; 870cb14a3feSDimitry Andric template <class, class, class> 871cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS multiset; 872cb14a3feSDimitry Andric template <class> 873cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator; 8740b57cec5SDimitry Andric}; 8750b57cec5SDimitry Andric 8760b57cec5SDimitry Andrictemplate <class _Tp, class _Compare> 8770b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 878e8d8bef9SDimitry Andric_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value, 8790b57cec5SDimitry Andric "the specified comparator type does not provide a viable const call operator") 8800b57cec5SDimitry Andric#endif 8810b57cec5SDimitry Andricint __diagnose_non_const_comparator(); 8820b57cec5SDimitry Andric 8830b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 884cb14a3feSDimitry Andricclass __tree { 8850b57cec5SDimitry Andricpublic: 8860b57cec5SDimitry Andric typedef _Tp value_type; 8870b57cec5SDimitry Andric typedef _Compare value_compare; 8880b57cec5SDimitry Andric typedef _Allocator allocator_type; 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andricprivate: 8910b57cec5SDimitry Andric typedef allocator_traits<allocator_type> __alloc_traits; 892cb14a3feSDimitry Andric typedef typename __make_tree_node_types<value_type, typename __alloc_traits::void_pointer>::type _NodeTypes; 8930b57cec5SDimitry Andric typedef typename _NodeTypes::key_type key_type; 894cb14a3feSDimitry Andric 8950b57cec5SDimitry Andricpublic: 8960b57cec5SDimitry Andric typedef typename _NodeTypes::__node_value_type __node_value_type; 8970b57cec5SDimitry Andric typedef typename _NodeTypes::__container_value_type __container_value_type; 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 9000b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 9010b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 9020b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andricpublic: 9050b57cec5SDimitry Andric typedef typename _NodeTypes::__void_pointer __void_pointer; 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric typedef typename _NodeTypes::__node_type __node; 9080b57cec5SDimitry Andric typedef typename _NodeTypes::__node_pointer __node_pointer; 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_type __node_base; 9110b57cec5SDimitry Andric typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_type __end_node_t; 9140b57cec5SDimitry Andric typedef typename _NodeTypes::__end_node_pointer __end_node_ptr; 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric typedef typename _NodeTypes::__parent_pointer __parent_pointer; 9170b57cec5SDimitry Andric typedef typename _NodeTypes::__iter_pointer __iter_pointer; 9180b57cec5SDimitry Andric 919bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; 9200b57cec5SDimitry Andric typedef allocator_traits<__node_allocator> __node_traits; 9210b57cec5SDimitry Andric 9220b57cec5SDimitry Andricprivate: 9230b57cec5SDimitry Andric // check for sane allocator pointer rebinding semantics. Rebinding the 9240b57cec5SDimitry Andric // allocator for a new pointer type should be exactly the same as rebinding 9250b57cec5SDimitry Andric // the pointer using 'pointer_traits'. 926*0fca6ea1SDimitry Andric static_assert(is_same<__node_pointer, typename __node_traits::pointer>::value, 9270b57cec5SDimitry Andric "Allocator does not rebind pointers in a sane manner."); 928bdd1243dSDimitry Andric typedef __rebind_alloc<__node_traits, __node_base> __node_base_allocator; 9290b57cec5SDimitry Andric typedef allocator_traits<__node_base_allocator> __node_base_traits; 930*0fca6ea1SDimitry Andric static_assert(is_same<__node_base_pointer, typename __node_base_traits::pointer>::value, 9310b57cec5SDimitry Andric "Allocator does not rebind pointers in a sane manner."); 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andricprivate: 9340b57cec5SDimitry Andric __iter_pointer __begin_node_; 9350b57cec5SDimitry Andric __compressed_pair<__end_node_t, __node_allocator> __pair1_; 9360b57cec5SDimitry Andric __compressed_pair<size_type, value_compare> __pair3_; 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andricpublic: 939cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iter_pointer __end_node() _NOEXCEPT { 940cb14a3feSDimitry Andric return static_cast<__iter_pointer>(pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())); 9410b57cec5SDimitry Andric } 942cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iter_pointer __end_node() const _NOEXCEPT { 9430b57cec5SDimitry Andric return static_cast<__iter_pointer>( 944cb14a3feSDimitry Andric pointer_traits<__end_node_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first()))); 9450b57cec5SDimitry Andric } 946cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_allocator& __node_alloc() _NOEXCEPT { return __pair1_.second(); } 9470b57cec5SDimitry Andric 948cb14a3feSDimitry Andricprivate: 949cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __pair1_.second(); } 950cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iter_pointer& __begin_node() _NOEXCEPT { return __begin_node_; } 951cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const __iter_pointer& __begin_node() const _NOEXCEPT { return __begin_node_; } 952cb14a3feSDimitry Andric 953cb14a3feSDimitry Andricpublic: 954cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type __alloc() const _NOEXCEPT { return allocator_type(__node_alloc()); } 955cb14a3feSDimitry Andric 956cb14a3feSDimitry Andricprivate: 957cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __pair3_.first(); } 958cb14a3feSDimitry Andric 959cb14a3feSDimitry Andricpublic: 960cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const size_type& size() const _NOEXCEPT { return __pair3_.first(); } 961cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI value_compare& value_comp() _NOEXCEPT { return __pair3_.second(); } 962cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const value_compare& value_comp() const _NOEXCEPT { return __pair3_.second(); } 963cb14a3feSDimitry Andric 964cb14a3feSDimitry Andricpublic: 965cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_pointer __root() const _NOEXCEPT { 966cb14a3feSDimitry Andric return static_cast<__node_pointer>(__end_node()->__left_); 967cb14a3feSDimitry Andric } 9680b57cec5SDimitry Andric 96906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_base_pointer* __root_ptr() const _NOEXCEPT { 9705f757f3fSDimitry Andric return std::addressof(__end_node()->__left_); 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator; 9740b57cec5SDimitry Andric typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator; 9750b57cec5SDimitry Andric 976cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp) _NOEXCEPT_( 977cb14a3feSDimitry Andric is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value); 97806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a); 97906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a); 98006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t); 98106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t); 9820b57cec5SDimitry Andric template <class _ForwardIterator> 98306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last); 9840b57cec5SDimitry Andric template <class _InputIterator> 98506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last); 986cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_( 987cb14a3feSDimitry Andric is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value); 98806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a); 989cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t) _NOEXCEPT_( 990cb14a3feSDimitry Andric __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<value_compare>::value&& 9910b57cec5SDimitry Andric is_nothrow_move_assignable<__node_allocator>::value); 99206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__tree(); 9930b57cec5SDimitry Andric 994cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node()); } 995cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__begin_node()); } 996cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(__end_node()); } 997cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(__end_node()); } 9980b57cec5SDimitry Andric 999cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { 1000cb14a3feSDimitry Andric return std::min<size_type>(__node_traits::max_size(__node_alloc()), numeric_limits<difference_type >::max()); 1001cb14a3feSDimitry Andric } 10020b57cec5SDimitry Andric 100306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; 10040b57cec5SDimitry Andric 100506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t) 10060b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 11 1007*0fca6ea1SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> && 1008*0fca6ea1SDimitry Andric (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)); 10090b57cec5SDimitry Andric#else 1010*0fca6ea1SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>); 10110b57cec5SDimitry Andric#endif 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andric template <class _Key, class... _Args> 1014cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args&&... __args); 10150b57cec5SDimitry Andric template <class _Key, class... _Args> 1016cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric template <class... _Args> 101906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andric template <class... _Args> 102206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); 10230b57cec5SDimitry Andric 10240b57cec5SDimitry Andric template <class... _Args> 102506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args); 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric template <class... _Args> 102806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); 10290b57cec5SDimitry Andric 10300b57cec5SDimitry Andric template <class _Pp> 1031cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Pp&& __x) { 1032cb14a3feSDimitry Andric return __emplace_unique_extract_key(std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>()); 10330b57cec5SDimitry Andric } 10340b57cec5SDimitry Andric 1035cb14a3feSDimitry Andric template <class _First, 1036cb14a3feSDimitry Andric class _Second, 10375f757f3fSDimitry Andric __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, int> = 0> 1038cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_First&& __f, _Second&& __s) { 1039cb14a3feSDimitry Andric return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s)); 10400b57cec5SDimitry Andric } 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andric template <class... _Args> 1043cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Args&&... __args) { 10445f757f3fSDimitry Andric return __emplace_unique_impl(std::forward<_Args>(__args)...); 10450b57cec5SDimitry Andric } 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric template <class _Pp> 1048cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { 10495f757f3fSDimitry Andric return __emplace_unique_impl(std::forward<_Pp>(__x)); 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric template <class _Pp> 1053cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { 10545f757f3fSDimitry Andric return __emplace_unique_key_args(__x, std::forward<_Pp>(__x)); 10550b57cec5SDimitry Andric } 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric template <class _Pp> 1058cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { 10595f757f3fSDimitry Andric return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x)); 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric template <class _Pp> 1063cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { 1064cb14a3feSDimitry Andric return __emplace_hint_unique_extract_key(__p, std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>()); 10650b57cec5SDimitry Andric } 10660b57cec5SDimitry Andric 1067cb14a3feSDimitry Andric template <class _First, 1068cb14a3feSDimitry Andric class _Second, 10695f757f3fSDimitry Andric __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, int> = 0> 1070cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) { 1071cb14a3feSDimitry Andric return __emplace_hint_unique_key_args(__p, __f, std::forward<_First>(__f), std::forward<_Second>(__s)).first; 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric template <class... _Args> 1075cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { 10765f757f3fSDimitry Andric return __emplace_hint_unique_impl(__p, std::forward<_Args>(__args)...); 10770b57cec5SDimitry Andric } 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric template <class _Pp> 1080cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 10810b57cec5SDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { 10825f757f3fSDimitry Andric return __emplace_hint_unique_impl(__p, std::forward<_Pp>(__x)); 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric template <class _Pp> 1086cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 10870b57cec5SDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { 10885f757f3fSDimitry Andric return __emplace_hint_unique_key_args(__p, __x, std::forward<_Pp>(__x)).first; 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric template <class _Pp> 1092cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator 10930b57cec5SDimitry Andric __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { 10945f757f3fSDimitry Andric return __emplace_hint_unique_key_args(__p, __x.first, std::forward<_Pp>(__x)).first; 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric 1097cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(const __container_value_type& __v) { 10980b57cec5SDimitry Andric return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v); 10990b57cec5SDimitry Andric } 11000b57cec5SDimitry Andric 1101cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_unique(const_iterator __p, const __container_value_type& __v) { 1102e8d8bef9SDimitry Andric return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v).first; 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric 1105cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(__container_value_type&& __v) { 11065f757f3fSDimitry Andric return __emplace_unique_key_args(_NodeTypes::__get_key(__v), std::move(__v)); 11070b57cec5SDimitry Andric } 11080b57cec5SDimitry Andric 1109cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_unique(const_iterator __p, __container_value_type&& __v) { 11105f757f3fSDimitry Andric return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), std::move(__v)).first; 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric 1113*0fca6ea1SDimitry Andric template <class _Vp, __enable_if_t<!is_same<__remove_const_ref_t<_Vp>, __container_value_type>::value, int> = 0> 1114cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(_Vp&& __v) { 11155f757f3fSDimitry Andric return __emplace_unique(std::forward<_Vp>(__v)); 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric 1118*0fca6ea1SDimitry Andric template <class _Vp, __enable_if_t<!is_same<__remove_const_ref_t<_Vp>, __container_value_type>::value, int> = 0> 1119cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_unique(const_iterator __p, _Vp&& __v) { 11205f757f3fSDimitry Andric return __emplace_hint_unique(__p, std::forward<_Vp>(__v)); 11210b57cec5SDimitry Andric } 11220b57cec5SDimitry Andric 1123cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(__container_value_type&& __v) { 11245f757f3fSDimitry Andric return __emplace_multi(std::move(__v)); 11250b57cec5SDimitry Andric } 11260b57cec5SDimitry Andric 1127cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(const_iterator __p, __container_value_type&& __v) { 11285f757f3fSDimitry Andric return __emplace_hint_multi(__p, std::move(__v)); 11290b57cec5SDimitry Andric } 11300b57cec5SDimitry Andric 11310b57cec5SDimitry Andric template <class _Vp> 1132cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(_Vp&& __v) { 11335f757f3fSDimitry Andric return __emplace_multi(std::forward<_Vp>(__v)); 11340b57cec5SDimitry Andric } 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric template <class _Vp> 1137cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(const_iterator __p, _Vp&& __v) { 11385f757f3fSDimitry Andric return __emplace_hint_multi(__p, std::forward<_Vp>(__v)); 11390b57cec5SDimitry Andric } 11400b57cec5SDimitry Andric 1141cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> 1142cb14a3feSDimitry Andric __node_assign_unique(const __container_value_type& __v, __node_pointer __dest); 11430b57cec5SDimitry Andric 1144cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd); 1145cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); 11460b57cec5SDimitry Andric 1147cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __remove_node_pointer(__node_pointer) _NOEXCEPT; 11480b57cec5SDimitry Andric 114906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 11500b57cec5SDimitry Andric template <class _NodeHandle, class _InsertReturnType> 1151cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&&); 11520b57cec5SDimitry Andric template <class _NodeHandle> 1153cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&); 11540b57cec5SDimitry Andric template <class _Tree> 1155cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(_Tree& __source); 11560b57cec5SDimitry Andric 11570b57cec5SDimitry Andric template <class _NodeHandle> 1158cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&&); 11590b57cec5SDimitry Andric template <class _NodeHandle> 1160cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&); 11610b57cec5SDimitry Andric template <class _Tree> 1162cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Tree& __source); 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric template <class _NodeHandle> 1165cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const&); 11660b57cec5SDimitry Andric template <class _NodeHandle> 1167cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator); 11680b57cec5SDimitry Andric#endif 11690b57cec5SDimitry Andric 117006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); 117106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); 11720b57cec5SDimitry Andric template <class _Key> 117306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k); 11740b57cec5SDimitry Andric template <class _Key> 117506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k); 11760b57cec5SDimitry Andric 1177cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 1178cb14a3feSDimitry Andric __insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT; 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric template <class _Key> 118106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v); 11820b57cec5SDimitry Andric template <class _Key> 118306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const; 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric template <class _Key> 118606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const; 11870b57cec5SDimitry Andric template <class _Key> 118806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const; 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric template <class _Key> 1191cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Key& __v) { 1192cb14a3feSDimitry Andric return __lower_bound(__v, __root(), __end_node()); 1193cb14a3feSDimitry Andric } 11940b57cec5SDimitry Andric template <class _Key> 1195cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __lower_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result); 11960b57cec5SDimitry Andric template <class _Key> 1197cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Key& __v) const { 1198cb14a3feSDimitry Andric return __lower_bound(__v, __root(), __end_node()); 1199cb14a3feSDimitry Andric } 12000b57cec5SDimitry Andric template <class _Key> 1201cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator 1202cb14a3feSDimitry Andric __lower_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) const; 12030b57cec5SDimitry Andric template <class _Key> 1204cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Key& __v) { 1205cb14a3feSDimitry Andric return __upper_bound(__v, __root(), __end_node()); 1206cb14a3feSDimitry Andric } 12070b57cec5SDimitry Andric template <class _Key> 1208cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __upper_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result); 12090b57cec5SDimitry Andric template <class _Key> 1210cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Key& __v) const { 1211cb14a3feSDimitry Andric return __upper_bound(__v, __root(), __end_node()); 1212cb14a3feSDimitry Andric } 12130b57cec5SDimitry Andric template <class _Key> 1214cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator 1215cb14a3feSDimitry Andric __upper_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) const; 12160b57cec5SDimitry Andric template <class _Key> 1217cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_unique(const _Key& __k); 12180b57cec5SDimitry Andric template <class _Key> 1219cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_unique(const _Key& __k) const; 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric template <class _Key> 1222cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_multi(const _Key& __k); 12230b57cec5SDimitry Andric template <class _Key> 1224cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const; 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric typedef __tree_node_destructor<__node_allocator> _Dp; 12270b57cec5SDimitry Andric typedef unique_ptr<__node, _Dp> __node_holder; 12280b57cec5SDimitry Andric 122906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT; 1230cb14a3feSDimitry Andric 12310b57cec5SDimitry Andricprivate: 123206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_low(__parent_pointer& __parent, const key_type& __v); 123306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_high(__parent_pointer& __parent, const key_type& __v); 123406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_base_pointer& 123506c3fb27SDimitry Andric __find_leaf(const_iterator __hint, __parent_pointer& __parent, const key_type& __v); 1236e8d8bef9SDimitry Andric // FIXME: Make this function const qualified. Unfortunately doing so 12370b57cec5SDimitry Andric // breaks existing code which uses non-const callable comparators. 12380b57cec5SDimitry Andric template <class _Key> 123906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__parent_pointer& __parent, const _Key& __v); 12400b57cec5SDimitry Andric template <class _Key> 1241cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__parent_pointer& __parent, const _Key& __v) const { 12420b57cec5SDimitry Andric return const_cast<__tree*>(this)->__find_equal(__parent, __v); 12430b57cec5SDimitry Andric } 12440b57cec5SDimitry Andric template <class _Key> 124506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_base_pointer& 1246cb14a3feSDimitry Andric __find_equal(const_iterator __hint, __parent_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v); 12470b57cec5SDimitry Andric 12480b57cec5SDimitry Andric template <class... _Args> 124906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args); 12500b57cec5SDimitry Andric 125106c3fb27SDimitry Andric // TODO: Make this _LIBCPP_HIDE_FROM_ABI 125206c3fb27SDimitry Andric _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT; 12530b57cec5SDimitry Andric 1254cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t) { 1255cb14a3feSDimitry Andric __copy_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>()); 1256cb14a3feSDimitry Andric } 12570b57cec5SDimitry Andric 1258cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t, true_type) { 12590b57cec5SDimitry Andric if (__node_alloc() != __t.__node_alloc()) 12600b57cec5SDimitry Andric clear(); 12610b57cec5SDimitry Andric __node_alloc() = __t.__node_alloc(); 12620b57cec5SDimitry Andric } 1263cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree&, false_type) {} 12640b57cec5SDimitry Andric 126506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type); 1266cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type) _NOEXCEPT_( 1267cb14a3feSDimitry Andric is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value); 12680b57cec5SDimitry Andric 1269cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t) 1270cb14a3feSDimitry Andric _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || 1271cb14a3feSDimitry Andric is_nothrow_move_assignable<__node_allocator>::value) { 1272cb14a3feSDimitry Andric __move_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>()); 1273cb14a3feSDimitry Andric } 12740b57cec5SDimitry Andric 1275cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t, true_type) 1276cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) { 1277cb14a3feSDimitry Andric __node_alloc() = std::move(__t.__node_alloc()); 1278cb14a3feSDimitry Andric } 1279cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {} 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric struct _DetachedTreeCache { 1282cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache(__tree* __t) _NOEXCEPT 1283cb14a3feSDimitry Andric : __t_(__t), 12840b57cec5SDimitry Andric __cache_root_(__detach_from_tree(__t)) { 12850b57cec5SDimitry Andric __advance(); 12860b57cec5SDimitry Andric } 12870b57cec5SDimitry Andric 1288cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_pointer __get() const _NOEXCEPT { return __cache_elem_; } 12890b57cec5SDimitry Andric 1290cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __advance() _NOEXCEPT { 12910b57cec5SDimitry Andric __cache_elem_ = __cache_root_; 12920b57cec5SDimitry Andric if (__cache_root_) { 12930b57cec5SDimitry Andric __cache_root_ = __detach_next(__cache_root_); 12940b57cec5SDimitry Andric } 12950b57cec5SDimitry Andric } 12960b57cec5SDimitry Andric 1297cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~_DetachedTreeCache() { 12980b57cec5SDimitry Andric __t_->destroy(__cache_elem_); 12990b57cec5SDimitry Andric if (__cache_root_) { 13000b57cec5SDimitry Andric while (__cache_root_->__parent_ != nullptr) 13010b57cec5SDimitry Andric __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_); 13020b57cec5SDimitry Andric __t_->destroy(__cache_root_); 13030b57cec5SDimitry Andric } 13040b57cec5SDimitry Andric } 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andric _DetachedTreeCache(_DetachedTreeCache const&) = delete; 13070b57cec5SDimitry Andric _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete; 13080b57cec5SDimitry Andric 13090b57cec5SDimitry Andric private: 1310cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_from_tree(__tree* __t) _NOEXCEPT; 1311cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_next(__node_pointer) _NOEXCEPT; 13120b57cec5SDimitry Andric 13130b57cec5SDimitry Andric __tree* __t_; 13140b57cec5SDimitry Andric __node_pointer __cache_root_; 13150b57cec5SDimitry Andric __node_pointer __cache_elem_; 13160b57cec5SDimitry Andric }; 13170b57cec5SDimitry Andric 1318cb14a3feSDimitry Andric template <class, class, class, class> 1319cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS map; 1320cb14a3feSDimitry Andric template <class, class, class, class> 1321cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS multimap; 13220b57cec5SDimitry Andric}; 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1325cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) _NOEXCEPT_( 1326cb14a3feSDimitry Andric is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value) 1327cb14a3feSDimitry Andric : __pair3_(0, __comp) { 13280b57cec5SDimitry Andric __begin_node() = __end_node(); 13290b57cec5SDimitry Andric} 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 13320b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) 13330b57cec5SDimitry Andric : __begin_node_(__iter_pointer()), 1334480093f4SDimitry Andric __pair1_(__default_init_tag(), __node_allocator(__a)), 1335cb14a3feSDimitry Andric __pair3_(0, __default_init_tag()) { 13360b57cec5SDimitry Andric __begin_node() = __end_node(); 13370b57cec5SDimitry Andric} 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1340cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, const allocator_type& __a) 1341cb14a3feSDimitry Andric : __begin_node_(__iter_pointer()), __pair1_(__default_init_tag(), __node_allocator(__a)), __pair3_(0, __comp) { 13420b57cec5SDimitry Andric __begin_node() = __end_node(); 13430b57cec5SDimitry Andric} 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric// Precondition: size() != 0 13460b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 13470b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_pointer 1348cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree* __t) _NOEXCEPT { 13490b57cec5SDimitry Andric __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node()); 13500b57cec5SDimitry Andric __t->__begin_node() = __t->__end_node(); 13510b57cec5SDimitry Andric __t->__end_node()->__left_->__parent_ = nullptr; 13520b57cec5SDimitry Andric __t->__end_node()->__left_ = nullptr; 13530b57cec5SDimitry Andric __t->size() = 0; 13540b57cec5SDimitry Andric // __cache->__left_ == nullptr 13550b57cec5SDimitry Andric if (__cache->__right_ != nullptr) 13560b57cec5SDimitry Andric __cache = static_cast<__node_pointer>(__cache->__right_); 13570b57cec5SDimitry Andric // __cache->__left_ == nullptr 13580b57cec5SDimitry Andric // __cache->__right_ == nullptr 13590b57cec5SDimitry Andric return __cache; 13600b57cec5SDimitry Andric} 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andric// Precondition: __cache != nullptr 13630b57cec5SDimitry Andric// __cache->left_ == nullptr 13640b57cec5SDimitry Andric// __cache->right_ == nullptr 13650b57cec5SDimitry Andric// This is no longer a red-black tree 13660b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 13670b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_pointer 1368cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT { 13690b57cec5SDimitry Andric if (__cache->__parent_ == nullptr) 13700b57cec5SDimitry Andric return nullptr; 1371cb14a3feSDimitry Andric if (std::__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) { 13720b57cec5SDimitry Andric __cache->__parent_->__left_ = nullptr; 13730b57cec5SDimitry Andric __cache = static_cast<__node_pointer>(__cache->__parent_); 13740b57cec5SDimitry Andric if (__cache->__right_ == nullptr) 13750b57cec5SDimitry Andric return __cache; 13765f757f3fSDimitry Andric return static_cast<__node_pointer>(std::__tree_leaf(__cache->__right_)); 13770b57cec5SDimitry Andric } 13780b57cec5SDimitry Andric // __cache is right child 13790b57cec5SDimitry Andric __cache->__parent_unsafe()->__right_ = nullptr; 13800b57cec5SDimitry Andric __cache = static_cast<__node_pointer>(__cache->__parent_); 13810b57cec5SDimitry Andric if (__cache->__left_ == nullptr) 13820b57cec5SDimitry Andric return __cache; 13835f757f3fSDimitry Andric return static_cast<__node_pointer>(std::__tree_leaf(__cache->__left_)); 13840b57cec5SDimitry Andric} 13850b57cec5SDimitry Andric 13860b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1387cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) { 1388cb14a3feSDimitry Andric if (this != std::addressof(__t)) { 13890b57cec5SDimitry Andric value_comp() = __t.value_comp(); 13900b57cec5SDimitry Andric __copy_assign_alloc(__t); 13910b57cec5SDimitry Andric __assign_multi(__t.begin(), __t.end()); 13920b57cec5SDimitry Andric } 13930b57cec5SDimitry Andric return *this; 13940b57cec5SDimitry Andric} 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 13970b57cec5SDimitry Andrictemplate <class _ForwardIterator> 1398cb14a3feSDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last) { 13990b57cec5SDimitry Andric typedef iterator_traits<_ForwardIterator> _ITraits; 14000b57cec5SDimitry Andric typedef typename _ITraits::value_type _ItValueType; 1401*0fca6ea1SDimitry Andric static_assert(is_same<_ItValueType, __container_value_type>::value, 14020b57cec5SDimitry Andric "__assign_unique may only be called with the containers value type"); 1403cb14a3feSDimitry Andric static_assert( 1404cb14a3feSDimitry Andric __has_forward_iterator_category<_ForwardIterator>::value, "__assign_unique requires a forward iterator"); 1405cb14a3feSDimitry Andric if (size() != 0) { 14060b57cec5SDimitry Andric _DetachedTreeCache __cache(this); 14070b57cec5SDimitry Andric for (; __cache.__get() != nullptr && __first != __last; ++__first) { 14080b57cec5SDimitry Andric if (__node_assign_unique(*__first, __cache.__get()).second) 14090b57cec5SDimitry Andric __cache.__advance(); 14100b57cec5SDimitry Andric } 14110b57cec5SDimitry Andric } 14120b57cec5SDimitry Andric for (; __first != __last; ++__first) 14130b57cec5SDimitry Andric __insert_unique(*__first); 14140b57cec5SDimitry Andric} 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 14170b57cec5SDimitry Andrictemplate <class _InputIterator> 1418cb14a3feSDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) { 14190b57cec5SDimitry Andric typedef iterator_traits<_InputIterator> _ITraits; 14200b57cec5SDimitry Andric typedef typename _ITraits::value_type _ItValueType; 1421cb14a3feSDimitry Andric static_assert( 1422cb14a3feSDimitry Andric (is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value), 14230b57cec5SDimitry Andric "__assign_multi may only be called with the containers value type" 14240b57cec5SDimitry Andric " or the nodes value type"); 1425cb14a3feSDimitry Andric if (size() != 0) { 14260b57cec5SDimitry Andric _DetachedTreeCache __cache(this); 14270b57cec5SDimitry Andric for (; __cache.__get() && __first != __last; ++__first) { 14280b57cec5SDimitry Andric __cache.__get()->__value_ = *__first; 14290b57cec5SDimitry Andric __node_insert_multi(__cache.__get()); 14300b57cec5SDimitry Andric __cache.__advance(); 14310b57cec5SDimitry Andric } 14320b57cec5SDimitry Andric } 14330b57cec5SDimitry Andric for (; __first != __last; ++__first) 14340b57cec5SDimitry Andric __insert_multi(_NodeTypes::__get_value(*__first)); 14350b57cec5SDimitry Andric} 14360b57cec5SDimitry Andric 14370b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 14380b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) 14390b57cec5SDimitry Andric : __begin_node_(__iter_pointer()), 1440480093f4SDimitry Andric __pair1_(__default_init_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())), 1441cb14a3feSDimitry Andric __pair3_(0, __t.value_comp()) { 14420b57cec5SDimitry Andric __begin_node() = __end_node(); 14430b57cec5SDimitry Andric} 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1446cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_( 1447cb14a3feSDimitry Andric is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value) 14485f757f3fSDimitry Andric : __begin_node_(std::move(__t.__begin_node_)), 14495f757f3fSDimitry Andric __pair1_(std::move(__t.__pair1_)), 1450cb14a3feSDimitry Andric __pair3_(std::move(__t.__pair3_)) { 14510b57cec5SDimitry Andric if (size() == 0) 14520b57cec5SDimitry Andric __begin_node() = __end_node(); 1453cb14a3feSDimitry Andric else { 14540b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 14550b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 14560b57cec5SDimitry Andric __t.__end_node()->__left_ = nullptr; 14570b57cec5SDimitry Andric __t.size() = 0; 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric} 14600b57cec5SDimitry Andric 14610b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 14620b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) 1463cb14a3feSDimitry Andric : __pair1_(__default_init_tag(), __node_allocator(__a)), __pair3_(0, std::move(__t.value_comp())) { 1464cb14a3feSDimitry Andric if (__a == __t.__alloc()) { 14650b57cec5SDimitry Andric if (__t.size() == 0) 14660b57cec5SDimitry Andric __begin_node() = __end_node(); 1467cb14a3feSDimitry Andric else { 14680b57cec5SDimitry Andric __begin_node() = __t.__begin_node(); 14690b57cec5SDimitry Andric __end_node()->__left_ = __t.__end_node()->__left_; 14700b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 14710b57cec5SDimitry Andric size() = __t.size(); 14720b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 14730b57cec5SDimitry Andric __t.__end_node()->__left_ = nullptr; 14740b57cec5SDimitry Andric __t.size() = 0; 14750b57cec5SDimitry Andric } 1476cb14a3feSDimitry Andric } else { 14770b57cec5SDimitry Andric __begin_node() = __end_node(); 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric} 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1482cb14a3feSDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) 1483cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value) { 14840b57cec5SDimitry Andric destroy(static_cast<__node_pointer>(__end_node()->__left_)); 14850b57cec5SDimitry Andric __begin_node_ = __t.__begin_node_; 14860b57cec5SDimitry Andric __pair1_.first() = __t.__pair1_.first(); 14870b57cec5SDimitry Andric __move_assign_alloc(__t); 14885f757f3fSDimitry Andric __pair3_ = std::move(__t.__pair3_); 14890b57cec5SDimitry Andric if (size() == 0) 14900b57cec5SDimitry Andric __begin_node() = __end_node(); 1491cb14a3feSDimitry Andric else { 14920b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 14930b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 14940b57cec5SDimitry Andric __t.__end_node()->__left_ = nullptr; 14950b57cec5SDimitry Andric __t.size() = 0; 14960b57cec5SDimitry Andric } 14970b57cec5SDimitry Andric} 14980b57cec5SDimitry Andric 14990b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1500cb14a3feSDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) { 15010b57cec5SDimitry Andric if (__node_alloc() == __t.__node_alloc()) 15020b57cec5SDimitry Andric __move_assign(__t, true_type()); 1503cb14a3feSDimitry Andric else { 15045f757f3fSDimitry Andric value_comp() = std::move(__t.value_comp()); 15050b57cec5SDimitry Andric const_iterator __e = end(); 1506cb14a3feSDimitry Andric if (size() != 0) { 15070b57cec5SDimitry Andric _DetachedTreeCache __cache(this); 15080b57cec5SDimitry Andric while (__cache.__get() != nullptr && __t.size() != 0) { 15095f757f3fSDimitry Andric __cache.__get()->__value_ = std::move(__t.remove(__t.begin())->__value_); 15100b57cec5SDimitry Andric __node_insert_multi(__cache.__get()); 15110b57cec5SDimitry Andric __cache.__advance(); 15120b57cec5SDimitry Andric } 15130b57cec5SDimitry Andric } 15140b57cec5SDimitry Andric while (__t.size() != 0) 15150b57cec5SDimitry Andric __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); 15160b57cec5SDimitry Andric } 15170b57cec5SDimitry Andric} 15180b57cec5SDimitry Andric 15190b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1520cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) _NOEXCEPT_( 1521cb14a3feSDimitry Andric __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<value_compare>::value&& 15220b57cec5SDimitry Andric is_nothrow_move_assignable<__node_allocator>::value) 15230b57cec5SDimitry Andric 15240b57cec5SDimitry Andric{ 1525cb14a3feSDimitry Andric __move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>()); 15260b57cec5SDimitry Andric return *this; 15270b57cec5SDimitry Andric} 15280b57cec5SDimitry Andric 15290b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1530cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::~__tree() { 1531*0fca6ea1SDimitry Andric static_assert(is_copy_constructible<value_compare>::value, "Comparator must be copy-constructible."); 15320b57cec5SDimitry Andric destroy(__root()); 15330b57cec5SDimitry Andric} 15340b57cec5SDimitry Andric 15350b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1536cb14a3feSDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT { 1537cb14a3feSDimitry Andric if (__nd != nullptr) { 15380b57cec5SDimitry Andric destroy(static_cast<__node_pointer>(__nd->__left_)); 15390b57cec5SDimitry Andric destroy(static_cast<__node_pointer>(__nd->__right_)); 15400b57cec5SDimitry Andric __node_allocator& __na = __node_alloc(); 15410b57cec5SDimitry Andric __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); 15420b57cec5SDimitry Andric __node_traits::deallocate(__na, __nd, 1); 15430b57cec5SDimitry Andric } 15440b57cec5SDimitry Andric} 15450b57cec5SDimitry Andric 15460b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1547cb14a3feSDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) 15480b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 11 1549*0fca6ea1SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> && 1550*0fca6ea1SDimitry Andric (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)) 15510b57cec5SDimitry Andric#else 1552*0fca6ea1SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>) 15530b57cec5SDimitry Andric#endif 15540b57cec5SDimitry Andric{ 15555f757f3fSDimitry Andric using std::swap; 15560b57cec5SDimitry Andric swap(__begin_node_, __t.__begin_node_); 15570b57cec5SDimitry Andric swap(__pair1_.first(), __t.__pair1_.first()); 15585f757f3fSDimitry Andric std::__swap_allocator(__node_alloc(), __t.__node_alloc()); 15590b57cec5SDimitry Andric __pair3_.swap(__t.__pair3_); 15600b57cec5SDimitry Andric if (size() == 0) 15610b57cec5SDimitry Andric __begin_node() = __end_node(); 15620b57cec5SDimitry Andric else 15630b57cec5SDimitry Andric __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); 15640b57cec5SDimitry Andric if (__t.size() == 0) 15650b57cec5SDimitry Andric __t.__begin_node() = __t.__end_node(); 15660b57cec5SDimitry Andric else 15670b57cec5SDimitry Andric __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node()); 15680b57cec5SDimitry Andric} 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 1571cb14a3feSDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT { 15720b57cec5SDimitry Andric destroy(__root()); 15730b57cec5SDimitry Andric size() = 0; 15740b57cec5SDimitry Andric __begin_node() = __end_node(); 15750b57cec5SDimitry Andric __end_node()->__left_ = nullptr; 15760b57cec5SDimitry Andric} 15770b57cec5SDimitry Andric 15780b57cec5SDimitry Andric// Find lower_bound place to insert 15790b57cec5SDimitry Andric// Set __parent to parent of null leaf 15800b57cec5SDimitry Andric// Return reference to null leaf 15810b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 15820b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1583cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent, const key_type& __v) { 15840b57cec5SDimitry Andric __node_pointer __nd = __root(); 1585cb14a3feSDimitry Andric if (__nd != nullptr) { 1586cb14a3feSDimitry Andric while (true) { 1587cb14a3feSDimitry Andric if (value_comp()(__nd->__value_, __v)) { 15880b57cec5SDimitry Andric if (__nd->__right_ != nullptr) 15890b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__right_); 1590cb14a3feSDimitry Andric else { 15910b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 15920b57cec5SDimitry Andric return __nd->__right_; 15930b57cec5SDimitry Andric } 1594cb14a3feSDimitry Andric } else { 15950b57cec5SDimitry Andric if (__nd->__left_ != nullptr) 15960b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__left_); 1597cb14a3feSDimitry Andric else { 15980b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 15990b57cec5SDimitry Andric return __parent->__left_; 16000b57cec5SDimitry Andric } 16010b57cec5SDimitry Andric } 16020b57cec5SDimitry Andric } 16030b57cec5SDimitry Andric } 16040b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 16050b57cec5SDimitry Andric return __parent->__left_; 16060b57cec5SDimitry Andric} 16070b57cec5SDimitry Andric 16080b57cec5SDimitry Andric// Find upper_bound place to insert 16090b57cec5SDimitry Andric// Set __parent to parent of null leaf 16100b57cec5SDimitry Andric// Return reference to null leaf 16110b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 16120b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1613cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent, const key_type& __v) { 16140b57cec5SDimitry Andric __node_pointer __nd = __root(); 1615cb14a3feSDimitry Andric if (__nd != nullptr) { 1616cb14a3feSDimitry Andric while (true) { 1617cb14a3feSDimitry Andric if (value_comp()(__v, __nd->__value_)) { 16180b57cec5SDimitry Andric if (__nd->__left_ != nullptr) 16190b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__left_); 1620cb14a3feSDimitry Andric else { 16210b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 16220b57cec5SDimitry Andric return __parent->__left_; 16230b57cec5SDimitry Andric } 1624cb14a3feSDimitry Andric } else { 16250b57cec5SDimitry Andric if (__nd->__right_ != nullptr) 16260b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__right_); 1627cb14a3feSDimitry Andric else { 16280b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 16290b57cec5SDimitry Andric return __nd->__right_; 16300b57cec5SDimitry Andric } 16310b57cec5SDimitry Andric } 16320b57cec5SDimitry Andric } 16330b57cec5SDimitry Andric } 16340b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 16350b57cec5SDimitry Andric return __parent->__left_; 16360b57cec5SDimitry Andric} 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric// Find leaf place to insert closest to __hint 16390b57cec5SDimitry Andric// First check prior to __hint. 16400b57cec5SDimitry Andric// Next check after __hint. 16410b57cec5SDimitry Andric// Next do O(log N) search. 16420b57cec5SDimitry Andric// Set __parent to parent of null leaf 16430b57cec5SDimitry Andric// Return reference to null leaf 16440b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 16450b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1646cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, __parent_pointer& __parent, const key_type& __v) { 16470b57cec5SDimitry Andric if (__hint == end() || !value_comp()(*__hint, __v)) // check before 16480b57cec5SDimitry Andric { 16490b57cec5SDimitry Andric // __v <= *__hint 16500b57cec5SDimitry Andric const_iterator __prior = __hint; 1651cb14a3feSDimitry Andric if (__prior == begin() || !value_comp()(__v, *--__prior)) { 16520b57cec5SDimitry Andric // *prev(__hint) <= __v <= *__hint 1653cb14a3feSDimitry Andric if (__hint.__ptr_->__left_ == nullptr) { 16540b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 16550b57cec5SDimitry Andric return __parent->__left_; 1656cb14a3feSDimitry Andric } else { 16570b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__prior.__ptr_); 16580b57cec5SDimitry Andric return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; 16590b57cec5SDimitry Andric } 16600b57cec5SDimitry Andric } 16610b57cec5SDimitry Andric // __v < *prev(__hint) 16620b57cec5SDimitry Andric return __find_leaf_high(__parent, __v); 16630b57cec5SDimitry Andric } 16640b57cec5SDimitry Andric // else __v > *__hint 16650b57cec5SDimitry Andric return __find_leaf_low(__parent, __v); 16660b57cec5SDimitry Andric} 16670b57cec5SDimitry Andric 16680b57cec5SDimitry Andric// Find place to insert if __v doesn't exist 16690b57cec5SDimitry Andric// Set __parent to parent of null leaf 16700b57cec5SDimitry Andric// Return reference to null leaf 16710b57cec5SDimitry Andric// If __v exists, set parent to node of __v and return reference to node of __v 16720b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 16730b57cec5SDimitry Andrictemplate <class _Key> 16740b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& 1675cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent, const _Key& __v) { 16760b57cec5SDimitry Andric __node_pointer __nd = __root(); 16770b57cec5SDimitry Andric __node_base_pointer* __nd_ptr = __root_ptr(); 1678cb14a3feSDimitry Andric if (__nd != nullptr) { 1679cb14a3feSDimitry Andric while (true) { 1680cb14a3feSDimitry Andric if (value_comp()(__v, __nd->__value_)) { 16810b57cec5SDimitry Andric if (__nd->__left_ != nullptr) { 16825f757f3fSDimitry Andric __nd_ptr = std::addressof(__nd->__left_); 16830b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__left_); 16840b57cec5SDimitry Andric } else { 16850b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 16860b57cec5SDimitry Andric return __parent->__left_; 16870b57cec5SDimitry Andric } 1688cb14a3feSDimitry Andric } else if (value_comp()(__nd->__value_, __v)) { 16890b57cec5SDimitry Andric if (__nd->__right_ != nullptr) { 16905f757f3fSDimitry Andric __nd_ptr = std::addressof(__nd->__right_); 16910b57cec5SDimitry Andric __nd = static_cast<__node_pointer>(__nd->__right_); 16920b57cec5SDimitry Andric } else { 16930b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 16940b57cec5SDimitry Andric return __nd->__right_; 16950b57cec5SDimitry Andric } 1696cb14a3feSDimitry Andric } else { 16970b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__nd); 16980b57cec5SDimitry Andric return *__nd_ptr; 16990b57cec5SDimitry Andric } 17000b57cec5SDimitry Andric } 17010b57cec5SDimitry Andric } 17020b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__end_node()); 17030b57cec5SDimitry Andric return __parent->__left_; 17040b57cec5SDimitry Andric} 17050b57cec5SDimitry Andric 17060b57cec5SDimitry Andric// Find place to insert if __v doesn't exist 17070b57cec5SDimitry Andric// First check prior to __hint. 17080b57cec5SDimitry Andric// Next check after __hint. 17090b57cec5SDimitry Andric// Next do O(log N) search. 17100b57cec5SDimitry Andric// Set __parent to parent of null leaf 17110b57cec5SDimitry Andric// Return reference to null leaf 17120b57cec5SDimitry Andric// If __v exists, set parent to node of __v and return reference to node of __v 17130b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 17140b57cec5SDimitry Andrictemplate <class _Key> 1715cb14a3feSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal( 1716cb14a3feSDimitry Andric const_iterator __hint, __parent_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v) { 17170b57cec5SDimitry Andric if (__hint == end() || value_comp()(__v, *__hint)) // check before 17180b57cec5SDimitry Andric { 17190b57cec5SDimitry Andric // __v < *__hint 17200b57cec5SDimitry Andric const_iterator __prior = __hint; 1721cb14a3feSDimitry Andric if (__prior == begin() || value_comp()(*--__prior, __v)) { 17220b57cec5SDimitry Andric // *prev(__hint) < __v < *__hint 1723cb14a3feSDimitry Andric if (__hint.__ptr_->__left_ == nullptr) { 17240b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 17250b57cec5SDimitry Andric return __parent->__left_; 1726cb14a3feSDimitry Andric } else { 17270b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__prior.__ptr_); 17280b57cec5SDimitry Andric return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; 17290b57cec5SDimitry Andric } 17300b57cec5SDimitry Andric } 17310b57cec5SDimitry Andric // __v <= *prev(__hint) 17320b57cec5SDimitry Andric return __find_equal(__parent, __v); 1733cb14a3feSDimitry Andric } else if (value_comp()(*__hint, __v)) // check after 17340b57cec5SDimitry Andric { 17350b57cec5SDimitry Andric // *__hint < __v 17365f757f3fSDimitry Andric const_iterator __next = std::next(__hint); 1737cb14a3feSDimitry Andric if (__next == end() || value_comp()(__v, *__next)) { 17385f757f3fSDimitry Andric // *__hint < __v < *std::next(__hint) 1739cb14a3feSDimitry Andric if (__hint.__get_np()->__right_ == nullptr) { 17400b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 17410b57cec5SDimitry Andric return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_; 1742cb14a3feSDimitry Andric } else { 17430b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__next.__ptr_); 17440b57cec5SDimitry Andric return __parent->__left_; 17450b57cec5SDimitry Andric } 17460b57cec5SDimitry Andric } 17470b57cec5SDimitry Andric // *next(__hint) <= __v 17480b57cec5SDimitry Andric return __find_equal(__parent, __v); 17490b57cec5SDimitry Andric } 17500b57cec5SDimitry Andric // else __v == *__hint 17510b57cec5SDimitry Andric __parent = static_cast<__parent_pointer>(__hint.__ptr_); 17520b57cec5SDimitry Andric __dummy = static_cast<__node_base_pointer>(__hint.__ptr_); 17530b57cec5SDimitry Andric return __dummy; 17540b57cec5SDimitry Andric} 17550b57cec5SDimitry Andric 17560b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 17570b57cec5SDimitry Andricvoid __tree<_Tp, _Compare, _Allocator>::__insert_node_at( 1758cb14a3feSDimitry Andric __parent_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT { 17590b57cec5SDimitry Andric __new_node->__left_ = nullptr; 17600b57cec5SDimitry Andric __new_node->__right_ = nullptr; 17610b57cec5SDimitry Andric __new_node->__parent_ = __parent; 17620b57cec5SDimitry Andric // __new_node->__is_black_ is initialized in __tree_balance_after_insert 17630b57cec5SDimitry Andric __child = __new_node; 17640b57cec5SDimitry Andric if (__begin_node()->__left_ != nullptr) 17650b57cec5SDimitry Andric __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_); 17665f757f3fSDimitry Andric std::__tree_balance_after_insert(__end_node()->__left_, __child); 17670b57cec5SDimitry Andric ++size(); 17680b57cec5SDimitry Andric} 17690b57cec5SDimitry Andric 17700b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 17710b57cec5SDimitry Andrictemplate <class _Key, class... _Args> 17720b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 1773cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) { 17740b57cec5SDimitry Andric __parent_pointer __parent; 17750b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, __k); 17760b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 17770b57cec5SDimitry Andric bool __inserted = false; 1778cb14a3feSDimitry Andric if (__child == nullptr) { 17795f757f3fSDimitry Andric __node_holder __h = __construct_node(std::forward<_Args>(__args)...); 17800b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 17810b57cec5SDimitry Andric __r = __h.release(); 17820b57cec5SDimitry Andric __inserted = true; 17830b57cec5SDimitry Andric } 17840b57cec5SDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 17850b57cec5SDimitry Andric} 17860b57cec5SDimitry Andric 17870b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 17880b57cec5SDimitry Andrictemplate <class _Key, class... _Args> 1789e8d8bef9SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 17900b57cec5SDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( 1791cb14a3feSDimitry Andric const_iterator __p, _Key const& __k, _Args&&... __args) { 17920b57cec5SDimitry Andric __parent_pointer __parent; 17930b57cec5SDimitry Andric __node_base_pointer __dummy; 17940b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k); 17950b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 1796e8d8bef9SDimitry Andric bool __inserted = false; 1797cb14a3feSDimitry Andric if (__child == nullptr) { 17985f757f3fSDimitry Andric __node_holder __h = __construct_node(std::forward<_Args>(__args)...); 17990b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 18000b57cec5SDimitry Andric __r = __h.release(); 1801e8d8bef9SDimitry Andric __inserted = true; 18020b57cec5SDimitry Andric } 1803e8d8bef9SDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 18040b57cec5SDimitry Andric} 18050b57cec5SDimitry Andric 18060b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18070b57cec5SDimitry Andrictemplate <class... _Args> 18080b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_holder 1809cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) { 1810cb14a3feSDimitry Andric static_assert(!__is_tree_value_type<_Args...>::value, "Cannot construct from __value_type"); 18110b57cec5SDimitry Andric __node_allocator& __na = __node_alloc(); 18120b57cec5SDimitry Andric __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 18135f757f3fSDimitry Andric __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), std::forward<_Args>(__args)...); 18140b57cec5SDimitry Andric __h.get_deleter().__value_constructed = true; 18150b57cec5SDimitry Andric return __h; 18160b57cec5SDimitry Andric} 18170b57cec5SDimitry Andric 18180b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18190b57cec5SDimitry Andrictemplate <class... _Args> 18200b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 1821cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) { 18225f757f3fSDimitry Andric __node_holder __h = __construct_node(std::forward<_Args>(__args)...); 18230b57cec5SDimitry Andric __parent_pointer __parent; 18240b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, __h->__value_); 18250b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 18260b57cec5SDimitry Andric bool __inserted = false; 1827cb14a3feSDimitry Andric if (__child == nullptr) { 18280b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 18290b57cec5SDimitry Andric __r = __h.release(); 18300b57cec5SDimitry Andric __inserted = true; 18310b57cec5SDimitry Andric } 18320b57cec5SDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 18330b57cec5SDimitry Andric} 18340b57cec5SDimitry Andric 18350b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18360b57cec5SDimitry Andrictemplate <class... _Args> 18370b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 1838cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) { 18395f757f3fSDimitry Andric __node_holder __h = __construct_node(std::forward<_Args>(__args)...); 18400b57cec5SDimitry Andric __parent_pointer __parent; 18410b57cec5SDimitry Andric __node_base_pointer __dummy; 18420b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_); 18430b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 1844cb14a3feSDimitry Andric if (__child == nullptr) { 18450b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 18460b57cec5SDimitry Andric __r = __h.release(); 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric return iterator(__r); 18490b57cec5SDimitry Andric} 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18520b57cec5SDimitry Andrictemplate <class... _Args> 18530b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 1854cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) { 18555f757f3fSDimitry Andric __node_holder __h = __construct_node(std::forward<_Args>(__args)...); 18560b57cec5SDimitry Andric __parent_pointer __parent; 18570b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_)); 18580b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 18590b57cec5SDimitry Andric return iterator(static_cast<__node_pointer>(__h.release())); 18600b57cec5SDimitry Andric} 18610b57cec5SDimitry Andric 18620b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18630b57cec5SDimitry Andrictemplate <class... _Args> 18640b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 1865cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) { 18665f757f3fSDimitry Andric __node_holder __h = __construct_node(std::forward<_Args>(__args)...); 18670b57cec5SDimitry Andric __parent_pointer __parent; 18680b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_)); 18690b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 18700b57cec5SDimitry Andric return iterator(static_cast<__node_pointer>(__h.release())); 18710b57cec5SDimitry Andric} 18720b57cec5SDimitry Andric 18730b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18740b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> 1875cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_type& __v, __node_pointer __nd) { 18760b57cec5SDimitry Andric __parent_pointer __parent; 18770b57cec5SDimitry Andric __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__v)); 18780b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 18790b57cec5SDimitry Andric bool __inserted = false; 1880cb14a3feSDimitry Andric if (__child == nullptr) { 18810b57cec5SDimitry Andric __nd->__value_ = __v; 18820b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 18830b57cec5SDimitry Andric __r = __nd; 18840b57cec5SDimitry Andric __inserted = true; 18850b57cec5SDimitry Andric } 18860b57cec5SDimitry Andric return pair<iterator, bool>(iterator(__r), __inserted); 18870b57cec5SDimitry Andric} 18880b57cec5SDimitry Andric 18890b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18900b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 1891cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) { 18920b57cec5SDimitry Andric __parent_pointer __parent; 18930b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_)); 18940b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 18950b57cec5SDimitry Andric return iterator(__nd); 18960b57cec5SDimitry Andric} 18970b57cec5SDimitry Andric 18980b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 18990b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 1900cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) { 19010b57cec5SDimitry Andric __parent_pointer __parent; 19020b57cec5SDimitry Andric __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_)); 19030b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); 19040b57cec5SDimitry Andric return iterator(__nd); 19050b57cec5SDimitry Andric} 19060b57cec5SDimitry Andric 19070b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 19080b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 1909cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT { 19100b57cec5SDimitry Andric iterator __r(__ptr); 19110b57cec5SDimitry Andric ++__r; 19120b57cec5SDimitry Andric if (__begin_node() == __ptr) 19130b57cec5SDimitry Andric __begin_node() = __r.__ptr_; 19140b57cec5SDimitry Andric --size(); 1915cb14a3feSDimitry Andric std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__ptr)); 19160b57cec5SDimitry Andric return __r; 19170b57cec5SDimitry Andric} 19180b57cec5SDimitry Andric 191906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 19200b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 19210b57cec5SDimitry Andrictemplate <class _NodeHandle, class _InsertReturnType> 1922cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _InsertReturnType 1923cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __nh) { 19240b57cec5SDimitry Andric if (__nh.empty()) 19250b57cec5SDimitry Andric return _InsertReturnType{end(), false, _NodeHandle()}; 19260b57cec5SDimitry Andric 19270b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 19280b57cec5SDimitry Andric __parent_pointer __parent; 1929cb14a3feSDimitry Andric __node_base_pointer& __child = __find_equal(__parent, __ptr->__value_); 19300b57cec5SDimitry Andric if (__child != nullptr) 1931cb14a3feSDimitry Andric return _InsertReturnType{iterator(static_cast<__node_pointer>(__child)), false, std::move(__nh)}; 19320b57cec5SDimitry Andric 1933cb14a3feSDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 19340b57cec5SDimitry Andric __nh.__release_ptr(); 19350b57cec5SDimitry Andric return _InsertReturnType{iterator(__ptr), true, _NodeHandle()}; 19360b57cec5SDimitry Andric} 19370b57cec5SDimitry Andric 19380b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 19390b57cec5SDimitry Andrictemplate <class _NodeHandle> 1940cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator 1941cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __hint, _NodeHandle&& __nh) { 19420b57cec5SDimitry Andric if (__nh.empty()) 19430b57cec5SDimitry Andric return end(); 19440b57cec5SDimitry Andric 19450b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 19460b57cec5SDimitry Andric __parent_pointer __parent; 19470b57cec5SDimitry Andric __node_base_pointer __dummy; 1948cb14a3feSDimitry Andric __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, __ptr->__value_); 19490b57cec5SDimitry Andric __node_pointer __r = static_cast<__node_pointer>(__child); 1950cb14a3feSDimitry Andric if (__child == nullptr) { 1951cb14a3feSDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 19520b57cec5SDimitry Andric __r = __ptr; 19530b57cec5SDimitry Andric __nh.__release_ptr(); 19540b57cec5SDimitry Andric } 19550b57cec5SDimitry Andric return iterator(__r); 19560b57cec5SDimitry Andric} 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 19590b57cec5SDimitry Andrictemplate <class _NodeHandle> 1960cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) { 19610b57cec5SDimitry Andric iterator __it = find(__key); 19620b57cec5SDimitry Andric if (__it == end()) 19630b57cec5SDimitry Andric return _NodeHandle(); 19640b57cec5SDimitry Andric return __node_handle_extract<_NodeHandle>(__it); 19650b57cec5SDimitry Andric} 19660b57cec5SDimitry Andric 19670b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 19680b57cec5SDimitry Andrictemplate <class _NodeHandle> 1969cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) { 19700b57cec5SDimitry Andric __node_pointer __np = __p.__get_np(); 19710b57cec5SDimitry Andric __remove_node_pointer(__np); 19720b57cec5SDimitry Andric return _NodeHandle(__np, __alloc()); 19730b57cec5SDimitry Andric} 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 19760b57cec5SDimitry Andrictemplate <class _Tree> 1977cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) { 19780b57cec5SDimitry Andric static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); 19790b57cec5SDimitry Andric 1980cb14a3feSDimitry Andric for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) { 19810b57cec5SDimitry Andric __node_pointer __src_ptr = __i.__get_np(); 19820b57cec5SDimitry Andric __parent_pointer __parent; 1983cb14a3feSDimitry Andric __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_)); 19840b57cec5SDimitry Andric ++__i; 19850b57cec5SDimitry Andric if (__child != nullptr) 19860b57cec5SDimitry Andric continue; 19870b57cec5SDimitry Andric __source.__remove_node_pointer(__src_ptr); 1988cb14a3feSDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr)); 19890b57cec5SDimitry Andric } 19900b57cec5SDimitry Andric} 19910b57cec5SDimitry Andric 19920b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 19930b57cec5SDimitry Andrictemplate <class _NodeHandle> 1994cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator 1995cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh) { 19960b57cec5SDimitry Andric if (__nh.empty()) 19970b57cec5SDimitry Andric return end(); 19980b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 19990b57cec5SDimitry Andric __parent_pointer __parent; 2000cb14a3feSDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__ptr->__value_)); 20010b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 20020b57cec5SDimitry Andric __nh.__release_ptr(); 20030b57cec5SDimitry Andric return iterator(__ptr); 20040b57cec5SDimitry Andric} 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20070b57cec5SDimitry Andrictemplate <class _NodeHandle> 2008cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator 2009cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh) { 20100b57cec5SDimitry Andric if (__nh.empty()) 20110b57cec5SDimitry Andric return end(); 20120b57cec5SDimitry Andric 20130b57cec5SDimitry Andric __node_pointer __ptr = __nh.__ptr_; 20140b57cec5SDimitry Andric __parent_pointer __parent; 2015cb14a3feSDimitry Andric __node_base_pointer& __child = __find_leaf(__hint, __parent, _NodeTypes::__get_key(__ptr->__value_)); 20160b57cec5SDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); 20170b57cec5SDimitry Andric __nh.__release_ptr(); 20180b57cec5SDimitry Andric return iterator(__ptr); 20190b57cec5SDimitry Andric} 20200b57cec5SDimitry Andric 20210b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20220b57cec5SDimitry Andrictemplate <class _Tree> 2023cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) { 20240b57cec5SDimitry Andric static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); 20250b57cec5SDimitry Andric 2026cb14a3feSDimitry Andric for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) { 20270b57cec5SDimitry Andric __node_pointer __src_ptr = __i.__get_np(); 20280b57cec5SDimitry Andric __parent_pointer __parent; 2029cb14a3feSDimitry Andric __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__src_ptr->__value_)); 20300b57cec5SDimitry Andric ++__i; 20310b57cec5SDimitry Andric __source.__remove_node_pointer(__src_ptr); 2032cb14a3feSDimitry Andric __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr)); 20330b57cec5SDimitry Andric } 20340b57cec5SDimitry Andric} 20350b57cec5SDimitry Andric 203606c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 17 20370b57cec5SDimitry Andric 20380b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2039cb14a3feSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) { 20400b57cec5SDimitry Andric __node_pointer __np = __p.__get_np(); 20410b57cec5SDimitry Andric iterator __r = __remove_node_pointer(__np); 20420b57cec5SDimitry Andric __node_allocator& __na = __node_alloc(); 2043cb14a3feSDimitry Andric __node_traits::destroy(__na, _NodeTypes::__get_ptr(const_cast<__node_value_type&>(*__p))); 20440b57cec5SDimitry Andric __node_traits::deallocate(__na, __np, 1); 20450b57cec5SDimitry Andric return __r; 20460b57cec5SDimitry Andric} 20470b57cec5SDimitry Andric 20480b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20490b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2050cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) { 20510b57cec5SDimitry Andric while (__f != __l) 20520b57cec5SDimitry Andric __f = erase(__f); 20530b57cec5SDimitry Andric return iterator(__l.__ptr_); 20540b57cec5SDimitry Andric} 20550b57cec5SDimitry Andric 20560b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20570b57cec5SDimitry Andrictemplate <class _Key> 20580b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2059cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) { 20600b57cec5SDimitry Andric iterator __i = find(__k); 20610b57cec5SDimitry Andric if (__i == end()) 20620b57cec5SDimitry Andric return 0; 20630b57cec5SDimitry Andric erase(__i); 20640b57cec5SDimitry Andric return 1; 20650b57cec5SDimitry Andric} 20660b57cec5SDimitry Andric 20670b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20680b57cec5SDimitry Andrictemplate <class _Key> 20690b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2070cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) { 20710b57cec5SDimitry Andric pair<iterator, iterator> __p = __equal_range_multi(__k); 20720b57cec5SDimitry Andric size_type __r = 0; 20730b57cec5SDimitry Andric for (; __p.first != __p.second; ++__r) 20740b57cec5SDimitry Andric __p.first = erase(__p.first); 20750b57cec5SDimitry Andric return __r; 20760b57cec5SDimitry Andric} 20770b57cec5SDimitry Andric 20780b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20790b57cec5SDimitry Andrictemplate <class _Key> 2080cb14a3feSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) { 20810b57cec5SDimitry Andric iterator __p = __lower_bound(__v, __root(), __end_node()); 20820b57cec5SDimitry Andric if (__p != end() && !value_comp()(__v, *__p)) 20830b57cec5SDimitry Andric return __p; 20840b57cec5SDimitry Andric return end(); 20850b57cec5SDimitry Andric} 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20880b57cec5SDimitry Andrictemplate <class _Key> 20890b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::const_iterator 2090cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const { 20910b57cec5SDimitry Andric const_iterator __p = __lower_bound(__v, __root(), __end_node()); 20920b57cec5SDimitry Andric if (__p != end() && !value_comp()(__v, *__p)) 20930b57cec5SDimitry Andric return __p; 20940b57cec5SDimitry Andric return end(); 20950b57cec5SDimitry Andric} 20960b57cec5SDimitry Andric 20970b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 20980b57cec5SDimitry Andrictemplate <class _Key> 20990b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2100cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const { 21010b57cec5SDimitry Andric __node_pointer __rt = __root(); 2102cb14a3feSDimitry Andric while (__rt != nullptr) { 2103cb14a3feSDimitry Andric if (value_comp()(__k, __rt->__value_)) { 21040b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2105cb14a3feSDimitry Andric } else if (value_comp()(__rt->__value_, __k)) 21060b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 21070b57cec5SDimitry Andric else 21080b57cec5SDimitry Andric return 1; 21090b57cec5SDimitry Andric } 21100b57cec5SDimitry Andric return 0; 21110b57cec5SDimitry Andric} 21120b57cec5SDimitry Andric 21130b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21140b57cec5SDimitry Andrictemplate <class _Key> 21150b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::size_type 2116cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const { 21170b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 21180b57cec5SDimitry Andric __node_pointer __rt = __root(); 2119cb14a3feSDimitry Andric while (__rt != nullptr) { 2120cb14a3feSDimitry Andric if (value_comp()(__k, __rt->__value_)) { 21210b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 21220b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2123cb14a3feSDimitry Andric } else if (value_comp()(__rt->__value_, __k)) 21240b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 21250b57cec5SDimitry Andric else 21265f757f3fSDimitry Andric return std::distance( 21270b57cec5SDimitry Andric __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 2128cb14a3feSDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); 21290b57cec5SDimitry Andric } 21300b57cec5SDimitry Andric return 0; 21310b57cec5SDimitry Andric} 21320b57cec5SDimitry Andric 21330b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21340b57cec5SDimitry Andrictemplate <class _Key> 21350b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2136cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) { 2137cb14a3feSDimitry Andric while (__root != nullptr) { 2138cb14a3feSDimitry Andric if (!value_comp()(__root->__value_, __v)) { 21390b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 21400b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2141cb14a3feSDimitry Andric } else 21420b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 21430b57cec5SDimitry Andric } 21440b57cec5SDimitry Andric return iterator(__result); 21450b57cec5SDimitry Andric} 21460b57cec5SDimitry Andric 21470b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21480b57cec5SDimitry Andrictemplate <class _Key> 2149cb14a3feSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound( 2150cb14a3feSDimitry Andric const _Key& __v, __node_pointer __root, __iter_pointer __result) const { 2151cb14a3feSDimitry Andric while (__root != nullptr) { 2152cb14a3feSDimitry Andric if (!value_comp()(__root->__value_, __v)) { 21530b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 21540b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2155cb14a3feSDimitry Andric } else 21560b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 21570b57cec5SDimitry Andric } 21580b57cec5SDimitry Andric return const_iterator(__result); 21590b57cec5SDimitry Andric} 21600b57cec5SDimitry Andric 21610b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21620b57cec5SDimitry Andrictemplate <class _Key> 21630b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::iterator 2164cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) { 2165cb14a3feSDimitry Andric while (__root != nullptr) { 2166cb14a3feSDimitry Andric if (value_comp()(__v, __root->__value_)) { 21670b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 21680b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2169cb14a3feSDimitry Andric } else 21700b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 21710b57cec5SDimitry Andric } 21720b57cec5SDimitry Andric return iterator(__result); 21730b57cec5SDimitry Andric} 21740b57cec5SDimitry Andric 21750b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21760b57cec5SDimitry Andrictemplate <class _Key> 2177cb14a3feSDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound( 2178cb14a3feSDimitry Andric const _Key& __v, __node_pointer __root, __iter_pointer __result) const { 2179cb14a3feSDimitry Andric while (__root != nullptr) { 2180cb14a3feSDimitry Andric if (value_comp()(__v, __root->__value_)) { 21810b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__root); 21820b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__left_); 2183cb14a3feSDimitry Andric } else 21840b57cec5SDimitry Andric __root = static_cast<__node_pointer>(__root->__right_); 21850b57cec5SDimitry Andric } 21860b57cec5SDimitry Andric return const_iterator(__result); 21870b57cec5SDimitry Andric} 21880b57cec5SDimitry Andric 21890b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 21900b57cec5SDimitry Andrictemplate <class _Key> 2191cb14a3feSDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator> 2192cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) { 21930b57cec5SDimitry Andric typedef pair<iterator, iterator> _Pp; 21940b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 21950b57cec5SDimitry Andric __node_pointer __rt = __root(); 2196cb14a3feSDimitry Andric while (__rt != nullptr) { 2197cb14a3feSDimitry Andric if (value_comp()(__k, __rt->__value_)) { 21980b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 21990b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2200cb14a3feSDimitry Andric } else if (value_comp()(__rt->__value_, __k)) 22010b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 22020b57cec5SDimitry Andric else 22030b57cec5SDimitry Andric return _Pp(iterator(__rt), 2204cb14a3feSDimitry Andric iterator(__rt->__right_ != nullptr ? static_cast<__iter_pointer>(std::__tree_min(__rt->__right_)) 22050b57cec5SDimitry Andric : __result)); 22060b57cec5SDimitry Andric } 22070b57cec5SDimitry Andric return _Pp(iterator(__result), iterator(__result)); 22080b57cec5SDimitry Andric} 22090b57cec5SDimitry Andric 22100b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 22110b57cec5SDimitry Andrictemplate <class _Key> 22120b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, 22130b57cec5SDimitry Andric typename __tree<_Tp, _Compare, _Allocator>::const_iterator> 2214cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const { 22150b57cec5SDimitry Andric typedef pair<const_iterator, const_iterator> _Pp; 22160b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 22170b57cec5SDimitry Andric __node_pointer __rt = __root(); 2218cb14a3feSDimitry Andric while (__rt != nullptr) { 2219cb14a3feSDimitry Andric if (value_comp()(__k, __rt->__value_)) { 22200b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 22210b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2222cb14a3feSDimitry Andric } else if (value_comp()(__rt->__value_, __k)) 22230b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 22240b57cec5SDimitry Andric else 2225cb14a3feSDimitry Andric return _Pp( 2226cb14a3feSDimitry Andric const_iterator(__rt), 22270b57cec5SDimitry Andric const_iterator( 2228cb14a3feSDimitry Andric __rt->__right_ != nullptr ? static_cast<__iter_pointer>(std::__tree_min(__rt->__right_)) : __result)); 22290b57cec5SDimitry Andric } 22300b57cec5SDimitry Andric return _Pp(const_iterator(__result), const_iterator(__result)); 22310b57cec5SDimitry Andric} 22320b57cec5SDimitry Andric 22330b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 22340b57cec5SDimitry Andrictemplate <class _Key> 2235cb14a3feSDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator> 2236cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) { 22370b57cec5SDimitry Andric typedef pair<iterator, iterator> _Pp; 22380b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 22390b57cec5SDimitry Andric __node_pointer __rt = __root(); 2240cb14a3feSDimitry Andric while (__rt != nullptr) { 2241cb14a3feSDimitry Andric if (value_comp()(__k, __rt->__value_)) { 22420b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 22430b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2244cb14a3feSDimitry Andric } else if (value_comp()(__rt->__value_, __k)) 22450b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 22460b57cec5SDimitry Andric else 22470b57cec5SDimitry Andric return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 22480b57cec5SDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); 22490b57cec5SDimitry Andric } 22500b57cec5SDimitry Andric return _Pp(iterator(__result), iterator(__result)); 22510b57cec5SDimitry Andric} 22520b57cec5SDimitry Andric 22530b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 22540b57cec5SDimitry Andrictemplate <class _Key> 22550b57cec5SDimitry Andricpair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, 22560b57cec5SDimitry Andric typename __tree<_Tp, _Compare, _Allocator>::const_iterator> 2257cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const { 22580b57cec5SDimitry Andric typedef pair<const_iterator, const_iterator> _Pp; 22590b57cec5SDimitry Andric __iter_pointer __result = __end_node(); 22600b57cec5SDimitry Andric __node_pointer __rt = __root(); 2261cb14a3feSDimitry Andric while (__rt != nullptr) { 2262cb14a3feSDimitry Andric if (value_comp()(__k, __rt->__value_)) { 22630b57cec5SDimitry Andric __result = static_cast<__iter_pointer>(__rt); 22640b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__left_); 2265cb14a3feSDimitry Andric } else if (value_comp()(__rt->__value_, __k)) 22660b57cec5SDimitry Andric __rt = static_cast<__node_pointer>(__rt->__right_); 22670b57cec5SDimitry Andric else 22680b57cec5SDimitry Andric return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), 22690b57cec5SDimitry Andric __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); 22700b57cec5SDimitry Andric } 22710b57cec5SDimitry Andric return _Pp(const_iterator(__result), const_iterator(__result)); 22720b57cec5SDimitry Andric} 22730b57cec5SDimitry Andric 22740b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 22750b57cec5SDimitry Andrictypename __tree<_Tp, _Compare, _Allocator>::__node_holder 2276cb14a3feSDimitry Andric__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT { 22770b57cec5SDimitry Andric __node_pointer __np = __p.__get_np(); 2278cb14a3feSDimitry Andric if (__begin_node() == __p.__ptr_) { 22790b57cec5SDimitry Andric if (__np->__right_ != nullptr) 22800b57cec5SDimitry Andric __begin_node() = static_cast<__iter_pointer>(__np->__right_); 22810b57cec5SDimitry Andric else 22820b57cec5SDimitry Andric __begin_node() = static_cast<__iter_pointer>(__np->__parent_); 22830b57cec5SDimitry Andric } 22840b57cec5SDimitry Andric --size(); 2285cb14a3feSDimitry Andric std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np)); 22860b57cec5SDimitry Andric return __node_holder(__np, _Dp(__node_alloc(), true)); 22870b57cec5SDimitry Andric} 22880b57cec5SDimitry Andric 22890b57cec5SDimitry Andrictemplate <class _Tp, class _Compare, class _Allocator> 2290cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(__tree<_Tp, _Compare, _Allocator>& __x, __tree<_Tp, _Compare, _Allocator>& __y) 2291cb14a3feSDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { 22920b57cec5SDimitry Andric __x.swap(__y); 22930b57cec5SDimitry Andric} 22940b57cec5SDimitry Andric 22950b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 22960b57cec5SDimitry Andric 22970b57cec5SDimitry Andric_LIBCPP_POP_MACROS 22980b57cec5SDimitry Andric 22990b57cec5SDimitry Andric#endif // _LIBCPP___TREE 2300