blob: 4144a9599925582dfafcabbd6b16379840977c57 [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
Howard Hinnant944510a2011-06-14 19:58:17 +000029template <class _Tp, class _Compare, class _Allocator> class __tree;
30template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000031 class _LIBCPP_TEMPLATE_VIS __tree_iterator;
Howard Hinnant944510a2011-06-14 19:58:17 +000032template <class _Tp, class _ConstNodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000033 class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +000034
Eric Fiseliera00b4842016-02-20 05:28:30 +000035template <class _Pointer> class __tree_end_node;
36template <class _VoidPtr> class __tree_node_base;
37template <class _Tp, class _VoidPtr> class __tree_node;
38
Eric Fiseliera00b4842016-02-20 05:28:30 +000039template <class _Key, class _Value>
40struct __value_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +000041
42template <class _Allocator> class __map_node_destructor;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000043template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
44template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiseliera00b4842016-02-20 05:28:30 +000045
Howard Hinnantc51e1022010-05-11 19:42:16 +000046/*
47
48_NodePtr algorithms
49
50The algorithms taking _NodePtr are red black tree algorithms. Those
51algorithms taking a parameter named __root should assume that __root
52points to a proper red black tree (unless otherwise specified).
53
54Each algorithm herein assumes that __root->__parent_ points to a non-null
55structure which has a member __left_ which points back to __root. No other
56member is read or written to at __root->__parent_.
57
58__root->__parent_ will be referred to below (in comments only) as end_node.
59end_node->__left_ is an externably accessible lvalue for __root, and can be
60changed by node insertion and removal (without explicit reference to end_node).
61
62All nodes (with the exception of end_node), even the node referred to as
63__root, have a non-null __parent_ field.
64
65*/
66
67// Returns: true if __x is a left child of its parent, else false
68// Precondition: __x != nullptr.
69template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +000070inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +000071bool
Howard Hinnant1113b5e2011-06-04 17:10:24 +000072__tree_is_left_child(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +000073{
74 return __x == __x->__parent_->__left_;
75}
76
Joerg Sonnenbergerd74b3192017-08-18 12:57:36 +000077// Determines if the subtree rooted at __x is a proper red black subtree. If
Howard Hinnantc51e1022010-05-11 19:42:16 +000078// __x is a proper subtree, returns the black height (null counts as 1). If
79// __x is an improper subtree, returns 0.
80template <class _NodePtr>
81unsigned
82__tree_sub_invariant(_NodePtr __x)
83{
84 if (__x == nullptr)
85 return 1;
86 // parent consistency checked by caller
87 // check __x->__left_ consistency
88 if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
89 return 0;
90 // check __x->__right_ consistency
91 if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
92 return 0;
93 // check __x->__left_ != __x->__right_ unless both are nullptr
94 if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
95 return 0;
96 // If this is red, neither child can be red
97 if (!__x->__is_black_)
98 {
99 if (__x->__left_ && !__x->__left_->__is_black_)
100 return 0;
101 if (__x->__right_ && !__x->__right_->__is_black_)
102 return 0;
103 }
104 unsigned __h = __tree_sub_invariant(__x->__left_);
105 if (__h == 0)
106 return 0; // invalid left subtree
107 if (__h != __tree_sub_invariant(__x->__right_))
108 return 0; // invalid or different height right subtree
109 return __h + __x->__is_black_; // return black height of this node
110}
111
Joerg Sonnenbergerd74b3192017-08-18 12:57:36 +0000112// Determines if the red black tree rooted at __root is a proper red black tree.
Howard Hinnantc51e1022010-05-11 19:42:16 +0000113// __root == nullptr is a proper tree. Returns true is __root is a proper
114// red black tree, else returns false.
115template <class _NodePtr>
116bool
117__tree_invariant(_NodePtr __root)
118{
119 if (__root == nullptr)
120 return true;
121 // check __x->__parent_ consistency
122 if (__root->__parent_ == nullptr)
123 return false;
124 if (!__tree_is_left_child(__root))
125 return false;
126 // root must be black
127 if (!__root->__is_black_)
128 return false;
129 // do normal node checks
130 return __tree_sub_invariant(__root) != 0;
131}
132
133// Returns: pointer to the left-most node under __x.
134// Precondition: __x != nullptr.
135template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000136inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000137_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000138__tree_min(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000139{
140 while (__x->__left_ != nullptr)
141 __x = __x->__left_;
142 return __x;
143}
144
145// Returns: pointer to the right-most node under __x.
146// Precondition: __x != nullptr.
147template <class _NodePtr>
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000148inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000149_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000150__tree_max(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000151{
152 while (__x->__right_ != nullptr)
153 __x = __x->__right_;
154 return __x;
155}
156
157// Returns: pointer to the next in-order node after __x.
158// Precondition: __x != nullptr.
159template <class _NodePtr>
160_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000161__tree_next(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000162{
163 if (__x->__right_ != nullptr)
164 return __tree_min(__x->__right_);
165 while (!__tree_is_left_child(__x))
Eric Fiselier70f5f872016-07-19 17:56:20 +0000166 __x = __x->__parent_unsafe();
167 return __x->__parent_unsafe();
168}
169
170template <class _EndNodePtr, class _NodePtr>
171inline _LIBCPP_INLINE_VISIBILITY
172_EndNodePtr
173__tree_next_iter(_NodePtr __x) _NOEXCEPT
174{
175 if (__x->__right_ != nullptr)
176 return static_cast<_EndNodePtr>(__tree_min(__x->__right_));
177 while (!__tree_is_left_child(__x))
178 __x = __x->__parent_unsafe();
179 return static_cast<_EndNodePtr>(__x->__parent_);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000180}
181
182// Returns: pointer to the previous in-order node before __x.
183// Precondition: __x != nullptr.
Eric Fiselier70f5f872016-07-19 17:56:20 +0000184// Note: __x may be the end node.
185template <class _NodePtr, class _EndNodePtr>
186inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187_NodePtr
Eric Fiselier70f5f872016-07-19 17:56:20 +0000188__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000189{
190 if (__x->__left_ != nullptr)
191 return __tree_max(__x->__left_);
Eric Fiselier70f5f872016-07-19 17:56:20 +0000192 _NodePtr __xx = static_cast<_NodePtr>(__x);
193 while (__tree_is_left_child(__xx))
194 __xx = __xx->__parent_unsafe();
195 return __xx->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000196}
197
198// Returns: pointer to a node which has no children
199// Precondition: __x != nullptr.
200template <class _NodePtr>
201_NodePtr
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000202__tree_leaf(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000203{
204 while (true)
205 {
206 if (__x->__left_ != nullptr)
207 {
208 __x = __x->__left_;
209 continue;
210 }
211 if (__x->__right_ != nullptr)
212 {
213 __x = __x->__right_;
214 continue;
215 }
216 break;
217 }
218 return __x;
219}
220
221// Effects: Makes __x->__right_ the subtree root with __x as its left child
222// while preserving in-order order.
223// Precondition: __x->__right_ != nullptr
224template <class _NodePtr>
225void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000226__tree_left_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000227{
228 _NodePtr __y = __x->__right_;
229 __x->__right_ = __y->__left_;
230 if (__x->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000231 __x->__right_->__set_parent(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000232 __y->__parent_ = __x->__parent_;
233 if (__tree_is_left_child(__x))
234 __x->__parent_->__left_ = __y;
235 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000236 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000237 __y->__left_ = __x;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000238 __x->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000239}
240
241// Effects: Makes __x->__left_ the subtree root with __x as its right child
242// while preserving in-order order.
243// Precondition: __x->__left_ != nullptr
244template <class _NodePtr>
245void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000246__tree_right_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000247{
248 _NodePtr __y = __x->__left_;
249 __x->__left_ = __y->__right_;
250 if (__x->__left_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000251 __x->__left_->__set_parent(__x);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000252 __y->__parent_ = __x->__parent_;
253 if (__tree_is_left_child(__x))
254 __x->__parent_->__left_ = __y;
255 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000256 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000257 __y->__right_ = __x;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000258 __x->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000259}
260
261// Effects: Rebalances __root after attaching __x to a leaf.
262// Precondition: __root != nulptr && __x != nullptr.
263// __x has no children.
264// __x == __root or == a direct or indirect child of __root.
265// If __x were to be unlinked from __root (setting __root to
266// nullptr if __root == __x), __tree_invariant(__root) == true.
267// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_
268// may be different than the value passed in as __root.
269template <class _NodePtr>
270void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000271__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000272{
273 __x->__is_black_ = __x == __root;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000274 while (__x != __root && !__x->__parent_unsafe()->__is_black_)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000275 {
276 // __x->__parent_ != __root because __x->__parent_->__is_black == false
Eric Fiselier70f5f872016-07-19 17:56:20 +0000277 if (__tree_is_left_child(__x->__parent_unsafe()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000278 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000279 _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000280 if (__y != nullptr && !__y->__is_black_)
281 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000282 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000283 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000284 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000285 __x->__is_black_ = __x == __root;
286 __y->__is_black_ = true;
287 }
288 else
289 {
290 if (!__tree_is_left_child(__x))
291 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000292 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000293 __tree_left_rotate(__x);
294 }
Eric Fiselier70f5f872016-07-19 17:56:20 +0000295 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000296 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000297 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000298 __x->__is_black_ = false;
299 __tree_right_rotate(__x);
300 break;
301 }
302 }
303 else
304 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000305 _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000306 if (__y != nullptr && !__y->__is_black_)
307 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000308 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000309 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000310 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000311 __x->__is_black_ = __x == __root;
312 __y->__is_black_ = true;
313 }
314 else
315 {
316 if (__tree_is_left_child(__x))
317 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000318 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000319 __tree_right_rotate(__x);
320 }
Eric Fiselier70f5f872016-07-19 17:56:20 +0000321 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000322 __x->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000323 __x = __x->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000324 __x->__is_black_ = false;
325 __tree_left_rotate(__x);
326 break;
327 }
328 }
329 }
330}
331
332// Precondition: __root != nullptr && __z != nullptr.
333// __tree_invariant(__root) == true.
334// __z == __root or == a direct or indirect child of __root.
335// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed.
336// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
337// nor any of its children refer to __z. end_node->__left_
338// may be different than the value passed in as __root.
339template <class _NodePtr>
340void
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000341__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000342{
343 // __z will be removed from the tree. Client still needs to destruct/deallocate it
344 // __y is either __z, or if __z has two children, __tree_next(__z).
345 // __y will have at most one child.
346 // __y will be the initial hole in the tree (make the hole at a leaf)
347 _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
348 __z : __tree_next(__z);
349 // __x is __y's possibly null single child
350 _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
351 // __w is __x's possibly null uncle (will become __x's sibling)
352 _NodePtr __w = nullptr;
353 // link __x to __y's parent, and find __w
354 if (__x != nullptr)
355 __x->__parent_ = __y->__parent_;
356 if (__tree_is_left_child(__y))
357 {
358 __y->__parent_->__left_ = __x;
359 if (__y != __root)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000360 __w = __y->__parent_unsafe()->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000361 else
362 __root = __x; // __w == nullptr
363 }
364 else
365 {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000366 __y->__parent_unsafe()->__right_ = __x;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000367 // __y can't be root if it is a right child
368 __w = __y->__parent_->__left_;
369 }
370 bool __removed_black = __y->__is_black_;
371 // If we didn't remove __z, do so now by splicing in __y for __z,
372 // but copy __z's color. This does not impact __x or __w.
373 if (__y != __z)
374 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000375 // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376 __y->__parent_ = __z->__parent_;
377 if (__tree_is_left_child(__z))
378 __y->__parent_->__left_ = __y;
379 else
Eric Fiselier70f5f872016-07-19 17:56:20 +0000380 __y->__parent_unsafe()->__right_ = __y;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000381 __y->__left_ = __z->__left_;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000382 __y->__left_->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000383 __y->__right_ = __z->__right_;
384 if (__y->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +0000385 __y->__right_->__set_parent(__y);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386 __y->__is_black_ = __z->__is_black_;
387 if (__root == __z)
388 __root = __y;
389 }
390 // There is no need to rebalance if we removed a red, or if we removed
391 // the last node.
392 if (__removed_black && __root != nullptr)
393 {
394 // Rebalance:
395 // __x has an implicit black color (transferred from the removed __y)
396 // associated with it, no matter what its color is.
397 // If __x is __root (in which case it can't be null), it is supposed
398 // to be black anyway, and if it is doubly black, then the double
399 // can just be ignored.
400 // If __x is red (in which case it can't be null), then it can absorb
401 // the implicit black just by setting its color to black.
402 // Since __y was black and only had one child (which __x points to), __x
403 // is either red with no children, else null, otherwise __y would have
404 // different black heights under left and right pointers.
405 // if (__x == __root || __x != nullptr && !__x->__is_black_)
406 if (__x != nullptr)
407 __x->__is_black_ = true;
408 else
409 {
410 // Else __x isn't root, and is "doubly black", even though it may
411 // be null. __w can not be null here, else the parent would
412 // see a black height >= 2 on the __x side and a black height
413 // of 1 on the __w side (__w must be a non-null black or a red
414 // with a non-null black child).
415 while (true)
416 {
417 if (!__tree_is_left_child(__w)) // if x is left child
418 {
419 if (!__w->__is_black_)
420 {
421 __w->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000422 __w->__parent_unsafe()->__is_black_ = false;
423 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000424 // __x is still valid
425 // reset __root only if necessary
426 if (__root == __w->__left_)
427 __root = __w;
428 // reset sibling, and it still can't be null
429 __w = __w->__left_->__right_;
430 }
431 // __w->__is_black_ is now true, __w may have null children
432 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
433 (__w->__right_ == nullptr || __w->__right_->__is_black_))
434 {
435 __w->__is_black_ = false;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000436 __x = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000437 // __x can no longer be null
438 if (__x == __root || !__x->__is_black_)
439 {
440 __x->__is_black_ = true;
441 break;
442 }
443 // reset sibling, and it still can't be null
444 __w = __tree_is_left_child(__x) ?
Eric Fiselier70f5f872016-07-19 17:56:20 +0000445 __x->__parent_unsafe()->__right_ :
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000446 __x->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000447 // continue;
448 }
449 else // __w has a red child
450 {
451 if (__w->__right_ == nullptr || __w->__right_->__is_black_)
452 {
453 // __w left child is non-null and red
454 __w->__left_->__is_black_ = true;
455 __w->__is_black_ = false;
456 __tree_right_rotate(__w);
457 // __w is known not to be root, so root hasn't changed
458 // reset sibling, and it still can't be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000459 __w = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000460 }
461 // __w has a right red child, left child may be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000462 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
463 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000464 __w->__right_->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000465 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000466 break;
467 }
468 }
469 else
470 {
471 if (!__w->__is_black_)
472 {
473 __w->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000474 __w->__parent_unsafe()->__is_black_ = false;
475 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000476 // __x is still valid
477 // reset __root only if necessary
478 if (__root == __w->__right_)
479 __root = __w;
480 // reset sibling, and it still can't be null
481 __w = __w->__right_->__left_;
482 }
483 // __w->__is_black_ is now true, __w may have null children
484 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
485 (__w->__right_ == nullptr || __w->__right_->__is_black_))
486 {
487 __w->__is_black_ = false;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000488 __x = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000489 // __x can no longer be null
490 if (!__x->__is_black_ || __x == __root)
491 {
492 __x->__is_black_ = true;
493 break;
494 }
495 // reset sibling, and it still can't be null
496 __w = __tree_is_left_child(__x) ?
Eric Fiselier70f5f872016-07-19 17:56:20 +0000497 __x->__parent_unsafe()->__right_ :
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000498 __x->__parent_->__left_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000499 // continue;
500 }
501 else // __w has a red child
502 {
503 if (__w->__left_ == nullptr || __w->__left_->__is_black_)
504 {
505 // __w right child is non-null and red
506 __w->__right_->__is_black_ = true;
507 __w->__is_black_ = false;
508 __tree_left_rotate(__w);
509 // __w is known not to be root, so root hasn't changed
510 // reset sibling, and it still can't be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000511 __w = __w->__parent_unsafe();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000512 }
513 // __w has a left red child, right child may be null
Eric Fiselier70f5f872016-07-19 17:56:20 +0000514 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
515 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000516 __w->__left_->__is_black_ = true;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000517 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000518 break;
519 }
520 }
521 }
522 }
523 }
524}
525
Eric Fiseliera00b4842016-02-20 05:28:30 +0000526// node traits
527
Eric Fiselierd06276b2016-03-31 02:15:15 +0000528
529#ifndef _LIBCPP_CXX03_LANG
530template <class _Tp>
531struct __is_tree_value_type_imp : false_type {};
532
533template <class _Key, class _Value>
534struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {};
535
536template <class ..._Args>
537struct __is_tree_value_type : false_type {};
538
539template <class _One>
540struct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {};
541#endif
542
Eric Fiseliera00b4842016-02-20 05:28:30 +0000543template <class _Tp>
544struct __tree_key_value_types {
545 typedef _Tp key_type;
546 typedef _Tp __node_value_type;
547 typedef _Tp __container_value_type;
548 static const bool __is_map = false;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000549
550 _LIBCPP_INLINE_VISIBILITY
551 static key_type const& __get_key(_Tp const& __v) {
552 return __v;
553 }
554 _LIBCPP_INLINE_VISIBILITY
555 static __container_value_type const& __get_value(__node_value_type const& __v) {
556 return __v;
557 }
558 _LIBCPP_INLINE_VISIBILITY
559 static __container_value_type* __get_ptr(__node_value_type& __n) {
560 return _VSTD::addressof(__n);
561 }
Eric Fiselierd06276b2016-03-31 02:15:15 +0000562#ifndef _LIBCPP_CXX03_LANG
563 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000564 static __container_value_type&& __move(__node_value_type& __v) {
Eric Fiselierd06276b2016-03-31 02:15:15 +0000565 return _VSTD::move(__v);
566 }
567#endif
Eric Fiseliera00b4842016-02-20 05:28:30 +0000568};
569
570template <class _Key, class _Tp>
571struct __tree_key_value_types<__value_type<_Key, _Tp> > {
572 typedef _Key key_type;
573 typedef _Tp mapped_type;
574 typedef __value_type<_Key, _Tp> __node_value_type;
575 typedef pair<const _Key, _Tp> __container_value_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000576 typedef __container_value_type __map_value_type;
577 static const bool __is_map = true;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000578
579 _LIBCPP_INLINE_VISIBILITY
580 static key_type const&
581 __get_key(__node_value_type const& __t) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000582 return __t.__get_value().first;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000583 }
584
585 template <class _Up>
586 _LIBCPP_INLINE_VISIBILITY
587 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
588 key_type const&>::type
589 __get_key(_Up& __t) {
590 return __t.first;
591 }
592
593 _LIBCPP_INLINE_VISIBILITY
594 static __container_value_type const&
595 __get_value(__node_value_type const& __t) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000596 return __t.__get_value();
Eric Fiselierd06276b2016-03-31 02:15:15 +0000597 }
598
599 template <class _Up>
600 _LIBCPP_INLINE_VISIBILITY
601 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
602 __container_value_type const&>::type
603 __get_value(_Up& __t) {
604 return __t;
605 }
606
607 _LIBCPP_INLINE_VISIBILITY
608 static __container_value_type* __get_ptr(__node_value_type& __n) {
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000609 return _VSTD::addressof(__n.__get_value());
Eric Fiselierd06276b2016-03-31 02:15:15 +0000610 }
611
612#ifndef _LIBCPP_CXX03_LANG
613 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtond3fe2992018-06-04 20:38:23 +0000614 static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
615 return __v.__move();
Eric Fiselierd06276b2016-03-31 02:15:15 +0000616 }
617#endif
Eric Fiseliera00b4842016-02-20 05:28:30 +0000618};
619
620template <class _VoidPtr>
621struct __tree_node_base_types {
622 typedef _VoidPtr __void_pointer;
623
624 typedef __tree_node_base<__void_pointer> __node_base_type;
625 typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
626 __node_base_pointer;
627
628 typedef __tree_end_node<__node_base_pointer> __end_node_type;
629 typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
630 __end_node_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000631#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
632 typedef __end_node_pointer __parent_pointer;
633#else
634 typedef typename conditional<
635 is_pointer<__end_node_pointer>::value,
636 __end_node_pointer,
637 __node_base_pointer>::type __parent_pointer;
638#endif
639
Eric Fiseliera00b4842016-02-20 05:28:30 +0000640private:
641 static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
642 "_VoidPtr does not point to unqualified void type");
643};
644
645template <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>,
646 bool = _KVTypes::__is_map>
647struct __tree_map_pointer_types {};
648
649template <class _Tp, class _AllocPtr, class _KVTypes>
650struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
651 typedef typename _KVTypes::__map_value_type _Mv;
652 typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
653 __map_value_type_pointer;
654 typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
655 __const_map_value_type_pointer;
656};
657
658template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
659struct __tree_node_types;
660
661template <class _NodePtr, class _Tp, class _VoidPtr>
662struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> >
663 : public __tree_node_base_types<_VoidPtr>,
664 __tree_key_value_types<_Tp>,
665 __tree_map_pointer_types<_Tp, _VoidPtr>
666{
667 typedef __tree_node_base_types<_VoidPtr> __base;
668 typedef __tree_key_value_types<_Tp> __key_base;
669 typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base;
670public:
671
672 typedef typename pointer_traits<_NodePtr>::element_type __node_type;
673 typedef _NodePtr __node_pointer;
674
675 typedef _Tp __node_value_type;
676 typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
677 __node_value_type_pointer;
678 typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
679 __const_node_value_type_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000680#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
681 typedef typename __base::__end_node_pointer __iter_pointer;
682#else
683 typedef typename conditional<
684 is_pointer<__node_pointer>::value,
685 typename __base::__end_node_pointer,
686 __node_pointer>::type __iter_pointer;
687#endif
Eric Fiseliera00b4842016-02-20 05:28:30 +0000688private:
689 static_assert(!is_const<__node_type>::value,
690 "_NodePtr should never be a pointer to const");
691 static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
692 _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
693};
694
695template <class _ValueTp, class _VoidPtr>
696struct __make_tree_node_types {
697 typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
698 _NodePtr;
699 typedef __tree_node_types<_NodePtr> type;
700};
701
Howard Hinnantc51e1022010-05-11 19:42:16 +0000702// node
703
704template <class _Pointer>
705class __tree_end_node
706{
707public:
708 typedef _Pointer pointer;
709 pointer __left_;
710
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000711 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1113b5e2011-06-04 17:10:24 +0000712 __tree_end_node() _NOEXCEPT : __left_() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000713};
714
715template <class _VoidPtr>
716class __tree_node_base
Eric Fiseliera00b4842016-02-20 05:28:30 +0000717 : public __tree_node_base_types<_VoidPtr>::__end_node_type
Howard Hinnantc51e1022010-05-11 19:42:16 +0000718{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000719 typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
720
Howard Hinnantc51e1022010-05-11 19:42:16 +0000721public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000722 typedef typename _NodeBaseTypes::__node_base_pointer pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000723 typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000724
Eric Fiselier70f5f872016-07-19 17:56:20 +0000725 pointer __right_;
726 __parent_pointer __parent_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000727 bool __is_black_;
728
Eric Fiselier70f5f872016-07-19 17:56:20 +0000729 _LIBCPP_INLINE_VISIBILITY
730 pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
731
732 _LIBCPP_INLINE_VISIBILITY
733 void __set_parent(pointer __p) {
734 __parent_ = static_cast<__parent_pointer>(__p);
735 }
736
Eric Fiselierd06276b2016-03-31 02:15:15 +0000737private:
738 ~__tree_node_base() _LIBCPP_EQUAL_DELETE;
739 __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
740 __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000741};
742
743template <class _Tp, class _VoidPtr>
744class __tree_node
745 : public __tree_node_base<_VoidPtr>
746{
747public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000748 typedef _Tp __node_value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000749
Eric Fiseliera00b4842016-02-20 05:28:30 +0000750 __node_value_type __value_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000751
Eric Fiselierd06276b2016-03-31 02:15:15 +0000752private:
753 ~__tree_node() _LIBCPP_EQUAL_DELETE;
754 __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE;
755 __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000756};
757
Eric Fiselierd06276b2016-03-31 02:15:15 +0000758
759template <class _Allocator>
760class __tree_node_destructor
761{
762 typedef _Allocator allocator_type;
763 typedef allocator_traits<allocator_type> __alloc_traits;
764
765public:
766 typedef typename __alloc_traits::pointer pointer;
767private:
768 typedef __tree_node_types<pointer> _NodeTypes;
769 allocator_type& __na_;
770
771 __tree_node_destructor& operator=(const __tree_node_destructor&);
772
773public:
774 bool __value_constructed;
775
776 _LIBCPP_INLINE_VISIBILITY
777 explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
778 : __na_(__na),
779 __value_constructed(__val)
780 {}
781
782 _LIBCPP_INLINE_VISIBILITY
783 void operator()(pointer __p) _NOEXCEPT
784 {
785 if (__value_constructed)
786 __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
787 if (__p)
788 __alloc_traits::deallocate(__na_, __p, 1);
789 }
790
791 template <class> friend class __map_node_destructor;
792};
793
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +0000794#if _LIBCPP_STD_VER > 14
795template <class _NodeType, class _Alloc>
796struct __generic_container_node_destructor;
797template <class _Tp, class _VoidPtr, class _Alloc>
798struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
799 : __tree_node_destructor<_Alloc>
800{
801 using __tree_node_destructor<_Alloc>::__tree_node_destructor;
802};
803#endif
Eric Fiselierd06276b2016-03-31 02:15:15 +0000804
Howard Hinnantc51e1022010-05-11 19:42:16 +0000805template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000806class _LIBCPP_TEMPLATE_VIS __tree_iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +0000807{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000808 typedef __tree_node_types<_NodePtr> _NodeTypes;
809 typedef _NodePtr __node_pointer;
810 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000811 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
812 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000813 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000814
Eric Fiselier70f5f872016-07-19 17:56:20 +0000815 __iter_pointer __ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000816
Howard Hinnantc51e1022010-05-11 19:42:16 +0000817public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000818 typedef bidirectional_iterator_tag iterator_category;
819 typedef _Tp value_type;
820 typedef _DiffType difference_type;
821 typedef value_type& reference;
822 typedef typename _NodeTypes::__node_value_type_pointer pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000823
Marshall Clow8fc07302013-08-08 21:52:50 +0000824 _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
825#if _LIBCPP_STD_VER > 11
826 : __ptr_(nullptr)
827#endif
828 {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000829
Eric Fiselier70f5f872016-07-19 17:56:20 +0000830 _LIBCPP_INLINE_VISIBILITY reference operator*() const
831 {return __get_np()->__value_;}
Howard Hinnant2d0046b2013-06-19 21:29:40 +0000832 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier70f5f872016-07-19 17:56:20 +0000833 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000834
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000835 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000836 __tree_iterator& operator++() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000837 __ptr_ = static_cast<__iter_pointer>(
838 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000839 return *this;
840 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000841 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000842 __tree_iterator operator++(int)
843 {__tree_iterator __t(*this); ++(*this); return __t;}
844
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000845 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000846 __tree_iterator& operator--() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000847 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
848 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000849 return *this;
850 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000851 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000852 __tree_iterator operator--(int)
853 {__tree_iterator __t(*this); --(*this); return __t;}
854
Louis Dionne44bcff92018-08-03 22:36:53 +0000855 friend _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000856 bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000857 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000858 friend _LIBCPP_INLINE_VISIBILITY
859 bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000860 {return !(__x == __y);}
861
862private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000863 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000864 explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Eric Fiselier70f5f872016-07-19 17:56:20 +0000865 _LIBCPP_INLINE_VISIBILITY
866 explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
867 _LIBCPP_INLINE_VISIBILITY
868 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000869 template <class, class, class> friend class __tree;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000870 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
871 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
872 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
873 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
874 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
875 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000876};
877
Eric Fiseliera00b4842016-02-20 05:28:30 +0000878template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000879class _LIBCPP_TEMPLATE_VIS __tree_const_iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +0000880{
Eric Fiseliera00b4842016-02-20 05:28:30 +0000881 typedef __tree_node_types<_NodePtr> _NodeTypes;
882 typedef typename _NodeTypes::__node_pointer __node_pointer;
883 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000884 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
885 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000886 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000887
Eric Fiselier70f5f872016-07-19 17:56:20 +0000888 __iter_pointer __ptr_;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000889
Howard Hinnantc51e1022010-05-11 19:42:16 +0000890public:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000891 typedef bidirectional_iterator_tag iterator_category;
892 typedef _Tp value_type;
893 typedef _DiffType difference_type;
894 typedef const value_type& reference;
895 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000896
Marshall Clow8fc07302013-08-08 21:52:50 +0000897 _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
898#if _LIBCPP_STD_VER > 11
899 : __ptr_(nullptr)
900#endif
901 {}
902
Howard Hinnantc51e1022010-05-11 19:42:16 +0000903private:
Eric Fiseliera00b4842016-02-20 05:28:30 +0000904 typedef __tree_iterator<value_type, __node_pointer, difference_type>
905 __non_const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000906public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000907 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000908 __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
909 : __ptr_(__p.__ptr_) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000910
Eric Fiselier70f5f872016-07-19 17:56:20 +0000911 _LIBCPP_INLINE_VISIBILITY reference operator*() const
912 {return __get_np()->__value_;}
Howard Hinnant2d0046b2013-06-19 21:29:40 +0000913 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier70f5f872016-07-19 17:56:20 +0000914 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000915
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000916 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000917 __tree_const_iterator& operator++() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000918 __ptr_ = static_cast<__iter_pointer>(
919 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000920 return *this;
921 }
922
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000923 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000924 __tree_const_iterator operator++(int)
925 {__tree_const_iterator __t(*this); ++(*this); return __t;}
926
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000927 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000928 __tree_const_iterator& operator--() {
Eric Fiselier70f5f872016-07-19 17:56:20 +0000929 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
930 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier44f9fd02015-03-03 20:10:01 +0000931 return *this;
932 }
933
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000934 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000935 __tree_const_iterator operator--(int)
936 {__tree_const_iterator __t(*this); --(*this); return __t;}
937
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000938 friend _LIBCPP_INLINE_VISIBILITY
939 bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000940 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000941 friend _LIBCPP_INLINE_VISIBILITY
942 bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000943 {return !(__x == __y);}
944
945private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +0000946 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +0000947 explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
948 : __ptr_(__p) {}
Eric Fiselier70f5f872016-07-19 17:56:20 +0000949 _LIBCPP_INLINE_VISIBILITY
950 explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
951 : __ptr_(__p) {}
952 _LIBCPP_INLINE_VISIBILITY
953 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
954
Howard Hinnantc51e1022010-05-11 19:42:16 +0000955 template <class, class, class> friend class __tree;
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000956 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
957 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
958 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
959 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
960 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiselier70f5f872016-07-19 17:56:20 +0000961
Howard Hinnantc51e1022010-05-11 19:42:16 +0000962};
963
Louis Dionne878a3a82018-12-06 21:46:17 +0000964template<class _Tp, class _Compare>
Eric Fiseliera7a14ed2017-01-13 22:02:08 +0000965#ifndef _LIBCPP_CXX03_LANG
Louis Dionne878a3a82018-12-06 21:46:17 +0000966 _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
967 "the specified comparator type does not provide a const call operator")
968#endif
969int __diagnose_non_const_comparator();
Eric Fiseliera7a14ed2017-01-13 22:02:08 +0000970
Howard Hinnantc51e1022010-05-11 19:42:16 +0000971template <class _Tp, class _Compare, class _Allocator>
972class __tree
973{
974public:
975 typedef _Tp value_type;
976 typedef _Compare value_compare;
977 typedef _Allocator allocator_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000978
979private:
Howard Hinnantc51e1022010-05-11 19:42:16 +0000980 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000981 typedef typename __make_tree_node_types<value_type,
982 typename __alloc_traits::void_pointer>::type
983 _NodeTypes;
Eric Fiselierd06276b2016-03-31 02:15:15 +0000984 typedef typename _NodeTypes::key_type key_type;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000985public:
986 typedef typename _NodeTypes::__node_value_type __node_value_type;
987 typedef typename _NodeTypes::__container_value_type __container_value_type;
988
Howard Hinnantc51e1022010-05-11 19:42:16 +0000989 typedef typename __alloc_traits::pointer pointer;
990 typedef typename __alloc_traits::const_pointer const_pointer;
991 typedef typename __alloc_traits::size_type size_type;
992 typedef typename __alloc_traits::difference_type difference_type;
993
Eric Fiseliera00b4842016-02-20 05:28:30 +0000994public:
995 typedef typename _NodeTypes::__void_pointer __void_pointer;
Howard Hinnant2d0046b2013-06-19 21:29:40 +0000996
Eric Fiseliera00b4842016-02-20 05:28:30 +0000997 typedef typename _NodeTypes::__node_type __node;
998 typedef typename _NodeTypes::__node_pointer __node_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +0000999
1000 typedef typename _NodeTypes::__node_base_type __node_base;
1001 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001002
1003 typedef typename _NodeTypes::__end_node_type __end_node_t;
1004 typedef typename _NodeTypes::__end_node_pointer __end_node_ptr;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001005
Eric Fiselier70f5f872016-07-19 17:56:20 +00001006 typedef typename _NodeTypes::__parent_pointer __parent_pointer;
1007 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
1008
Marshall Clow940e01c2015-04-07 05:21:38 +00001009 typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
Eric Fiseliera00b4842016-02-20 05:28:30 +00001010 typedef allocator_traits<__node_allocator> __node_traits;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001011
Eric Fiseliera00b4842016-02-20 05:28:30 +00001012private:
1013 // check for sane allocator pointer rebinding semantics. Rebinding the
1014 // allocator for a new pointer type should be exactly the same as rebinding
1015 // the pointer using 'pointer_traits'.
1016 static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1017 "Allocator does not rebind pointers in a sane manner.");
1018 typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1019 __node_base_allocator;
1020 typedef allocator_traits<__node_base_allocator> __node_base_traits;
1021 static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1022 "Allocator does not rebind pointers in a sane manner.");
1023
1024private:
Eric Fiselier70f5f872016-07-19 17:56:20 +00001025 __iter_pointer __begin_node_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001026 __compressed_pair<__end_node_t, __node_allocator> __pair1_;
1027 __compressed_pair<size_type, value_compare> __pair3_;
1028
1029public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001030 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001031 __iter_pointer __end_node() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001032 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001033 return static_cast<__iter_pointer>(
Eric Fiseliera92b0732016-02-20 07:12:17 +00001034 pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
1035 );
Howard Hinnantc51e1022010-05-11 19:42:16 +00001036 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001037 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001038 __iter_pointer __end_node() const _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(
1042 const_cast<__end_node_t&>(__pair1_.first())
1043 )
1044 );
Howard Hinnantc51e1022010-05-11 19:42:16 +00001045 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001046 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001047 __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001048private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001049 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001050 const __node_allocator& __node_alloc() const _NOEXCEPT
1051 {return __pair1_.second();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001052 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001053 __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001054 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70f5f872016-07-19 17:56:20 +00001055 const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001056public:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001057 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001058 allocator_type __alloc() const _NOEXCEPT
1059 {return allocator_type(__node_alloc());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001060private:
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001062 size_type& size() _NOEXCEPT {return __pair3_.first();}
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 const size_type& size() const _NOEXCEPT {return __pair3_.first();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001067 value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001069 const value_compare& value_comp() const _NOEXCEPT
1070 {return __pair3_.second();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001071public:
Eric Fiseliera92b0732016-02-20 07:12:17 +00001072
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001073 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera92b0732016-02-20 07:12:17 +00001074 __node_pointer __root() const _NOEXCEPT
1075 {return static_cast<__node_pointer>(__end_node()->__left_);}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001076
Eric Fiselier70f5f872016-07-19 17:56:20 +00001077 __node_base_pointer* __root_ptr() const _NOEXCEPT {
1078 return _VSTD::addressof(__end_node()->__left_);
1079 }
1080
Howard Hinnantc51e1022010-05-11 19:42:16 +00001081 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001082 typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001083
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001084 explicit __tree(const value_compare& __comp)
1085 _NOEXCEPT_(
1086 is_nothrow_default_constructible<__node_allocator>::value &&
1087 is_nothrow_copy_constructible<value_compare>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001088 explicit __tree(const allocator_type& __a);
1089 __tree(const value_compare& __comp, const allocator_type& __a);
1090 __tree(const __tree& __t);
1091 __tree& operator=(const __tree& __t);
1092 template <class _InputIterator>
1093 void __assign_unique(_InputIterator __first, _InputIterator __last);
1094 template <class _InputIterator>
1095 void __assign_multi(_InputIterator __first, _InputIterator __last);
Eric Fiselierb63508a2017-04-19 01:23:04 +00001096#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001097 __tree(__tree&& __t)
1098 _NOEXCEPT_(
1099 is_nothrow_move_constructible<__node_allocator>::value &&
1100 is_nothrow_move_constructible<value_compare>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001101 __tree(__tree&& __t, const allocator_type& __a);
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001102 __tree& operator=(__tree&& __t)
1103 _NOEXCEPT_(
1104 __node_traits::propagate_on_container_move_assignment::value &&
1105 is_nothrow_move_assignable<value_compare>::value &&
1106 is_nothrow_move_assignable<__node_allocator>::value);
Eric Fiselierb63508a2017-04-19 01:23:04 +00001107#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001108
1109 ~__tree();
1110
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001111 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001112 iterator begin() _NOEXCEPT {return iterator(__begin_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001113 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001114 const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001115 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001116 iterator end() _NOEXCEPT {return iterator(__end_node());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001117 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001118 const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001119
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001120 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001121 size_type max_size() const _NOEXCEPT
Eric Fiselierb5d9f442016-11-23 01:18:56 +00001122 {return std::min<size_type>(
1123 __node_traits::max_size(__node_alloc()),
1124 numeric_limits<difference_type >::max());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001125
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001126 void clear() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001127
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001128 void swap(__tree& __t)
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001129#if _LIBCPP_STD_VER <= 11
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001130 _NOEXCEPT_(
Marshall Clow8982dcd2015-07-13 20:04:56 +00001131 __is_nothrow_swappable<value_compare>::value
Marshall Clow8982dcd2015-07-13 20:04:56 +00001132 && (!__node_traits::propagate_on_container_swap::value ||
1133 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001134 );
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001135#else
1136 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1137#endif
Eric Fiselierd06276b2016-03-31 02:15:15 +00001138
1139#ifndef _LIBCPP_CXX03_LANG
1140 template <class _Key, class ..._Args>
1141 pair<iterator, bool>
1142 __emplace_unique_key_args(_Key const&, _Args&&... __args);
1143 template <class _Key, class ..._Args>
1144 iterator
1145 __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001146
1147 template <class... _Args>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001148 pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
Eric Fiselierd06276b2016-03-31 02:15:15 +00001149
Howard Hinnantc51e1022010-05-11 19:42:16 +00001150 template <class... _Args>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001151 iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001152
Eric Fiselierd06276b2016-03-31 02:15:15 +00001153 template <class... _Args>
1154 iterator __emplace_multi(_Args&&... __args);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001155
Eric Fiselierd06276b2016-03-31 02:15:15 +00001156 template <class... _Args>
1157 iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001158
1159 template <class _Pp>
1160 _LIBCPP_INLINE_VISIBILITY
1161 pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1162 return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1163 __can_extract_key<_Pp, key_type>());
1164 }
1165
Eric Fiselierf1e45ce2016-04-16 00:23:12 +00001166 template <class _First, class _Second>
1167 _LIBCPP_INLINE_VISIBILITY
1168 typename enable_if<
1169 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1170 pair<iterator, bool>
1171 >::type __emplace_unique(_First&& __f, _Second&& __s) {
1172 return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1173 _VSTD::forward<_Second>(__s));
1174 }
1175
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001176 template <class... _Args>
1177 _LIBCPP_INLINE_VISIBILITY
1178 pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1179 return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1180 }
1181
1182 template <class _Pp>
1183 _LIBCPP_INLINE_VISIBILITY
1184 pair<iterator, bool>
1185 __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1186 return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1187 }
1188
1189 template <class _Pp>
1190 _LIBCPP_INLINE_VISIBILITY
1191 pair<iterator, bool>
1192 __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1193 return __emplace_unique_key_args(__x, _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_first_tag) {
1200 return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1201 }
1202
1203 template <class _Pp>
1204 _LIBCPP_INLINE_VISIBILITY
1205 iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1206 return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1207 __can_extract_key<_Pp, key_type>());
1208 }
1209
Eric Fiselierf1e45ce2016-04-16 00:23:12 +00001210 template <class _First, class _Second>
1211 _LIBCPP_INLINE_VISIBILITY
1212 typename enable_if<
1213 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1214 iterator
1215 >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
1216 return __emplace_hint_unique_key_args(__p, __f,
1217 _VSTD::forward<_First>(__f),
1218 _VSTD::forward<_Second>(__s));
1219 }
1220
Eric Fiselier6cce51e2016-04-15 23:27:27 +00001221 template <class... _Args>
1222 _LIBCPP_INLINE_VISIBILITY
1223 iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1224 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1225 }
1226
1227 template <class _Pp>
1228 _LIBCPP_INLINE_VISIBILITY
1229 iterator
1230 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1231 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
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_self_tag) {
1238 return __emplace_hint_unique_key_args(__p, __x, _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_first_tag) {
1245 return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x));
1246 }
1247
Eric Fiselierd06276b2016-03-31 02:15:15 +00001248#else
1249 template <class _Key, class _Args>
1250 _LIBCPP_INLINE_VISIBILITY
1251 pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args);
1252 template <class _Key, class _Args>
1253 _LIBCPP_INLINE_VISIBILITY
1254 iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&);
Marshall Clowd430d022016-01-05 19:32:41 +00001255#endif
1256
Eric Fiselierd06276b2016-03-31 02:15:15 +00001257 _LIBCPP_INLINE_VISIBILITY
1258 pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
1259 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
1260 }
1261
1262 _LIBCPP_INLINE_VISIBILITY
1263 iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
1264 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v);
1265 }
1266
1267#ifdef _LIBCPP_CXX03_LANG
1268 _LIBCPP_INLINE_VISIBILITY
1269 iterator __insert_multi(const __container_value_type& __v);
1270 _LIBCPP_INLINE_VISIBILITY
1271 iterator __insert_multi(const_iterator __p, const __container_value_type& __v);
1272#else
1273 _LIBCPP_INLINE_VISIBILITY
1274 pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
1275 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
1276 }
1277
1278 _LIBCPP_INLINE_VISIBILITY
1279 iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
1280 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v));
1281 }
1282
1283 template <class _Vp, class = typename enable_if<
1284 !is_same<typename __unconstref<_Vp>::type,
1285 __container_value_type
1286 >::value
1287 >::type>
1288 _LIBCPP_INLINE_VISIBILITY
1289 pair<iterator, bool> __insert_unique(_Vp&& __v) {
1290 return __emplace_unique(_VSTD::forward<_Vp>(__v));
1291 }
1292
1293 template <class _Vp, class = typename enable_if<
1294 !is_same<typename __unconstref<_Vp>::type,
1295 __container_value_type
1296 >::value
1297 >::type>
1298 _LIBCPP_INLINE_VISIBILITY
1299 iterator __insert_unique(const_iterator __p, _Vp&& __v) {
1300 return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
1301 }
1302
1303 _LIBCPP_INLINE_VISIBILITY
1304 iterator __insert_multi(__container_value_type&& __v) {
1305 return __emplace_multi(_VSTD::move(__v));
1306 }
1307
1308 _LIBCPP_INLINE_VISIBILITY
1309 iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
1310 return __emplace_hint_multi(__p, _VSTD::move(__v));
1311 }
1312
1313 template <class _Vp>
1314 _LIBCPP_INLINE_VISIBILITY
1315 iterator __insert_multi(_Vp&& __v) {
1316 return __emplace_multi(_VSTD::forward<_Vp>(__v));
1317 }
1318
1319 template <class _Vp>
1320 _LIBCPP_INLINE_VISIBILITY
1321 iterator __insert_multi(const_iterator __p, _Vp&& __v) {
1322 return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
1323 }
1324
1325#endif // !_LIBCPP_CXX03_LANG
1326
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001328 pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001330 iterator __node_insert_unique(const_iterator __p,
1331 __node_pointer __nd);
1332
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001334 iterator __node_insert_multi(__node_pointer __nd);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001335 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001336 iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1337
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001338
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001339 _LIBCPP_INLINE_VISIBILITY iterator
1340 __remove_node_pointer(__node_pointer) _NOEXCEPT;
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001341
1342#if _LIBCPP_STD_VER > 14
1343 template <class _NodeHandle, class _InsertReturnType>
1344 _LIBCPP_INLINE_VISIBILITY
1345 _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
1346 template <class _NodeHandle>
1347 _LIBCPP_INLINE_VISIBILITY
1348 iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001349 template <class _Tree>
1350 _LIBCPP_INLINE_VISIBILITY
1351 void __node_handle_merge_unique(_Tree& __source);
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001352
1353 template <class _NodeHandle>
1354 _LIBCPP_INLINE_VISIBILITY
1355 iterator __node_handle_insert_multi(_NodeHandle&&);
1356 template <class _NodeHandle>
1357 _LIBCPP_INLINE_VISIBILITY
1358 iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001359 template <class _Tree>
1360 _LIBCPP_INLINE_VISIBILITY
1361 void __node_handle_merge_multi(_Tree& __source);
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00001362
1363
1364 template <class _NodeHandle>
1365 _LIBCPP_INLINE_VISIBILITY
1366 _NodeHandle __node_handle_extract(key_type const&);
1367 template <class _NodeHandle>
1368 _LIBCPP_INLINE_VISIBILITY
1369 _NodeHandle __node_handle_extract(const_iterator);
1370#endif
1371
Howard Hinnantc51e1022010-05-11 19:42:16 +00001372 iterator erase(const_iterator __p);
1373 iterator erase(const_iterator __f, const_iterator __l);
1374 template <class _Key>
1375 size_type __erase_unique(const _Key& __k);
1376 template <class _Key>
1377 size_type __erase_multi(const _Key& __k);
1378
Eric Fiselier70f5f872016-07-19 17:56:20 +00001379 void __insert_node_at(__parent_pointer __parent,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001380 __node_base_pointer& __child,
Erik Pilkington82a65ad2018-10-31 17:31:35 +00001381 __node_base_pointer __new_node) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001382
1383 template <class _Key>
1384 iterator find(const _Key& __v);
1385 template <class _Key>
1386 const_iterator find(const _Key& __v) const;
1387
1388 template <class _Key>
1389 size_type __count_unique(const _Key& __k) const;
1390 template <class _Key>
1391 size_type __count_multi(const _Key& __k) const;
1392
1393 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001395 iterator lower_bound(const _Key& __v)
1396 {return __lower_bound(__v, __root(), __end_node());}
1397 template <class _Key>
1398 iterator __lower_bound(const _Key& __v,
1399 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001400 __iter_pointer __result);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001401 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001403 const_iterator lower_bound(const _Key& __v) const
1404 {return __lower_bound(__v, __root(), __end_node());}
1405 template <class _Key>
1406 const_iterator __lower_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00001407 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001408 __iter_pointer __result) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001409 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001411 iterator upper_bound(const _Key& __v)
1412 {return __upper_bound(__v, __root(), __end_node());}
1413 template <class _Key>
1414 iterator __upper_bound(const _Key& __v,
1415 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001416 __iter_pointer __result);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001417 template <class _Key>
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001418 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001419 const_iterator upper_bound(const _Key& __v) const
1420 {return __upper_bound(__v, __root(), __end_node());}
1421 template <class _Key>
1422 const_iterator __upper_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00001423 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001424 __iter_pointer __result) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001425 template <class _Key>
1426 pair<iterator, iterator>
1427 __equal_range_unique(const _Key& __k);
1428 template <class _Key>
1429 pair<const_iterator, const_iterator>
1430 __equal_range_unique(const _Key& __k) const;
1431
1432 template <class _Key>
1433 pair<iterator, iterator>
1434 __equal_range_multi(const _Key& __k);
1435 template <class _Key>
1436 pair<const_iterator, const_iterator>
1437 __equal_range_multi(const _Key& __k) const;
1438
Howard Hinnantc834c512011-11-29 18:15:50 +00001439 typedef __tree_node_destructor<__node_allocator> _Dp;
1440 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001441
Howard Hinnant1113b5e2011-06-04 17:10:24 +00001442 __node_holder remove(const_iterator __p) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001443private:
Eric Fiselier70f5f872016-07-19 17:56:20 +00001444 __node_base_pointer&
1445 __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1446 __node_base_pointer&
1447 __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1448 __node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00001449 __find_leaf(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001450 __parent_pointer& __parent, const key_type& __v);
Eric Fiseliercf8c0212017-01-05 06:06:18 +00001451 // FIXME: Make this function const qualified. Unfortunetly doing so
1452 // breaks existing code which uses non-const callable comparators.
Howard Hinnantc51e1022010-05-11 19:42:16 +00001453 template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001454 __node_base_pointer&
1455 __find_equal(__parent_pointer& __parent, const _Key& __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001456 template <class _Key>
Eric Fiseliercf8c0212017-01-05 06:06:18 +00001457 _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1458 __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1459 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1460 }
1461 template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001462 __node_base_pointer&
1463 __find_equal(const_iterator __hint, __parent_pointer& __parent,
1464 __node_base_pointer& __dummy,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001465 const _Key& __v);
1466
Eric Fiselierd06276b2016-03-31 02:15:15 +00001467#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001468 template <class ..._Args>
Eric Fiselierd06276b2016-03-31 02:15:15 +00001469 __node_holder __construct_node(_Args&& ...__args);
1470#else
1471 __node_holder __construct_node(const __container_value_type& __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001472#endif
1473
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001474 void destroy(__node_pointer __nd) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001475
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001477 void __copy_assign_alloc(const __tree& __t)
1478 {__copy_assign_alloc(__t, integral_constant<bool,
1479 __node_traits::propagate_on_container_copy_assignment::value>());}
1480
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001482 void __copy_assign_alloc(const __tree& __t, true_type)
Marshall Clowac8a40b2016-08-17 23:24:02 +00001483 {
1484 if (__node_alloc() != __t.__node_alloc())
Louis Dionne44bcff92018-08-03 22:36:53 +00001485 clear();
Marshall Clowac8a40b2016-08-17 23:24:02 +00001486 __node_alloc() = __t.__node_alloc();
1487 }
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001488 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001489 void __copy_assign_alloc(const __tree&, false_type) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001490
1491 void __move_assign(__tree& __t, false_type);
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001492 void __move_assign(__tree& __t, true_type)
1493 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1494 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001495
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001496 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001497 void __move_assign_alloc(__tree& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001498 _NOEXCEPT_(
1499 !__node_traits::propagate_on_container_move_assignment::value ||
1500 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001501 {__move_assign_alloc(__t, integral_constant<bool,
1502 __node_traits::propagate_on_container_move_assignment::value>());}
1503
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001504 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001505 void __move_assign_alloc(__tree& __t, true_type)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001506 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001507 {__node_alloc() = _VSTD::move(__t.__node_alloc());}
Howard Hinnant8e29cda2010-09-21 20:16:37 +00001508 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001509 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001510
Howard Hinnantc51e1022010-05-11 19:42:16 +00001511 __node_pointer __detach();
1512 static __node_pointer __detach(__node_pointer);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001513
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001514 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1515 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001516};
1517
1518template <class _Tp, class _Compare, class _Allocator>
1519__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001520 _NOEXCEPT_(
1521 is_nothrow_default_constructible<__node_allocator>::value &&
1522 is_nothrow_copy_constructible<value_compare>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001523 : __pair3_(0, __comp)
1524{
1525 __begin_node() = __end_node();
1526}
1527
1528template <class _Tp, class _Compare, class _Allocator>
1529__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001530 : __begin_node_(__iter_pointer()),
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001531 __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001532 __pair3_(0)
1533{
1534 __begin_node() = __end_node();
1535}
1536
1537template <class _Tp, class _Compare, class _Allocator>
1538__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1539 const allocator_type& __a)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001540 : __begin_node_(__iter_pointer()),
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001541 __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001542 __pair3_(0, __comp)
1543{
1544 __begin_node() = __end_node();
1545}
1546
1547// Precondition: size() != 0
1548template <class _Tp, class _Compare, class _Allocator>
1549typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1550__tree<_Tp, _Compare, _Allocator>::__detach()
1551{
Eric Fiselier70f5f872016-07-19 17:56:20 +00001552 __node_pointer __cache = static_cast<__node_pointer>(__begin_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001553 __begin_node() = __end_node();
1554 __end_node()->__left_->__parent_ = nullptr;
1555 __end_node()->__left_ = nullptr;
1556 size() = 0;
1557 // __cache->__left_ == nullptr
1558 if (__cache->__right_ != nullptr)
1559 __cache = static_cast<__node_pointer>(__cache->__right_);
1560 // __cache->__left_ == nullptr
1561 // __cache->__right_ == nullptr
1562 return __cache;
1563}
1564
1565// Precondition: __cache != nullptr
1566// __cache->left_ == nullptr
1567// __cache->right_ == nullptr
1568// This is no longer a red-black tree
1569template <class _Tp, class _Compare, class _Allocator>
1570typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1571__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
1572{
1573 if (__cache->__parent_ == nullptr)
1574 return nullptr;
Howard Hinnant2d0046b2013-06-19 21:29:40 +00001575 if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001576 {
1577 __cache->__parent_->__left_ = nullptr;
1578 __cache = static_cast<__node_pointer>(__cache->__parent_);
1579 if (__cache->__right_ == nullptr)
1580 return __cache;
1581 return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
1582 }
1583 // __cache is right child
Eric Fiselier70f5f872016-07-19 17:56:20 +00001584 __cache->__parent_unsafe()->__right_ = nullptr;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001585 __cache = static_cast<__node_pointer>(__cache->__parent_);
1586 if (__cache->__left_ == nullptr)
1587 return __cache;
1588 return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
1589}
1590
1591template <class _Tp, class _Compare, class _Allocator>
1592__tree<_Tp, _Compare, _Allocator>&
1593__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1594{
1595 if (this != &__t)
1596 {
1597 value_comp() = __t.value_comp();
1598 __copy_assign_alloc(__t);
1599 __assign_multi(__t.begin(), __t.end());
1600 }
1601 return *this;
1602}
1603
1604template <class _Tp, class _Compare, class _Allocator>
1605template <class _InputIterator>
1606void
1607__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
1608{
Eric Fiselierd06276b2016-03-31 02:15:15 +00001609 typedef iterator_traits<_InputIterator> _ITraits;
1610 typedef typename _ITraits::value_type _ItValueType;
1611 static_assert((is_same<_ItValueType, __container_value_type>::value),
1612 "__assign_unique may only be called with the containers value type");
1613
Howard Hinnantc51e1022010-05-11 19:42:16 +00001614 if (size() != 0)
1615 {
1616 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001617#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001618 try
1619 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001620#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001621 for (; __cache != nullptr && __first != __last; ++__first)
1622 {
1623 __cache->__value_ = *__first;
1624 __node_pointer __next = __detach(__cache);
1625 __node_insert_unique(__cache);
1626 __cache = __next;
1627 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001628#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001629 }
1630 catch (...)
1631 {
1632 while (__cache->__parent_ != nullptr)
1633 __cache = static_cast<__node_pointer>(__cache->__parent_);
1634 destroy(__cache);
1635 throw;
1636 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001637#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001638 if (__cache != nullptr)
1639 {
1640 while (__cache->__parent_ != nullptr)
1641 __cache = static_cast<__node_pointer>(__cache->__parent_);
1642 destroy(__cache);
1643 }
1644 }
1645 for (; __first != __last; ++__first)
1646 __insert_unique(*__first);
1647}
1648
1649template <class _Tp, class _Compare, class _Allocator>
1650template <class _InputIterator>
1651void
1652__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1653{
Eric Fiselierd06276b2016-03-31 02:15:15 +00001654 typedef iterator_traits<_InputIterator> _ITraits;
1655 typedef typename _ITraits::value_type _ItValueType;
1656 static_assert((is_same<_ItValueType, __container_value_type>::value ||
1657 is_same<_ItValueType, __node_value_type>::value),
1658 "__assign_multi may only be called with the containers value type"
1659 " or the nodes value type");
Howard Hinnantc51e1022010-05-11 19:42:16 +00001660 if (size() != 0)
1661 {
1662 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001663#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001664 try
1665 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001666#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001667 for (; __cache != nullptr && __first != __last; ++__first)
1668 {
1669 __cache->__value_ = *__first;
1670 __node_pointer __next = __detach(__cache);
1671 __node_insert_multi(__cache);
1672 __cache = __next;
1673 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001674#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001675 }
1676 catch (...)
1677 {
1678 while (__cache->__parent_ != nullptr)
1679 __cache = static_cast<__node_pointer>(__cache->__parent_);
1680 destroy(__cache);
1681 throw;
1682 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001683#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001684 if (__cache != nullptr)
1685 {
1686 while (__cache->__parent_ != nullptr)
1687 __cache = static_cast<__node_pointer>(__cache->__parent_);
1688 destroy(__cache);
1689 }
1690 }
1691 for (; __first != __last; ++__first)
Eric Fiselierd06276b2016-03-31 02:15:15 +00001692 __insert_multi(_NodeTypes::__get_value(*__first));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001693}
1694
1695template <class _Tp, class _Compare, class _Allocator>
1696__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
Eric Fiselier70f5f872016-07-19 17:56:20 +00001697 : __begin_node_(__iter_pointer()),
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001698 __pair1_(__second_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())),
Howard Hinnantc51e1022010-05-11 19:42:16 +00001699 __pair3_(0, __t.value_comp())
1700{
1701 __begin_node() = __end_node();
1702}
1703
Eric Fiselierb63508a2017-04-19 01:23:04 +00001704#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001705
1706template <class _Tp, class _Compare, class _Allocator>
1707__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001708 _NOEXCEPT_(
1709 is_nothrow_move_constructible<__node_allocator>::value &&
1710 is_nothrow_move_constructible<value_compare>::value)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001711 : __begin_node_(_VSTD::move(__t.__begin_node_)),
1712 __pair1_(_VSTD::move(__t.__pair1_)),
1713 __pair3_(_VSTD::move(__t.__pair3_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001714{
1715 if (size() == 0)
1716 __begin_node() = __end_node();
1717 else
1718 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001719 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001720 __t.__begin_node() = __t.__end_node();
1721 __t.__end_node()->__left_ = nullptr;
1722 __t.size() = 0;
1723 }
1724}
1725
1726template <class _Tp, class _Compare, class _Allocator>
1727__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
Eric Fiselier68b5f0b2017-04-13 00:34:24 +00001728 : __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001729 __pair3_(0, _VSTD::move(__t.value_comp()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001730{
1731 if (__a == __t.__alloc())
1732 {
1733 if (__t.size() == 0)
1734 __begin_node() = __end_node();
1735 else
1736 {
1737 __begin_node() = __t.__begin_node();
1738 __end_node()->__left_ = __t.__end_node()->__left_;
Eric Fiselier70f5f872016-07-19 17:56:20 +00001739 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001740 size() = __t.size();
1741 __t.__begin_node() = __t.__end_node();
1742 __t.__end_node()->__left_ = nullptr;
1743 __t.size() = 0;
1744 }
1745 }
1746 else
1747 {
1748 __begin_node() = __end_node();
1749 }
1750}
1751
1752template <class _Tp, class _Compare, class _Allocator>
1753void
1754__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001755 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1756 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001757{
1758 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1759 __begin_node_ = __t.__begin_node_;
1760 __pair1_.first() = __t.__pair1_.first();
1761 __move_assign_alloc(__t);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001762 __pair3_ = _VSTD::move(__t.__pair3_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001763 if (size() == 0)
1764 __begin_node() = __end_node();
1765 else
1766 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001767 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001768 __t.__begin_node() = __t.__end_node();
1769 __t.__end_node()->__left_ = nullptr;
1770 __t.size() = 0;
1771 }
1772}
1773
1774template <class _Tp, class _Compare, class _Allocator>
1775void
1776__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1777{
1778 if (__node_alloc() == __t.__node_alloc())
1779 __move_assign(__t, true_type());
1780 else
1781 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001782 value_comp() = _VSTD::move(__t.value_comp());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001783 const_iterator __e = end();
1784 if (size() != 0)
1785 {
1786 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001787#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001788 try
1789 {
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001790#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001791 while (__cache != nullptr && __t.size() != 0)
1792 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001793 __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001794 __node_pointer __next = __detach(__cache);
1795 __node_insert_multi(__cache);
1796 __cache = __next;
1797 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001798#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001799 }
1800 catch (...)
1801 {
1802 while (__cache->__parent_ != nullptr)
1803 __cache = static_cast<__node_pointer>(__cache->__parent_);
1804 destroy(__cache);
1805 throw;
1806 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001807#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001808 if (__cache != nullptr)
1809 {
1810 while (__cache->__parent_ != nullptr)
1811 __cache = static_cast<__node_pointer>(__cache->__parent_);
1812 destroy(__cache);
1813 }
1814 }
1815 while (__t.size() != 0)
Eric Fiselierd06276b2016-03-31 02:15:15 +00001816 __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001817 }
1818}
1819
1820template <class _Tp, class _Compare, class _Allocator>
1821__tree<_Tp, _Compare, _Allocator>&
1822__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001823 _NOEXCEPT_(
1824 __node_traits::propagate_on_container_move_assignment::value &&
1825 is_nothrow_move_assignable<value_compare>::value &&
1826 is_nothrow_move_assignable<__node_allocator>::value)
Louis Dionne44bcff92018-08-03 22:36:53 +00001827
Howard Hinnantc51e1022010-05-11 19:42:16 +00001828{
1829 __move_assign(__t, integral_constant<bool,
1830 __node_traits::propagate_on_container_move_assignment::value>());
1831 return *this;
1832}
1833
Eric Fiselierb63508a2017-04-19 01:23:04 +00001834#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00001835
1836template <class _Tp, class _Compare, class _Allocator>
1837__tree<_Tp, _Compare, _Allocator>::~__tree()
1838{
Marshall Clow140d9432016-06-30 22:05:45 +00001839 static_assert((is_copy_constructible<value_compare>::value),
1840 "Comparator must be copy-constructible.");
Eric Fiseliera7a14ed2017-01-13 22:02:08 +00001841 destroy(__root());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001842}
1843
1844template <class _Tp, class _Compare, class _Allocator>
1845void
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001846__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001847{
1848 if (__nd != nullptr)
1849 {
1850 destroy(static_cast<__node_pointer>(__nd->__left_));
1851 destroy(static_cast<__node_pointer>(__nd->__right_));
1852 __node_allocator& __na = __node_alloc();
Eric Fiselierd06276b2016-03-31 02:15:15 +00001853 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001854 __node_traits::deallocate(__na, __nd, 1);
1855 }
1856}
1857
1858template <class _Tp, class _Compare, class _Allocator>
1859void
1860__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001861#if _LIBCPP_STD_VER <= 11
Marshall Clow8982dcd2015-07-13 20:04:56 +00001862 _NOEXCEPT_(
1863 __is_nothrow_swappable<value_compare>::value
Marshall Clow8982dcd2015-07-13 20:04:56 +00001864 && (!__node_traits::propagate_on_container_swap::value ||
1865 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow8982dcd2015-07-13 20:04:56 +00001866 )
Dimitry Andrice3dda3f2016-08-27 19:32:03 +00001867#else
1868 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1869#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001870{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001871 using _VSTD::swap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001872 swap(__begin_node_, __t.__begin_node_);
1873 swap(__pair1_.first(), __t.__pair1_.first());
Marshall Clow8982dcd2015-07-13 20:04:56 +00001874 __swap_allocator(__node_alloc(), __t.__node_alloc());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001875 __pair3_.swap(__t.__pair3_);
1876 if (size() == 0)
1877 __begin_node() = __end_node();
1878 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00001879 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001880 if (__t.size() == 0)
1881 __t.__begin_node() = __t.__end_node();
1882 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00001883 __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001884}
1885
1886template <class _Tp, class _Compare, class _Allocator>
1887void
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00001888__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001889{
1890 destroy(__root());
1891 size() = 0;
1892 __begin_node() = __end_node();
1893 __end_node()->__left_ = nullptr;
1894}
1895
1896// Find lower_bound place to insert
1897// Set __parent to parent of null leaf
1898// Return reference to null leaf
1899template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001900typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1901__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001902 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001903{
1904 __node_pointer __nd = __root();
1905 if (__nd != nullptr)
1906 {
1907 while (true)
1908 {
1909 if (value_comp()(__nd->__value_, __v))
1910 {
1911 if (__nd->__right_ != nullptr)
1912 __nd = static_cast<__node_pointer>(__nd->__right_);
1913 else
1914 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001915 __parent = static_cast<__parent_pointer>(__nd);
1916 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001917 }
1918 }
1919 else
1920 {
1921 if (__nd->__left_ != nullptr)
1922 __nd = static_cast<__node_pointer>(__nd->__left_);
1923 else
1924 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001925 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001926 return __parent->__left_;
1927 }
1928 }
1929 }
1930 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00001931 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001932 return __parent->__left_;
1933}
1934
1935// Find upper_bound place to insert
1936// Set __parent to parent of null leaf
1937// Return reference to null leaf
1938template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001939typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1940__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001941 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001942{
1943 __node_pointer __nd = __root();
1944 if (__nd != nullptr)
1945 {
1946 while (true)
1947 {
1948 if (value_comp()(__v, __nd->__value_))
1949 {
1950 if (__nd->__left_ != nullptr)
1951 __nd = static_cast<__node_pointer>(__nd->__left_);
1952 else
1953 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001954 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001955 return __parent->__left_;
1956 }
1957 }
1958 else
1959 {
1960 if (__nd->__right_ != nullptr)
1961 __nd = static_cast<__node_pointer>(__nd->__right_);
1962 else
1963 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001964 __parent = static_cast<__parent_pointer>(__nd);
1965 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001966 }
1967 }
1968 }
1969 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00001970 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001971 return __parent->__left_;
1972}
1973
1974// Find leaf place to insert closest to __hint
1975// First check prior to __hint.
1976// Next check after __hint.
1977// Next do O(log N) search.
1978// Set __parent to parent of null leaf
1979// Return reference to null leaf
1980template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier70f5f872016-07-19 17:56:20 +00001981typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00001982__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00001983 __parent_pointer& __parent,
Eric Fiselierd06276b2016-03-31 02:15:15 +00001984 const key_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001985{
1986 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1987 {
1988 // __v <= *__hint
1989 const_iterator __prior = __hint;
1990 if (__prior == begin() || !value_comp()(__v, *--__prior))
1991 {
1992 // *prev(__hint) <= __v <= *__hint
1993 if (__hint.__ptr_->__left_ == nullptr)
1994 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00001995 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001996 return __parent->__left_;
1997 }
1998 else
1999 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002000 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2001 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002002 }
2003 }
2004 // __v < *prev(__hint)
2005 return __find_leaf_high(__parent, __v);
2006 }
2007 // else __v > *__hint
2008 return __find_leaf_low(__parent, __v);
2009}
2010
2011// Find place to insert if __v doesn't exist
2012// Set __parent to parent of null leaf
2013// Return reference to null leaf
2014// If __v exists, set parent to node of __v and return reference to node of __v
2015template <class _Tp, class _Compare, class _Allocator>
2016template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00002017typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
2018__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002019 const _Key& __v)
2020{
2021 __node_pointer __nd = __root();
Eric Fiselier70f5f872016-07-19 17:56:20 +00002022 __node_base_pointer* __nd_ptr = __root_ptr();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002023 if (__nd != nullptr)
2024 {
2025 while (true)
2026 {
2027 if (value_comp()(__v, __nd->__value_))
2028 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002029 if (__nd->__left_ != nullptr) {
2030 __nd_ptr = _VSTD::addressof(__nd->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002031 __nd = static_cast<__node_pointer>(__nd->__left_);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002032 } else {
2033 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002034 return __parent->__left_;
2035 }
2036 }
2037 else if (value_comp()(__nd->__value_, __v))
2038 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002039 if (__nd->__right_ != nullptr) {
2040 __nd_ptr = _VSTD::addressof(__nd->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002041 __nd = static_cast<__node_pointer>(__nd->__right_);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002042 } else {
2043 __parent = static_cast<__parent_pointer>(__nd);
2044 return __nd->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002045 }
2046 }
2047 else
2048 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002049 __parent = static_cast<__parent_pointer>(__nd);
2050 return *__nd_ptr;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002051 }
2052 }
2053 }
Eric Fiselier70f5f872016-07-19 17:56:20 +00002054 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002055 return __parent->__left_;
2056}
2057
2058// Find place to insert if __v doesn't exist
2059// First check prior to __hint.
2060// Next check after __hint.
2061// Next do O(log N) search.
2062// Set __parent to parent of null leaf
2063// Return reference to null leaf
2064// If __v exists, set parent to node of __v and return reference to node of __v
2065template <class _Tp, class _Compare, class _Allocator>
2066template <class _Key>
Eric Fiselier70f5f872016-07-19 17:56:20 +00002067typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantc51e1022010-05-11 19:42:16 +00002068__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002069 __parent_pointer& __parent,
2070 __node_base_pointer& __dummy,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002071 const _Key& __v)
2072{
2073 if (__hint == end() || value_comp()(__v, *__hint)) // check before
2074 {
2075 // __v < *__hint
2076 const_iterator __prior = __hint;
2077 if (__prior == begin() || value_comp()(*--__prior, __v))
2078 {
2079 // *prev(__hint) < __v < *__hint
2080 if (__hint.__ptr_->__left_ == nullptr)
2081 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002082 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002083 return __parent->__left_;
2084 }
2085 else
2086 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002087 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2088 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002089 }
2090 }
2091 // __v <= *prev(__hint)
2092 return __find_equal(__parent, __v);
2093 }
2094 else if (value_comp()(*__hint, __v)) // check after
2095 {
2096 // *__hint < __v
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002097 const_iterator __next = _VSTD::next(__hint);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002098 if (__next == end() || value_comp()(__v, *__next))
2099 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002100 // *__hint < __v < *_VSTD::next(__hint)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002101 if (__hint.__get_np()->__right_ == nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002102 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002103 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2104 return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002105 }
2106 else
2107 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002108 __parent = static_cast<__parent_pointer>(__next.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002109 return __parent->__left_;
2110 }
2111 }
2112 // *next(__hint) <= __v
2113 return __find_equal(__parent, __v);
2114 }
2115 // else __v == *__hint
Eric Fiselier70f5f872016-07-19 17:56:20 +00002116 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2117 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2118 return __dummy;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002119}
2120
2121template <class _Tp, class _Compare, class _Allocator>
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002122void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
2123 __parent_pointer __parent, __node_base_pointer& __child,
2124 __node_base_pointer __new_node) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002125{
2126 __new_node->__left_ = nullptr;
2127 __new_node->__right_ = nullptr;
2128 __new_node->__parent_ = __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002129 // __new_node->__is_black_ is initialized in __tree_balance_after_insert
Howard Hinnantc51e1022010-05-11 19:42:16 +00002130 __child = __new_node;
2131 if (__begin_node()->__left_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002132 __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002133 __tree_balance_after_insert(__end_node()->__left_, __child);
2134 ++size();
2135}
2136
Eric Fiselierd06276b2016-03-31 02:15:15 +00002137#ifndef _LIBCPP_CXX03_LANG
2138template <class _Tp, class _Compare, class _Allocator>
2139template <class _Key, class... _Args>
2140pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2141__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
2142#else
2143template <class _Tp, class _Compare, class _Allocator>
2144template <class _Key, class _Args>
2145pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2146__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args)
2147#endif
2148{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002149 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002150 __node_base_pointer& __child = __find_equal(__parent, __k);
2151 __node_pointer __r = static_cast<__node_pointer>(__child);
2152 bool __inserted = false;
2153 if (__child == nullptr)
2154 {
2155#ifndef _LIBCPP_CXX03_LANG
2156 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2157#else
2158 __node_holder __h = __construct_node(__args);
2159#endif
2160 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2161 __r = __h.release();
2162 __inserted = true;
2163 }
2164 return pair<iterator, bool>(iterator(__r), __inserted);
2165}
2166
2167
2168#ifndef _LIBCPP_CXX03_LANG
2169template <class _Tp, class _Compare, class _Allocator>
2170template <class _Key, class... _Args>
2171typename __tree<_Tp, _Compare, _Allocator>::iterator
2172__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2173 const_iterator __p, _Key const& __k, _Args&&... __args)
2174#else
2175template <class _Tp, class _Compare, class _Allocator>
2176template <class _Key, class _Args>
2177typename __tree<_Tp, _Compare, _Allocator>::iterator
2178__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2179 const_iterator __p, _Key const& __k, _Args& __args)
2180#endif
2181{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002182 __parent_pointer __parent;
2183 __node_base_pointer __dummy;
2184 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
Eric Fiselierd06276b2016-03-31 02:15:15 +00002185 __node_pointer __r = static_cast<__node_pointer>(__child);
2186 if (__child == nullptr)
2187 {
2188#ifndef _LIBCPP_CXX03_LANG
2189 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2190#else
2191 __node_holder __h = __construct_node(__args);
2192#endif
2193 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2194 __r = __h.release();
2195 }
2196 return iterator(__r);
2197}
2198
2199
2200#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00002201
2202template <class _Tp, class _Compare, class _Allocator>
2203template <class ..._Args>
2204typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2205__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
2206{
Eric Fiselierd06276b2016-03-31 02:15:15 +00002207 static_assert(!__is_tree_value_type<_Args...>::value,
2208 "Cannot construct from __value_type");
Howard Hinnantc51e1022010-05-11 19:42:16 +00002209 __node_allocator& __na = __node_alloc();
Howard Hinnantc834c512011-11-29 18:15:50 +00002210 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierd06276b2016-03-31 02:15:15 +00002211 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002212 __h.get_deleter().__value_constructed = true;
2213 return __h;
2214}
2215
Eric Fiselierd06276b2016-03-31 02:15:15 +00002216
Howard Hinnantc51e1022010-05-11 19:42:16 +00002217template <class _Tp, class _Compare, class _Allocator>
2218template <class... _Args>
2219pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselier6cce51e2016-04-15 23:27:27 +00002220__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002221{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002222 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002223 __parent_pointer __parent;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002224 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
2225 __node_pointer __r = static_cast<__node_pointer>(__child);
2226 bool __inserted = false;
2227 if (__child == nullptr)
2228 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002229 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002230 __r = __h.release();
2231 __inserted = true;
2232 }
2233 return pair<iterator, bool>(iterator(__r), __inserted);
2234}
2235
2236template <class _Tp, class _Compare, class _Allocator>
2237template <class... _Args>
2238typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselier6cce51e2016-04-15 23:27:27 +00002239__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002240{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002241 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002242 __parent_pointer __parent;
2243 __node_base_pointer __dummy;
2244 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002245 __node_pointer __r = static_cast<__node_pointer>(__child);
2246 if (__child == nullptr)
2247 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002248 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002249 __r = __h.release();
2250 }
2251 return iterator(__r);
2252}
2253
2254template <class _Tp, class _Compare, class _Allocator>
2255template <class... _Args>
2256typename __tree<_Tp, _Compare, _Allocator>::iterator
2257__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
2258{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002259 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002260 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002261 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002262 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002263 return iterator(static_cast<__node_pointer>(__h.release()));
2264}
2265
2266template <class _Tp, class _Compare, class _Allocator>
2267template <class... _Args>
2268typename __tree<_Tp, _Compare, _Allocator>::iterator
2269__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
2270 _Args&&... __args)
2271{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002272 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier70f5f872016-07-19 17:56:20 +00002273 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002274 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002275 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002276 return iterator(static_cast<__node_pointer>(__h.release()));
2277}
2278
Howard Hinnant74279a52010-09-04 23:28:19 +00002279
Eric Fiselierd06276b2016-03-31 02:15:15 +00002280#else // _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00002281
2282template <class _Tp, class _Compare, class _Allocator>
2283typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Eric Fiselierd06276b2016-03-31 02:15:15 +00002284__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002285{
2286 __node_allocator& __na = __node_alloc();
Howard Hinnantc834c512011-11-29 18:15:50 +00002287 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierd06276b2016-03-31 02:15:15 +00002288 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002289 __h.get_deleter().__value_constructed = true;
Dimitry Andric830fb602015-08-19 06:43:33 +00002290 return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
Howard Hinnantc51e1022010-05-11 19:42:16 +00002291}
2292
Eric Fiselierd06276b2016-03-31 02:15:15 +00002293#endif // _LIBCPP_CXX03_LANG
Howard Hinnantc5bc8672011-03-10 17:27:57 +00002294
Eric Fiselierd06276b2016-03-31 02:15:15 +00002295#ifdef _LIBCPP_CXX03_LANG
Howard Hinnantc51e1022010-05-11 19:42:16 +00002296template <class _Tp, class _Compare, class _Allocator>
2297typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierd06276b2016-03-31 02:15:15 +00002298__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002299{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002300 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002301 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002302 __node_holder __h = __construct_node(__v);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002303 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002304 return iterator(__h.release());
2305}
2306
2307template <class _Tp, class _Compare, class _Allocator>
2308typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierd06276b2016-03-31 02:15:15 +00002309__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002310{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002311 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002312 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002313 __node_holder __h = __construct_node(__v);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002314 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002315 return iterator(__h.release());
2316}
Eric Fiselierd06276b2016-03-31 02:15:15 +00002317#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00002318
Howard Hinnantc51e1022010-05-11 19:42:16 +00002319template <class _Tp, class _Compare, class _Allocator>
2320pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2321__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
2322{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002323 __parent_pointer __parent;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002324 __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
2325 __node_pointer __r = static_cast<__node_pointer>(__child);
2326 bool __inserted = false;
2327 if (__child == nullptr)
2328 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002329 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002330 __r = __nd;
2331 __inserted = true;
2332 }
2333 return pair<iterator, bool>(iterator(__r), __inserted);
2334}
2335
2336template <class _Tp, class _Compare, class _Allocator>
2337typename __tree<_Tp, _Compare, _Allocator>::iterator
2338__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
2339 __node_pointer __nd)
2340{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002341 __parent_pointer __parent;
2342 __node_base_pointer __dummy;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002343 __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
2344 __node_pointer __r = static_cast<__node_pointer>(__child);
2345 if (__child == nullptr)
2346 {
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002347 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002348 __r = __nd;
2349 }
2350 return iterator(__r);
2351}
2352
2353template <class _Tp, class _Compare, class _Allocator>
2354typename __tree<_Tp, _Compare, _Allocator>::iterator
2355__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
2356{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002357 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002358 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002359 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002360 return iterator(__nd);
2361}
2362
2363template <class _Tp, class _Compare, class _Allocator>
2364typename __tree<_Tp, _Compare, _Allocator>::iterator
2365__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
2366 __node_pointer __nd)
2367{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002368 __parent_pointer __parent;
Eric Fiselierd06276b2016-03-31 02:15:15 +00002369 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002370 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002371 return iterator(__nd);
2372}
2373
2374template <class _Tp, class _Compare, class _Allocator>
2375typename __tree<_Tp, _Compare, _Allocator>::iterator
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002376__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002377{
2378 iterator __r(__ptr);
2379 ++__r;
2380 if (__begin_node() == __ptr)
2381 __begin_node() = __r.__ptr_;
2382 --size();
2383 __tree_remove(__end_node()->__left_,
2384 static_cast<__node_base_pointer>(__ptr));
2385 return __r;
2386}
2387
2388#if _LIBCPP_STD_VER > 14
2389template <class _Tp, class _Compare, class _Allocator>
2390template <class _NodeHandle, class _InsertReturnType>
2391_LIBCPP_INLINE_VISIBILITY
2392_InsertReturnType
2393__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2394 _NodeHandle&& __nh)
2395{
2396 if (__nh.empty())
2397 return _InsertReturnType{end(), false, _NodeHandle()};
2398
2399 __node_pointer __ptr = __nh.__ptr_;
2400 __parent_pointer __parent;
2401 __node_base_pointer& __child = __find_equal(__parent,
2402 __ptr->__value_);
2403 if (__child != nullptr)
2404 return _InsertReturnType{
2405 iterator(static_cast<__node_pointer>(__child)),
2406 false, _VSTD::move(__nh)};
2407
2408 __insert_node_at(__parent, __child,
2409 static_cast<__node_base_pointer>(__ptr));
2410 __nh.__release();
2411 return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
2412}
2413
2414template <class _Tp, class _Compare, class _Allocator>
2415template <class _NodeHandle>
2416_LIBCPP_INLINE_VISIBILITY
2417typename __tree<_Tp, _Compare, _Allocator>::iterator
2418__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
2419 const_iterator __hint, _NodeHandle&& __nh)
2420{
2421 if (__nh.empty())
2422 return end();
2423
2424 __node_pointer __ptr = __nh.__ptr_;
2425 __parent_pointer __parent;
2426 __node_base_pointer __dummy;
2427 __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
2428 __ptr->__value_);
2429 __node_pointer __r = static_cast<__node_pointer>(__child);
2430 if (__child == nullptr)
2431 {
2432 __insert_node_at(__parent, __child,
2433 static_cast<__node_base_pointer>(__ptr));
2434 __r = __ptr;
2435 __nh.__release();
2436 }
2437 return iterator(__r);
2438}
2439
2440template <class _Tp, class _Compare, class _Allocator>
2441template <class _NodeHandle>
2442_LIBCPP_INLINE_VISIBILITY
2443_NodeHandle
2444__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
2445{
2446 iterator __it = find(__key);
2447 if (__it == end())
2448 return _NodeHandle();
2449 return __node_handle_extract<_NodeHandle>(__it);
2450}
2451
2452template <class _Tp, class _Compare, class _Allocator>
2453template <class _NodeHandle>
2454_LIBCPP_INLINE_VISIBILITY
2455_NodeHandle
2456__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
2457{
2458 __node_pointer __np = __p.__get_np();
2459 __remove_node_pointer(__np);
2460 return _NodeHandle(__np, __alloc());
2461}
2462
2463template <class _Tp, class _Compare, class _Allocator>
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002464template <class _Tree>
2465_LIBCPP_INLINE_VISIBILITY
2466void
2467__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
2468{
2469 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2470
2471 for (typename _Tree::iterator __i = __source.begin();
2472 __i != __source.end();)
2473 {
2474 __node_pointer __src_ptr = __i.__get_np();
2475 __parent_pointer __parent;
2476 __node_base_pointer& __child =
2477 __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
2478 ++__i;
2479 if (__child != nullptr)
2480 continue;
2481 __source.__remove_node_pointer(__src_ptr);
2482 __insert_node_at(__parent, __child,
2483 static_cast<__node_base_pointer>(__src_ptr));
2484 }
2485}
2486
2487template <class _Tp, class _Compare, class _Allocator>
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002488template <class _NodeHandle>
2489_LIBCPP_INLINE_VISIBILITY
2490typename __tree<_Tp, _Compare, _Allocator>::iterator
2491__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
2492{
2493 if (__nh.empty())
2494 return end();
2495 __node_pointer __ptr = __nh.__ptr_;
2496 __parent_pointer __parent;
2497 __node_base_pointer& __child = __find_leaf_high(
2498 __parent, _NodeTypes::__get_key(__ptr->__value_));
2499 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
2500 __nh.__release();
2501 return iterator(__ptr);
2502}
2503
2504template <class _Tp, class _Compare, class _Allocator>
2505template <class _NodeHandle>
2506_LIBCPP_INLINE_VISIBILITY
2507typename __tree<_Tp, _Compare, _Allocator>::iterator
2508__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
2509 const_iterator __hint, _NodeHandle&& __nh)
2510{
2511 if (__nh.empty())
2512 return end();
2513
2514 __node_pointer __ptr = __nh.__ptr_;
2515 __parent_pointer __parent;
2516 __node_base_pointer& __child = __find_leaf(__hint, __parent,
2517 _NodeTypes::__get_key(__ptr->__value_));
2518 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
2519 __nh.__release();
2520 return iterator(__ptr);
2521}
2522
Erik Pilkington82a65ad2018-10-31 17:31:35 +00002523template <class _Tp, class _Compare, class _Allocator>
2524template <class _Tree>
2525_LIBCPP_INLINE_VISIBILITY
2526void
2527__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
2528{
2529 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
2530
2531 for (typename _Tree::iterator __i = __source.begin();
2532 __i != __source.end();)
2533 {
2534 __node_pointer __src_ptr = __i.__get_np();
2535 __parent_pointer __parent;
2536 __node_base_pointer& __child = __find_leaf_high(
2537 __parent, _NodeTypes::__get_key(__src_ptr->__value_));
2538 ++__i;
2539 __source.__remove_node_pointer(__src_ptr);
2540 __insert_node_at(__parent, __child,
2541 static_cast<__node_base_pointer>(__src_ptr));
2542 }
2543}
2544
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002545#endif // _LIBCPP_STD_VER > 14
2546
2547template <class _Tp, class _Compare, class _Allocator>
2548typename __tree<_Tp, _Compare, _Allocator>::iterator
Howard Hinnantc51e1022010-05-11 19:42:16 +00002549__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
2550{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002551 __node_pointer __np = __p.__get_np();
Erik Pilkingtonc37a3d82018-08-01 01:33:38 +00002552 iterator __r = __remove_node_pointer(__np);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002553 __node_allocator& __na = __node_alloc();
Eric Fiselierd06276b2016-03-31 02:15:15 +00002554 __node_traits::destroy(__na, _NodeTypes::__get_ptr(
2555 const_cast<__node_value_type&>(*__p)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002556 __node_traits::deallocate(__na, __np, 1);
2557 return __r;
2558}
2559
2560template <class _Tp, class _Compare, class _Allocator>
2561typename __tree<_Tp, _Compare, _Allocator>::iterator
2562__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
2563{
2564 while (__f != __l)
2565 __f = erase(__f);
Howard Hinnant2d0046b2013-06-19 21:29:40 +00002566 return iterator(__l.__ptr_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002567}
2568
2569template <class _Tp, class _Compare, class _Allocator>
2570template <class _Key>
2571typename __tree<_Tp, _Compare, _Allocator>::size_type
2572__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
2573{
2574 iterator __i = find(__k);
2575 if (__i == end())
2576 return 0;
2577 erase(__i);
2578 return 1;
2579}
2580
2581template <class _Tp, class _Compare, class _Allocator>
2582template <class _Key>
2583typename __tree<_Tp, _Compare, _Allocator>::size_type
2584__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
2585{
2586 pair<iterator, iterator> __p = __equal_range_multi(__k);
2587 size_type __r = 0;
2588 for (; __p.first != __p.second; ++__r)
2589 __p.first = erase(__p.first);
2590 return __r;
2591}
2592
2593template <class _Tp, class _Compare, class _Allocator>
2594template <class _Key>
2595typename __tree<_Tp, _Compare, _Allocator>::iterator
2596__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
2597{
2598 iterator __p = __lower_bound(__v, __root(), __end_node());
2599 if (__p != end() && !value_comp()(__v, *__p))
2600 return __p;
2601 return end();
2602}
2603
2604template <class _Tp, class _Compare, class _Allocator>
2605template <class _Key>
2606typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2607__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
2608{
2609 const_iterator __p = __lower_bound(__v, __root(), __end_node());
2610 if (__p != end() && !value_comp()(__v, *__p))
2611 return __p;
2612 return end();
2613}
2614
2615template <class _Tp, class _Compare, class _Allocator>
2616template <class _Key>
2617typename __tree<_Tp, _Compare, _Allocator>::size_type
2618__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
2619{
Eric Fiseliera92b0732016-02-20 07:12:17 +00002620 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002621 while (__rt != nullptr)
2622 {
2623 if (value_comp()(__k, __rt->__value_))
2624 {
Eric Fiseliera92b0732016-02-20 07:12:17 +00002625 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002626 }
2627 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002628 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002629 else
2630 return 1;
2631 }
2632 return 0;
2633}
2634
2635template <class _Tp, class _Compare, class _Allocator>
2636template <class _Key>
2637typename __tree<_Tp, _Compare, _Allocator>::size_type
2638__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
2639{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002640 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002641 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002642 while (__rt != nullptr)
2643 {
2644 if (value_comp()(__k, __rt->__value_))
2645 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002646 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002647 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002648 }
2649 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002650 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002651 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002652 return _VSTD::distance(
Eric Fiselier70f5f872016-07-19 17:56:20 +00002653 __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiseliera92b0732016-02-20 07:12:17 +00002654 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002655 );
2656 }
2657 return 0;
2658}
2659
2660template <class _Tp, class _Compare, class _Allocator>
2661template <class _Key>
2662typename __tree<_Tp, _Compare, _Allocator>::iterator
2663__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2664 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002665 __iter_pointer __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002666{
2667 while (__root != nullptr)
2668 {
2669 if (!value_comp()(__root->__value_, __v))
2670 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002671 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002672 __root = static_cast<__node_pointer>(__root->__left_);
2673 }
2674 else
2675 __root = static_cast<__node_pointer>(__root->__right_);
2676 }
2677 return iterator(__result);
2678}
2679
2680template <class _Tp, class _Compare, class _Allocator>
2681template <class _Key>
2682typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2683__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00002684 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002685 __iter_pointer __result) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00002686{
2687 while (__root != nullptr)
2688 {
2689 if (!value_comp()(__root->__value_, __v))
2690 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002691 __result = static_cast<__iter_pointer>(__root);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002692 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002693 }
2694 else
Eric Fiseliera92b0732016-02-20 07:12:17 +00002695 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002696 }
2697 return const_iterator(__result);
2698}
2699
2700template <class _Tp, class _Compare, class _Allocator>
2701template <class _Key>
2702typename __tree<_Tp, _Compare, _Allocator>::iterator
2703__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2704 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002705 __iter_pointer __result)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002706{
2707 while (__root != nullptr)
2708 {
2709 if (value_comp()(__v, __root->__value_))
2710 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002711 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002712 __root = static_cast<__node_pointer>(__root->__left_);
2713 }
2714 else
2715 __root = static_cast<__node_pointer>(__root->__right_);
2716 }
2717 return iterator(__result);
2718}
2719
2720template <class _Tp, class _Compare, class _Allocator>
2721template <class _Key>
2722typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2723__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
Eric Fiseliera92b0732016-02-20 07:12:17 +00002724 __node_pointer __root,
Eric Fiselier70f5f872016-07-19 17:56:20 +00002725 __iter_pointer __result) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00002726{
2727 while (__root != nullptr)
2728 {
2729 if (value_comp()(__v, __root->__value_))
2730 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002731 __result = static_cast<__iter_pointer>(__root);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002732 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002733 }
2734 else
Eric Fiseliera92b0732016-02-20 07:12:17 +00002735 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002736 }
2737 return const_iterator(__result);
2738}
2739
2740template <class _Tp, class _Compare, class _Allocator>
2741template <class _Key>
2742pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2743 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2744__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2745{
Howard Hinnantc834c512011-11-29 18:15:50 +00002746 typedef pair<iterator, iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002747 __iter_pointer __result = __end_node();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002748 __node_pointer __rt = __root();
2749 while (__rt != nullptr)
2750 {
2751 if (value_comp()(__k, __rt->__value_))
2752 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002753 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002754 __rt = static_cast<__node_pointer>(__rt->__left_);
2755 }
2756 else if (value_comp()(__rt->__value_, __k))
2757 __rt = static_cast<__node_pointer>(__rt->__right_);
2758 else
Howard Hinnantc834c512011-11-29 18:15:50 +00002759 return _Pp(iterator(__rt),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002760 iterator(
2761 __rt->__right_ != nullptr ?
Eric Fiselier70f5f872016-07-19 17:56:20 +00002762 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00002763 : __result));
2764 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002765 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002766}
2767
2768template <class _Tp, class _Compare, class _Allocator>
2769template <class _Key>
2770pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2771 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2772__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2773{
Howard Hinnantc834c512011-11-29 18:15:50 +00002774 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002775 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002776 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002777 while (__rt != nullptr)
2778 {
2779 if (value_comp()(__k, __rt->__value_))
2780 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002781 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002782 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002783 }
2784 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002785 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002786 else
Howard Hinnantc834c512011-11-29 18:15:50 +00002787 return _Pp(const_iterator(__rt),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002788 const_iterator(
2789 __rt->__right_ != nullptr ?
Eric Fiselier70f5f872016-07-19 17:56:20 +00002790 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantc51e1022010-05-11 19:42:16 +00002791 : __result));
2792 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002793 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002794}
2795
2796template <class _Tp, class _Compare, class _Allocator>
2797template <class _Key>
2798pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2799 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2800__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2801{
Howard Hinnantc834c512011-11-29 18:15:50 +00002802 typedef pair<iterator, iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002803 __iter_pointer __result = __end_node();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002804 __node_pointer __rt = __root();
2805 while (__rt != nullptr)
2806 {
2807 if (value_comp()(__k, __rt->__value_))
2808 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002809 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002810 __rt = static_cast<__node_pointer>(__rt->__left_);
2811 }
2812 else if (value_comp()(__rt->__value_, __k))
2813 __rt = static_cast<__node_pointer>(__rt->__right_);
2814 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002815 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Howard Hinnantc51e1022010-05-11 19:42:16 +00002816 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2817 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002818 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002819}
2820
2821template <class _Tp, class _Compare, class _Allocator>
2822template <class _Key>
2823pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2824 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2825__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2826{
Howard Hinnantc834c512011-11-29 18:15:50 +00002827 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier70f5f872016-07-19 17:56:20 +00002828 __iter_pointer __result = __end_node();
Eric Fiseliera92b0732016-02-20 07:12:17 +00002829 __node_pointer __rt = __root();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002830 while (__rt != nullptr)
2831 {
2832 if (value_comp()(__k, __rt->__value_))
2833 {
Eric Fiselier70f5f872016-07-19 17:56:20 +00002834 __result = static_cast<__iter_pointer>(__rt);
Eric Fiseliera92b0732016-02-20 07:12:17 +00002835 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002836 }
2837 else if (value_comp()(__rt->__value_, __k))
Eric Fiseliera92b0732016-02-20 07:12:17 +00002838 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002839 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002840 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiseliera92b0732016-02-20 07:12:17 +00002841 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002842 }
Howard Hinnantc834c512011-11-29 18:15:50 +00002843 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002844}
2845
2846template <class _Tp, class _Compare, class _Allocator>
2847typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Howard Hinnant1113b5e2011-06-04 17:10:24 +00002848__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002849{
Eric Fiselier70f5f872016-07-19 17:56:20 +00002850 __node_pointer __np = __p.__get_np();
2851 if (__begin_node() == __p.__ptr_)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002852 {
2853 if (__np->__right_ != nullptr)
Eric Fiselier70f5f872016-07-19 17:56:20 +00002854 __begin_node() = static_cast<__iter_pointer>(__np->__right_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002855 else
Eric Fiselier70f5f872016-07-19 17:56:20 +00002856 __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002857 }
2858 --size();
2859 __tree_remove(__end_node()->__left_,
2860 static_cast<__node_base_pointer>(__np));
Marshall Clow95af65e2015-01-28 19:54:25 +00002861 return __node_holder(__np, _Dp(__node_alloc(), true));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002862}
2863
Howard Hinnant2f1ea9c2011-06-04 14:31:57 +00002864template <class _Tp, class _Compare, class _Allocator>
2865inline _LIBCPP_INLINE_VISIBILITY
2866void
2867swap(__tree<_Tp, _Compare, _Allocator>& __x,
2868 __tree<_Tp, _Compare, _Allocator>& __y)
2869 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2870{
2871 __x.swap(__y);
2872}
2873
Howard Hinnantc51e1022010-05-11 19:42:16 +00002874_LIBCPP_END_NAMESPACE_STD
2875
Eric Fiselierf4433a32017-05-31 22:07:49 +00002876_LIBCPP_POP_MACROS
2877
Howard Hinnantc51e1022010-05-11 19:42:16 +00002878#endif // _LIBCPP___TREE