blob: 4473ac36977fffeb14d571617388b047b7205d07 [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>
14#include <iterator>
15#include <memory>
16#include <stdexcept>
17#include <algorithm>
18
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000019#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +000020#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000021#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000022
Eric Fiselierf4433a32017-05-31 22:07:49 +000023_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26
Howard Hinnantc51e1022010-05-11 19:42:16 +000027_LIBCPP_BEGIN_NAMESPACE_STD
28
Marshall Clowa2fd8b82019-01-23 23:06:18 +000029#if defined(__GNUC__) && !defined(__clang__) // gcc.gnu.org/PR37804
30template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS map;
31template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS multimap;
32template <class, class, class> class _LIBCPP_TEMPLATE_VIS set;
33template <class, class, class> class _LIBCPP_TEMPLATE_VIS multiset;
34#endif
35
Howard Hinnant944510a2011-06-14 19:58:17 +000036template <class _Tp, class _Compare, class _Allocator> class __tree;
37template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000038 class _LIBCPP_TEMPLATE_VIS __tree_iterator;
Howard Hinnant944510a2011-06-14 19:58:17 +000039template <class _Tp, class _ConstNodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000040 class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +000041
Eric Fiseliera00b4842016-02-20 05:28:30 +000042template <class _Pointer> class __tree_end_node;
43template <class _VoidPtr> class __tree_node_base;
44template <class _Tp, class _VoidPtr> class __tree_node;
45
Eric Fiseliera00b4842016-02-20 05:28:30 +000046template <class _Key, class _Value>
47struct __value_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +000048
49template <class _Allocator> class __map_node_destructor;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000050template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
51template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiseliera00b4842016-02-20 05:28:30 +000052
Howard Hinnantc51e1022010-05-11 19:42:16 +000053/*
54
55_NodePtr algorithms
56
57The algorithms taking _NodePtr are red black tree algorithms. Those
58algorithms taking a parameter named __root should assume that __root
59points to a proper red black tree (unless otherwise specified).
60
61Each algorithm herein assumes that __root->__parent_ points to a non-null
62structure which has a member __left_ which points back to __root. No other
63member is read or written to at __root->__parent_.
64
65__root->__parent_ will be referred to below (in comments only) as end_node.
66end_node->__left_ is an externably accessible lvalue for __root, and can be
67changed by node insertion and removal (without explicit reference to end_node).
68
69All nodes (with the exception of end_node), even the node referred to as
70__root, have a non-null __parent_ field.
71
72*/
73
74// Returns: true if __x is a left child of its parent, else false
75// Precondition: __x != nullptr.
76template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +000077inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +000078bool
Howard Hinnant1113b5e2011-06-04 17:10:24 +000079__tree_is_left_child(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000080{
81 return __x == __x->__parent_->__left_;
82}
83
Joerg Sonnenbergerd74b3192017-08-18 12:57:36 +000084// Determines if the subtree rooted at __x is a proper red black subtree. If
Howard Hinnantc51e1022010-05-11 19:42:16 +000085// __x is a proper subtree, returns the black height (null counts as 1). If
86// __x is an improper subtree, returns 0.
87template <class _NodePtr>
88unsigned
89__tree_sub_invariant(_NodePtr __x)
90{
91 if (__x == nullptr)
92 return 1;
93 // parent consistency checked by caller
94 // check __x->__left_ consistency
95 if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
96 return 0;
97 // check __x->__right_ consistency
98 if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
99 return 0;
100 // check __x->__left_ != __x->__right_ unless both are nullptr
101 if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
102 return 0;
103 // If this is red, neither child can be red
104 if (!__x->__is_black_)
105 {
106 if (__x->__left_ && !__x->__left_->__is_black_)
107 return 0;
108 if (__x->__right_ && !__x->__right_->__is_black_)
109 return 0;
110 }
111 unsigned __h = __tree_sub_invariant(__x->__left_);
112 if (__h == 0)
113 return 0; // invalid left subtree
114 if (__h != __tree_sub_invariant(__x->__right_))
115 return 0; // invalid or different height right subtree
116 return __h + __x->__is_black_; // return black height of this node
117}
118
Joerg Sonnenbergerd74b3192017-08-18 12:57:36 +0000119// Determines if the red black tree rooted at __root is a proper red black tree.
Howard Hinnantc51e1022010-05-11 19:42:16 +0000120// __root == nullptr is a proper tree. Returns true is __root is a proper
121// red black tree, else returns false.
122template <class _NodePtr>
123bool
124__tree_invariant(_NodePtr __root)
125{
126 if (__root == nullptr)
127 return true;
128 // check __x->__parent_ consistency
129 if (__root->__parent_ == nullptr)
130 return false;
131 if (!__tree_is_left_child(__root))
132 return false;
133 // root must be black
134 if (!__root->__is_black_)
135 return false;
136 // do normal node checks
137 return __tree_sub_invariant(__root) != 0;
138}
139
140// Returns: pointer to the left-most node under __x.
141// Precondition: __x != nullptr.
142template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000143inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000144_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000145__tree_min(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000146{
147 while (__x->__left_ != nullptr)
148 __x = __x->__left_;
149 return __x;
150}
151
152// Returns: pointer to the right-most node under __x.
153// Precondition: __x != nullptr.
154template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000155inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000156_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000157__tree_max(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000158{
159 while (__x->__right_ != nullptr)
160 __x = __x->__right_;
161 return __x;
162}
163
164// Returns: pointer to the next in-order node after __x.
165// Precondition: __x != nullptr.
166template <class _NodePtr>
167_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000168__tree_next(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000169{
170 if (__x->__right_ != nullptr)
171 return __tree_min(__x->__right_);
172 while (!__tree_is_left_child(__x))
Eric Fiselier70f5f872016-07-19 17:56:20 +0000173 __x = __x->__parent_unsafe();
174 return __x->__parent_unsafe();
175}
176
177template <class _EndNodePtr, class _NodePtr>
178inline _LIBCPP_INLINE_VISIBILITY
179_EndNodePtr
180__tree_next_iter(_NodePtr __x) _NOEXCEPT
181{
182 if (__x->__right_ != nullptr)
183 return static_cast<_EndNodePtr>(__tree_min(__x->__right_));
184 while (!__tree_is_left_child(__x))
185 __x = __x->__parent_unsafe();
186 return static_cast<_EndNodePtr>(__x->__parent_);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187}
188
189// Returns: pointer to the previous in-order node before __x.
190// Precondition: __x != nullptr.
Eric Fiselier70f5f872016-07-19 17:56:20 +0000191// Note: __x may be the end node.
192template <class _NodePtr, class _EndNodePtr>
193inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000194_NodePtr
Eric Fiselier70f5f872016-07-19 17:56:20 +0000195__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000196{
197 if (__x->__left_ != nullptr)
198 return __tree_max(__x->__left_);
Eric Fiselier70f5f872016-07-19 17:56:20 +0000199 _NodePtr __xx = static_cast<_NodePtr>(__x);
200 while (__tree_is_left_child(__xx))
201 __xx = __xx->__parent_unsafe();
202 return __xx->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000203}
204
205// Returns: pointer to a node which has no children
206// Precondition: __x != nullptr.
207template <class _NodePtr>
208_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000209__tree_leaf(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000210{
211 while (true)
212 {
213 if (__x->__left_ != nullptr)
214 {
215 __x = __x->__left_;
216 continue;
217 }
218 if (__x->__right_ != nullptr)
219 {
220 __x = __x->__right_;
221 continue;
222 }
223 break;
224 }
225 return __x;
226}
227
228// Effects: Makes __x->__right_ the subtree root with __x as its left child
229// while preserving in-order order.
230// Precondition: __x->__right_ != nullptr
231template <class _NodePtr>
232void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000233__tree_left_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000234{
235 _NodePtr __y = __x->__right_;
236 __x->__right_ = __y->__left_;
237 if (__x->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000238 __x->__right_->__set_parent(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000239 __y->__parent_ = __x->__parent_;
240 if (__tree_is_left_child(__x))
241 __x->__parent_->__left_ = __y;
242 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000243 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000244 __y->__left_ = __x;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000245 __x->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246}
247
248// Effects: Makes __x->__left_ the subtree root with __x as its right child
249// while preserving in-order order.
250// Precondition: __x->__left_ != nullptr
251template <class _NodePtr>
252void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000253__tree_right_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000254{
255 _NodePtr __y = __x->__left_;
256 __x->__left_ = __y->__right_;
257 if (__x->__left_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000258 __x->__left_->__set_parent(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000259 __y->__parent_ = __x->__parent_;
260 if (__tree_is_left_child(__x))
261 __x->__parent_->__left_ = __y;
262 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000263 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264 __y->__right_ = __x;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000265 __x->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000266}
267
268// Effects: Rebalances __root after attaching __x to a leaf.
269// Precondition: __root != nulptr && __x != nullptr.
270// __x has no children.
271// __x == __root or == a direct or indirect child of __root.
272// If __x were to be unlinked from __root (setting __root to
273// nullptr if __root == __x), __tree_invariant(__root) == true.
274// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_
275// may be different than the value passed in as __root.
276template <class _NodePtr>
277void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000278__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000279{
280 __x->__is_black_ = __x == __root;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000281 while (__x != __root && !__x->__parent_unsafe()->__is_black_)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000282 {
283 // __x->__parent_ != __root because __x->__parent_->__is_black == false
Eric Fiselier70f5f872016-07-19 17:56:20 +0000284 if (__tree_is_left_child(__x->__parent_unsafe()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000285 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000286 _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000287 if (__y != nullptr && !__y->__is_black_)
288 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000289 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000290 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000291 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292 __x->__is_black_ = __x == __root;
293 __y->__is_black_ = true;
294 }
295 else
296 {
297 if (!__tree_is_left_child(__x))
298 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000299 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000300 __tree_left_rotate(__x);
301 }
Eric Fiselier70f5f872016-07-19 17:56:20 +0000302 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000303 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000304 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000305 __x->__is_black_ = false;
306 __tree_right_rotate(__x);
307 break;
308 }
309 }
310 else
311 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000312 _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000313 if (__y != nullptr && !__y->__is_black_)
314 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000315 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000316 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000317 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000318 __x->__is_black_ = __x == __root;
319 __y->__is_black_ = true;
320 }
321 else
322 {
323 if (__tree_is_left_child(__x))
324 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000325 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000326 __tree_right_rotate(__x);
327 }
Eric Fiselier70f5f872016-07-19 17:56:20 +0000328 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000330 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000331 __x->__is_black_ = false;
332 __tree_left_rotate(__x);
333 break;
334 }
335 }
336 }
337}
338
339// Precondition: __root != nullptr && __z != nullptr.
340// __tree_invariant(__root) == true.
341// __z == __root or == a direct or indirect child of __root.
342// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed.
343// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
344// nor any of its children refer to __z. end_node->__left_
345// may be different than the value passed in as __root.
346template <class _NodePtr>
347void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000348__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000349{
350 // __z will be removed from the tree. Client still needs to destruct/deallocate it
351 // __y is either __z, or if __z has two children, __tree_next(__z).
352 // __y will have at most one child.
353 // __y will be the initial hole in the tree (make the hole at a leaf)
354 _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
355 __z : __tree_next(__z);
356 // __x is __y's possibly null single child
357 _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
358 // __w is __x's possibly null uncle (will become __x's sibling)
359 _NodePtr __w = nullptr;
360 // link __x to __y's parent, and find __w
361 if (__x != nullptr)
362 __x->__parent_ = __y->__parent_;
363 if (__tree_is_left_child(__y))
364 {
365 __y->__parent_->__left_ = __x;
366 if (__y != __root)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000367 __w = __y->__parent_unsafe()->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000368 else
369 __root = __x; // __w == nullptr
370 }
371 else
372 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000373 __y->__parent_unsafe()->__right_ = __x;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000374 // __y can't be root if it is a right child
375 __w = __y->__parent_->__left_;
376 }
377 bool __removed_black = __y->__is_black_;
378 // If we didn't remove __z, do so now by splicing in __y for __z,
379 // but copy __z's color. This does not impact __x or __w.
380 if (__y != __z)
381 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000382 // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000383 __y->__parent_ = __z->__parent_;
384 if (__tree_is_left_child(__z))
385 __y->__parent_->__left_ = __y;
386 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000387 __y->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000388 __y->__left_ = __z->__left_;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000389 __y->__left_->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390 __y->__right_ = __z->__right_;
391 if (__y->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000392 __y->__right_->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000393 __y->__is_black_ = __z->__is_black_;
394 if (__root == __z)
395 __root = __y;
396 }
397 // There is no need to rebalance if we removed a red, or if we removed
398 // the last node.
399 if (__removed_black && __root != nullptr)
400 {
401 // Rebalance:
402 // __x has an implicit black color (transferred from the removed __y)
403 // associated with it, no matter what its color is.
404 // If __x is __root (in which case it can't be null), it is supposed
405 // to be black anyway, and if it is doubly black, then the double
406 // can just be ignored.
407 // If __x is red (in which case it can't be null), then it can absorb
408 // the implicit black just by setting its color to black.
409 // Since __y was black and only had one child (which __x points to), __x
410 // is either red with no children, else null, otherwise __y would have
411 // different black heights under left and right pointers.
412 // if (__x == __root || __x != nullptr && !__x->__is_black_)
413 if (__x != nullptr)
414 __x->__is_black_ = true;
415 else
416 {
417 // Else __x isn't root, and is "doubly black", even though it may
418 // be null. __w can not be null here, else the parent would
419 // see a black height >= 2 on the __x side and a black height
420 // of 1 on the __w side (__w must be a non-null black or a red
421 // with a non-null black child).
422 while (true)
423 {
424 if (!__tree_is_left_child(__w)) // if x is left child
425 {
426 if (!__w->__is_black_)
427 {
428 __w->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000429 __w->__parent_unsafe()->__is_black_ = false;
430 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000431 // __x is still valid
432 // reset __root only if necessary
433 if (__root == __w->__left_)
434 __root = __w;
435 // reset sibling, and it still can't be null
436 __w = __w->__left_->__right_;
437 }
438 // __w->__is_black_ is now true, __w may have null children
439 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
440 (__w->__right_ == nullptr || __w->__right_->__is_black_))
441 {
442 __w->__is_black_ = false;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000443 __x = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000444 // __x can no longer be null
445 if (__x == __root || !__x->__is_black_)
446 {
447 __x->__is_black_ = true;
448 break;
449 }
450 // reset sibling, and it still can't be null
451 __w = __tree_is_left_child(__x) ?
Eric Fiselier70f5f872016-07-19 17:56:20 +0000452 __x->__parent_unsafe()->__right_ :
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000453 __x->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000454 // continue;
455 }
456 else // __w has a red child
457 {
458 if (__w->__right_ == nullptr || __w->__right_->__is_black_)
459 {
460 // __w left child is non-null and red
461 __w->__left_->__is_black_ = true;
462 __w->__is_black_ = false;
463 __tree_right_rotate(__w);
464 // __w is known not to be root, so root hasn't changed
465 // reset sibling, and it still can't be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000466 __w = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000467 }
468 // __w has a right red child, left child may be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000469 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
470 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000471 __w->__right_->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000472 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000473 break;
474 }
475 }
476 else
477 {
478 if (!__w->__is_black_)
479 {
480 __w->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000481 __w->__parent_unsafe()->__is_black_ = false;
482 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000483 // __x is still valid
484 // reset __root only if necessary
485 if (__root == __w->__right_)
486 __root = __w;
487 // reset sibling, and it still can't be null
488 __w = __w->__right_->__left_;
489 }
490 // __w->__is_black_ is now true, __w may have null children
491 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
492 (__w->__right_ == nullptr || __w->__right_->__is_black_))
493 {
494 __w->__is_black_ = false;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000495 __x = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000496 // __x can no longer be null
497 if (!__x->__is_black_ || __x == __root)
498 {
499 __x->__is_black_ = true;
500 break;
501 }
502 // reset sibling, and it still can't be null
503 __w = __tree_is_left_child(__x) ?
Eric Fiselier70f5f872016-07-19 17:56:20 +0000504 __x->__parent_unsafe()->__right_ :
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000505 __x->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000506 // continue;
507 }
508 else // __w has a red child
509 {
510 if (__w->__left_ == nullptr || __w->__left_->__is_black_)
511 {
512 // __w right child is non-null and red
513 __w->__right_->__is_black_ = true;
514 __w->__is_black_ = false;
515 __tree_left_rotate(__w);
516 // __w is known not to be root, so root hasn't changed
517 // reset sibling, and it still can't be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000518 __w = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000519 }
520 // __w has a left red child, right child may be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000521 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
522 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000523 __w->__left_->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000524 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000525 break;
526 }
527 }
528 }
529 }
530 }
531}
532
Eric Fiseliera00b4842016-02-20 05:28:30 +0000533// node traits
534
Eric Fiselierd06276b2016-03-31 02:15:15 +0000535
536#ifndef _LIBCPP_CXX03_LANG
537template <class _Tp>
538struct __is_tree_value_type_imp : false_type {};
539
540template <class _Key, class _Value>
541struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {};
542
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> {};
548#endif
549
Eric Fiseliera00b4842016-02-20 05:28:30 +0000550template <class _Tp>
551struct __tree_key_value_types {
552 typedef _Tp key_type;
553 typedef _Tp __node_value_type;
554 typedef _Tp __container_value_type;
555 static const bool __is_map = false;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000556
557 _LIBCPP_INLINE_VISIBILITY
558 static key_type const& __get_key(_Tp const& __v) {
559 return __v;
560 }
561 _LIBCPP_INLINE_VISIBILITY
562 static __container_value_type const& __get_value(__node_value_type const& __v) {
563 return __v;
564 }
565 _LIBCPP_INLINE_VISIBILITY
566 static __container_value_type* __get_ptr(__node_value_type& __n) {
567 return _VSTD::addressof(__n);
568 }
Eric Fiselierd06276b2016-03-31 02:15:15 +0000569#ifndef _LIBCPP_CXX03_LANG
570 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000571 static __container_value_type&& __move(__node_value_type& __v) {
Eric Fiselierd06276b2016-03-31 02:15:15 +0000572 return _VSTD::move(__v);
573 }
574#endif
Eric Fiseliera00b4842016-02-20 05:28:30 +0000575};
576
577template <class _Key, class _Tp>
578struct __tree_key_value_types<__value_type<_Key, _Tp> > {
579 typedef _Key key_type;
580 typedef _Tp mapped_type;
581 typedef __value_type<_Key, _Tp> __node_value_type;
582 typedef pair<const _Key, _Tp> __container_value_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000583 typedef __container_value_type __map_value_type;
584 static const bool __is_map = true;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000585
586 _LIBCPP_INLINE_VISIBILITY
587 static key_type const&
588 __get_key(__node_value_type const& __t) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000589 return __t.__get_value().first;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000590 }
591
592 template <class _Up>
593 _LIBCPP_INLINE_VISIBILITY
594 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
595 key_type const&>::type
596 __get_key(_Up& __t) {
597 return __t.first;
598 }
599
600 _LIBCPP_INLINE_VISIBILITY
601 static __container_value_type const&
602 __get_value(__node_value_type const& __t) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000603 return __t.__get_value();
Eric Fiselierd06276b2016-03-31 02:15:15 +0000604 }
605
606 template <class _Up>
607 _LIBCPP_INLINE_VISIBILITY
608 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
609 __container_value_type const&>::type
610 __get_value(_Up& __t) {
611 return __t;
612 }
613
614 _LIBCPP_INLINE_VISIBILITY
615 static __container_value_type* __get_ptr(__node_value_type& __n) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000616 return _VSTD::addressof(__n.__get_value());
Eric Fiselierd06276b2016-03-31 02:15:15 +0000617 }
618
619#ifndef _LIBCPP_CXX03_LANG
620 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000621 static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
622 return __v.__move();
Eric Fiselierd06276b2016-03-31 02:15:15 +0000623 }
624#endif
Eric Fiseliera00b4842016-02-20 05:28:30 +0000625};
626
627template <class _VoidPtr>
628struct __tree_node_base_types {
629 typedef _VoidPtr __void_pointer;
630
631 typedef __tree_node_base<__void_pointer> __node_base_type;
632 typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
633 __node_base_pointer;
634
635 typedef __tree_end_node<__node_base_pointer> __end_node_type;
636 typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
637 __end_node_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000638#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
639 typedef __end_node_pointer __parent_pointer;
640#else
641 typedef typename conditional<
642 is_pointer<__end_node_pointer>::value,
643 __end_node_pointer,
644 __node_base_pointer>::type __parent_pointer;
645#endif
646
Eric Fiseliera00b4842016-02-20 05:28:30 +0000647private:
648 static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
649 "_VoidPtr does not point to unqualified void type");
650};
651
652template <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>,
653 bool = _KVTypes::__is_map>
654struct __tree_map_pointer_types {};
655
656template <class _Tp, class _AllocPtr, class _KVTypes>
657struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
658 typedef typename _KVTypes::__map_value_type _Mv;
659 typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
660 __map_value_type_pointer;
661 typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
662 __const_map_value_type_pointer;
663};
664
665template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
666struct __tree_node_types;
667
668template <class _NodePtr, class _Tp, class _VoidPtr>
669struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> >
670 : public __tree_node_base_types<_VoidPtr>,
671 __tree_key_value_types<_Tp>,
672 __tree_map_pointer_types<_Tp, _VoidPtr>
673{
674 typedef __tree_node_base_types<_VoidPtr> __base;
675 typedef __tree_key_value_types<_Tp> __key_base;
676 typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base;
677public:
678
679 typedef typename pointer_traits<_NodePtr>::element_type __node_type;
680 typedef _NodePtr __node_pointer;
681
682 typedef _Tp __node_value_type;
683 typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
684 __node_value_type_pointer;
685 typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
686 __const_node_value_type_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000687#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
688 typedef typename __base::__end_node_pointer __iter_pointer;
689#else
690 typedef typename conditional<
691 is_pointer<__node_pointer>::value,
692 typename __base::__end_node_pointer,
693 __node_pointer>::type __iter_pointer;
694#endif
Eric Fiseliera00b4842016-02-20 05:28:30 +0000695private:
696 static_assert(!is_const<__node_type>::value,
697 "_NodePtr should never be a pointer to const");
698 static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
699 _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
700};
701
702template <class _ValueTp, class _VoidPtr>
703struct __make_tree_node_types {
704 typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
705 _NodePtr;
706 typedef __tree_node_types<_NodePtr> type;
707};
708
Howard Hinnantc51e1022010-05-11 19:42:16 +0000709// node
710
711template <class _Pointer>
712class __tree_end_node
713{
714public:
715 typedef _Pointer pointer;
716 pointer __left_;
717
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000718 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000719 __tree_end_node() _NOEXCEPT : __left_() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000720};
721
722template <class _VoidPtr>
723class __tree_node_base
Eric Fiseliera00b4842016-02-20 05:28:30 +0000724 : public __tree_node_base_types<_VoidPtr>::__end_node_type
Howard Hinnantc51e1022010-05-11 19:42:16 +0000725{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000726 typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
727
Howard Hinnantc51e1022010-05-11 19:42:16 +0000728public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000729 typedef typename _NodeBaseTypes::__node_base_pointer pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000730 typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000731
Eric Fiselier70f5f872016-07-19 17:56:20 +0000732 pointer __right_;
733 __parent_pointer __parent_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000734 bool __is_black_;
735
Eric Fiselier70f5f872016-07-19 17:56:20 +0000736 _LIBCPP_INLINE_VISIBILITY
737 pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
738
739 _LIBCPP_INLINE_VISIBILITY
740 void __set_parent(pointer __p) {
741 __parent_ = static_cast<__parent_pointer>(__p);
742 }
743
Eric Fiselierd06276b2016-03-31 02:15:15 +0000744private:
745 ~__tree_node_base() _LIBCPP_EQUAL_DELETE;
746 __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
747 __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000748};
749
750template <class _Tp, class _VoidPtr>
751class __tree_node
752 : public __tree_node_base<_VoidPtr>
753{
754public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000755 typedef _Tp __node_value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000756
Eric Fiseliera00b4842016-02-20 05:28:30 +0000757 __node_value_type __value_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000758
Eric Fiselierd06276b2016-03-31 02:15:15 +0000759private:
760 ~__tree_node() _LIBCPP_EQUAL_DELETE;
761 __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE;
762 __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000763};
764
Eric Fiselierd06276b2016-03-31 02:15:15 +0000765
766template <class _Allocator>
767class __tree_node_destructor
768{
769 typedef _Allocator allocator_type;
770 typedef allocator_traits<allocator_type> __alloc_traits;
771
772public:
773 typedef typename __alloc_traits::pointer pointer;
774private:
775 typedef __tree_node_types<pointer> _NodeTypes;
776 allocator_type& __na_;
777
778 __tree_node_destructor& operator=(const __tree_node_destructor&);
779
780public:
781 bool __value_constructed;
782
783 _LIBCPP_INLINE_VISIBILITY
784 explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
785 : __na_(__na),
786 __value_constructed(__val)
787 {}
788
789 _LIBCPP_INLINE_VISIBILITY
790 void operator()(pointer __p) _NOEXCEPT
791 {
792 if (__value_constructed)
793 __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
794 if (__p)
795 __alloc_traits::deallocate(__na_, __p, 1);
796 }
797
798 template <class> friend class __map_node_destructor;
799};
800
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +0000801#if _LIBCPP_STD_VER > 14
802template <class _NodeType, class _Alloc>
803struct __generic_container_node_destructor;
804template <class _Tp, class _VoidPtr, class _Alloc>
805struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
806 : __tree_node_destructor<_Alloc>
807{
808 using __tree_node_destructor<_Alloc>::__tree_node_destructor;
809};
810#endif
Eric Fiselierd06276b2016-03-31 02:15:15 +0000811
Howard Hinnantc51e1022010-05-11 19:42:16 +0000812template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000813class _LIBCPP_TEMPLATE_VIS __tree_iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +0000814{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000815 typedef __tree_node_types<_NodePtr> _NodeTypes;
816 typedef _NodePtr __node_pointer;
817 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000818 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
819 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000820 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000821
Eric Fiselier70f5f872016-07-19 17:56:20 +0000822 __iter_pointer __ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000823
Howard Hinnantc51e1022010-05-11 19:42:16 +0000824public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000825 typedef bidirectional_iterator_tag iterator_category;
826 typedef _Tp value_type;
827 typedef _DiffType difference_type;
828 typedef value_type& reference;
829 typedef typename _NodeTypes::__node_value_type_pointer pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000830
Marshall Clow8fc07302013-08-08 21:52:50 +0000831 _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
832#if _LIBCPP_STD_VER > 11
833 : __ptr_(nullptr)
834#endif
835 {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000836
Eric Fiselier70f5f872016-07-19 17:56:20 +0000837 _LIBCPP_INLINE_VISIBILITY reference operator*() const
838 {return __get_np()->__value_;}
Howard Hinnant2d0046b2013-06-19 21:29:40 +0000839 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier70f5f872016-07-19 17:56:20 +0000840 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000841
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000842 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000843 __tree_iterator& operator++() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000844 __ptr_ = static_cast<__iter_pointer>(
845 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000846 return *this;
847 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000848 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000849 __tree_iterator operator++(int)
850 {__tree_iterator __t(*this); ++(*this); return __t;}
851
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000852 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000853 __tree_iterator& operator--() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000854 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
855 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000856 return *this;
857 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000858 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000859 __tree_iterator operator--(int)
860 {__tree_iterator __t(*this); --(*this); return __t;}
861
Louis Dionne44bcff92018-08-03 22:36:53 +0000862 friend _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000863 bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000864 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000865 friend _LIBCPP_INLINE_VISIBILITY
866 bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000867 {return !(__x == __y);}
868
869private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000870 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000871 explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Eric Fiselier70f5f872016-07-19 17:56:20 +0000872 _LIBCPP_INLINE_VISIBILITY
873 explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
874 _LIBCPP_INLINE_VISIBILITY
875 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000876 template <class, class, class> friend class __tree;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000877 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
878 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
879 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
880 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
881 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
882 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000883};
884
Eric Fiseliera00b4842016-02-20 05:28:30 +0000885template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000886class _LIBCPP_TEMPLATE_VIS __tree_const_iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +0000887{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000888 typedef __tree_node_types<_NodePtr> _NodeTypes;
889 typedef typename _NodeTypes::__node_pointer __node_pointer;
890 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000891 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
892 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000893 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000894
Eric Fiselier70f5f872016-07-19 17:56:20 +0000895 __iter_pointer __ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000896
Howard Hinnantc51e1022010-05-11 19:42:16 +0000897public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000898 typedef bidirectional_iterator_tag iterator_category;
899 typedef _Tp value_type;
900 typedef _DiffType difference_type;
901 typedef const value_type& reference;
902 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000903
Marshall Clow8fc07302013-08-08 21:52:50 +0000904 _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
905#if _LIBCPP_STD_VER > 11
906 : __ptr_(nullptr)
907#endif
908 {}
909
Howard Hinnantc51e1022010-05-11 19:42:16 +0000910private:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000911 typedef __tree_iterator<value_type, __node_pointer, difference_type>
912 __non_const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000913public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000914 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000915 __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
916 : __ptr_(__p.__ptr_) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000917
Eric Fiselier70f5f872016-07-19 17:56:20 +0000918 _LIBCPP_INLINE_VISIBILITY reference operator*() const
919 {return __get_np()->__value_;}
Howard Hinnant2d0046b2013-06-19 21:29:40 +0000920 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier70f5f872016-07-19 17:56:20 +0000921 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000922
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000923 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000924 __tree_const_iterator& operator++() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000925 __ptr_ = static_cast<__iter_pointer>(
926 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000927 return *this;
928 }
929
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000930 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000931 __tree_const_iterator operator++(int)
932 {__tree_const_iterator __t(*this); ++(*this); return __t;}
933
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000934 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000935 __tree_const_iterator& operator--() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000936 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
937 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000938 return *this;
939 }
940
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000941 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000942 __tree_const_iterator operator--(int)
943 {__tree_const_iterator __t(*this); --(*this); return __t;}
944
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000945 friend _LIBCPP_INLINE_VISIBILITY
946 bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000947 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000948 friend _LIBCPP_INLINE_VISIBILITY
949 bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000950 {return !(__x == __y);}
951
952private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000953 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000954 explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
955 : __ptr_(__p) {}
Eric Fiselier70f5f872016-07-19 17:56:20 +0000956 _LIBCPP_INLINE_VISIBILITY
957 explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
958 : __ptr_(__p) {}
959 _LIBCPP_INLINE_VISIBILITY
960 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
961
Howard Hinnantc51e1022010-05-11 19:42:16 +0000962 template <class, class, class> friend class __tree;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000963 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
964 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
965 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
966 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
967 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000968
Howard Hinnantc51e1022010-05-11 19:42:16 +0000969};
970
Louis Dionne878a3a82018-12-06 21:46:17 +0000971template<class _Tp, class _Compare>
Eric Fiseliera7a14ed2017-01-13 22:02:08 +0000972#ifndef _LIBCPP_CXX03_LANG
Louis Dionne878a3a82018-12-06 21:46:17 +0000973 _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
Louis Dionne69c42c02019-04-11 16:14:56 +0000974 "the specified comparator type does not provide a viable const call operator")
Louis Dionne878a3a82018-12-06 21:46:17 +0000975#endif
976int __diagnose_non_const_comparator();
Eric Fiseliera7a14ed2017-01-13 22:02:08 +0000977
Howard Hinnantc51e1022010-05-11 19:42:16 +0000978template <class _Tp, class _Compare, class _Allocator>
979class __tree
980{
981public:
982 typedef _Tp value_type;
983 typedef _Compare value_compare;
984 typedef _Allocator allocator_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000985
986private:
Howard Hinnantc51e1022010-05-11 19:42:16 +0000987 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000988 typedef typename __make_tree_node_types<value_type,
989 typename __alloc_traits::void_pointer>::type
990 _NodeTypes;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000991 typedef typename _NodeTypes::key_type key_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000992public:
993 typedef typename _NodeTypes::__node_value_type __node_value_type;
994 typedef typename _NodeTypes::__container_value_type __container_value_type;
995
Howard Hinnantc51e1022010-05-11 19:42:16 +0000996 typedef typename __alloc_traits::pointer pointer;
997 typedef typename __alloc_traits::const_pointer const_pointer;
998 typedef typename __alloc_traits::size_type size_type;
999 typedef typename __alloc_traits::difference_type difference_type;
1000
Eric Fiseliera00b4842016-02-20 05:28:30 +00001001public:
1002 typedef typename _NodeTypes::__void_pointer __void_pointer;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001003
Eric Fiseliera00b4842016-02-20 05:28:30 +00001004 typedef typename _NodeTypes::__node_type __node;
1005 typedef typename _NodeTypes::__node_pointer __node_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001006
1007 typedef typename _NodeTypes::__node_base_type __node_base;
1008 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001009
1010 typedef typename _NodeTypes::__end_node_type __end_node_t;
1011 typedef typename _NodeTypes::__end_node_pointer __end_node_ptr;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001012
Eric Fiselier70f5f872016-07-19 17:56:20 +00001013 typedef typename _NodeTypes::__parent_pointer __parent_pointer;
1014 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
1015
Marshall Clow940e01c2015-04-07 05:21:38 +00001016 typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001017 typedef allocator_traits<__node_allocator> __node_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001018
Eric Fiseliera00b4842016-02-20 05:28:30 +00001019private:
1020 // check for sane allocator pointer rebinding semantics. Rebinding the
1021 // allocator for a new pointer type should be exactly the same as rebinding
1022 // the pointer using 'pointer_traits'.
1023 static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1024 "Allocator does not rebind pointers in a sane manner.");
1025 typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1026 __node_base_allocator;
1027 typedef allocator_traits<__node_base_allocator> __node_base_traits;
1028 static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1029 "Allocator does not rebind pointers in a sane manner.");
1030
1031private:
Eric Fiselier70f5f872016-07-19 17:56:20 +00001032 __iter_pointer __begin_node_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001033 __compressed_pair<__end_node_t, __node_allocator> __pair1_;
1034 __compressed_pair<size_type, value_compare> __pair3_;
1035
1036public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001037 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001038 __iter_pointer __end_node() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001039 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001040 return static_cast<__iter_pointer>(
Eric Fiseliera92b0732016-02-20 07:12:17 +00001041 pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
1042 );
Howard Hinnantc51e1022010-05-11 19:42:16 +00001043 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001044 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001045 __iter_pointer __end_node() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001046 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001047 return static_cast<__iter_pointer>(
Eric Fiseliera92b0732016-02-20 07:12:17 +00001048 pointer_traits<__end_node_ptr>::pointer_to(
1049 const_cast<__end_node_t&>(__pair1_.first())
1050 )
1051 );
Howard Hinnantc51e1022010-05-11 19:42:16 +00001052 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001053 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001054 __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001055private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001057 const __node_allocator& __node_alloc() const _NOEXCEPT
1058 {return __pair1_.second();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001059 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001060 __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001061 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001062 const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001063public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001065 allocator_type __alloc() const _NOEXCEPT
1066 {return allocator_type(__node_alloc());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001067private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001069 size_type& size() _NOEXCEPT {return __pair3_.first();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001070public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001071 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001072 const size_type& size() const _NOEXCEPT {return __pair3_.first();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001074 value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001075 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001076 const value_compare& value_comp() const _NOEXCEPT
1077 {return __pair3_.second();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001078public:
Eric Fiseliera92b0732016-02-20 07:12:17 +00001079
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001080 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera92b0732016-02-20 07:12:17 +00001081 __node_pointer __root() const _NOEXCEPT
1082 {return static_cast<__node_pointer>(__end_node()->__left_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001083
Eric Fiselier70f5f872016-07-19 17:56:20 +00001084 __node_base_pointer* __root_ptr() const _NOEXCEPT {
1085 return _VSTD::addressof(__end_node()->__left_);
1086 }
1087
Howard Hinnantc51e1022010-05-11 19:42:16 +00001088 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001089 typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001090
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001091 explicit __tree(const value_compare& __comp)
1092 _NOEXCEPT_(
1093 is_nothrow_default_constructible<__node_allocator>::value &&
1094 is_nothrow_copy_constructible<value_compare>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001095 explicit __tree(const allocator_type& __a);
1096 __tree(const value_compare& __comp, const allocator_type& __a);
1097 __tree(const __tree& __t);
1098 __tree& operator=(const __tree& __t);
1099 template <class _InputIterator>
1100 void __assign_unique(_InputIterator __first, _InputIterator __last);
1101 template <class _InputIterator>
1102 void __assign_multi(_InputIterator __first, _InputIterator __last);
Eric Fiselierb63508a2017-04-19 01:23:04 +00001103#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001104 __tree(__tree&& __t)
1105 _NOEXCEPT_(
1106 is_nothrow_move_constructible<__node_allocator>::value &&
1107 is_nothrow_move_constructible<value_compare>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001108 __tree(__tree&& __t, const allocator_type& __a);
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001109 __tree& operator=(__tree&& __t)
1110 _NOEXCEPT_(
1111 __node_traits::propagate_on_container_move_assignment::value &&
1112 is_nothrow_move_assignable<value_compare>::value &&
1113 is_nothrow_move_assignable<__node_allocator>::value);
Eric Fiselierb63508a2017-04-19 01:23:04 +00001114#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001115
1116 ~__tree();
1117
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001118 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001119 iterator begin() _NOEXCEPT {return iterator(__begin_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001120 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001121 const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001122 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001123 iterator end() _NOEXCEPT {return iterator(__end_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001124 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001125 const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001126
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001127 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001128 size_type max_size() const _NOEXCEPT
Eric Fiselierb5d9f442016-11-23 01:18:56 +00001129 {return std::min<size_type>(
1130 __node_traits::max_size(__node_alloc()),
1131 numeric_limits<difference_type >::max());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001132
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001133 void clear() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001134
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001135 void swap(__tree& __t)
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001136#if _LIBCPP_STD_VER <= 11
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001137 _NOEXCEPT_(
Marshall Clow8982dcd2015-07-13 20:04:56 +00001138 __is_nothrow_swappable<value_compare>::value
Marshall Clow8982dcd2015-07-13 20:04:56 +00001139 && (!__node_traits::propagate_on_container_swap::value ||
1140 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001141 );
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001142#else
1143 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1144#endif
Eric Fiselierd06276b2016-03-31 02:15:15 +00001145
1146#ifndef _LIBCPP_CXX03_LANG
1147 template <class _Key, class ..._Args>
1148 pair<iterator, bool>
1149 __emplace_unique_key_args(_Key const&, _Args&&... __args);
1150 template <class _Key, class ..._Args>
1151 iterator
1152 __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001153
1154 template <class... _Args>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001155 pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
Eric Fiselierd06276b2016-03-31 02:15:15 +00001156
Howard Hinnantc51e1022010-05-11 19:42:16 +00001157 template <class... _Args>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001158 iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001159
Eric Fiselierd06276b2016-03-31 02:15:15 +00001160 template <class... _Args>
1161 iterator __emplace_multi(_Args&&... __args);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001162
Eric Fiselierd06276b2016-03-31 02:15:15 +00001163 template <class... _Args>
1164 iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001165
1166 template <class _Pp>
1167 _LIBCPP_INLINE_VISIBILITY
1168 pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1169 return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1170 __can_extract_key<_Pp, key_type>());
1171 }
1172
Eric Fiselierf1e45ce2016-04-16 00:23:12 +00001173 template <class _First, class _Second>
1174 _LIBCPP_INLINE_VISIBILITY
1175 typename enable_if<
1176 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1177 pair<iterator, bool>
1178 >::type __emplace_unique(_First&& __f, _Second&& __s) {
1179 return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1180 _VSTD::forward<_Second>(__s));
1181 }
1182
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001183 template <class... _Args>
1184 _LIBCPP_INLINE_VISIBILITY
1185 pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1186 return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1187 }
1188
1189 template <class _Pp>
1190 _LIBCPP_INLINE_VISIBILITY
1191 pair<iterator, bool>
1192 __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1193 return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1194 }
1195
1196 template <class _Pp>
1197 _LIBCPP_INLINE_VISIBILITY
1198 pair<iterator, bool>
1199 __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1200 return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1201 }
1202
1203 template <class _Pp>
1204 _LIBCPP_INLINE_VISIBILITY
1205 pair<iterator, bool>
1206 __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1207 return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1208 }
1209
1210 template <class _Pp>
1211 _LIBCPP_INLINE_VISIBILITY
1212 iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1213 return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1214 __can_extract_key<_Pp, key_type>());
1215 }
1216
Eric Fiselierf1e45ce2016-04-16 00:23:12 +00001217 template <class _First, class _Second>
1218 _LIBCPP_INLINE_VISIBILITY
1219 typename enable_if<
1220 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1221 iterator
1222 >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
1223 return __emplace_hint_unique_key_args(__p, __f,
1224 _VSTD::forward<_First>(__f),
1225 _VSTD::forward<_Second>(__s));
1226 }
1227
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001228 template <class... _Args>
1229 _LIBCPP_INLINE_VISIBILITY
1230 iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1231 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1232 }
1233
1234 template <class _Pp>
1235 _LIBCPP_INLINE_VISIBILITY
1236 iterator
1237 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1238 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
1239 }
1240
1241 template <class _Pp>
1242 _LIBCPP_INLINE_VISIBILITY
1243 iterator
1244 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1245 return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x));
1246 }
1247
1248 template <class _Pp>
1249 _LIBCPP_INLINE_VISIBILITY
1250 iterator
1251 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1252 return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x));
1253 }
1254
Eric Fiselierd06276b2016-03-31 02:15:15 +00001255#else
1256 template <class _Key, class _Args>
1257 _LIBCPP_INLINE_VISIBILITY
1258 pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args);
1259 template <class _Key, class _Args>
1260 _LIBCPP_INLINE_VISIBILITY
1261 iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&);
Marshall Clowd430d022016-01-05 19:32:41 +00001262#endif
1263
Eric Fiselierd06276b2016-03-31 02:15:15 +00001264 _LIBCPP_INLINE_VISIBILITY
1265 pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
1266 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
1267 }
1268
1269 _LIBCPP_INLINE_VISIBILITY
1270 iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
1271 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v);
1272 }
1273
1274#ifdef _LIBCPP_CXX03_LANG
1275 _LIBCPP_INLINE_VISIBILITY
1276 iterator __insert_multi(const __container_value_type& __v);
1277 _LIBCPP_INLINE_VISIBILITY
1278 iterator __insert_multi(const_iterator __p, const __container_value_type& __v);
1279#else
1280 _LIBCPP_INLINE_VISIBILITY
1281 pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
1282 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
1283 }
1284
1285 _LIBCPP_INLINE_VISIBILITY
1286 iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
1287 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v));
1288 }
1289
1290 template <class _Vp, class = typename enable_if<
1291 !is_same<typename __unconstref<_Vp>::type,
1292 __container_value_type
1293 >::value
1294 >::type>
1295 _LIBCPP_INLINE_VISIBILITY
1296 pair<iterator, bool> __insert_unique(_Vp&& __v) {
1297 return __emplace_unique(_VSTD::forward<_Vp>(__v));
1298 }
1299
1300 template <class _Vp, class = typename enable_if<
1301 !is_same<typename __unconstref<_Vp>::type,
1302 __container_value_type
1303 >::value
1304 >::type>
1305 _LIBCPP_INLINE_VISIBILITY
1306 iterator __insert_unique(const_iterator __p, _Vp&& __v) {
1307 return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
1308 }
1309
1310 _LIBCPP_INLINE_VISIBILITY
1311 iterator __insert_multi(__container_value_type&& __v) {
1312 return __emplace_multi(_VSTD::move(__v));
1313 }
1314
1315 _LIBCPP_INLINE_VISIBILITY
1316 iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
1317 return __emplace_hint_multi(__p, _VSTD::move(__v));
1318 }
1319
1320 template <class _Vp>
1321 _LIBCPP_INLINE_VISIBILITY
1322 iterator __insert_multi(_Vp&& __v) {
1323 return __emplace_multi(_VSTD::forward<_Vp>(__v));
1324 }
1325
1326 template <class _Vp>
1327 _LIBCPP_INLINE_VISIBILITY
1328 iterator __insert_multi(const_iterator __p, _Vp&& __v) {
1329 return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
1330 }
1331
1332#endif // !_LIBCPP_CXX03_LANG
1333
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001335 pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001336 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001337 iterator __node_insert_unique(const_iterator __p,
1338 __node_pointer __nd);
1339
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001340 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001341 iterator __node_insert_multi(__node_pointer __nd);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001342 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001343 iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1344
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001345
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001346 _LIBCPP_INLINE_VISIBILITY iterator
1347 __remove_node_pointer(__node_pointer) _NOEXCEPT;
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001348
1349#if _LIBCPP_STD_VER > 14
1350 template <class _NodeHandle, class _InsertReturnType>
1351 _LIBCPP_INLINE_VISIBILITY
1352 _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
1353 template <class _NodeHandle>
1354 _LIBCPP_INLINE_VISIBILITY
1355 iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001356 template <class _Tree>
1357 _LIBCPP_INLINE_VISIBILITY
1358 void __node_handle_merge_unique(_Tree& __source);
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001359
1360 template <class _NodeHandle>
1361 _LIBCPP_INLINE_VISIBILITY
1362 iterator __node_handle_insert_multi(_NodeHandle&&);
1363 template <class _NodeHandle>
1364 _LIBCPP_INLINE_VISIBILITY
1365 iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001366 template <class _Tree>
1367 _LIBCPP_INLINE_VISIBILITY
1368 void __node_handle_merge_multi(_Tree& __source);
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001369
1370
1371 template <class _NodeHandle>
1372 _LIBCPP_INLINE_VISIBILITY
1373 _NodeHandle __node_handle_extract(key_type const&);
1374 template <class _NodeHandle>
1375 _LIBCPP_INLINE_VISIBILITY
1376 _NodeHandle __node_handle_extract(const_iterator);
1377#endif
1378
Howard Hinnantc51e1022010-05-11 19:42:16 +00001379 iterator erase(const_iterator __p);
1380 iterator erase(const_iterator __f, const_iterator __l);
1381 template <class _Key>
1382 size_type __erase_unique(const _Key& __k);
1383 template <class _Key>
1384 size_type __erase_multi(const _Key& __k);
1385
Eric Fiselier70f5f872016-07-19 17:56:20 +00001386 void __insert_node_at(__parent_pointer __parent,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001387 __node_base_pointer& __child,
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001388 __node_base_pointer __new_node) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001389
1390 template <class _Key>
1391 iterator find(const _Key& __v);
1392 template <class _Key>
1393 const_iterator find(const _Key& __v) const;
1394
1395 template <class _Key>
1396 size_type __count_unique(const _Key& __k) const;
1397 template <class _Key>
1398 size_type __count_multi(const _Key& __k) const;
1399
1400 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001402 iterator lower_bound(const _Key& __v)
1403 {return __lower_bound(__v, __root(), __end_node());}
1404 template <class _Key>
1405 iterator __lower_bound(const _Key& __v,
1406 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001407 __iter_pointer __result);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001408 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001409 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001410 const_iterator lower_bound(const _Key& __v) const
1411 {return __lower_bound(__v, __root(), __end_node());}
1412 template <class _Key>
1413 const_iterator __lower_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00001414 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001415 __iter_pointer __result) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001416 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001418 iterator upper_bound(const _Key& __v)
1419 {return __upper_bound(__v, __root(), __end_node());}
1420 template <class _Key>
1421 iterator __upper_bound(const _Key& __v,
1422 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001423 __iter_pointer __result);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001424 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001425 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001426 const_iterator upper_bound(const _Key& __v) const
1427 {return __upper_bound(__v, __root(), __end_node());}
1428 template <class _Key>
1429 const_iterator __upper_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00001430 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001431 __iter_pointer __result) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001432 template <class _Key>
1433 pair<iterator, iterator>
1434 __equal_range_unique(const _Key& __k);
1435 template <class _Key>
1436 pair<const_iterator, const_iterator>
1437 __equal_range_unique(const _Key& __k) const;
1438
1439 template <class _Key>
1440 pair<iterator, iterator>
1441 __equal_range_multi(const _Key& __k);
1442 template <class _Key>
1443 pair<const_iterator, const_iterator>
1444 __equal_range_multi(const _Key& __k) const;
1445
Howard Hinnantc834c512011-11-29 18:15:50 +00001446 typedef __tree_node_destructor<__node_allocator> _Dp;
1447 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001448
Howard Hinnant1113b5e2011-06-04 17:10:24 +00001449 __node_holder remove(const_iterator __p) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001450private:
Eric Fiselier70f5f872016-07-19 17:56:20 +00001451 __node_base_pointer&
1452 __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1453 __node_base_pointer&
1454 __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1455 __node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00001456 __find_leaf(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001457 __parent_pointer& __parent, const key_type& __v);
Eric Fiseliercf8c0212017-01-05 06:06:18 +00001458 // FIXME: Make this function const qualified. Unfortunetly doing so
1459 // breaks existing code which uses non-const callable comparators.
Howard Hinnantc51e1022010-05-11 19:42:16 +00001460 template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001461 __node_base_pointer&
1462 __find_equal(__parent_pointer& __parent, const _Key& __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001463 template <class _Key>
Eric Fiseliercf8c0212017-01-05 06:06:18 +00001464 _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1465 __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1466 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1467 }
1468 template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001469 __node_base_pointer&
1470 __find_equal(const_iterator __hint, __parent_pointer& __parent,
1471 __node_base_pointer& __dummy,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001472 const _Key& __v);
1473
Eric Fiselierd06276b2016-03-31 02:15:15 +00001474#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001475 template <class ..._Args>
Eric Fiselierd06276b2016-03-31 02:15:15 +00001476 __node_holder __construct_node(_Args&& ...__args);
1477#else
1478 __node_holder __construct_node(const __container_value_type& __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001479#endif
1480
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001481 void destroy(__node_pointer __nd) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001482
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001484 void __copy_assign_alloc(const __tree& __t)
1485 {__copy_assign_alloc(__t, integral_constant<bool,
1486 __node_traits::propagate_on_container_copy_assignment::value>());}
1487
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001488 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001489 void __copy_assign_alloc(const __tree& __t, true_type)
Marshall Clowac8a40b2016-08-17 23:24:02 +00001490 {
1491 if (__node_alloc() != __t.__node_alloc())
Louis Dionne44bcff92018-08-03 22:36:53 +00001492 clear();
Marshall Clowac8a40b2016-08-17 23:24:02 +00001493 __node_alloc() = __t.__node_alloc();
1494 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001495 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001496 void __copy_assign_alloc(const __tree&, false_type) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001497
1498 void __move_assign(__tree& __t, false_type);
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001499 void __move_assign(__tree& __t, true_type)
1500 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1501 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001502
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001503 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001504 void __move_assign_alloc(__tree& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001505 _NOEXCEPT_(
1506 !__node_traits::propagate_on_container_move_assignment::value ||
1507 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001508 {__move_assign_alloc(__t, integral_constant<bool,
1509 __node_traits::propagate_on_container_move_assignment::value>());}
1510
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001512 void __move_assign_alloc(__tree& __t, true_type)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001513 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001514 {__node_alloc() = _VSTD::move(__t.__node_alloc());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001515 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001516 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001517
Howard Hinnantc51e1022010-05-11 19:42:16 +00001518 __node_pointer __detach();
1519 static __node_pointer __detach(__node_pointer);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001520
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001521 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1522 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001523};
1524
1525template <class _Tp, class _Compare, class _Allocator>
1526__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001527 _NOEXCEPT_(
1528 is_nothrow_default_constructible<__node_allocator>::value &&
1529 is_nothrow_copy_constructible<value_compare>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001530 : __pair3_(0, __comp)
1531{
1532 __begin_node() = __end_node();
1533}
1534
1535template <class _Tp, class _Compare, class _Allocator>
1536__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001537 : __begin_node_(__iter_pointer()),
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001538 __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001539 __pair3_(0)
1540{
1541 __begin_node() = __end_node();
1542}
1543
1544template <class _Tp, class _Compare, class _Allocator>
1545__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1546 const allocator_type& __a)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001547 : __begin_node_(__iter_pointer()),
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001548 __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001549 __pair3_(0, __comp)
1550{
1551 __begin_node() = __end_node();
1552}
1553
1554// Precondition: size() != 0
1555template <class _Tp, class _Compare, class _Allocator>
1556typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1557__tree<_Tp, _Compare, _Allocator>::__detach()
1558{
Eric Fiselier70f5f872016-07-19 17:56:20 +00001559 __node_pointer __cache = static_cast<__node_pointer>(__begin_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001560 __begin_node() = __end_node();
1561 __end_node()->__left_->__parent_ = nullptr;
1562 __end_node()->__left_ = nullptr;
1563 size() = 0;
1564 // __cache->__left_ == nullptr
1565 if (__cache->__right_ != nullptr)
1566 __cache = static_cast<__node_pointer>(__cache->__right_);
1567 // __cache->__left_ == nullptr
1568 // __cache->__right_ == nullptr
1569 return __cache;
1570}
1571
1572// Precondition: __cache != nullptr
1573// __cache->left_ == nullptr
1574// __cache->right_ == nullptr
1575// This is no longer a red-black tree
1576template <class _Tp, class _Compare, class _Allocator>
1577typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1578__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
1579{
1580 if (__cache->__parent_ == nullptr)
1581 return nullptr;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001582 if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001583 {
1584 __cache->__parent_->__left_ = nullptr;
1585 __cache = static_cast<__node_pointer>(__cache->__parent_);
1586 if (__cache->__right_ == nullptr)
1587 return __cache;
1588 return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
1589 }
1590 // __cache is right child
Eric Fiselier70f5f872016-07-19 17:56:20 +00001591 __cache->__parent_unsafe()->__right_ = nullptr;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001592 __cache = static_cast<__node_pointer>(__cache->__parent_);
1593 if (__cache->__left_ == nullptr)
1594 return __cache;
1595 return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
1596}
1597
1598template <class _Tp, class _Compare, class _Allocator>
1599__tree<_Tp, _Compare, _Allocator>&
1600__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1601{
1602 if (this != &__t)
1603 {
1604 value_comp() = __t.value_comp();
1605 __copy_assign_alloc(__t);
1606 __assign_multi(__t.begin(), __t.end());
1607 }
1608 return *this;
1609}
1610
1611template <class _Tp, class _Compare, class _Allocator>
1612template <class _InputIterator>
1613void
1614__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
1615{
Eric Fiselierd06276b2016-03-31 02:15:15 +00001616 typedef iterator_traits<_InputIterator> _ITraits;
1617 typedef typename _ITraits::value_type _ItValueType;
1618 static_assert((is_same<_ItValueType, __container_value_type>::value),
1619 "__assign_unique may only be called with the containers value type");
1620
Howard Hinnantc51e1022010-05-11 19:42:16 +00001621 if (size() != 0)
1622 {
1623 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001624#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001625 try
1626 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001627#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001628 for (; __cache != nullptr && __first != __last; ++__first)
1629 {
1630 __cache->__value_ = *__first;
1631 __node_pointer __next = __detach(__cache);
1632 __node_insert_unique(__cache);
1633 __cache = __next;
1634 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001635#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001636 }
1637 catch (...)
1638 {
1639 while (__cache->__parent_ != nullptr)
1640 __cache = static_cast<__node_pointer>(__cache->__parent_);
1641 destroy(__cache);
1642 throw;
1643 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001644#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001645 if (__cache != nullptr)
1646 {
1647 while (__cache->__parent_ != nullptr)
1648 __cache = static_cast<__node_pointer>(__cache->__parent_);
1649 destroy(__cache);
1650 }
1651 }
1652 for (; __first != __last; ++__first)
1653 __insert_unique(*__first);
1654}
1655
1656template <class _Tp, class _Compare, class _Allocator>
1657template <class _InputIterator>
1658void
1659__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1660{
Eric Fiselierd06276b2016-03-31 02:15:15 +00001661 typedef iterator_traits<_InputIterator> _ITraits;
1662 typedef typename _ITraits::value_type _ItValueType;
1663 static_assert((is_same<_ItValueType, __container_value_type>::value ||
1664 is_same<_ItValueType, __node_value_type>::value),
1665 "__assign_multi may only be called with the containers value type"
1666 " or the nodes value type");
Howard Hinnantc51e1022010-05-11 19:42:16 +00001667 if (size() != 0)
1668 {
1669 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001670#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001671 try
1672 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001673#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001674 for (; __cache != nullptr && __first != __last; ++__first)
1675 {
1676 __cache->__value_ = *__first;
1677 __node_pointer __next = __detach(__cache);
1678 __node_insert_multi(__cache);
1679 __cache = __next;
1680 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001681#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001682 }
1683 catch (...)
1684 {
1685 while (__cache->__parent_ != nullptr)
1686 __cache = static_cast<__node_pointer>(__cache->__parent_);
1687 destroy(__cache);
1688 throw;
1689 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001690#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001691 if (__cache != nullptr)
1692 {
1693 while (__cache->__parent_ != nullptr)
1694 __cache = static_cast<__node_pointer>(__cache->__parent_);
1695 destroy(__cache);
1696 }
1697 }
1698 for (; __first != __last; ++__first)
Eric Fiselierd06276b2016-03-31 02:15:15 +00001699 __insert_multi(_NodeTypes::__get_value(*__first));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001700}
1701
1702template <class _Tp, class _Compare, class _Allocator>
1703__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001704 : __begin_node_(__iter_pointer()),
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001705 __pair1_(__second_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001706 __pair3_(0, __t.value_comp())
1707{
1708 __begin_node() = __end_node();
1709}
1710
Eric Fiselierb63508a2017-04-19 01:23:04 +00001711#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001712
1713template <class _Tp, class _Compare, class _Allocator>
1714__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001715 _NOEXCEPT_(
1716 is_nothrow_move_constructible<__node_allocator>::value &&
1717 is_nothrow_move_constructible<value_compare>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001718 : __begin_node_(_VSTD::move(__t.__begin_node_)),
1719 __pair1_(_VSTD::move(__t.__pair1_)),
1720 __pair3_(_VSTD::move(__t.__pair3_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001721{
1722 if (size() == 0)
1723 __begin_node() = __end_node();
1724 else
1725 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001726 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001727 __t.__begin_node() = __t.__end_node();
1728 __t.__end_node()->__left_ = nullptr;
1729 __t.size() = 0;
1730 }
1731}
1732
1733template <class _Tp, class _Compare, class _Allocator>
1734__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001735 : __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001736 __pair3_(0, _VSTD::move(__t.value_comp()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001737{
1738 if (__a == __t.__alloc())
1739 {
1740 if (__t.size() == 0)
1741 __begin_node() = __end_node();
1742 else
1743 {
1744 __begin_node() = __t.__begin_node();
1745 __end_node()->__left_ = __t.__end_node()->__left_;
Eric Fiselier70f5f872016-07-19 17:56:20 +00001746 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001747 size() = __t.size();
1748 __t.__begin_node() = __t.__end_node();
1749 __t.__end_node()->__left_ = nullptr;
1750 __t.size() = 0;
1751 }
1752 }
1753 else
1754 {
1755 __begin_node() = __end_node();
1756 }
1757}
1758
1759template <class _Tp, class _Compare, class _Allocator>
1760void
1761__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001762 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1763 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001764{
1765 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1766 __begin_node_ = __t.__begin_node_;
1767 __pair1_.first() = __t.__pair1_.first();
1768 __move_assign_alloc(__t);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001769 __pair3_ = _VSTD::move(__t.__pair3_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001770 if (size() == 0)
1771 __begin_node() = __end_node();
1772 else
1773 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001774 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001775 __t.__begin_node() = __t.__end_node();
1776 __t.__end_node()->__left_ = nullptr;
1777 __t.size() = 0;
1778 }
1779}
1780
1781template <class _Tp, class _Compare, class _Allocator>
1782void
1783__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1784{
1785 if (__node_alloc() == __t.__node_alloc())
1786 __move_assign(__t, true_type());
1787 else
1788 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001789 value_comp() = _VSTD::move(__t.value_comp());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001790 const_iterator __e = end();
1791 if (size() != 0)
1792 {
1793 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001794#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001795 try
1796 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001797#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001798 while (__cache != nullptr && __t.size() != 0)
1799 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001800 __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001801 __node_pointer __next = __detach(__cache);
1802 __node_insert_multi(__cache);
1803 __cache = __next;
1804 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001805#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001806 }
1807 catch (...)
1808 {
1809 while (__cache->__parent_ != nullptr)
1810 __cache = static_cast<__node_pointer>(__cache->__parent_);
1811 destroy(__cache);
1812 throw;
1813 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001814#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001815 if (__cache != nullptr)
1816 {
1817 while (__cache->__parent_ != nullptr)
1818 __cache = static_cast<__node_pointer>(__cache->__parent_);
1819 destroy(__cache);
1820 }
1821 }
1822 while (__t.size() != 0)
Eric Fiselierd06276b2016-03-31 02:15:15 +00001823 __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001824 }
1825}
1826
1827template <class _Tp, class _Compare, class _Allocator>
1828__tree<_Tp, _Compare, _Allocator>&
1829__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001830 _NOEXCEPT_(
1831 __node_traits::propagate_on_container_move_assignment::value &&
1832 is_nothrow_move_assignable<value_compare>::value &&
1833 is_nothrow_move_assignable<__node_allocator>::value)
Louis Dionne44bcff92018-08-03 22:36:53 +00001834
Howard Hinnantc51e1022010-05-11 19:42:16 +00001835{
1836 __move_assign(__t, integral_constant<bool,
1837 __node_traits::propagate_on_container_move_assignment::value>());
1838 return *this;
1839}
1840
Eric Fiselierb63508a2017-04-19 01:23:04 +00001841#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001842
1843template <class _Tp, class _Compare, class _Allocator>
1844__tree<_Tp, _Compare, _Allocator>::~__tree()
1845{
Marshall Clow140d9432016-06-30 22:05:45 +00001846 static_assert((is_copy_constructible<value_compare>::value),
1847 "Comparator must be copy-constructible.");
Eric Fiseliera7a14ed2017-01-13 22:02:08 +00001848 destroy(__root());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001849}
1850
1851template <class _Tp, class _Compare, class _Allocator>
1852void
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001853__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001854{
1855 if (__nd != nullptr)
1856 {
1857 destroy(static_cast<__node_pointer>(__nd->__left_));
1858 destroy(static_cast<__node_pointer>(__nd->__right_));
1859 __node_allocator& __na = __node_alloc();
Eric Fiselierd06276b2016-03-31 02:15:15 +00001860 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001861 __node_traits::deallocate(__na, __nd, 1);
1862 }
1863}
1864
1865template <class _Tp, class _Compare, class _Allocator>
1866void
1867__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001868#if _LIBCPP_STD_VER <= 11
Marshall Clow8982dcd2015-07-13 20:04:56 +00001869 _NOEXCEPT_(
1870 __is_nothrow_swappable<value_compare>::value
Marshall Clow8982dcd2015-07-13 20:04:56 +00001871 && (!__node_traits::propagate_on_container_swap::value ||
1872 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001873 )
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001874#else
1875 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1876#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001877{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001878 using _VSTD::swap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001879 swap(__begin_node_, __t.__begin_node_);
1880 swap(__pair1_.first(), __t.__pair1_.first());
Marshall Clow8982dcd2015-07-13 20:04:56 +00001881 __swap_allocator(__node_alloc(), __t.__node_alloc());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001882 __pair3_.swap(__t.__pair3_);
1883 if (size() == 0)
1884 __begin_node() = __end_node();
1885 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00001886 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001887 if (__t.size() == 0)
1888 __t.__begin_node() = __t.__end_node();
1889 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00001890 __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001891}
1892
1893template <class _Tp, class _Compare, class _Allocator>
1894void
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001895__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001896{
1897 destroy(__root());
1898 size() = 0;
1899 __begin_node() = __end_node();
1900 __end_node()->__left_ = nullptr;
1901}
1902
1903// Find lower_bound place to insert
1904// Set __parent to parent of null leaf
1905// Return reference to null leaf
1906template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001907typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1908__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001909 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001910{
1911 __node_pointer __nd = __root();
1912 if (__nd != nullptr)
1913 {
1914 while (true)
1915 {
1916 if (value_comp()(__nd->__value_, __v))
1917 {
1918 if (__nd->__right_ != nullptr)
1919 __nd = static_cast<__node_pointer>(__nd->__right_);
1920 else
1921 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001922 __parent = static_cast<__parent_pointer>(__nd);
1923 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001924 }
1925 }
1926 else
1927 {
1928 if (__nd->__left_ != nullptr)
1929 __nd = static_cast<__node_pointer>(__nd->__left_);
1930 else
1931 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001932 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001933 return __parent->__left_;
1934 }
1935 }
1936 }
1937 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00001938 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001939 return __parent->__left_;
1940}
1941
1942// Find upper_bound place to insert
1943// Set __parent to parent of null leaf
1944// Return reference to null leaf
1945template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001946typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1947__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001948 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001949{
1950 __node_pointer __nd = __root();
1951 if (__nd != nullptr)
1952 {
1953 while (true)
1954 {
1955 if (value_comp()(__v, __nd->__value_))
1956 {
1957 if (__nd->__left_ != nullptr)
1958 __nd = static_cast<__node_pointer>(__nd->__left_);
1959 else
1960 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001961 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001962 return __parent->__left_;
1963 }
1964 }
1965 else
1966 {
1967 if (__nd->__right_ != nullptr)
1968 __nd = static_cast<__node_pointer>(__nd->__right_);
1969 else
1970 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001971 __parent = static_cast<__parent_pointer>(__nd);
1972 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001973 }
1974 }
1975 }
1976 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00001977 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001978 return __parent->__left_;
1979}
1980
1981// Find leaf place to insert closest to __hint
1982// First check prior to __hint.
1983// Next check after __hint.
1984// Next do O(log N) search.
1985// Set __parent to parent of null leaf
1986// Return reference to null leaf
1987template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001988typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00001989__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001990 __parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001991 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001992{
1993 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1994 {
1995 // __v <= *__hint
1996 const_iterator __prior = __hint;
1997 if (__prior == begin() || !value_comp()(__v, *--__prior))
1998 {
1999 // *prev(__hint) <= __v <= *__hint
2000 if (__hint.__ptr_->__left_ == nullptr)
2001 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002002 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002003 return __parent->__left_;
2004 }
2005 else
2006 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002007 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2008 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002009 }
2010 }
2011 // __v < *prev(__hint)
2012 return __find_leaf_high(__parent, __v);
2013 }
2014 // else __v > *__hint
2015 return __find_leaf_low(__parent, __v);
2016}
2017
2018// Find place to insert if __v doesn't exist
2019// Set __parent to parent of null leaf
2020// Return reference to null leaf
2021// If __v exists, set parent to node of __v and return reference to node of __v
2022template <class _Tp, class _Compare, class _Allocator>
2023template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00002024typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
2025__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002026 const _Key& __v)
2027{
2028 __node_pointer __nd = __root();
Eric Fiselier70f5f872016-07-19 17:56:20 +00002029 __node_base_pointer* __nd_ptr = __root_ptr();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002030 if (__nd != nullptr)
2031 {
2032 while (true)
2033 {
2034 if (value_comp()(__v, __nd->__value_))
2035 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002036 if (__nd->__left_ != nullptr) {
2037 __nd_ptr = _VSTD::addressof(__nd->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002038 __nd = static_cast<__node_pointer>(__nd->__left_);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002039 } else {
2040 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002041 return __parent->__left_;
2042 }
2043 }
2044 else if (value_comp()(__nd->__value_, __v))
2045 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002046 if (__nd->__right_ != nullptr) {
2047 __nd_ptr = _VSTD::addressof(__nd->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002048 __nd = static_cast<__node_pointer>(__nd->__right_);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002049 } else {
2050 __parent = static_cast<__parent_pointer>(__nd);
2051 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002052 }
2053 }
2054 else
2055 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002056 __parent = static_cast<__parent_pointer>(__nd);
2057 return *__nd_ptr;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002058 }
2059 }
2060 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00002061 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002062 return __parent->__left_;
2063}
2064
2065// Find place to insert if __v doesn't exist
2066// First check prior to __hint.
2067// Next check after __hint.
2068// Next do O(log N) search.
2069// Set __parent to parent of null leaf
2070// Return reference to null leaf
2071// If __v exists, set parent to node of __v and return reference to node of __v
2072template <class _Tp, class _Compare, class _Allocator>
2073template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00002074typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00002075__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002076 __parent_pointer& __parent,
2077 __node_base_pointer& __dummy,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002078 const _Key& __v)
2079{
2080 if (__hint == end() || value_comp()(__v, *__hint)) // check before
2081 {
2082 // __v < *__hint
2083 const_iterator __prior = __hint;
2084 if (__prior == begin() || value_comp()(*--__prior, __v))
2085 {
2086 // *prev(__hint) < __v < *__hint
2087 if (__hint.__ptr_->__left_ == nullptr)
2088 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002089 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002090 return __parent->__left_;
2091 }
2092 else
2093 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002094 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2095 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002096 }
2097 }
2098 // __v <= *prev(__hint)
2099 return __find_equal(__parent, __v);
2100 }
2101 else if (value_comp()(*__hint, __v)) // check after
2102 {
2103 // *__hint < __v
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002104 const_iterator __next = _VSTD::next(__hint);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002105 if (__next == end() || value_comp()(__v, *__next))
2106 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002107 // *__hint < __v < *_VSTD::next(__hint)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002108 if (__hint.__get_np()->__right_ == nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002109 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002110 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2111 return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002112 }
2113 else
2114 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002115 __parent = static_cast<__parent_pointer>(__next.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002116 return __parent->__left_;
2117 }
2118 }
2119 // *next(__hint) <= __v
2120 return __find_equal(__parent, __v);
2121 }
2122 // else __v == *__hint
Eric Fiselier70f5f872016-07-19 17:56:20 +00002123 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2124 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2125 return __dummy;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002126}
2127
2128template <class _Tp, class _Compare, class _Allocator>
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002129void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
2130 __parent_pointer __parent, __node_base_pointer& __child,
2131 __node_base_pointer __new_node) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002132{
2133 __new_node->__left_ = nullptr;
2134 __new_node->__right_ = nullptr;
2135 __new_node->__parent_ = __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002136 // __new_node->__is_black_ is initialized in __tree_balance_after_insert
Howard Hinnantc51e1022010-05-11 19:42:16 +00002137 __child = __new_node;
2138 if (__begin_node()->__left_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002139 __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002140 __tree_balance_after_insert(__end_node()->__left_, __child);
2141 ++size();
2142}
2143
Eric Fiselierd06276b2016-03-31 02:15:15 +00002144#ifndef _LIBCPP_CXX03_LANG
2145template <class _Tp, class _Compare, class _Allocator>
2146template <class _Key, class... _Args>
2147pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2148__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
2149#else
2150template <class _Tp, class _Compare, class _Allocator>
2151template <class _Key, class _Args>
2152pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2153__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args)
2154#endif
2155{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002156 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002157 __node_base_pointer& __child = __find_equal(__parent, __k);
2158 __node_pointer __r = static_cast<__node_pointer>(__child);
2159 bool __inserted = false;
2160 if (__child == nullptr)
2161 {
2162#ifndef _LIBCPP_CXX03_LANG
2163 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2164#else
2165 __node_holder __h = __construct_node(__args);
2166#endif
2167 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2168 __r = __h.release();
2169 __inserted = true;
2170 }
2171 return pair<iterator, bool>(iterator(__r), __inserted);
2172}
2173
2174
2175#ifndef _LIBCPP_CXX03_LANG
2176template <class _Tp, class _Compare, class _Allocator>
2177template <class _Key, class... _Args>
2178typename __tree<_Tp, _Compare, _Allocator>::iterator
2179__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2180 const_iterator __p, _Key const& __k, _Args&&... __args)
2181#else
2182template <class _Tp, class _Compare, class _Allocator>
2183template <class _Key, class _Args>
2184typename __tree<_Tp, _Compare, _Allocator>::iterator
2185__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2186 const_iterator __p, _Key const& __k, _Args& __args)
2187#endif
2188{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002189 __parent_pointer __parent;
2190 __node_base_pointer __dummy;
2191 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
Eric Fiselierd06276b2016-03-31 02:15:15 +00002192 __node_pointer __r = static_cast<__node_pointer>(__child);
2193 if (__child == nullptr)
2194 {
2195#ifndef _LIBCPP_CXX03_LANG
2196 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2197#else
2198 __node_holder __h = __construct_node(__args);
2199#endif
2200 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2201 __r = __h.release();
2202 }
2203 return iterator(__r);
2204}
2205
2206
2207#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00002208
2209template <class _Tp, class _Compare, class _Allocator>
2210template <class ..._Args>
2211typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2212__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
2213{
Eric Fiselierd06276b2016-03-31 02:15:15 +00002214 static_assert(!__is_tree_value_type<_Args...>::value,
2215 "Cannot construct from __value_type");
Howard Hinnantc51e1022010-05-11 19:42:16 +00002216 __node_allocator& __na = __node_alloc();
Howard Hinnantc834c512011-11-29 18:15:50 +00002217 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierd06276b2016-03-31 02:15:15 +00002218 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002219 __h.get_deleter().__value_constructed = true;
2220 return __h;
2221}
2222
Eric Fiselierd06276b2016-03-31 02:15:15 +00002223
Howard Hinnantc51e1022010-05-11 19:42:16 +00002224template <class _Tp, class _Compare, class _Allocator>
2225template <class... _Args>
2226pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00002227__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002228{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002229 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002230 __parent_pointer __parent;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002231 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
2232 __node_pointer __r = static_cast<__node_pointer>(__child);
2233 bool __inserted = false;
2234 if (__child == nullptr)
2235 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002236 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002237 __r = __h.release();
2238 __inserted = true;
2239 }
2240 return pair<iterator, bool>(iterator(__r), __inserted);
2241}
2242
2243template <class _Tp, class _Compare, class _Allocator>
2244template <class... _Args>
2245typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselier6cce51e2016-04-15 23:27:27 +00002246__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002247{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002248 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002249 __parent_pointer __parent;
2250 __node_base_pointer __dummy;
2251 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002252 __node_pointer __r = static_cast<__node_pointer>(__child);
2253 if (__child == nullptr)
2254 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002255 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002256 __r = __h.release();
2257 }
2258 return iterator(__r);
2259}
2260
2261template <class _Tp, class _Compare, class _Allocator>
2262template <class... _Args>
2263typename __tree<_Tp, _Compare, _Allocator>::iterator
2264__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
2265{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002266 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002267 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002268 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002269 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002270 return iterator(static_cast<__node_pointer>(__h.release()));
2271}
2272
2273template <class _Tp, class _Compare, class _Allocator>
2274template <class... _Args>
2275typename __tree<_Tp, _Compare, _Allocator>::iterator
2276__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
2277 _Args&&... __args)
2278{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002279 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002280 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002281 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002282 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002283 return iterator(static_cast<__node_pointer>(__h.release()));
2284}
2285
Howard Hinnant74279a52010-09-04 23:28:19 +00002286
Eric Fiselierd06276b2016-03-31 02:15:15 +00002287#else // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00002288
2289template <class _Tp, class _Compare, class _Allocator>
2290typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Eric Fiselierd06276b2016-03-31 02:15:15 +00002291__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002292{
2293 __node_allocator& __na = __node_alloc();
Howard Hinnantc834c512011-11-29 18:15:50 +00002294 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierd06276b2016-03-31 02:15:15 +00002295 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002296 __h.get_deleter().__value_constructed = true;
Dimitry Andric830fb602015-08-19 06:43:33 +00002297 return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
Howard Hinnantc51e1022010-05-11 19:42:16 +00002298}
2299
Eric Fiselierd06276b2016-03-31 02:15:15 +00002300#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc5bc8672011-03-10 17:27:57 +00002301
Eric Fiselierd06276b2016-03-31 02:15:15 +00002302#ifdef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00002303template <class _Tp, class _Compare, class _Allocator>
2304typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierd06276b2016-03-31 02:15:15 +00002305__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002306{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002307 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002308 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002309 __node_holder __h = __construct_node(__v);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002310 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002311 return iterator(__h.release());
2312}
2313
2314template <class _Tp, class _Compare, class _Allocator>
2315typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierd06276b2016-03-31 02:15:15 +00002316__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002317{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002318 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002319 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002320 __node_holder __h = __construct_node(__v);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002321 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002322 return iterator(__h.release());
2323}
Eric Fiselierd06276b2016-03-31 02:15:15 +00002324#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00002325
Howard Hinnantc51e1022010-05-11 19:42:16 +00002326template <class _Tp, class _Compare, class _Allocator>
2327pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2328__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
2329{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002330 __parent_pointer __parent;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002331 __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
2332 __node_pointer __r = static_cast<__node_pointer>(__child);
2333 bool __inserted = false;
2334 if (__child == nullptr)
2335 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002336 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002337 __r = __nd;
2338 __inserted = true;
2339 }
2340 return pair<iterator, bool>(iterator(__r), __inserted);
2341}
2342
2343template <class _Tp, class _Compare, class _Allocator>
2344typename __tree<_Tp, _Compare, _Allocator>::iterator
2345__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
2346 __node_pointer __nd)
2347{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002348 __parent_pointer __parent;
2349 __node_base_pointer __dummy;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002350 __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
2351 __node_pointer __r = static_cast<__node_pointer>(__child);
2352 if (__child == nullptr)
2353 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002354 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002355 __r = __nd;
2356 }
2357 return iterator(__r);
2358}
2359
2360template <class _Tp, class _Compare, class _Allocator>
2361typename __tree<_Tp, _Compare, _Allocator>::iterator
2362__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
2363{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002364 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002365 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002366 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002367 return iterator(__nd);
2368}
2369
2370template <class _Tp, class _Compare, class _Allocator>
2371typename __tree<_Tp, _Compare, _Allocator>::iterator
2372__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
2373 __node_pointer __nd)
2374{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002375 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002376 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002377 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002378 return iterator(__nd);
2379}
2380
2381template <class _Tp, class _Compare, class _Allocator>
2382typename __tree<_Tp, _Compare, _Allocator>::iterator
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002383__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002384{
2385 iterator __r(__ptr);
2386 ++__r;
2387 if (__begin_node() == __ptr)
2388 __begin_node() = __r.__ptr_;
2389 --size();
2390 __tree_remove(__end_node()->__left_,
2391 static_cast<__node_base_pointer>(__ptr));
2392 return __r;
2393}
2394
2395#if _LIBCPP_STD_VER > 14
2396template <class _Tp, class _Compare, class _Allocator>
2397template <class _NodeHandle, class _InsertReturnType>
2398_LIBCPP_INLINE_VISIBILITY
2399_InsertReturnType
2400__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2401 _NodeHandle&& __nh)
2402{
2403 if (__nh.empty())
2404 return _InsertReturnType{end(), false, _NodeHandle()};
2405
2406 __node_pointer __ptr = __nh.__ptr_;
2407 __parent_pointer __parent;
2408 __node_base_pointer& __child = __find_equal(__parent,
2409 __ptr->__value_);
2410 if (__child != nullptr)
2411 return _InsertReturnType{
2412 iterator(static_cast<__node_pointer>(__child)),
2413 false, _VSTD::move(__nh)};
2414
2415 __insert_node_at(__parent, __child,
2416 static_cast<__node_base_pointer>(__ptr));
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002417 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002418 return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
2419}
2420
2421template <class _Tp, class _Compare, class _Allocator>
2422template <class _NodeHandle>
2423_LIBCPP_INLINE_VISIBILITY
2424typename __tree<_Tp, _Compare, _Allocator>::iterator
2425__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2426 const_iterator __hint, _NodeHandle&& __nh)
2427{
2428 if (__nh.empty())
2429 return end();
2430
2431 __node_pointer __ptr = __nh.__ptr_;
2432 __parent_pointer __parent;
2433 __node_base_pointer __dummy;
2434 __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
2435 __ptr->__value_);
2436 __node_pointer __r = static_cast<__node_pointer>(__child);
2437 if (__child == nullptr)
2438 {
2439 __insert_node_at(__parent, __child,
2440 static_cast<__node_base_pointer>(__ptr));
2441 __r = __ptr;
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002442 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002443 }
2444 return iterator(__r);
2445}
2446
2447template <class _Tp, class _Compare, class _Allocator>
2448template <class _NodeHandle>
2449_LIBCPP_INLINE_VISIBILITY
2450_NodeHandle
2451__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
2452{
2453 iterator __it = find(__key);
2454 if (__it == end())
2455 return _NodeHandle();
2456 return __node_handle_extract<_NodeHandle>(__it);
2457}
2458
2459template <class _Tp, class _Compare, class _Allocator>
2460template <class _NodeHandle>
2461_LIBCPP_INLINE_VISIBILITY
2462_NodeHandle
2463__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
2464{
2465 __node_pointer __np = __p.__get_np();
2466 __remove_node_pointer(__np);
2467 return _NodeHandle(__np, __alloc());
2468}
2469
2470template <class _Tp, class _Compare, class _Allocator>
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002471template <class _Tree>
2472_LIBCPP_INLINE_VISIBILITY
2473void
2474__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
2475{
2476 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2477
2478 for (typename _Tree::iterator __i = __source.begin();
2479 __i != __source.end();)
2480 {
2481 __node_pointer __src_ptr = __i.__get_np();
2482 __parent_pointer __parent;
2483 __node_base_pointer& __child =
2484 __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
2485 ++__i;
2486 if (__child != nullptr)
2487 continue;
2488 __source.__remove_node_pointer(__src_ptr);
2489 __insert_node_at(__parent, __child,
2490 static_cast<__node_base_pointer>(__src_ptr));
2491 }
2492}
2493
2494template <class _Tp, class _Compare, class _Allocator>
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002495template <class _NodeHandle>
2496_LIBCPP_INLINE_VISIBILITY
2497typename __tree<_Tp, _Compare, _Allocator>::iterator
2498__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
2499{
2500 if (__nh.empty())
2501 return end();
2502 __node_pointer __ptr = __nh.__ptr_;
2503 __parent_pointer __parent;
2504 __node_base_pointer& __child = __find_leaf_high(
2505 __parent, _NodeTypes::__get_key(__ptr->__value_));
2506 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002507 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002508 return iterator(__ptr);
2509}
2510
2511template <class _Tp, class _Compare, class _Allocator>
2512template <class _NodeHandle>
2513_LIBCPP_INLINE_VISIBILITY
2514typename __tree<_Tp, _Compare, _Allocator>::iterator
2515__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
2516 const_iterator __hint, _NodeHandle&& __nh)
2517{
2518 if (__nh.empty())
2519 return end();
2520
2521 __node_pointer __ptr = __nh.__ptr_;
2522 __parent_pointer __parent;
2523 __node_base_pointer& __child = __find_leaf(__hint, __parent,
2524 _NodeTypes::__get_key(__ptr->__value_));
2525 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
Eric Fiselierb59eaa72019-04-24 09:43:44 +00002526 __nh.__release_ptr();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002527 return iterator(__ptr);
2528}
2529
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002530template <class _Tp, class _Compare, class _Allocator>
2531template <class _Tree>
2532_LIBCPP_INLINE_VISIBILITY
2533void
2534__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
2535{
2536 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2537
2538 for (typename _Tree::iterator __i = __source.begin();
2539 __i != __source.end();)
2540 {
2541 __node_pointer __src_ptr = __i.__get_np();
2542 __parent_pointer __parent;
2543 __node_base_pointer& __child = __find_leaf_high(
2544 __parent, _NodeTypes::__get_key(__src_ptr->__value_));
2545 ++__i;
2546 __source.__remove_node_pointer(__src_ptr);
2547 __insert_node_at(__parent, __child,
2548 static_cast<__node_base_pointer>(__src_ptr));
2549 }
2550}
2551
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002552#endif // _LIBCPP_STD_VER > 14
2553
2554template <class _Tp, class _Compare, class _Allocator>
2555typename __tree<_Tp, _Compare, _Allocator>::iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +00002556__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
2557{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002558 __node_pointer __np = __p.__get_np();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002559 iterator __r = __remove_node_pointer(__np);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002560 __node_allocator& __na = __node_alloc();
Eric Fiselierd06276b2016-03-31 02:15:15 +00002561 __node_traits::destroy(__na, _NodeTypes::__get_ptr(
2562 const_cast<__node_value_type&>(*__p)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002563 __node_traits::deallocate(__na, __np, 1);
2564 return __r;
2565}
2566
2567template <class _Tp, class _Compare, class _Allocator>
2568typename __tree<_Tp, _Compare, _Allocator>::iterator
2569__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
2570{
2571 while (__f != __l)
2572 __f = erase(__f);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002573 return iterator(__l.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002574}
2575
2576template <class _Tp, class _Compare, class _Allocator>
2577template <class _Key>
2578typename __tree<_Tp, _Compare, _Allocator>::size_type
2579__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
2580{
2581 iterator __i = find(__k);
2582 if (__i == end())
2583 return 0;
2584 erase(__i);
2585 return 1;
2586}
2587
2588template <class _Tp, class _Compare, class _Allocator>
2589template <class _Key>
2590typename __tree<_Tp, _Compare, _Allocator>::size_type
2591__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
2592{
2593 pair<iterator, iterator> __p = __equal_range_multi(__k);
2594 size_type __r = 0;
2595 for (; __p.first != __p.second; ++__r)
2596 __p.first = erase(__p.first);
2597 return __r;
2598}
2599
2600template <class _Tp, class _Compare, class _Allocator>
2601template <class _Key>
2602typename __tree<_Tp, _Compare, _Allocator>::iterator
2603__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
2604{
2605 iterator __p = __lower_bound(__v, __root(), __end_node());
2606 if (__p != end() && !value_comp()(__v, *__p))
2607 return __p;
2608 return end();
2609}
2610
2611template <class _Tp, class _Compare, class _Allocator>
2612template <class _Key>
2613typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2614__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
2615{
2616 const_iterator __p = __lower_bound(__v, __root(), __end_node());
2617 if (__p != end() && !value_comp()(__v, *__p))
2618 return __p;
2619 return end();
2620}
2621
2622template <class _Tp, class _Compare, class _Allocator>
2623template <class _Key>
2624typename __tree<_Tp, _Compare, _Allocator>::size_type
2625__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
2626{
Eric Fiseliera92b0732016-02-20 07:12:17 +00002627 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002628 while (__rt != nullptr)
2629 {
2630 if (value_comp()(__k, __rt->__value_))
2631 {
Eric Fiseliera92b0732016-02-20 07:12:17 +00002632 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002633 }
2634 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002635 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002636 else
2637 return 1;
2638 }
2639 return 0;
2640}
2641
2642template <class _Tp, class _Compare, class _Allocator>
2643template <class _Key>
2644typename __tree<_Tp, _Compare, _Allocator>::size_type
2645__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
2646{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002647 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002648 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002649 while (__rt != nullptr)
2650 {
2651 if (value_comp()(__k, __rt->__value_))
2652 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002653 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002654 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002655 }
2656 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002657 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002658 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002659 return _VSTD::distance(
Eric Fiselier70f5f872016-07-19 17:56:20 +00002660 __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiseliera92b0732016-02-20 07:12:17 +00002661 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002662 );
2663 }
2664 return 0;
2665}
2666
2667template <class _Tp, class _Compare, class _Allocator>
2668template <class _Key>
2669typename __tree<_Tp, _Compare, _Allocator>::iterator
2670__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2671 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002672 __iter_pointer __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002673{
2674 while (__root != nullptr)
2675 {
2676 if (!value_comp()(__root->__value_, __v))
2677 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002678 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002679 __root = static_cast<__node_pointer>(__root->__left_);
2680 }
2681 else
2682 __root = static_cast<__node_pointer>(__root->__right_);
2683 }
2684 return iterator(__result);
2685}
2686
2687template <class _Tp, class _Compare, class _Allocator>
2688template <class _Key>
2689typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2690__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00002691 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002692 __iter_pointer __result) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00002693{
2694 while (__root != nullptr)
2695 {
2696 if (!value_comp()(__root->__value_, __v))
2697 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002698 __result = static_cast<__iter_pointer>(__root);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002699 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002700 }
2701 else
Eric Fiseliera92b0732016-02-20 07:12:17 +00002702 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002703 }
2704 return const_iterator(__result);
2705}
2706
2707template <class _Tp, class _Compare, class _Allocator>
2708template <class _Key>
2709typename __tree<_Tp, _Compare, _Allocator>::iterator
2710__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2711 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002712 __iter_pointer __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002713{
2714 while (__root != nullptr)
2715 {
2716 if (value_comp()(__v, __root->__value_))
2717 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002718 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002719 __root = static_cast<__node_pointer>(__root->__left_);
2720 }
2721 else
2722 __root = static_cast<__node_pointer>(__root->__right_);
2723 }
2724 return iterator(__result);
2725}
2726
2727template <class _Tp, class _Compare, class _Allocator>
2728template <class _Key>
2729typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2730__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00002731 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002732 __iter_pointer __result) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00002733{
2734 while (__root != nullptr)
2735 {
2736 if (value_comp()(__v, __root->__value_))
2737 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002738 __result = static_cast<__iter_pointer>(__root);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002739 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002740 }
2741 else
Eric Fiseliera92b0732016-02-20 07:12:17 +00002742 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002743 }
2744 return const_iterator(__result);
2745}
2746
2747template <class _Tp, class _Compare, class _Allocator>
2748template <class _Key>
2749pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2750 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2751__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2752{
Howard Hinnantc834c512011-11-29 18:15:50 +00002753 typedef pair<iterator, iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002754 __iter_pointer __result = __end_node();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002755 __node_pointer __rt = __root();
2756 while (__rt != nullptr)
2757 {
2758 if (value_comp()(__k, __rt->__value_))
2759 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002760 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002761 __rt = static_cast<__node_pointer>(__rt->__left_);
2762 }
2763 else if (value_comp()(__rt->__value_, __k))
2764 __rt = static_cast<__node_pointer>(__rt->__right_);
2765 else
Howard Hinnantc834c512011-11-29 18:15:50 +00002766 return _Pp(iterator(__rt),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002767 iterator(
2768 __rt->__right_ != nullptr ?
Eric Fiselier70f5f872016-07-19 17:56:20 +00002769 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00002770 : __result));
2771 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002772 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002773}
2774
2775template <class _Tp, class _Compare, class _Allocator>
2776template <class _Key>
2777pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2778 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2779__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2780{
Howard Hinnantc834c512011-11-29 18:15:50 +00002781 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002782 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002783 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002784 while (__rt != nullptr)
2785 {
2786 if (value_comp()(__k, __rt->__value_))
2787 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002788 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002789 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002790 }
2791 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002792 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002793 else
Howard Hinnantc834c512011-11-29 18:15:50 +00002794 return _Pp(const_iterator(__rt),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002795 const_iterator(
2796 __rt->__right_ != nullptr ?
Eric Fiselier70f5f872016-07-19 17:56:20 +00002797 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00002798 : __result));
2799 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002800 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002801}
2802
2803template <class _Tp, class _Compare, class _Allocator>
2804template <class _Key>
2805pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2806 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2807__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2808{
Howard Hinnantc834c512011-11-29 18:15:50 +00002809 typedef pair<iterator, iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002810 __iter_pointer __result = __end_node();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002811 __node_pointer __rt = __root();
2812 while (__rt != nullptr)
2813 {
2814 if (value_comp()(__k, __rt->__value_))
2815 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002816 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002817 __rt = static_cast<__node_pointer>(__rt->__left_);
2818 }
2819 else if (value_comp()(__rt->__value_, __k))
2820 __rt = static_cast<__node_pointer>(__rt->__right_);
2821 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002822 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002823 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2824 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002825 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002826}
2827
2828template <class _Tp, class _Compare, class _Allocator>
2829template <class _Key>
2830pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2831 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2832__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2833{
Howard Hinnantc834c512011-11-29 18:15:50 +00002834 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002835 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002836 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002837 while (__rt != nullptr)
2838 {
2839 if (value_comp()(__k, __rt->__value_))
2840 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002841 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002842 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002843 }
2844 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002845 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002846 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002847 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiseliera92b0732016-02-20 07:12:17 +00002848 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002849 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002850 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002851}
2852
2853template <class _Tp, class _Compare, class _Allocator>
2854typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Howard Hinnant1113b5e2011-06-04 17:10:24 +00002855__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002856{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002857 __node_pointer __np = __p.__get_np();
2858 if (__begin_node() == __p.__ptr_)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002859 {
2860 if (__np->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002861 __begin_node() = static_cast<__iter_pointer>(__np->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002862 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002863 __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002864 }
2865 --size();
2866 __tree_remove(__end_node()->__left_,
2867 static_cast<__node_base_pointer>(__np));
Marshall Clow95af65e2015-01-28 19:54:25 +00002868 return __node_holder(__np, _Dp(__node_alloc(), true));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002869}
2870
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00002871template <class _Tp, class _Compare, class _Allocator>
2872inline _LIBCPP_INLINE_VISIBILITY
2873void
2874swap(__tree<_Tp, _Compare, _Allocator>& __x,
2875 __tree<_Tp, _Compare, _Allocator>& __y)
2876 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2877{
2878 __x.swap(__y);
2879}
2880
Howard Hinnantc51e1022010-05-11 19:42:16 +00002881_LIBCPP_END_NAMESPACE_STD
2882
Eric Fiselierf4433a32017-05-31 22:07:49 +00002883_LIBCPP_POP_MACROS
2884
Howard Hinnantc51e1022010-05-11 19:42:16 +00002885#endif // _LIBCPP___TREE