blob: 5f9ba8be79711a9fc0ca84b62ad6f8eb4974aca6 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___TREE
11#define _LIBCPP___TREE
12
13#include <__config>
Christopher Di Bella41f26e82021-06-05 02:47:47 +000014#include <__utility/forward.h>
Arthur O'Dwyeref181602021-05-19 11:57:04 -040015#include <algorithm>
Howard Hinnantc51e1022010-05-11 19:42:16 +000016#include <iterator>
17#include <memory>
18#include <stdexcept>
Howard Hinnantc51e1022010-05-11 19:42:16 +000019
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000020#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +000021#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000022#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000023
Eric Fiselierf4433a32017-05-31 22:07:49 +000024_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27
Howard Hinnantc51e1022010-05-11 19:42:16 +000028_LIBCPP_BEGIN_NAMESPACE_STD
29
Marshall Clowa2fd8b82019-01-23 23:06:18 +000030#if defined(__GNUC__) && !defined(__clang__) // gcc.gnu.org/PR37804
31template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS map;
32template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS multimap;
33template <class, class, class> class _LIBCPP_TEMPLATE_VIS set;
34template <class, class, class> class _LIBCPP_TEMPLATE_VIS multiset;
35#endif
36
Howard Hinnant944510a2011-06-14 19:58:17 +000037template <class _Tp, class _Compare, class _Allocator> class __tree;
38template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000039 class _LIBCPP_TEMPLATE_VIS __tree_iterator;
Howard Hinnant944510a2011-06-14 19:58:17 +000040template <class _Tp, class _ConstNodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000041 class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +000042
Eric Fiseliera00b4842016-02-20 05:28:30 +000043template <class _Pointer> class __tree_end_node;
44template <class _VoidPtr> class __tree_node_base;
45template <class _Tp, class _VoidPtr> class __tree_node;
46
Eric Fiseliera00b4842016-02-20 05:28:30 +000047template <class _Key, class _Value>
48struct __value_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +000049
50template <class _Allocator> class __map_node_destructor;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000051template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
52template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiseliera00b4842016-02-20 05:28:30 +000053
Howard Hinnantc51e1022010-05-11 19:42:16 +000054/*
55
56_NodePtr algorithms
57
58The algorithms taking _NodePtr are red black tree algorithms. Those
59algorithms taking a parameter named __root should assume that __root
60points to a proper red black tree (unless otherwise specified).
61
62Each algorithm herein assumes that __root->__parent_ points to a non-null
63structure which has a member __left_ which points back to __root. No other
64member is read or written to at __root->__parent_.
65
66__root->__parent_ will be referred to below (in comments only) as end_node.
67end_node->__left_ is an externably accessible lvalue for __root, and can be
68changed by node insertion and removal (without explicit reference to end_node).
69
70All nodes (with the exception of end_node), even the node referred to as
71__root, have a non-null __parent_ field.
72
73*/
74
75// Returns: true if __x is a left child of its parent, else false
76// Precondition: __x != nullptr.
77template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +000078inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +000079bool
Howard Hinnant1113b5e2011-06-04 17:10:24 +000080__tree_is_left_child(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000081{
82 return __x == __x->__parent_->__left_;
83}
84
Joerg Sonnenbergerd74b3192017-08-18 12:57:36 +000085// Determines if the subtree rooted at __x is a proper red black subtree. If
Howard Hinnantc51e1022010-05-11 19:42:16 +000086// __x is a proper subtree, returns the black height (null counts as 1). If
87// __x is an improper subtree, returns 0.
88template <class _NodePtr>
89unsigned
90__tree_sub_invariant(_NodePtr __x)
91{
92 if (__x == nullptr)
93 return 1;
94 // parent consistency checked by caller
95 // check __x->__left_ consistency
96 if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
97 return 0;
98 // check __x->__right_ consistency
99 if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
100 return 0;
101 // check __x->__left_ != __x->__right_ unless both are nullptr
102 if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
103 return 0;
104 // If this is red, neither child can be red
105 if (!__x->__is_black_)
106 {
107 if (__x->__left_ && !__x->__left_->__is_black_)
108 return 0;
109 if (__x->__right_ && !__x->__right_->__is_black_)
110 return 0;
111 }
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500112 unsigned __h = _VSTD::__tree_sub_invariant(__x->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000113 if (__h == 0)
114 return 0; // invalid left subtree
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500115 if (__h != _VSTD::__tree_sub_invariant(__x->__right_))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000116 return 0; // invalid or different height right subtree
117 return __h + __x->__is_black_; // return black height of this node
118}
119
Joerg Sonnenbergerd74b3192017-08-18 12:57:36 +0000120// Determines if the red black tree rooted at __root is a proper red black tree.
Howard Hinnantc51e1022010-05-11 19:42:16 +0000121// __root == nullptr is a proper tree. Returns true is __root is a proper
122// red black tree, else returns false.
123template <class _NodePtr>
124bool
125__tree_invariant(_NodePtr __root)
126{
127 if (__root == nullptr)
128 return true;
129 // check __x->__parent_ consistency
130 if (__root->__parent_ == nullptr)
131 return false;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500132 if (!_VSTD::__tree_is_left_child(__root))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000133 return false;
134 // root must be black
135 if (!__root->__is_black_)
136 return false;
137 // do normal node checks
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500138 return _VSTD::__tree_sub_invariant(__root) != 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000139}
140
141// Returns: pointer to the left-most node under __x.
142// Precondition: __x != nullptr.
143template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000144inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000145_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000146__tree_min(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000147{
148 while (__x->__left_ != nullptr)
149 __x = __x->__left_;
150 return __x;
151}
152
153// Returns: pointer to the right-most node under __x.
154// Precondition: __x != nullptr.
155template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000156inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000157_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000158__tree_max(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000159{
160 while (__x->__right_ != nullptr)
161 __x = __x->__right_;
162 return __x;
163}
164
165// Returns: pointer to the next in-order node after __x.
166// Precondition: __x != nullptr.
167template <class _NodePtr>
168_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000169__tree_next(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000170{
171 if (__x->__right_ != nullptr)
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500172 return _VSTD::__tree_min(__x->__right_);
173 while (!_VSTD::__tree_is_left_child(__x))
Eric Fiselier70f5f872016-07-19 17:56:20 +0000174 __x = __x->__parent_unsafe();
175 return __x->__parent_unsafe();
176}
177
178template <class _EndNodePtr, class _NodePtr>
179inline _LIBCPP_INLINE_VISIBILITY
180_EndNodePtr
181__tree_next_iter(_NodePtr __x) _NOEXCEPT
182{
183 if (__x->__right_ != nullptr)
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500184 return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_));
185 while (!_VSTD::__tree_is_left_child(__x))
Eric Fiselier70f5f872016-07-19 17:56:20 +0000186 __x = __x->__parent_unsafe();
187 return static_cast<_EndNodePtr>(__x->__parent_);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000188}
189
190// Returns: pointer to the previous in-order node before __x.
191// Precondition: __x != nullptr.
Eric Fiselier70f5f872016-07-19 17:56:20 +0000192// Note: __x may be the end node.
193template <class _NodePtr, class _EndNodePtr>
194inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000195_NodePtr
Eric Fiselier70f5f872016-07-19 17:56:20 +0000196__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000197{
198 if (__x->__left_ != nullptr)
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500199 return _VSTD::__tree_max(__x->__left_);
Eric Fiselier70f5f872016-07-19 17:56:20 +0000200 _NodePtr __xx = static_cast<_NodePtr>(__x);
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500201 while (_VSTD::__tree_is_left_child(__xx))
Eric Fiselier70f5f872016-07-19 17:56:20 +0000202 __xx = __xx->__parent_unsafe();
203 return __xx->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000204}
205
206// Returns: pointer to a node which has no children
207// Precondition: __x != nullptr.
208template <class _NodePtr>
209_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000210__tree_leaf(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000211{
212 while (true)
213 {
214 if (__x->__left_ != nullptr)
215 {
216 __x = __x->__left_;
217 continue;
218 }
219 if (__x->__right_ != nullptr)
220 {
221 __x = __x->__right_;
222 continue;
223 }
224 break;
225 }
226 return __x;
227}
228
229// Effects: Makes __x->__right_ the subtree root with __x as its left child
230// while preserving in-order order.
231// Precondition: __x->__right_ != nullptr
232template <class _NodePtr>
233void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000234__tree_left_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235{
236 _NodePtr __y = __x->__right_;
237 __x->__right_ = __y->__left_;
238 if (__x->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000239 __x->__right_->__set_parent(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000240 __y->__parent_ = __x->__parent_;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500241 if (_VSTD::__tree_is_left_child(__x))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000242 __x->__parent_->__left_ = __y;
243 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000244 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000245 __y->__left_ = __x;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000246 __x->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000247}
248
249// Effects: Makes __x->__left_ the subtree root with __x as its right child
250// while preserving in-order order.
251// Precondition: __x->__left_ != nullptr
252template <class _NodePtr>
253void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000254__tree_right_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000255{
256 _NodePtr __y = __x->__left_;
257 __x->__left_ = __y->__right_;
258 if (__x->__left_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000259 __x->__left_->__set_parent(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000260 __y->__parent_ = __x->__parent_;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500261 if (_VSTD::__tree_is_left_child(__x))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000262 __x->__parent_->__left_ = __y;
263 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000264 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265 __y->__right_ = __x;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000266 __x->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000267}
268
269// Effects: Rebalances __root after attaching __x to a leaf.
270// Precondition: __root != nulptr && __x != nullptr.
271// __x has no children.
272// __x == __root or == a direct or indirect child of __root.
273// If __x were to be unlinked from __root (setting __root to
274// nullptr if __root == __x), __tree_invariant(__root) == true.
275// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_
276// may be different than the value passed in as __root.
277template <class _NodePtr>
278void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000279__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000280{
281 __x->__is_black_ = __x == __root;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000282 while (__x != __root && !__x->__parent_unsafe()->__is_black_)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000283 {
284 // __x->__parent_ != __root because __x->__parent_->__is_black == false
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500285 if (_VSTD::__tree_is_left_child(__x->__parent_unsafe()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000286 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000287 _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000288 if (__y != nullptr && !__y->__is_black_)
289 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000290 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000291 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000292 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000293 __x->__is_black_ = __x == __root;
294 __y->__is_black_ = true;
295 }
296 else
297 {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500298 if (!_VSTD::__tree_is_left_child(__x))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000299 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000300 __x = __x->__parent_unsafe();
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500301 _VSTD::__tree_left_rotate(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000302 }
Eric Fiselier70f5f872016-07-19 17:56:20 +0000303 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000304 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000305 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000306 __x->__is_black_ = false;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500307 _VSTD::__tree_right_rotate(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000308 break;
309 }
310 }
311 else
312 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000313 _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000314 if (__y != nullptr && !__y->__is_black_)
315 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000316 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000318 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000319 __x->__is_black_ = __x == __root;
320 __y->__is_black_ = true;
321 }
322 else
323 {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500324 if (_VSTD::__tree_is_left_child(__x))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000326 __x = __x->__parent_unsafe();
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500327 _VSTD::__tree_right_rotate(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000328 }
Eric Fiselier70f5f872016-07-19 17:56:20 +0000329 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000330 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000331 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332 __x->__is_black_ = false;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500333 _VSTD::__tree_left_rotate(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000334 break;
335 }
336 }
337 }
338}
339
340// Precondition: __root != nullptr && __z != nullptr.
341// __tree_invariant(__root) == true.
342// __z == __root or == a direct or indirect child of __root.
343// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed.
344// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
345// nor any of its children refer to __z. end_node->__left_
346// may be different than the value passed in as __root.
347template <class _NodePtr>
348void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000349__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000350{
351 // __z will be removed from the tree. Client still needs to destruct/deallocate it
352 // __y is either __z, or if __z has two children, __tree_next(__z).
353 // __y will have at most one child.
354 // __y will be the initial hole in the tree (make the hole at a leaf)
355 _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500356 __z : _VSTD::__tree_next(__z);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000357 // __x is __y's possibly null single child
358 _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
359 // __w is __x's possibly null uncle (will become __x's sibling)
360 _NodePtr __w = nullptr;
361 // link __x to __y's parent, and find __w
362 if (__x != nullptr)
363 __x->__parent_ = __y->__parent_;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500364 if (_VSTD::__tree_is_left_child(__y))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000365 {
366 __y->__parent_->__left_ = __x;
367 if (__y != __root)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000368 __w = __y->__parent_unsafe()->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000369 else
370 __root = __x; // __w == nullptr
371 }
372 else
373 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000374 __y->__parent_unsafe()->__right_ = __x;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000375 // __y can't be root if it is a right child
376 __w = __y->__parent_->__left_;
377 }
378 bool __removed_black = __y->__is_black_;
379 // If we didn't remove __z, do so now by splicing in __y for __z,
380 // but copy __z's color. This does not impact __x or __w.
381 if (__y != __z)
382 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000383 // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000384 __y->__parent_ = __z->__parent_;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500385 if (_VSTD::__tree_is_left_child(__z))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386 __y->__parent_->__left_ = __y;
387 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000388 __y->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000389 __y->__left_ = __z->__left_;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000390 __y->__left_->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000391 __y->__right_ = __z->__right_;
392 if (__y->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000393 __y->__right_->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000394 __y->__is_black_ = __z->__is_black_;
395 if (__root == __z)
396 __root = __y;
397 }
398 // There is no need to rebalance if we removed a red, or if we removed
399 // the last node.
400 if (__removed_black && __root != nullptr)
401 {
402 // Rebalance:
403 // __x has an implicit black color (transferred from the removed __y)
404 // associated with it, no matter what its color is.
405 // If __x is __root (in which case it can't be null), it is supposed
406 // to be black anyway, and if it is doubly black, then the double
407 // can just be ignored.
408 // If __x is red (in which case it can't be null), then it can absorb
409 // the implicit black just by setting its color to black.
410 // Since __y was black and only had one child (which __x points to), __x
411 // is either red with no children, else null, otherwise __y would have
412 // different black heights under left and right pointers.
413 // if (__x == __root || __x != nullptr && !__x->__is_black_)
414 if (__x != nullptr)
415 __x->__is_black_ = true;
416 else
417 {
418 // Else __x isn't root, and is "doubly black", even though it may
419 // be null. __w can not be null here, else the parent would
420 // see a black height >= 2 on the __x side and a black height
421 // of 1 on the __w side (__w must be a non-null black or a red
422 // with a non-null black child).
423 while (true)
424 {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500425 if (!_VSTD::__tree_is_left_child(__w)) // if x is left child
Howard Hinnantc51e1022010-05-11 19:42:16 +0000426 {
427 if (!__w->__is_black_)
428 {
429 __w->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000430 __w->__parent_unsafe()->__is_black_ = false;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500431 _VSTD::__tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000432 // __x is still valid
433 // reset __root only if necessary
434 if (__root == __w->__left_)
435 __root = __w;
436 // reset sibling, and it still can't be null
437 __w = __w->__left_->__right_;
438 }
439 // __w->__is_black_ is now true, __w may have null children
440 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
441 (__w->__right_ == nullptr || __w->__right_->__is_black_))
442 {
443 __w->__is_black_ = false;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000444 __x = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000445 // __x can no longer be null
446 if (__x == __root || !__x->__is_black_)
447 {
448 __x->__is_black_ = true;
449 break;
450 }
451 // reset sibling, and it still can't be null
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500452 __w = _VSTD::__tree_is_left_child(__x) ?
Eric Fiselier70f5f872016-07-19 17:56:20 +0000453 __x->__parent_unsafe()->__right_ :
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000454 __x->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000455 // continue;
456 }
457 else // __w has a red child
458 {
459 if (__w->__right_ == nullptr || __w->__right_->__is_black_)
460 {
461 // __w left child is non-null and red
462 __w->__left_->__is_black_ = true;
463 __w->__is_black_ = false;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500464 _VSTD::__tree_right_rotate(__w);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000465 // __w is known not to be root, so root hasn't changed
466 // reset sibling, and it still can't be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000467 __w = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000468 }
469 // __w has a right red child, left child may be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000470 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
471 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000472 __w->__right_->__is_black_ = true;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500473 _VSTD::__tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474 break;
475 }
476 }
477 else
478 {
479 if (!__w->__is_black_)
480 {
481 __w->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000482 __w->__parent_unsafe()->__is_black_ = false;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500483 _VSTD::__tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000484 // __x is still valid
485 // reset __root only if necessary
486 if (__root == __w->__right_)
487 __root = __w;
488 // reset sibling, and it still can't be null
489 __w = __w->__right_->__left_;
490 }
491 // __w->__is_black_ is now true, __w may have null children
492 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
493 (__w->__right_ == nullptr || __w->__right_->__is_black_))
494 {
495 __w->__is_black_ = false;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000496 __x = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000497 // __x can no longer be null
498 if (!__x->__is_black_ || __x == __root)
499 {
500 __x->__is_black_ = true;
501 break;
502 }
503 // reset sibling, and it still can't be null
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500504 __w = _VSTD::__tree_is_left_child(__x) ?
Eric Fiselier70f5f872016-07-19 17:56:20 +0000505 __x->__parent_unsafe()->__right_ :
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000506 __x->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000507 // continue;
508 }
509 else // __w has a red child
510 {
511 if (__w->__left_ == nullptr || __w->__left_->__is_black_)
512 {
513 // __w right child is non-null and red
514 __w->__right_->__is_black_ = true;
515 __w->__is_black_ = false;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500516 _VSTD::__tree_left_rotate(__w);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000517 // __w is known not to be root, so root hasn't changed
518 // reset sibling, and it still can't be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000519 __w = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000520 }
521 // __w has a left red child, right child may be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000522 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
523 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000524 __w->__left_->__is_black_ = true;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500525 _VSTD::__tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000526 break;
527 }
528 }
529 }
530 }
531 }
532}
533
Eric Fiseliera00b4842016-02-20 05:28:30 +0000534// node traits
535
Eric Fiselierd06276b2016-03-31 02:15:15 +0000536
Eric Fiselierd06276b2016-03-31 02:15:15 +0000537template <class _Tp>
538struct __is_tree_value_type_imp : false_type {};
539
540template <class _Key, class _Value>
Louis Dionne08e1a782020-10-09 12:33:49 -0400541struct __is_tree_value_type_imp<__value_type<_Key, _Value> > : true_type {};
Eric Fiselierd06276b2016-03-31 02:15:15 +0000542
543template <class ..._Args>
544struct __is_tree_value_type : false_type {};
545
546template <class _One>
547struct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {};
Eric Fiselierd06276b2016-03-31 02:15:15 +0000548
Eric Fiseliera00b4842016-02-20 05:28:30 +0000549template <class _Tp>
550struct __tree_key_value_types {
551 typedef _Tp key_type;
552 typedef _Tp __node_value_type;
553 typedef _Tp __container_value_type;
554 static const bool __is_map = false;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000555
556 _LIBCPP_INLINE_VISIBILITY
557 static key_type const& __get_key(_Tp const& __v) {
558 return __v;
559 }
560 _LIBCPP_INLINE_VISIBILITY
561 static __container_value_type const& __get_value(__node_value_type const& __v) {
562 return __v;
563 }
564 _LIBCPP_INLINE_VISIBILITY
565 static __container_value_type* __get_ptr(__node_value_type& __n) {
566 return _VSTD::addressof(__n);
567 }
Eric Fiselierd06276b2016-03-31 02:15:15 +0000568 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000569 static __container_value_type&& __move(__node_value_type& __v) {
Eric Fiselierd06276b2016-03-31 02:15:15 +0000570 return _VSTD::move(__v);
571 }
Eric Fiseliera00b4842016-02-20 05:28:30 +0000572};
573
574template <class _Key, class _Tp>
575struct __tree_key_value_types<__value_type<_Key, _Tp> > {
576 typedef _Key key_type;
577 typedef _Tp mapped_type;
578 typedef __value_type<_Key, _Tp> __node_value_type;
579 typedef pair<const _Key, _Tp> __container_value_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000580 typedef __container_value_type __map_value_type;
581 static const bool __is_map = true;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000582
583 _LIBCPP_INLINE_VISIBILITY
584 static key_type const&
585 __get_key(__node_value_type const& __t) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000586 return __t.__get_value().first;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000587 }
588
589 template <class _Up>
590 _LIBCPP_INLINE_VISIBILITY
591 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
592 key_type const&>::type
593 __get_key(_Up& __t) {
594 return __t.first;
595 }
596
597 _LIBCPP_INLINE_VISIBILITY
598 static __container_value_type const&
599 __get_value(__node_value_type const& __t) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000600 return __t.__get_value();
Eric Fiselierd06276b2016-03-31 02:15:15 +0000601 }
602
603 template <class _Up>
604 _LIBCPP_INLINE_VISIBILITY
605 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
606 __container_value_type const&>::type
607 __get_value(_Up& __t) {
608 return __t;
609 }
610
611 _LIBCPP_INLINE_VISIBILITY
612 static __container_value_type* __get_ptr(__node_value_type& __n) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000613 return _VSTD::addressof(__n.__get_value());
Eric Fiselierd06276b2016-03-31 02:15:15 +0000614 }
615
Eric Fiselierd06276b2016-03-31 02:15:15 +0000616 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000617 static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
618 return __v.__move();
Eric Fiselierd06276b2016-03-31 02:15:15 +0000619 }
Eric Fiseliera00b4842016-02-20 05:28:30 +0000620};
621
622template <class _VoidPtr>
623struct __tree_node_base_types {
624 typedef _VoidPtr __void_pointer;
625
626 typedef __tree_node_base<__void_pointer> __node_base_type;
627 typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
628 __node_base_pointer;
629
630 typedef __tree_end_node<__node_base_pointer> __end_node_type;
631 typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
632 __end_node_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000633#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
634 typedef __end_node_pointer __parent_pointer;
635#else
636 typedef typename conditional<
637 is_pointer<__end_node_pointer>::value,
638 __end_node_pointer,
639 __node_base_pointer>::type __parent_pointer;
640#endif
641
Eric Fiseliera00b4842016-02-20 05:28:30 +0000642private:
643 static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
644 "_VoidPtr does not point to unqualified void type");
645};
646
647template <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>,
648 bool = _KVTypes::__is_map>
649struct __tree_map_pointer_types {};
650
651template <class _Tp, class _AllocPtr, class _KVTypes>
652struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
653 typedef typename _KVTypes::__map_value_type _Mv;
654 typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
655 __map_value_type_pointer;
656 typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
657 __const_map_value_type_pointer;
658};
659
660template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
661struct __tree_node_types;
662
663template <class _NodePtr, class _Tp, class _VoidPtr>
664struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> >
665 : public __tree_node_base_types<_VoidPtr>,
666 __tree_key_value_types<_Tp>,
667 __tree_map_pointer_types<_Tp, _VoidPtr>
668{
669 typedef __tree_node_base_types<_VoidPtr> __base;
670 typedef __tree_key_value_types<_Tp> __key_base;
671 typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base;
672public:
673
674 typedef typename pointer_traits<_NodePtr>::element_type __node_type;
675 typedef _NodePtr __node_pointer;
676
677 typedef _Tp __node_value_type;
678 typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
679 __node_value_type_pointer;
680 typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
681 __const_node_value_type_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000682#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
683 typedef typename __base::__end_node_pointer __iter_pointer;
684#else
685 typedef typename conditional<
686 is_pointer<__node_pointer>::value,
687 typename __base::__end_node_pointer,
688 __node_pointer>::type __iter_pointer;
689#endif
Eric Fiseliera00b4842016-02-20 05:28:30 +0000690private:
691 static_assert(!is_const<__node_type>::value,
692 "_NodePtr should never be a pointer to const");
693 static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
694 _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
695};
696
697template <class _ValueTp, class _VoidPtr>
698struct __make_tree_node_types {
699 typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
700 _NodePtr;
701 typedef __tree_node_types<_NodePtr> type;
702};
703
Howard Hinnantc51e1022010-05-11 19:42:16 +0000704// node
705
706template <class _Pointer>
707class __tree_end_node
708{
709public:
710 typedef _Pointer pointer;
711 pointer __left_;
712
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000713 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000714 __tree_end_node() _NOEXCEPT : __left_() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000715};
716
717template <class _VoidPtr>
Amy Huang63f53b52021-03-15 14:20:49 -0700718class _LIBCPP_STANDALONE_DEBUG __tree_node_base
Eric Fiseliera00b4842016-02-20 05:28:30 +0000719 : public __tree_node_base_types<_VoidPtr>::__end_node_type
Howard Hinnantc51e1022010-05-11 19:42:16 +0000720{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000721 typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
722
Howard Hinnantc51e1022010-05-11 19:42:16 +0000723public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000724 typedef typename _NodeBaseTypes::__node_base_pointer pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000725 typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000726
Eric Fiselier70f5f872016-07-19 17:56:20 +0000727 pointer __right_;
728 __parent_pointer __parent_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000729 bool __is_black_;
730
Eric Fiselier70f5f872016-07-19 17:56:20 +0000731 _LIBCPP_INLINE_VISIBILITY
732 pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
733
734 _LIBCPP_INLINE_VISIBILITY
735 void __set_parent(pointer __p) {
736 __parent_ = static_cast<__parent_pointer>(__p);
737 }
738
Eric Fiselierd06276b2016-03-31 02:15:15 +0000739private:
740 ~__tree_node_base() _LIBCPP_EQUAL_DELETE;
741 __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
742 __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000743};
744
745template <class _Tp, class _VoidPtr>
Amy Huang63f53b52021-03-15 14:20:49 -0700746class _LIBCPP_STANDALONE_DEBUG __tree_node
Howard Hinnantc51e1022010-05-11 19:42:16 +0000747 : public __tree_node_base<_VoidPtr>
748{
749public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000750 typedef _Tp __node_value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000751
Eric Fiseliera00b4842016-02-20 05:28:30 +0000752 __node_value_type __value_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000753
Eric Fiselierd06276b2016-03-31 02:15:15 +0000754private:
755 ~__tree_node() _LIBCPP_EQUAL_DELETE;
756 __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE;
757 __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000758};
759
Eric Fiselierd06276b2016-03-31 02:15:15 +0000760
761template <class _Allocator>
762class __tree_node_destructor
763{
764 typedef _Allocator allocator_type;
765 typedef allocator_traits<allocator_type> __alloc_traits;
766
767public:
768 typedef typename __alloc_traits::pointer pointer;
769private:
770 typedef __tree_node_types<pointer> _NodeTypes;
771 allocator_type& __na_;
772
Eric Fiselierd06276b2016-03-31 02:15:15 +0000773
774public:
775 bool __value_constructed;
776
Eric Fiselierb9f37ca2019-12-12 20:48:11 -0500777
778 __tree_node_destructor(const __tree_node_destructor &) = default;
779 __tree_node_destructor& operator=(const __tree_node_destructor&) = delete;
780
Eric Fiselierd06276b2016-03-31 02:15:15 +0000781 _LIBCPP_INLINE_VISIBILITY
782 explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
783 : __na_(__na),
784 __value_constructed(__val)
785 {}
786
787 _LIBCPP_INLINE_VISIBILITY
788 void operator()(pointer __p) _NOEXCEPT
789 {
790 if (__value_constructed)
791 __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
792 if (__p)
793 __alloc_traits::deallocate(__na_, __p, 1);
794 }
795
796 template <class> friend class __map_node_destructor;
797};
798
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +0000799#if _LIBCPP_STD_VER > 14
800template <class _NodeType, class _Alloc>
801struct __generic_container_node_destructor;
802template <class _Tp, class _VoidPtr, class _Alloc>
803struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
804 : __tree_node_destructor<_Alloc>
805{
806 using __tree_node_destructor<_Alloc>::__tree_node_destructor;
807};
808#endif
Eric Fiselierd06276b2016-03-31 02:15:15 +0000809
Howard Hinnantc51e1022010-05-11 19:42:16 +0000810template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000811class _LIBCPP_TEMPLATE_VIS __tree_iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +0000812{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000813 typedef __tree_node_types<_NodePtr> _NodeTypes;
814 typedef _NodePtr __node_pointer;
815 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000816 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
817 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000818 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000819
Eric Fiselier70f5f872016-07-19 17:56:20 +0000820 __iter_pointer __ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000821
Howard Hinnantc51e1022010-05-11 19:42:16 +0000822public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000823 typedef bidirectional_iterator_tag iterator_category;
824 typedef _Tp value_type;
825 typedef _DiffType difference_type;
826 typedef value_type& reference;
827 typedef typename _NodeTypes::__node_value_type_pointer pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000828
Marshall Clow8fc07302013-08-08 21:52:50 +0000829 _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
830#if _LIBCPP_STD_VER > 11
831 : __ptr_(nullptr)
832#endif
833 {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000834
Eric Fiselier70f5f872016-07-19 17:56:20 +0000835 _LIBCPP_INLINE_VISIBILITY reference operator*() const
836 {return __get_np()->__value_;}
Howard Hinnant2d0046b2013-06-19 21:29:40 +0000837 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier70f5f872016-07-19 17:56:20 +0000838 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000839
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000840 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000841 __tree_iterator& operator++() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000842 __ptr_ = static_cast<__iter_pointer>(
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500843 _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000844 return *this;
845 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000846 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000847 __tree_iterator operator++(int)
848 {__tree_iterator __t(*this); ++(*this); return __t;}
849
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000850 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000851 __tree_iterator& operator--() {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500852 __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
Eric Fiselier70f5f872016-07-19 17:56:20 +0000853 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000854 return *this;
855 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000856 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000857 __tree_iterator operator--(int)
858 {__tree_iterator __t(*this); --(*this); return __t;}
859
Louis Dionne44bcff92018-08-03 22:36:53 +0000860 friend _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000861 bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000862 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000863 friend _LIBCPP_INLINE_VISIBILITY
864 bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000865 {return !(__x == __y);}
866
867private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000868 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000869 explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Eric Fiselier70f5f872016-07-19 17:56:20 +0000870 _LIBCPP_INLINE_VISIBILITY
871 explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
872 _LIBCPP_INLINE_VISIBILITY
873 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000874 template <class, class, class> friend class __tree;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000875 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
876 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
877 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
878 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
879 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
880 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000881};
882
Eric Fiseliera00b4842016-02-20 05:28:30 +0000883template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000884class _LIBCPP_TEMPLATE_VIS __tree_const_iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +0000885{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000886 typedef __tree_node_types<_NodePtr> _NodeTypes;
887 typedef typename _NodeTypes::__node_pointer __node_pointer;
888 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000889 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
890 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000891 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000892
Eric Fiselier70f5f872016-07-19 17:56:20 +0000893 __iter_pointer __ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000894
Howard Hinnantc51e1022010-05-11 19:42:16 +0000895public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000896 typedef bidirectional_iterator_tag iterator_category;
897 typedef _Tp value_type;
898 typedef _DiffType difference_type;
899 typedef const value_type& reference;
900 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000901
Marshall Clow8fc07302013-08-08 21:52:50 +0000902 _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
903#if _LIBCPP_STD_VER > 11
904 : __ptr_(nullptr)
905#endif
906 {}
907
Howard Hinnantc51e1022010-05-11 19:42:16 +0000908private:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000909 typedef __tree_iterator<value_type, __node_pointer, difference_type>
910 __non_const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000911public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000912 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000913 __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
914 : __ptr_(__p.__ptr_) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000915
Eric Fiselier70f5f872016-07-19 17:56:20 +0000916 _LIBCPP_INLINE_VISIBILITY reference operator*() const
917 {return __get_np()->__value_;}
Howard Hinnant2d0046b2013-06-19 21:29:40 +0000918 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier70f5f872016-07-19 17:56:20 +0000919 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000920
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000921 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000922 __tree_const_iterator& operator++() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000923 __ptr_ = static_cast<__iter_pointer>(
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500924 _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000925 return *this;
926 }
927
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000928 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000929 __tree_const_iterator operator++(int)
930 {__tree_const_iterator __t(*this); ++(*this); return __t;}
931
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000932 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000933 __tree_const_iterator& operator--() {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -0500934 __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
Eric Fiselier70f5f872016-07-19 17:56:20 +0000935 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000936 return *this;
937 }
938
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000939 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000940 __tree_const_iterator operator--(int)
941 {__tree_const_iterator __t(*this); --(*this); return __t;}
942
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000943 friend _LIBCPP_INLINE_VISIBILITY
944 bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000945 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000946 friend _LIBCPP_INLINE_VISIBILITY
947 bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000948 {return !(__x == __y);}
949
950private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000951 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000952 explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
953 : __ptr_(__p) {}
Eric Fiselier70f5f872016-07-19 17:56:20 +0000954 _LIBCPP_INLINE_VISIBILITY
955 explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
956 : __ptr_(__p) {}
957 _LIBCPP_INLINE_VISIBILITY
958 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
959
Howard Hinnantc51e1022010-05-11 19:42:16 +0000960 template <class, class, class> friend class __tree;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000961 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
962 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
963 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
964 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
965 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000966
Howard Hinnantc51e1022010-05-11 19:42:16 +0000967};
968
Louis Dionne878a3a82018-12-06 21:46:17 +0000969template<class _Tp, class _Compare>
Eric Fiseliera7a14ed2017-01-13 22:02:08 +0000970#ifndef _LIBCPP_CXX03_LANG
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500971 _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
Louis Dionne69c42c02019-04-11 16:14:56 +0000972 "the specified comparator type does not provide a viable const call operator")
Louis Dionne878a3a82018-12-06 21:46:17 +0000973#endif
974int __diagnose_non_const_comparator();
Eric Fiseliera7a14ed2017-01-13 22:02:08 +0000975
Howard Hinnantc51e1022010-05-11 19:42:16 +0000976template <class _Tp, class _Compare, class _Allocator>
977class __tree
978{
979public:
980 typedef _Tp value_type;
981 typedef _Compare value_compare;
982 typedef _Allocator allocator_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000983
984private:
Howard Hinnantc51e1022010-05-11 19:42:16 +0000985 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000986 typedef typename __make_tree_node_types<value_type,
987 typename __alloc_traits::void_pointer>::type
988 _NodeTypes;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000989 typedef typename _NodeTypes::key_type key_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000990public:
991 typedef typename _NodeTypes::__node_value_type __node_value_type;
992 typedef typename _NodeTypes::__container_value_type __container_value_type;
993
Howard Hinnantc51e1022010-05-11 19:42:16 +0000994 typedef typename __alloc_traits::pointer pointer;
995 typedef typename __alloc_traits::const_pointer const_pointer;
996 typedef typename __alloc_traits::size_type size_type;
997 typedef typename __alloc_traits::difference_type difference_type;
998
Eric Fiseliera00b4842016-02-20 05:28:30 +0000999public:
1000 typedef typename _NodeTypes::__void_pointer __void_pointer;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001001
Eric Fiseliera00b4842016-02-20 05:28:30 +00001002 typedef typename _NodeTypes::__node_type __node;
1003 typedef typename _NodeTypes::__node_pointer __node_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001004
1005 typedef typename _NodeTypes::__node_base_type __node_base;
1006 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001007
1008 typedef typename _NodeTypes::__end_node_type __end_node_t;
1009 typedef typename _NodeTypes::__end_node_pointer __end_node_ptr;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001010
Eric Fiselier70f5f872016-07-19 17:56:20 +00001011 typedef typename _NodeTypes::__parent_pointer __parent_pointer;
1012 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
1013
Marshall Clow940e01c2015-04-07 05:21:38 +00001014 typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001015 typedef allocator_traits<__node_allocator> __node_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001016
Eric Fiseliera00b4842016-02-20 05:28:30 +00001017private:
1018 // check for sane allocator pointer rebinding semantics. Rebinding the
1019 // allocator for a new pointer type should be exactly the same as rebinding
1020 // the pointer using 'pointer_traits'.
1021 static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1022 "Allocator does not rebind pointers in a sane manner.");
1023 typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1024 __node_base_allocator;
1025 typedef allocator_traits<__node_base_allocator> __node_base_traits;
1026 static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1027 "Allocator does not rebind pointers in a sane manner.");
1028
1029private:
Eric Fiselier70f5f872016-07-19 17:56:20 +00001030 __iter_pointer __begin_node_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001031 __compressed_pair<__end_node_t, __node_allocator> __pair1_;
1032 __compressed_pair<size_type, value_compare> __pair3_;
1033
1034public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001035 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001036 __iter_pointer __end_node() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001037 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001038 return static_cast<__iter_pointer>(
Eric Fiseliera92b0732016-02-20 07:12:17 +00001039 pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
1040 );
Howard Hinnantc51e1022010-05-11 19:42:16 +00001041 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001042 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001043 __iter_pointer __end_node() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001044 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001045 return static_cast<__iter_pointer>(
Eric Fiseliera92b0732016-02-20 07:12:17 +00001046 pointer_traits<__end_node_ptr>::pointer_to(
1047 const_cast<__end_node_t&>(__pair1_.first())
1048 )
1049 );
Howard Hinnantc51e1022010-05-11 19:42:16 +00001050 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001052 __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001053private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001055 const __node_allocator& __node_alloc() const _NOEXCEPT
1056 {return __pair1_.second();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001057 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001058 __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001059 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001060 const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001061public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001063 allocator_type __alloc() const _NOEXCEPT
1064 {return allocator_type(__node_alloc());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001065private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001067 size_type& size() _NOEXCEPT {return __pair3_.first();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001068public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001070 const size_type& size() const _NOEXCEPT {return __pair3_.first();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001071 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001072 value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001074 const value_compare& value_comp() const _NOEXCEPT
1075 {return __pair3_.second();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001076public:
Eric Fiseliera92b0732016-02-20 07:12:17 +00001077
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001078 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera92b0732016-02-20 07:12:17 +00001079 __node_pointer __root() const _NOEXCEPT
1080 {return static_cast<__node_pointer>(__end_node()->__left_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001081
Eric Fiselier70f5f872016-07-19 17:56:20 +00001082 __node_base_pointer* __root_ptr() const _NOEXCEPT {
1083 return _VSTD::addressof(__end_node()->__left_);
1084 }
1085
Howard Hinnantc51e1022010-05-11 19:42:16 +00001086 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001087 typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001088
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001089 explicit __tree(const value_compare& __comp)
1090 _NOEXCEPT_(
1091 is_nothrow_default_constructible<__node_allocator>::value &&
1092 is_nothrow_copy_constructible<value_compare>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001093 explicit __tree(const allocator_type& __a);
1094 __tree(const value_compare& __comp, const allocator_type& __a);
1095 __tree(const __tree& __t);
1096 __tree& operator=(const __tree& __t);
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001097 template <class _ForwardIterator>
1098 void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001099 template <class _InputIterator>
1100 void __assign_multi(_InputIterator __first, _InputIterator __last);
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001101 __tree(__tree&& __t)
1102 _NOEXCEPT_(
1103 is_nothrow_move_constructible<__node_allocator>::value &&
1104 is_nothrow_move_constructible<value_compare>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001105 __tree(__tree&& __t, const allocator_type& __a);
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001106 __tree& operator=(__tree&& __t)
1107 _NOEXCEPT_(
1108 __node_traits::propagate_on_container_move_assignment::value &&
1109 is_nothrow_move_assignable<value_compare>::value &&
1110 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001111 ~__tree();
1112
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001113 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001114 iterator begin() _NOEXCEPT {return iterator(__begin_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001115 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001116 const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001117 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001118 iterator end() _NOEXCEPT {return iterator(__end_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001120 const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001121
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001122 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001123 size_type max_size() const _NOEXCEPT
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001124 {return _VSTD::min<size_type>(
Eric Fiselierb5d9f442016-11-23 01:18:56 +00001125 __node_traits::max_size(__node_alloc()),
1126 numeric_limits<difference_type >::max());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001127
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001128 void clear() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001129
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001130 void swap(__tree& __t)
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001131#if _LIBCPP_STD_VER <= 11
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001132 _NOEXCEPT_(
Marshall Clow8982dcd2015-07-13 20:04:56 +00001133 __is_nothrow_swappable<value_compare>::value
Marshall Clow8982dcd2015-07-13 20:04:56 +00001134 && (!__node_traits::propagate_on_container_swap::value ||
1135 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001136 );
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001137#else
1138 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1139#endif
Eric Fiselierd06276b2016-03-31 02:15:15 +00001140
Eric Fiselierd06276b2016-03-31 02:15:15 +00001141 template <class _Key, class ..._Args>
1142 pair<iterator, bool>
1143 __emplace_unique_key_args(_Key const&, _Args&&... __args);
1144 template <class _Key, class ..._Args>
Mark de Wever1ba476f2020-09-19 15:39:09 +02001145 pair<iterator, bool>
Eric Fiselierd06276b2016-03-31 02:15:15 +00001146 __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001147
1148 template <class... _Args>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001149 pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
Eric Fiselierd06276b2016-03-31 02:15:15 +00001150
Howard Hinnantc51e1022010-05-11 19:42:16 +00001151 template <class... _Args>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001152 iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001153
Eric Fiselierd06276b2016-03-31 02:15:15 +00001154 template <class... _Args>
1155 iterator __emplace_multi(_Args&&... __args);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001156
Eric Fiselierd06276b2016-03-31 02:15:15 +00001157 template <class... _Args>
1158 iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001159
1160 template <class _Pp>
1161 _LIBCPP_INLINE_VISIBILITY
1162 pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1163 return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1164 __can_extract_key<_Pp, key_type>());
1165 }
1166
Eric Fiselierf1e45ce2016-04-16 00:23:12 +00001167 template <class _First, class _Second>
1168 _LIBCPP_INLINE_VISIBILITY
1169 typename enable_if<
1170 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1171 pair<iterator, bool>
1172 >::type __emplace_unique(_First&& __f, _Second&& __s) {
1173 return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1174 _VSTD::forward<_Second>(__s));
1175 }
1176
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001177 template <class... _Args>
1178 _LIBCPP_INLINE_VISIBILITY
1179 pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1180 return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1181 }
1182
1183 template <class _Pp>
1184 _LIBCPP_INLINE_VISIBILITY
1185 pair<iterator, bool>
1186 __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1187 return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1188 }
1189
1190 template <class _Pp>
1191 _LIBCPP_INLINE_VISIBILITY
1192 pair<iterator, bool>
1193 __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1194 return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1195 }
1196
1197 template <class _Pp>
1198 _LIBCPP_INLINE_VISIBILITY
1199 pair<iterator, bool>
1200 __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1201 return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1202 }
1203
1204 template <class _Pp>
1205 _LIBCPP_INLINE_VISIBILITY
1206 iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1207 return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1208 __can_extract_key<_Pp, key_type>());
1209 }
1210
Eric Fiselierf1e45ce2016-04-16 00:23:12 +00001211 template <class _First, class _Second>
1212 _LIBCPP_INLINE_VISIBILITY
1213 typename enable_if<
1214 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1215 iterator
1216 >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
1217 return __emplace_hint_unique_key_args(__p, __f,
1218 _VSTD::forward<_First>(__f),
Mark de Wever1ba476f2020-09-19 15:39:09 +02001219 _VSTD::forward<_Second>(__s)).first;
Eric Fiselierf1e45ce2016-04-16 00:23:12 +00001220 }
1221
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001222 template <class... _Args>
1223 _LIBCPP_INLINE_VISIBILITY
1224 iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1225 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1226 }
1227
1228 template <class _Pp>
1229 _LIBCPP_INLINE_VISIBILITY
1230 iterator
1231 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1232 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
1233 }
1234
1235 template <class _Pp>
1236 _LIBCPP_INLINE_VISIBILITY
1237 iterator
1238 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
Mark de Wever1ba476f2020-09-19 15:39:09 +02001239 return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)).first;
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001240 }
1241
1242 template <class _Pp>
1243 _LIBCPP_INLINE_VISIBILITY
1244 iterator
1245 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
Mark de Wever1ba476f2020-09-19 15:39:09 +02001246 return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)).first;
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001247 }
1248
Eric Fiselierd06276b2016-03-31 02:15:15 +00001249 _LIBCPP_INLINE_VISIBILITY
1250 pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
1251 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
1252 }
1253
1254 _LIBCPP_INLINE_VISIBILITY
1255 iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
Mark de Wever1ba476f2020-09-19 15:39:09 +02001256 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v).first;
Eric Fiselierd06276b2016-03-31 02:15:15 +00001257 }
1258
Eric Fiselierd06276b2016-03-31 02:15:15 +00001259 _LIBCPP_INLINE_VISIBILITY
1260 pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
1261 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
1262 }
1263
1264 _LIBCPP_INLINE_VISIBILITY
1265 iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
Mark de Wever1ba476f2020-09-19 15:39:09 +02001266 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)).first;
Eric Fiselierd06276b2016-03-31 02:15:15 +00001267 }
1268
1269 template <class _Vp, class = typename enable_if<
1270 !is_same<typename __unconstref<_Vp>::type,
1271 __container_value_type
1272 >::value
1273 >::type>
1274 _LIBCPP_INLINE_VISIBILITY
1275 pair<iterator, bool> __insert_unique(_Vp&& __v) {
1276 return __emplace_unique(_VSTD::forward<_Vp>(__v));
1277 }
1278
1279 template <class _Vp, class = typename enable_if<
1280 !is_same<typename __unconstref<_Vp>::type,
1281 __container_value_type
1282 >::value
1283 >::type>
1284 _LIBCPP_INLINE_VISIBILITY
1285 iterator __insert_unique(const_iterator __p, _Vp&& __v) {
1286 return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
1287 }
1288
1289 _LIBCPP_INLINE_VISIBILITY
1290 iterator __insert_multi(__container_value_type&& __v) {
1291 return __emplace_multi(_VSTD::move(__v));
1292 }
1293
1294 _LIBCPP_INLINE_VISIBILITY
1295 iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
1296 return __emplace_hint_multi(__p, _VSTD::move(__v));
1297 }
1298
1299 template <class _Vp>
1300 _LIBCPP_INLINE_VISIBILITY
1301 iterator __insert_multi(_Vp&& __v) {
1302 return __emplace_multi(_VSTD::forward<_Vp>(__v));
1303 }
1304
1305 template <class _Vp>
1306 _LIBCPP_INLINE_VISIBILITY
1307 iterator __insert_multi(const_iterator __p, _Vp&& __v) {
1308 return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
1309 }
1310
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001311 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001312 pair<iterator, bool> __node_assign_unique(const __container_value_type& __v, __node_pointer __dest);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001313
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001315 iterator __node_insert_multi(__node_pointer __nd);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001316 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001317 iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1318
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001319
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001320 _LIBCPP_INLINE_VISIBILITY iterator
1321 __remove_node_pointer(__node_pointer) _NOEXCEPT;
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001322
1323#if _LIBCPP_STD_VER > 14
1324 template <class _NodeHandle, class _InsertReturnType>
1325 _LIBCPP_INLINE_VISIBILITY
1326 _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
1327 template <class _NodeHandle>
1328 _LIBCPP_INLINE_VISIBILITY
1329 iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001330 template <class _Tree>
1331 _LIBCPP_INLINE_VISIBILITY
1332 void __node_handle_merge_unique(_Tree& __source);
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001333
1334 template <class _NodeHandle>
1335 _LIBCPP_INLINE_VISIBILITY
1336 iterator __node_handle_insert_multi(_NodeHandle&&);
1337 template <class _NodeHandle>
1338 _LIBCPP_INLINE_VISIBILITY
1339 iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001340 template <class _Tree>
1341 _LIBCPP_INLINE_VISIBILITY
1342 void __node_handle_merge_multi(_Tree& __source);
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001343
1344
1345 template <class _NodeHandle>
1346 _LIBCPP_INLINE_VISIBILITY
1347 _NodeHandle __node_handle_extract(key_type const&);
1348 template <class _NodeHandle>
1349 _LIBCPP_INLINE_VISIBILITY
1350 _NodeHandle __node_handle_extract(const_iterator);
1351#endif
1352
Howard Hinnantc51e1022010-05-11 19:42:16 +00001353 iterator erase(const_iterator __p);
1354 iterator erase(const_iterator __f, const_iterator __l);
1355 template <class _Key>
1356 size_type __erase_unique(const _Key& __k);
1357 template <class _Key>
1358 size_type __erase_multi(const _Key& __k);
1359
Eric Fiselier70f5f872016-07-19 17:56:20 +00001360 void __insert_node_at(__parent_pointer __parent,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001361 __node_base_pointer& __child,
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001362 __node_base_pointer __new_node) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001363
1364 template <class _Key>
1365 iterator find(const _Key& __v);
1366 template <class _Key>
1367 const_iterator find(const _Key& __v) const;
1368
1369 template <class _Key>
1370 size_type __count_unique(const _Key& __k) const;
1371 template <class _Key>
1372 size_type __count_multi(const _Key& __k) const;
1373
1374 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001376 iterator lower_bound(const _Key& __v)
1377 {return __lower_bound(__v, __root(), __end_node());}
1378 template <class _Key>
1379 iterator __lower_bound(const _Key& __v,
1380 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001381 __iter_pointer __result);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001382 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001384 const_iterator lower_bound(const _Key& __v) const
1385 {return __lower_bound(__v, __root(), __end_node());}
1386 template <class _Key>
1387 const_iterator __lower_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00001388 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001389 __iter_pointer __result) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001390 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001392 iterator upper_bound(const _Key& __v)
1393 {return __upper_bound(__v, __root(), __end_node());}
1394 template <class _Key>
1395 iterator __upper_bound(const _Key& __v,
1396 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001397 __iter_pointer __result);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001398 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001400 const_iterator upper_bound(const _Key& __v) const
1401 {return __upper_bound(__v, __root(), __end_node());}
1402 template <class _Key>
1403 const_iterator __upper_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00001404 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001405 __iter_pointer __result) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001406 template <class _Key>
1407 pair<iterator, iterator>
1408 __equal_range_unique(const _Key& __k);
1409 template <class _Key>
1410 pair<const_iterator, const_iterator>
1411 __equal_range_unique(const _Key& __k) const;
1412
1413 template <class _Key>
1414 pair<iterator, iterator>
1415 __equal_range_multi(const _Key& __k);
1416 template <class _Key>
1417 pair<const_iterator, const_iterator>
1418 __equal_range_multi(const _Key& __k) const;
1419
Howard Hinnantc834c512011-11-29 18:15:50 +00001420 typedef __tree_node_destructor<__node_allocator> _Dp;
1421 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001422
Howard Hinnant1113b5e2011-06-04 17:10:24 +00001423 __node_holder remove(const_iterator __p) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001424private:
Eric Fiselier70f5f872016-07-19 17:56:20 +00001425 __node_base_pointer&
1426 __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1427 __node_base_pointer&
1428 __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1429 __node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00001430 __find_leaf(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001431 __parent_pointer& __parent, const key_type& __v);
Arthur O'Dwyerdf5df562020-12-12 11:57:32 -05001432 // FIXME: Make this function const qualified. Unfortunately doing so
Eric Fiseliercf8c0212017-01-05 06:06:18 +00001433 // breaks existing code which uses non-const callable comparators.
Howard Hinnantc51e1022010-05-11 19:42:16 +00001434 template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001435 __node_base_pointer&
1436 __find_equal(__parent_pointer& __parent, const _Key& __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001437 template <class _Key>
Eric Fiseliercf8c0212017-01-05 06:06:18 +00001438 _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1439 __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1440 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1441 }
1442 template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001443 __node_base_pointer&
1444 __find_equal(const_iterator __hint, __parent_pointer& __parent,
1445 __node_base_pointer& __dummy,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001446 const _Key& __v);
1447
Howard Hinnantc51e1022010-05-11 19:42:16 +00001448 template <class ..._Args>
Eric Fiselierd06276b2016-03-31 02:15:15 +00001449 __node_holder __construct_node(_Args&& ...__args);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001450
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001451 void destroy(__node_pointer __nd) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001452
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001454 void __copy_assign_alloc(const __tree& __t)
1455 {__copy_assign_alloc(__t, integral_constant<bool,
1456 __node_traits::propagate_on_container_copy_assignment::value>());}
1457
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001459 void __copy_assign_alloc(const __tree& __t, true_type)
Marshall Clowac8a40b2016-08-17 23:24:02 +00001460 {
1461 if (__node_alloc() != __t.__node_alloc())
Louis Dionne44bcff92018-08-03 22:36:53 +00001462 clear();
Marshall Clowac8a40b2016-08-17 23:24:02 +00001463 __node_alloc() = __t.__node_alloc();
1464 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001465 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001466 void __copy_assign_alloc(const __tree&, false_type) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001467
1468 void __move_assign(__tree& __t, false_type);
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001469 void __move_assign(__tree& __t, true_type)
1470 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1471 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001472
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001474 void __move_assign_alloc(__tree& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001475 _NOEXCEPT_(
1476 !__node_traits::propagate_on_container_move_assignment::value ||
1477 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001478 {__move_assign_alloc(__t, integral_constant<bool,
1479 __node_traits::propagate_on_container_move_assignment::value>());}
1480
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001482 void __move_assign_alloc(__tree& __t, true_type)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001483 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001484 {__node_alloc() = _VSTD::move(__t.__node_alloc());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001485 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001486 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001487
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001488 struct _DetachedTreeCache {
1489 _LIBCPP_INLINE_VISIBILITY
1490 explicit _DetachedTreeCache(__tree *__t) _NOEXCEPT : __t_(__t),
1491 __cache_root_(__detach_from_tree(__t)) {
1492 __advance();
1493 }
1494
1495 _LIBCPP_INLINE_VISIBILITY
1496 __node_pointer __get() const _NOEXCEPT {
1497 return __cache_elem_;
1498 }
1499
1500 _LIBCPP_INLINE_VISIBILITY
1501 void __advance() _NOEXCEPT {
1502 __cache_elem_ = __cache_root_;
1503 if (__cache_root_) {
1504 __cache_root_ = __detach_next(__cache_root_);
1505 }
1506 }
1507
1508 _LIBCPP_INLINE_VISIBILITY
1509 ~_DetachedTreeCache() {
1510 __t_->destroy(__cache_elem_);
1511 if (__cache_root_) {
1512 while (__cache_root_->__parent_ != nullptr)
1513 __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_);
1514 __t_->destroy(__cache_root_);
1515 }
1516 }
1517
1518 _DetachedTreeCache(_DetachedTreeCache const&) = delete;
1519 _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete;
1520
1521 private:
1522 _LIBCPP_INLINE_VISIBILITY
1523 static __node_pointer __detach_from_tree(__tree *__t) _NOEXCEPT;
1524 _LIBCPP_INLINE_VISIBILITY
1525 static __node_pointer __detach_next(__node_pointer) _NOEXCEPT;
1526
1527 __tree *__t_;
1528 __node_pointer __cache_root_;
1529 __node_pointer __cache_elem_;
1530 };
1531
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001532
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001533 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1534 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001535};
1536
1537template <class _Tp, class _Compare, class _Allocator>
1538__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001539 _NOEXCEPT_(
1540 is_nothrow_default_constructible<__node_allocator>::value &&
1541 is_nothrow_copy_constructible<value_compare>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001542 : __pair3_(0, __comp)
1543{
1544 __begin_node() = __end_node();
1545}
1546
1547template <class _Tp, class _Compare, class _Allocator>
1548__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001549 : __begin_node_(__iter_pointer()),
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001550 __pair1_(__default_init_tag(), __node_allocator(__a)),
1551 __pair3_(0, __default_init_tag())
Howard Hinnantc51e1022010-05-11 19:42:16 +00001552{
1553 __begin_node() = __end_node();
1554}
1555
1556template <class _Tp, class _Compare, class _Allocator>
1557__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1558 const allocator_type& __a)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001559 : __begin_node_(__iter_pointer()),
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001560 __pair1_(__default_init_tag(), __node_allocator(__a)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001561 __pair3_(0, __comp)
1562{
1563 __begin_node() = __end_node();
1564}
1565
1566// Precondition: size() != 0
1567template <class _Tp, class _Compare, class _Allocator>
1568typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001569__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree *__t) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001570{
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001571 __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node());
1572 __t->__begin_node() = __t->__end_node();
1573 __t->__end_node()->__left_->__parent_ = nullptr;
1574 __t->__end_node()->__left_ = nullptr;
1575 __t->size() = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001576 // __cache->__left_ == nullptr
1577 if (__cache->__right_ != nullptr)
1578 __cache = static_cast<__node_pointer>(__cache->__right_);
1579 // __cache->__left_ == nullptr
1580 // __cache->__right_ == nullptr
1581 return __cache;
1582}
1583
1584// Precondition: __cache != nullptr
1585// __cache->left_ == nullptr
1586// __cache->right_ == nullptr
1587// This is no longer a red-black tree
1588template <class _Tp, class _Compare, class _Allocator>
1589typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001590__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001591{
1592 if (__cache->__parent_ == nullptr)
1593 return nullptr;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05001594 if (_VSTD::__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001595 {
1596 __cache->__parent_->__left_ = nullptr;
1597 __cache = static_cast<__node_pointer>(__cache->__parent_);
1598 if (__cache->__right_ == nullptr)
1599 return __cache;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05001600 return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__right_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001601 }
1602 // __cache is right child
Eric Fiselier70f5f872016-07-19 17:56:20 +00001603 __cache->__parent_unsafe()->__right_ = nullptr;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001604 __cache = static_cast<__node_pointer>(__cache->__parent_);
1605 if (__cache->__left_ == nullptr)
1606 return __cache;
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05001607 return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__left_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001608}
1609
1610template <class _Tp, class _Compare, class _Allocator>
1611__tree<_Tp, _Compare, _Allocator>&
1612__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1613{
1614 if (this != &__t)
1615 {
1616 value_comp() = __t.value_comp();
1617 __copy_assign_alloc(__t);
1618 __assign_multi(__t.begin(), __t.end());
1619 }
1620 return *this;
1621}
1622
1623template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001624template <class _ForwardIterator>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001625void
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001626__tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001627{
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001628 typedef iterator_traits<_ForwardIterator> _ITraits;
Eric Fiselierd06276b2016-03-31 02:15:15 +00001629 typedef typename _ITraits::value_type _ItValueType;
1630 static_assert((is_same<_ItValueType, __container_value_type>::value),
1631 "__assign_unique may only be called with the containers value type");
Eric Fiseliercd5a6772019-11-18 01:46:58 -05001632 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001633 "__assign_unique requires a forward iterator");
Howard Hinnantc51e1022010-05-11 19:42:16 +00001634 if (size() != 0)
1635 {
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001636 _DetachedTreeCache __cache(this);
1637 for (; __cache.__get() != nullptr && __first != __last; ++__first) {
1638 if (__node_assign_unique(*__first, __cache.__get()).second)
1639 __cache.__advance();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001640 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001641 }
1642 for (; __first != __last; ++__first)
1643 __insert_unique(*__first);
1644}
1645
1646template <class _Tp, class _Compare, class _Allocator>
1647template <class _InputIterator>
1648void
1649__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1650{
Eric Fiselierd06276b2016-03-31 02:15:15 +00001651 typedef iterator_traits<_InputIterator> _ITraits;
1652 typedef typename _ITraits::value_type _ItValueType;
1653 static_assert((is_same<_ItValueType, __container_value_type>::value ||
1654 is_same<_ItValueType, __node_value_type>::value),
1655 "__assign_multi may only be called with the containers value type"
1656 " or the nodes value type");
Howard Hinnantc51e1022010-05-11 19:42:16 +00001657 if (size() != 0)
1658 {
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001659 _DetachedTreeCache __cache(this);
1660 for (; __cache.__get() && __first != __last; ++__first) {
1661 __cache.__get()->__value_ = *__first;
1662 __node_insert_multi(__cache.__get());
1663 __cache.__advance();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001664 }
1665 }
1666 for (; __first != __last; ++__first)
Eric Fiselierd06276b2016-03-31 02:15:15 +00001667 __insert_multi(_NodeTypes::__get_value(*__first));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001668}
1669
1670template <class _Tp, class _Compare, class _Allocator>
1671__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001672 : __begin_node_(__iter_pointer()),
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001673 __pair1_(__default_init_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001674 __pair3_(0, __t.value_comp())
1675{
1676 __begin_node() = __end_node();
1677}
1678
Howard Hinnantc51e1022010-05-11 19:42:16 +00001679template <class _Tp, class _Compare, class _Allocator>
1680__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001681 _NOEXCEPT_(
1682 is_nothrow_move_constructible<__node_allocator>::value &&
1683 is_nothrow_move_constructible<value_compare>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001684 : __begin_node_(_VSTD::move(__t.__begin_node_)),
1685 __pair1_(_VSTD::move(__t.__pair1_)),
1686 __pair3_(_VSTD::move(__t.__pair3_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001687{
1688 if (size() == 0)
1689 __begin_node() = __end_node();
1690 else
1691 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001692 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001693 __t.__begin_node() = __t.__end_node();
1694 __t.__end_node()->__left_ = nullptr;
1695 __t.size() = 0;
1696 }
1697}
1698
1699template <class _Tp, class _Compare, class _Allocator>
1700__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001701 : __pair1_(__default_init_tag(), __node_allocator(__a)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001702 __pair3_(0, _VSTD::move(__t.value_comp()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001703{
1704 if (__a == __t.__alloc())
1705 {
1706 if (__t.size() == 0)
1707 __begin_node() = __end_node();
1708 else
1709 {
1710 __begin_node() = __t.__begin_node();
1711 __end_node()->__left_ = __t.__end_node()->__left_;
Eric Fiselier70f5f872016-07-19 17:56:20 +00001712 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001713 size() = __t.size();
1714 __t.__begin_node() = __t.__end_node();
1715 __t.__end_node()->__left_ = nullptr;
1716 __t.size() = 0;
1717 }
1718 }
1719 else
1720 {
1721 __begin_node() = __end_node();
1722 }
1723}
1724
1725template <class _Tp, class _Compare, class _Allocator>
1726void
1727__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001728 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1729 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001730{
1731 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1732 __begin_node_ = __t.__begin_node_;
1733 __pair1_.first() = __t.__pair1_.first();
1734 __move_assign_alloc(__t);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001735 __pair3_ = _VSTD::move(__t.__pair3_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001736 if (size() == 0)
1737 __begin_node() = __end_node();
1738 else
1739 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001740 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001741 __t.__begin_node() = __t.__end_node();
1742 __t.__end_node()->__left_ = nullptr;
1743 __t.size() = 0;
1744 }
1745}
1746
1747template <class _Tp, class _Compare, class _Allocator>
1748void
1749__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1750{
1751 if (__node_alloc() == __t.__node_alloc())
1752 __move_assign(__t, true_type());
1753 else
1754 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001755 value_comp() = _VSTD::move(__t.value_comp());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001756 const_iterator __e = end();
1757 if (size() != 0)
1758 {
Eric Fiselier9f3cb342019-07-11 23:13:38 +00001759 _DetachedTreeCache __cache(this);
1760 while (__cache.__get() != nullptr && __t.size() != 0) {
1761 __cache.__get()->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
1762 __node_insert_multi(__cache.__get());
1763 __cache.__advance();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001764 }
1765 }
1766 while (__t.size() != 0)
Eric Fiselierd06276b2016-03-31 02:15:15 +00001767 __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001768 }
1769}
1770
1771template <class _Tp, class _Compare, class _Allocator>
1772__tree<_Tp, _Compare, _Allocator>&
1773__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001774 _NOEXCEPT_(
1775 __node_traits::propagate_on_container_move_assignment::value &&
1776 is_nothrow_move_assignable<value_compare>::value &&
1777 is_nothrow_move_assignable<__node_allocator>::value)
Louis Dionne44bcff92018-08-03 22:36:53 +00001778
Howard Hinnantc51e1022010-05-11 19:42:16 +00001779{
1780 __move_assign(__t, integral_constant<bool,
1781 __node_traits::propagate_on_container_move_assignment::value>());
1782 return *this;
1783}
1784
Howard Hinnantc51e1022010-05-11 19:42:16 +00001785template <class _Tp, class _Compare, class _Allocator>
1786__tree<_Tp, _Compare, _Allocator>::~__tree()
1787{
Marshall Clow140d9432016-06-30 22:05:45 +00001788 static_assert((is_copy_constructible<value_compare>::value),
1789 "Comparator must be copy-constructible.");
Eric Fiseliera7a14ed2017-01-13 22:02:08 +00001790 destroy(__root());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001791}
1792
1793template <class _Tp, class _Compare, class _Allocator>
1794void
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001795__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001796{
1797 if (__nd != nullptr)
1798 {
1799 destroy(static_cast<__node_pointer>(__nd->__left_));
1800 destroy(static_cast<__node_pointer>(__nd->__right_));
1801 __node_allocator& __na = __node_alloc();
Eric Fiselierd06276b2016-03-31 02:15:15 +00001802 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001803 __node_traits::deallocate(__na, __nd, 1);
1804 }
1805}
1806
1807template <class _Tp, class _Compare, class _Allocator>
1808void
1809__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001810#if _LIBCPP_STD_VER <= 11
Marshall Clow8982dcd2015-07-13 20:04:56 +00001811 _NOEXCEPT_(
1812 __is_nothrow_swappable<value_compare>::value
Marshall Clow8982dcd2015-07-13 20:04:56 +00001813 && (!__node_traits::propagate_on_container_swap::value ||
1814 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001815 )
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001816#else
1817 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1818#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001819{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001820 using _VSTD::swap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001821 swap(__begin_node_, __t.__begin_node_);
1822 swap(__pair1_.first(), __t.__pair1_.first());
Arthur O'Dwyer4e0de312020-11-18 18:54:38 -05001823 _VSTD::__swap_allocator(__node_alloc(), __t.__node_alloc());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001824 __pair3_.swap(__t.__pair3_);
1825 if (size() == 0)
1826 __begin_node() = __end_node();
1827 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00001828 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001829 if (__t.size() == 0)
1830 __t.__begin_node() = __t.__end_node();
1831 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00001832 __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001833}
1834
1835template <class _Tp, class _Compare, class _Allocator>
1836void
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001837__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001838{
1839 destroy(__root());
1840 size() = 0;
1841 __begin_node() = __end_node();
1842 __end_node()->__left_ = nullptr;
1843}
1844
1845// Find lower_bound place to insert
1846// Set __parent to parent of null leaf
1847// Return reference to null leaf
1848template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001849typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1850__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001851 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001852{
1853 __node_pointer __nd = __root();
1854 if (__nd != nullptr)
1855 {
1856 while (true)
1857 {
1858 if (value_comp()(__nd->__value_, __v))
1859 {
1860 if (__nd->__right_ != nullptr)
1861 __nd = static_cast<__node_pointer>(__nd->__right_);
1862 else
1863 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001864 __parent = static_cast<__parent_pointer>(__nd);
1865 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001866 }
1867 }
1868 else
1869 {
1870 if (__nd->__left_ != nullptr)
1871 __nd = static_cast<__node_pointer>(__nd->__left_);
1872 else
1873 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001874 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001875 return __parent->__left_;
1876 }
1877 }
1878 }
1879 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00001880 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001881 return __parent->__left_;
1882}
1883
1884// Find upper_bound place to insert
1885// Set __parent to parent of null leaf
1886// Return reference to null leaf
1887template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001888typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1889__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001890 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001891{
1892 __node_pointer __nd = __root();
1893 if (__nd != nullptr)
1894 {
1895 while (true)
1896 {
1897 if (value_comp()(__v, __nd->__value_))
1898 {
1899 if (__nd->__left_ != nullptr)
1900 __nd = static_cast<__node_pointer>(__nd->__left_);
1901 else
1902 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001903 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001904 return __parent->__left_;
1905 }
1906 }
1907 else
1908 {
1909 if (__nd->__right_ != nullptr)
1910 __nd = static_cast<__node_pointer>(__nd->__right_);
1911 else
1912 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001913 __parent = static_cast<__parent_pointer>(__nd);
1914 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001915 }
1916 }
1917 }
1918 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00001919 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001920 return __parent->__left_;
1921}
1922
1923// Find leaf place to insert closest to __hint
1924// First check prior to __hint.
1925// Next check after __hint.
1926// Next do O(log N) search.
1927// Set __parent to parent of null leaf
1928// Return reference to null leaf
1929template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001930typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00001931__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001932 __parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001933 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001934{
1935 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1936 {
1937 // __v <= *__hint
1938 const_iterator __prior = __hint;
1939 if (__prior == begin() || !value_comp()(__v, *--__prior))
1940 {
1941 // *prev(__hint) <= __v <= *__hint
1942 if (__hint.__ptr_->__left_ == nullptr)
1943 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001944 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001945 return __parent->__left_;
1946 }
1947 else
1948 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001949 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
1950 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001951 }
1952 }
1953 // __v < *prev(__hint)
1954 return __find_leaf_high(__parent, __v);
1955 }
1956 // else __v > *__hint
1957 return __find_leaf_low(__parent, __v);
1958}
1959
1960// Find place to insert if __v doesn't exist
1961// Set __parent to parent of null leaf
1962// Return reference to null leaf
1963// If __v exists, set parent to node of __v and return reference to node of __v
1964template <class _Tp, class _Compare, class _Allocator>
1965template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001966typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1967__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001968 const _Key& __v)
1969{
1970 __node_pointer __nd = __root();
Eric Fiselier70f5f872016-07-19 17:56:20 +00001971 __node_base_pointer* __nd_ptr = __root_ptr();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001972 if (__nd != nullptr)
1973 {
1974 while (true)
1975 {
1976 if (value_comp()(__v, __nd->__value_))
1977 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001978 if (__nd->__left_ != nullptr) {
1979 __nd_ptr = _VSTD::addressof(__nd->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001980 __nd = static_cast<__node_pointer>(__nd->__left_);
Eric Fiselier70f5f872016-07-19 17:56:20 +00001981 } else {
1982 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001983 return __parent->__left_;
1984 }
1985 }
1986 else if (value_comp()(__nd->__value_, __v))
1987 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001988 if (__nd->__right_ != nullptr) {
1989 __nd_ptr = _VSTD::addressof(__nd->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001990 __nd = static_cast<__node_pointer>(__nd->__right_);
Eric Fiselier70f5f872016-07-19 17:56:20 +00001991 } else {
1992 __parent = static_cast<__parent_pointer>(__nd);
1993 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001994 }
1995 }
1996 else
1997 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001998 __parent = static_cast<__parent_pointer>(__nd);
1999 return *__nd_ptr;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002000 }
2001 }
2002 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00002003 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002004 return __parent->__left_;
2005}
2006
2007// Find place to insert if __v doesn't exist
2008// First check prior to __hint.
2009// Next check after __hint.
2010// Next do O(log N) search.
2011// Set __parent to parent of null leaf
2012// Return reference to null leaf
2013// If __v exists, set parent to node of __v and return reference to node of __v
2014template <class _Tp, class _Compare, class _Allocator>
2015template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00002016typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00002017__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002018 __parent_pointer& __parent,
2019 __node_base_pointer& __dummy,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002020 const _Key& __v)
2021{
2022 if (__hint == end() || value_comp()(__v, *__hint)) // check before
2023 {
2024 // __v < *__hint
2025 const_iterator __prior = __hint;
2026 if (__prior == begin() || value_comp()(*--__prior, __v))
2027 {
2028 // *prev(__hint) < __v < *__hint
2029 if (__hint.__ptr_->__left_ == nullptr)
2030 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002031 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002032 return __parent->__left_;
2033 }
2034 else
2035 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002036 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2037 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002038 }
2039 }
2040 // __v <= *prev(__hint)
2041 return __find_equal(__parent, __v);
2042 }
2043 else if (value_comp()(*__hint, __v)) // check after
2044 {
2045 // *__hint < __v
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002046 const_iterator __next = _VSTD::next(__hint);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002047 if (__next == end() || value_comp()(__v, *__next))
2048 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002049 // *__hint < __v < *_VSTD::next(__hint)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002050 if (__hint.__get_np()->__right_ == nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002051 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002052 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2053 return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002054 }
2055 else
2056 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002057 __parent = static_cast<__parent_pointer>(__next.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002058 return __parent->__left_;
2059 }
2060 }
2061 // *next(__hint) <= __v
2062 return __find_equal(__parent, __v);
2063 }
2064 // else __v == *__hint
Eric Fiselier70f5f872016-07-19 17:56:20 +00002065 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2066 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2067 return __dummy;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002068}
2069
2070template <class _Tp, class _Compare, class _Allocator>
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002071void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
2072 __parent_pointer __parent, __node_base_pointer& __child,
2073 __node_base_pointer __new_node) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002074{
2075 __new_node->__left_ = nullptr;
2076 __new_node->__right_ = nullptr;
2077 __new_node->__parent_ = __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002078 // __new_node->__is_black_ is initialized in __tree_balance_after_insert
Howard Hinnantc51e1022010-05-11 19:42:16 +00002079 __child = __new_node;
2080 if (__begin_node()->__left_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002081 __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002082 _VSTD::__tree_balance_after_insert(__end_node()->__left_, __child);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002083 ++size();
2084}
2085
Eric Fiselierd06276b2016-03-31 02:15:15 +00002086template <class _Tp, class _Compare, class _Allocator>
2087template <class _Key, class... _Args>
2088pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2089__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
Eric Fiselierd06276b2016-03-31 02:15:15 +00002090{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002091 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002092 __node_base_pointer& __child = __find_equal(__parent, __k);
2093 __node_pointer __r = static_cast<__node_pointer>(__child);
2094 bool __inserted = false;
2095 if (__child == nullptr)
2096 {
Eric Fiselierd06276b2016-03-31 02:15:15 +00002097 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselierd06276b2016-03-31 02:15:15 +00002098 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2099 __r = __h.release();
2100 __inserted = true;
2101 }
2102 return pair<iterator, bool>(iterator(__r), __inserted);
2103}
2104
Eric Fiselierd06276b2016-03-31 02:15:15 +00002105template <class _Tp, class _Compare, class _Allocator>
2106template <class _Key, class... _Args>
Mark de Wever1ba476f2020-09-19 15:39:09 +02002107pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselierd06276b2016-03-31 02:15:15 +00002108__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2109 const_iterator __p, _Key const& __k, _Args&&... __args)
Eric Fiselierd06276b2016-03-31 02:15:15 +00002110{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002111 __parent_pointer __parent;
2112 __node_base_pointer __dummy;
2113 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
Eric Fiselierd06276b2016-03-31 02:15:15 +00002114 __node_pointer __r = static_cast<__node_pointer>(__child);
Mark de Wever1ba476f2020-09-19 15:39:09 +02002115 bool __inserted = false;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002116 if (__child == nullptr)
2117 {
Eric Fiselierd06276b2016-03-31 02:15:15 +00002118 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselierd06276b2016-03-31 02:15:15 +00002119 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2120 __r = __h.release();
Mark de Wever1ba476f2020-09-19 15:39:09 +02002121 __inserted = true;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002122 }
Mark de Wever1ba476f2020-09-19 15:39:09 +02002123 return pair<iterator, bool>(iterator(__r), __inserted);
Eric Fiselierd06276b2016-03-31 02:15:15 +00002124}
2125
Howard Hinnantc51e1022010-05-11 19:42:16 +00002126template <class _Tp, class _Compare, class _Allocator>
2127template <class ..._Args>
2128typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2129__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
2130{
Eric Fiselierd06276b2016-03-31 02:15:15 +00002131 static_assert(!__is_tree_value_type<_Args...>::value,
2132 "Cannot construct from __value_type");
Howard Hinnantc51e1022010-05-11 19:42:16 +00002133 __node_allocator& __na = __node_alloc();
Howard Hinnantc834c512011-11-29 18:15:50 +00002134 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierd06276b2016-03-31 02:15:15 +00002135 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002136 __h.get_deleter().__value_constructed = true;
2137 return __h;
2138}
2139
Eric Fiselierd06276b2016-03-31 02:15:15 +00002140
Howard Hinnantc51e1022010-05-11 19:42:16 +00002141template <class _Tp, class _Compare, class _Allocator>
2142template <class... _Args>
2143pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00002144__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002145{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002146 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002147 __parent_pointer __parent;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002148 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
2149 __node_pointer __r = static_cast<__node_pointer>(__child);
2150 bool __inserted = false;
2151 if (__child == nullptr)
2152 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002153 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002154 __r = __h.release();
2155 __inserted = true;
2156 }
2157 return pair<iterator, bool>(iterator(__r), __inserted);
2158}
2159
2160template <class _Tp, class _Compare, class _Allocator>
2161template <class... _Args>
2162typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselier6cce51e2016-04-15 23:27:27 +00002163__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002164{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002165 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002166 __parent_pointer __parent;
2167 __node_base_pointer __dummy;
2168 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002169 __node_pointer __r = static_cast<__node_pointer>(__child);
2170 if (__child == nullptr)
2171 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002172 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002173 __r = __h.release();
2174 }
2175 return iterator(__r);
2176}
2177
2178template <class _Tp, class _Compare, class _Allocator>
2179template <class... _Args>
2180typename __tree<_Tp, _Compare, _Allocator>::iterator
2181__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
2182{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002183 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002184 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002185 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002186 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002187 return iterator(static_cast<__node_pointer>(__h.release()));
2188}
2189
2190template <class _Tp, class _Compare, class _Allocator>
2191template <class... _Args>
2192typename __tree<_Tp, _Compare, _Allocator>::iterator
2193__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
2194 _Args&&... __args)
2195{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002196 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002197 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002198 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002199 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002200 return iterator(static_cast<__node_pointer>(__h.release()));
2201}
2202
Howard Hinnantc51e1022010-05-11 19:42:16 +00002203template <class _Tp, class _Compare, class _Allocator>
2204pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselier9f3cb342019-07-11 23:13:38 +00002205__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_type& __v, __node_pointer __nd)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002206{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002207 __parent_pointer __parent;
Eric Fiselier9f3cb342019-07-11 23:13:38 +00002208 __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002209 __node_pointer __r = static_cast<__node_pointer>(__child);
2210 bool __inserted = false;
2211 if (__child == nullptr)
2212 {
Eric Fiselier9f3cb342019-07-11 23:13:38 +00002213 __nd->__value_ = __v;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002214 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002215 __r = __nd;
2216 __inserted = true;
2217 }
2218 return pair<iterator, bool>(iterator(__r), __inserted);
2219}
2220
Howard Hinnantc51e1022010-05-11 19:42:16 +00002221
2222template <class _Tp, class _Compare, class _Allocator>
2223typename __tree<_Tp, _Compare, _Allocator>::iterator
2224__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
2225{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002226 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002227 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002228 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002229 return iterator(__nd);
2230}
2231
2232template <class _Tp, class _Compare, class _Allocator>
2233typename __tree<_Tp, _Compare, _Allocator>::iterator
2234__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
2235 __node_pointer __nd)
2236{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002237 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002238 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002239 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002240 return iterator(__nd);
2241}
2242
2243template <class _Tp, class _Compare, class _Allocator>
2244typename __tree<_Tp, _Compare, _Allocator>::iterator
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002245__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002246{
2247 iterator __r(__ptr);
2248 ++__r;
2249 if (__begin_node() == __ptr)
2250 __begin_node() = __r.__ptr_;
2251 --size();
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002252 _VSTD::__tree_remove(__end_node()->__left_,
2253 static_cast<__node_base_pointer>(__ptr));
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002254 return __r;
2255}
2256
2257#if _LIBCPP_STD_VER > 14
2258template <class _Tp, class _Compare, class _Allocator>
2259template <class _NodeHandle, class _InsertReturnType>
2260_LIBCPP_INLINE_VISIBILITY
2261_InsertReturnType
2262__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2263 _NodeHandle&& __nh)
2264{
2265 if (__nh.empty())
2266 return _InsertReturnType{end(), false, _NodeHandle()};
2267
2268 __node_pointer __ptr = __nh.__ptr_;
2269 __parent_pointer __parent;
2270 __node_base_pointer& __child = __find_equal(__parent,
2271 __ptr->__value_);
2272 if (__child != nullptr)
2273 return _InsertReturnType{
2274 iterator(static_cast<__node_pointer>(__child)),
2275 false, _VSTD::move(__nh)};
2276
2277 __insert_node_at(__parent, __child,
2278 static_cast<__node_base_pointer>(__ptr));
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002279 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002280 return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
2281}
2282
2283template <class _Tp, class _Compare, class _Allocator>
2284template <class _NodeHandle>
2285_LIBCPP_INLINE_VISIBILITY
2286typename __tree<_Tp, _Compare, _Allocator>::iterator
2287__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2288 const_iterator __hint, _NodeHandle&& __nh)
2289{
2290 if (__nh.empty())
2291 return end();
2292
2293 __node_pointer __ptr = __nh.__ptr_;
2294 __parent_pointer __parent;
2295 __node_base_pointer __dummy;
2296 __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
2297 __ptr->__value_);
2298 __node_pointer __r = static_cast<__node_pointer>(__child);
2299 if (__child == nullptr)
2300 {
2301 __insert_node_at(__parent, __child,
2302 static_cast<__node_base_pointer>(__ptr));
2303 __r = __ptr;
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002304 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002305 }
2306 return iterator(__r);
2307}
2308
2309template <class _Tp, class _Compare, class _Allocator>
2310template <class _NodeHandle>
2311_LIBCPP_INLINE_VISIBILITY
2312_NodeHandle
2313__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
2314{
2315 iterator __it = find(__key);
2316 if (__it == end())
2317 return _NodeHandle();
2318 return __node_handle_extract<_NodeHandle>(__it);
2319}
2320
2321template <class _Tp, class _Compare, class _Allocator>
2322template <class _NodeHandle>
2323_LIBCPP_INLINE_VISIBILITY
2324_NodeHandle
2325__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
2326{
2327 __node_pointer __np = __p.__get_np();
2328 __remove_node_pointer(__np);
2329 return _NodeHandle(__np, __alloc());
2330}
2331
2332template <class _Tp, class _Compare, class _Allocator>
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002333template <class _Tree>
2334_LIBCPP_INLINE_VISIBILITY
2335void
2336__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
2337{
2338 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2339
2340 for (typename _Tree::iterator __i = __source.begin();
2341 __i != __source.end();)
2342 {
2343 __node_pointer __src_ptr = __i.__get_np();
2344 __parent_pointer __parent;
2345 __node_base_pointer& __child =
2346 __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
2347 ++__i;
2348 if (__child != nullptr)
2349 continue;
2350 __source.__remove_node_pointer(__src_ptr);
2351 __insert_node_at(__parent, __child,
2352 static_cast<__node_base_pointer>(__src_ptr));
2353 }
2354}
2355
2356template <class _Tp, class _Compare, class _Allocator>
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002357template <class _NodeHandle>
2358_LIBCPP_INLINE_VISIBILITY
2359typename __tree<_Tp, _Compare, _Allocator>::iterator
2360__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
2361{
2362 if (__nh.empty())
2363 return end();
2364 __node_pointer __ptr = __nh.__ptr_;
2365 __parent_pointer __parent;
2366 __node_base_pointer& __child = __find_leaf_high(
2367 __parent, _NodeTypes::__get_key(__ptr->__value_));
2368 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002369 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002370 return iterator(__ptr);
2371}
2372
2373template <class _Tp, class _Compare, class _Allocator>
2374template <class _NodeHandle>
2375_LIBCPP_INLINE_VISIBILITY
2376typename __tree<_Tp, _Compare, _Allocator>::iterator
2377__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
2378 const_iterator __hint, _NodeHandle&& __nh)
2379{
2380 if (__nh.empty())
2381 return end();
2382
2383 __node_pointer __ptr = __nh.__ptr_;
2384 __parent_pointer __parent;
2385 __node_base_pointer& __child = __find_leaf(__hint, __parent,
2386 _NodeTypes::__get_key(__ptr->__value_));
2387 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002388 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002389 return iterator(__ptr);
2390}
2391
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002392template <class _Tp, class _Compare, class _Allocator>
2393template <class _Tree>
2394_LIBCPP_INLINE_VISIBILITY
2395void
2396__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
2397{
2398 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2399
2400 for (typename _Tree::iterator __i = __source.begin();
2401 __i != __source.end();)
2402 {
2403 __node_pointer __src_ptr = __i.__get_np();
2404 __parent_pointer __parent;
2405 __node_base_pointer& __child = __find_leaf_high(
2406 __parent, _NodeTypes::__get_key(__src_ptr->__value_));
2407 ++__i;
2408 __source.__remove_node_pointer(__src_ptr);
2409 __insert_node_at(__parent, __child,
2410 static_cast<__node_base_pointer>(__src_ptr));
2411 }
2412}
2413
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002414#endif // _LIBCPP_STD_VER > 14
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002415
2416template <class _Tp, class _Compare, class _Allocator>
2417typename __tree<_Tp, _Compare, _Allocator>::iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +00002418__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
2419{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002420 __node_pointer __np = __p.__get_np();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002421 iterator __r = __remove_node_pointer(__np);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002422 __node_allocator& __na = __node_alloc();
Eric Fiselierd06276b2016-03-31 02:15:15 +00002423 __node_traits::destroy(__na, _NodeTypes::__get_ptr(
2424 const_cast<__node_value_type&>(*__p)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002425 __node_traits::deallocate(__na, __np, 1);
2426 return __r;
2427}
2428
2429template <class _Tp, class _Compare, class _Allocator>
2430typename __tree<_Tp, _Compare, _Allocator>::iterator
2431__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
2432{
2433 while (__f != __l)
2434 __f = erase(__f);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002435 return iterator(__l.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002436}
2437
2438template <class _Tp, class _Compare, class _Allocator>
2439template <class _Key>
2440typename __tree<_Tp, _Compare, _Allocator>::size_type
2441__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
2442{
2443 iterator __i = find(__k);
2444 if (__i == end())
2445 return 0;
2446 erase(__i);
2447 return 1;
2448}
2449
2450template <class _Tp, class _Compare, class _Allocator>
2451template <class _Key>
2452typename __tree<_Tp, _Compare, _Allocator>::size_type
2453__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
2454{
2455 pair<iterator, iterator> __p = __equal_range_multi(__k);
2456 size_type __r = 0;
2457 for (; __p.first != __p.second; ++__r)
2458 __p.first = erase(__p.first);
2459 return __r;
2460}
2461
2462template <class _Tp, class _Compare, class _Allocator>
2463template <class _Key>
2464typename __tree<_Tp, _Compare, _Allocator>::iterator
2465__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
2466{
2467 iterator __p = __lower_bound(__v, __root(), __end_node());
2468 if (__p != end() && !value_comp()(__v, *__p))
2469 return __p;
2470 return end();
2471}
2472
2473template <class _Tp, class _Compare, class _Allocator>
2474template <class _Key>
2475typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2476__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
2477{
2478 const_iterator __p = __lower_bound(__v, __root(), __end_node());
2479 if (__p != end() && !value_comp()(__v, *__p))
2480 return __p;
2481 return end();
2482}
2483
2484template <class _Tp, class _Compare, class _Allocator>
2485template <class _Key>
2486typename __tree<_Tp, _Compare, _Allocator>::size_type
2487__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
2488{
Eric Fiseliera92b0732016-02-20 07:12:17 +00002489 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002490 while (__rt != nullptr)
2491 {
2492 if (value_comp()(__k, __rt->__value_))
2493 {
Eric Fiseliera92b0732016-02-20 07:12:17 +00002494 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002495 }
2496 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002497 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002498 else
2499 return 1;
2500 }
2501 return 0;
2502}
2503
2504template <class _Tp, class _Compare, class _Allocator>
2505template <class _Key>
2506typename __tree<_Tp, _Compare, _Allocator>::size_type
2507__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
2508{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002509 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002510 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002511 while (__rt != nullptr)
2512 {
2513 if (value_comp()(__k, __rt->__value_))
2514 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002515 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002516 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002517 }
2518 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002519 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002520 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002521 return _VSTD::distance(
Eric Fiselier70f5f872016-07-19 17:56:20 +00002522 __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiseliera92b0732016-02-20 07:12:17 +00002523 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002524 );
2525 }
2526 return 0;
2527}
2528
2529template <class _Tp, class _Compare, class _Allocator>
2530template <class _Key>
2531typename __tree<_Tp, _Compare, _Allocator>::iterator
2532__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2533 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002534 __iter_pointer __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002535{
2536 while (__root != nullptr)
2537 {
2538 if (!value_comp()(__root->__value_, __v))
2539 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002540 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002541 __root = static_cast<__node_pointer>(__root->__left_);
2542 }
2543 else
2544 __root = static_cast<__node_pointer>(__root->__right_);
2545 }
2546 return iterator(__result);
2547}
2548
2549template <class _Tp, class _Compare, class _Allocator>
2550template <class _Key>
2551typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2552__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00002553 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002554 __iter_pointer __result) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00002555{
2556 while (__root != nullptr)
2557 {
2558 if (!value_comp()(__root->__value_, __v))
2559 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002560 __result = static_cast<__iter_pointer>(__root);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002561 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002562 }
2563 else
Eric Fiseliera92b0732016-02-20 07:12:17 +00002564 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002565 }
2566 return const_iterator(__result);
2567}
2568
2569template <class _Tp, class _Compare, class _Allocator>
2570template <class _Key>
2571typename __tree<_Tp, _Compare, _Allocator>::iterator
2572__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2573 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002574 __iter_pointer __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002575{
2576 while (__root != nullptr)
2577 {
2578 if (value_comp()(__v, __root->__value_))
2579 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002580 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002581 __root = static_cast<__node_pointer>(__root->__left_);
2582 }
2583 else
2584 __root = static_cast<__node_pointer>(__root->__right_);
2585 }
2586 return iterator(__result);
2587}
2588
2589template <class _Tp, class _Compare, class _Allocator>
2590template <class _Key>
2591typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2592__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00002593 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002594 __iter_pointer __result) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00002595{
2596 while (__root != nullptr)
2597 {
2598 if (value_comp()(__v, __root->__value_))
2599 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002600 __result = static_cast<__iter_pointer>(__root);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002601 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002602 }
2603 else
Eric Fiseliera92b0732016-02-20 07:12:17 +00002604 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002605 }
2606 return const_iterator(__result);
2607}
2608
2609template <class _Tp, class _Compare, class _Allocator>
2610template <class _Key>
2611pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2612 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2613__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2614{
Howard Hinnantc834c512011-11-29 18:15:50 +00002615 typedef pair<iterator, iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002616 __iter_pointer __result = __end_node();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002617 __node_pointer __rt = __root();
2618 while (__rt != nullptr)
2619 {
2620 if (value_comp()(__k, __rt->__value_))
2621 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002622 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002623 __rt = static_cast<__node_pointer>(__rt->__left_);
2624 }
2625 else if (value_comp()(__rt->__value_, __k))
2626 __rt = static_cast<__node_pointer>(__rt->__right_);
2627 else
Howard Hinnantc834c512011-11-29 18:15:50 +00002628 return _Pp(iterator(__rt),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002629 iterator(
2630 __rt->__right_ != nullptr ?
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002631 static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00002632 : __result));
2633 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002634 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002635}
2636
2637template <class _Tp, class _Compare, class _Allocator>
2638template <class _Key>
2639pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2640 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2641__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2642{
Howard Hinnantc834c512011-11-29 18:15:50 +00002643 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002644 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002645 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002646 while (__rt != nullptr)
2647 {
2648 if (value_comp()(__k, __rt->__value_))
2649 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002650 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002651 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002652 }
2653 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002654 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002655 else
Howard Hinnantc834c512011-11-29 18:15:50 +00002656 return _Pp(const_iterator(__rt),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002657 const_iterator(
2658 __rt->__right_ != nullptr ?
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002659 static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00002660 : __result));
2661 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002662 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002663}
2664
2665template <class _Tp, class _Compare, class _Allocator>
2666template <class _Key>
2667pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2668 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2669__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2670{
Howard Hinnantc834c512011-11-29 18:15:50 +00002671 typedef pair<iterator, iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002672 __iter_pointer __result = __end_node();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002673 __node_pointer __rt = __root();
2674 while (__rt != nullptr)
2675 {
2676 if (value_comp()(__k, __rt->__value_))
2677 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002678 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002679 __rt = static_cast<__node_pointer>(__rt->__left_);
2680 }
2681 else if (value_comp()(__rt->__value_, __k))
2682 __rt = static_cast<__node_pointer>(__rt->__right_);
2683 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002684 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002685 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2686 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002687 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002688}
2689
2690template <class _Tp, class _Compare, class _Allocator>
2691template <class _Key>
2692pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2693 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2694__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2695{
Howard Hinnantc834c512011-11-29 18:15:50 +00002696 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002697 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002698 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002699 while (__rt != nullptr)
2700 {
2701 if (value_comp()(__k, __rt->__value_))
2702 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002703 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002704 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002705 }
2706 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002707 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002708 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002709 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiseliera92b0732016-02-20 07:12:17 +00002710 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002711 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002712 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002713}
2714
2715template <class _Tp, class _Compare, class _Allocator>
2716typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Howard Hinnant1113b5e2011-06-04 17:10:24 +00002717__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002718{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002719 __node_pointer __np = __p.__get_np();
2720 if (__begin_node() == __p.__ptr_)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002721 {
2722 if (__np->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002723 __begin_node() = static_cast<__iter_pointer>(__np->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002724 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002725 __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002726 }
2727 --size();
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002728 _VSTD::__tree_remove(__end_node()->__left_,
2729 static_cast<__node_base_pointer>(__np));
Marshall Clow95af65e2015-01-28 19:54:25 +00002730 return __node_holder(__np, _Dp(__node_alloc(), true));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002731}
2732
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00002733template <class _Tp, class _Compare, class _Allocator>
2734inline _LIBCPP_INLINE_VISIBILITY
2735void
2736swap(__tree<_Tp, _Compare, _Allocator>& __x,
2737 __tree<_Tp, _Compare, _Allocator>& __y)
2738 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2739{
2740 __x.swap(__y);
2741}
2742
Howard Hinnantc51e1022010-05-11 19:42:16 +00002743_LIBCPP_END_NAMESPACE_STD
2744
Eric Fiselierf4433a32017-05-31 22:07:49 +00002745_LIBCPP_POP_MACROS
2746
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002747#endif // _LIBCPP___TREE