blob: 170d4c0b308aad41a8b048ba8a41e1ea3ab1c002 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___TREE
12#define _LIBCPP___TREE
13
14#include <__config>
15#include <iterator>
16#include <memory>
17#include <stdexcept>
18#include <algorithm>
19
Howard Hinnant08e17472011-10-17 20:05:10 +000020#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000021#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000022#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000023
24_LIBCPP_BEGIN_NAMESPACE_STD
25
Howard Hinnant2b1b2d42011-06-14 19:58:17 +000026template <class _Tp, class _Compare, class _Allocator> class __tree;
27template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +000028 class _LIBCPP_TEMPLATE_VIS __tree_iterator;
Howard Hinnant2b1b2d42011-06-14 19:58:17 +000029template <class _Tp, class _ConstNodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +000030 class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000031
Eric Fiselier55263482016-02-20 05:28:30 +000032template <class _Pointer> class __tree_end_node;
33template <class _VoidPtr> class __tree_node_base;
34template <class _Tp, class _VoidPtr> class __tree_node;
35
36#ifndef _LIBCPP_CXX03_LANG
37template <class _Key, class _Value>
38union __value_type;
39#else
40template <class _Key, class _Value>
41struct __value_type;
42#endif
43
Eric Fiselierebaf7da2017-01-13 22:02:08 +000044template <class _Key, class _CP, class _Compare,
45 bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
46class __map_value_compare;
47
Eric Fiselier55263482016-02-20 05:28:30 +000048template <class _Allocator> class __map_node_destructor;
Eric Fiselierc3589a82017-01-04 23:56:00 +000049template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
50template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiselier55263482016-02-20 05:28:30 +000051
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000052/*
53
54_NodePtr algorithms
55
56The algorithms taking _NodePtr are red black tree algorithms. Those
57algorithms taking a parameter named __root should assume that __root
58points to a proper red black tree (unless otherwise specified).
59
60Each algorithm herein assumes that __root->__parent_ points to a non-null
61structure which has a member __left_ which points back to __root. No other
62member is read or written to at __root->__parent_.
63
64__root->__parent_ will be referred to below (in comments only) as end_node.
65end_node->__left_ is an externably accessible lvalue for __root, and can be
66changed by node insertion and removal (without explicit reference to end_node).
67
68All nodes (with the exception of end_node), even the node referred to as
69__root, have a non-null __parent_ field.
70
71*/
72
73// Returns: true if __x is a left child of its parent, else false
74// Precondition: __x != nullptr.
75template <class _NodePtr>
Howard Hinnant333f50d2010-09-21 20:16:37 +000076inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000077bool
Howard Hinnant8b537682011-06-04 17:10:24 +000078__tree_is_left_child(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000079{
80 return __x == __x->__parent_->__left_;
81}
82
83// Determintes if the subtree rooted at __x is a proper red black subtree. If
84// __x is a proper subtree, returns the black height (null counts as 1). If
85// __x is an improper subtree, returns 0.
86template <class _NodePtr>
87unsigned
88__tree_sub_invariant(_NodePtr __x)
89{
90 if (__x == nullptr)
91 return 1;
92 // parent consistency checked by caller
93 // check __x->__left_ consistency
94 if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
95 return 0;
96 // check __x->__right_ consistency
97 if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
98 return 0;
99 // check __x->__left_ != __x->__right_ unless both are nullptr
100 if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
101 return 0;
102 // If this is red, neither child can be red
103 if (!__x->__is_black_)
104 {
105 if (__x->__left_ && !__x->__left_->__is_black_)
106 return 0;
107 if (__x->__right_ && !__x->__right_->__is_black_)
108 return 0;
109 }
110 unsigned __h = __tree_sub_invariant(__x->__left_);
111 if (__h == 0)
112 return 0; // invalid left subtree
113 if (__h != __tree_sub_invariant(__x->__right_))
114 return 0; // invalid or different height right subtree
115 return __h + __x->__is_black_; // return black height of this node
116}
117
118// Determintes if the red black tree rooted at __root is a proper red black tree.
119// __root == nullptr is a proper tree. Returns true is __root is a proper
120// red black tree, else returns false.
121template <class _NodePtr>
122bool
123__tree_invariant(_NodePtr __root)
124{
125 if (__root == nullptr)
126 return true;
127 // check __x->__parent_ consistency
128 if (__root->__parent_ == nullptr)
129 return false;
130 if (!__tree_is_left_child(__root))
131 return false;
132 // root must be black
133 if (!__root->__is_black_)
134 return false;
135 // do normal node checks
136 return __tree_sub_invariant(__root) != 0;
137}
138
139// Returns: pointer to the left-most node under __x.
140// Precondition: __x != nullptr.
141template <class _NodePtr>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000142inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000143_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000144__tree_min(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145{
146 while (__x->__left_ != nullptr)
147 __x = __x->__left_;
148 return __x;
149}
150
151// Returns: pointer to the right-most node under __x.
152// Precondition: __x != nullptr.
153template <class _NodePtr>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000154inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000155_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000156__tree_max(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000157{
158 while (__x->__right_ != nullptr)
159 __x = __x->__right_;
160 return __x;
161}
162
163// Returns: pointer to the next in-order node after __x.
164// Precondition: __x != nullptr.
165template <class _NodePtr>
166_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000167__tree_next(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000168{
169 if (__x->__right_ != nullptr)
170 return __tree_min(__x->__right_);
171 while (!__tree_is_left_child(__x))
Eric Fiselier7310ec82016-07-19 17:56:20 +0000172 __x = __x->__parent_unsafe();
173 return __x->__parent_unsafe();
174}
175
176template <class _EndNodePtr, class _NodePtr>
177inline _LIBCPP_INLINE_VISIBILITY
178_EndNodePtr
179__tree_next_iter(_NodePtr __x) _NOEXCEPT
180{
181 if (__x->__right_ != nullptr)
182 return static_cast<_EndNodePtr>(__tree_min(__x->__right_));
183 while (!__tree_is_left_child(__x))
184 __x = __x->__parent_unsafe();
185 return static_cast<_EndNodePtr>(__x->__parent_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000186}
187
188// Returns: pointer to the previous in-order node before __x.
189// Precondition: __x != nullptr.
Eric Fiselier7310ec82016-07-19 17:56:20 +0000190// Note: __x may be the end node.
191template <class _NodePtr, class _EndNodePtr>
192inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000193_NodePtr
Eric Fiselier7310ec82016-07-19 17:56:20 +0000194__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000195{
196 if (__x->__left_ != nullptr)
197 return __tree_max(__x->__left_);
Eric Fiselier7310ec82016-07-19 17:56:20 +0000198 _NodePtr __xx = static_cast<_NodePtr>(__x);
199 while (__tree_is_left_child(__xx))
200 __xx = __xx->__parent_unsafe();
201 return __xx->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000202}
203
204// Returns: pointer to a node which has no children
205// Precondition: __x != nullptr.
206template <class _NodePtr>
207_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000208__tree_leaf(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000209{
210 while (true)
211 {
212 if (__x->__left_ != nullptr)
213 {
214 __x = __x->__left_;
215 continue;
216 }
217 if (__x->__right_ != nullptr)
218 {
219 __x = __x->__right_;
220 continue;
221 }
222 break;
223 }
224 return __x;
225}
226
227// Effects: Makes __x->__right_ the subtree root with __x as its left child
228// while preserving in-order order.
229// Precondition: __x->__right_ != nullptr
230template <class _NodePtr>
231void
Howard Hinnant8b537682011-06-04 17:10:24 +0000232__tree_left_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000233{
234 _NodePtr __y = __x->__right_;
235 __x->__right_ = __y->__left_;
236 if (__x->__right_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000237 __x->__right_->__set_parent(__x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000238 __y->__parent_ = __x->__parent_;
239 if (__tree_is_left_child(__x))
240 __x->__parent_->__left_ = __y;
241 else
Eric Fiselier7310ec82016-07-19 17:56:20 +0000242 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000243 __y->__left_ = __x;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000244 __x->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000245}
246
247// Effects: Makes __x->__left_ the subtree root with __x as its right child
248// while preserving in-order order.
249// Precondition: __x->__left_ != nullptr
250template <class _NodePtr>
251void
Howard Hinnant8b537682011-06-04 17:10:24 +0000252__tree_right_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000253{
254 _NodePtr __y = __x->__left_;
255 __x->__left_ = __y->__right_;
256 if (__x->__left_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000257 __x->__left_->__set_parent(__x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000258 __y->__parent_ = __x->__parent_;
259 if (__tree_is_left_child(__x))
260 __x->__parent_->__left_ = __y;
261 else
Eric Fiselier7310ec82016-07-19 17:56:20 +0000262 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000263 __y->__right_ = __x;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000264 __x->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265}
266
267// Effects: Rebalances __root after attaching __x to a leaf.
268// Precondition: __root != nulptr && __x != nullptr.
269// __x has no children.
270// __x == __root or == a direct or indirect child of __root.
271// If __x were to be unlinked from __root (setting __root to
272// nullptr if __root == __x), __tree_invariant(__root) == true.
273// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_
274// may be different than the value passed in as __root.
275template <class _NodePtr>
276void
Howard Hinnant8b537682011-06-04 17:10:24 +0000277__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000278{
279 __x->__is_black_ = __x == __root;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000280 while (__x != __root && !__x->__parent_unsafe()->__is_black_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000281 {
282 // __x->__parent_ != __root because __x->__parent_->__is_black == false
Eric Fiselier7310ec82016-07-19 17:56:20 +0000283 if (__tree_is_left_child(__x->__parent_unsafe()))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000284 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000285 _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000286 if (__y != nullptr && !__y->__is_black_)
287 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000288 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000290 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000291 __x->__is_black_ = __x == __root;
292 __y->__is_black_ = true;
293 }
294 else
295 {
296 if (!__tree_is_left_child(__x))
297 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000298 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000299 __tree_left_rotate(__x);
300 }
Eric Fiselier7310ec82016-07-19 17:56:20 +0000301 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000302 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000303 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000304 __x->__is_black_ = false;
305 __tree_right_rotate(__x);
306 break;
307 }
308 }
309 else
310 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000311 _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000312 if (__y != nullptr && !__y->__is_black_)
313 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000314 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000315 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000316 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317 __x->__is_black_ = __x == __root;
318 __y->__is_black_ = true;
319 }
320 else
321 {
322 if (__tree_is_left_child(__x))
323 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000324 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000325 __tree_right_rotate(__x);
326 }
Eric Fiselier7310ec82016-07-19 17:56:20 +0000327 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000328 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000329 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 __x->__is_black_ = false;
331 __tree_left_rotate(__x);
332 break;
333 }
334 }
335 }
336}
337
338// Precondition: __root != nullptr && __z != nullptr.
339// __tree_invariant(__root) == true.
340// __z == __root or == a direct or indirect child of __root.
341// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed.
342// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
343// nor any of its children refer to __z. end_node->__left_
344// may be different than the value passed in as __root.
345template <class _NodePtr>
346void
Howard Hinnant8b537682011-06-04 17:10:24 +0000347__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000348{
349 // __z will be removed from the tree. Client still needs to destruct/deallocate it
350 // __y is either __z, or if __z has two children, __tree_next(__z).
351 // __y will have at most one child.
352 // __y will be the initial hole in the tree (make the hole at a leaf)
353 _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
354 __z : __tree_next(__z);
355 // __x is __y's possibly null single child
356 _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
357 // __w is __x's possibly null uncle (will become __x's sibling)
358 _NodePtr __w = nullptr;
359 // link __x to __y's parent, and find __w
360 if (__x != nullptr)
361 __x->__parent_ = __y->__parent_;
362 if (__tree_is_left_child(__y))
363 {
364 __y->__parent_->__left_ = __x;
365 if (__y != __root)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000366 __w = __y->__parent_unsafe()->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000367 else
368 __root = __x; // __w == nullptr
369 }
370 else
371 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000372 __y->__parent_unsafe()->__right_ = __x;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000373 // __y can't be root if it is a right child
374 __w = __y->__parent_->__left_;
375 }
376 bool __removed_black = __y->__is_black_;
377 // If we didn't remove __z, do so now by splicing in __y for __z,
378 // but copy __z's color. This does not impact __x or __w.
379 if (__y != __z)
380 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000381 // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000382 __y->__parent_ = __z->__parent_;
383 if (__tree_is_left_child(__z))
384 __y->__parent_->__left_ = __y;
385 else
Eric Fiselier7310ec82016-07-19 17:56:20 +0000386 __y->__parent_unsafe()->__right_ = __y;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000387 __y->__left_ = __z->__left_;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000388 __y->__left_->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000389 __y->__right_ = __z->__right_;
390 if (__y->__right_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000391 __y->__right_->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000392 __y->__is_black_ = __z->__is_black_;
393 if (__root == __z)
394 __root = __y;
395 }
396 // There is no need to rebalance if we removed a red, or if we removed
397 // the last node.
398 if (__removed_black && __root != nullptr)
399 {
400 // Rebalance:
401 // __x has an implicit black color (transferred from the removed __y)
402 // associated with it, no matter what its color is.
403 // If __x is __root (in which case it can't be null), it is supposed
404 // to be black anyway, and if it is doubly black, then the double
405 // can just be ignored.
406 // If __x is red (in which case it can't be null), then it can absorb
407 // the implicit black just by setting its color to black.
408 // Since __y was black and only had one child (which __x points to), __x
409 // is either red with no children, else null, otherwise __y would have
410 // different black heights under left and right pointers.
411 // if (__x == __root || __x != nullptr && !__x->__is_black_)
412 if (__x != nullptr)
413 __x->__is_black_ = true;
414 else
415 {
416 // Else __x isn't root, and is "doubly black", even though it may
417 // be null. __w can not be null here, else the parent would
418 // see a black height >= 2 on the __x side and a black height
419 // of 1 on the __w side (__w must be a non-null black or a red
420 // with a non-null black child).
421 while (true)
422 {
423 if (!__tree_is_left_child(__w)) // if x is left child
424 {
425 if (!__w->__is_black_)
426 {
427 __w->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000428 __w->__parent_unsafe()->__is_black_ = false;
429 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000430 // __x is still valid
431 // reset __root only if necessary
432 if (__root == __w->__left_)
433 __root = __w;
434 // reset sibling, and it still can't be null
435 __w = __w->__left_->__right_;
436 }
437 // __w->__is_black_ is now true, __w may have null children
438 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
439 (__w->__right_ == nullptr || __w->__right_->__is_black_))
440 {
441 __w->__is_black_ = false;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000442 __x = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000443 // __x can no longer be null
444 if (__x == __root || !__x->__is_black_)
445 {
446 __x->__is_black_ = true;
447 break;
448 }
449 // reset sibling, and it still can't be null
450 __w = __tree_is_left_child(__x) ?
Eric Fiselier7310ec82016-07-19 17:56:20 +0000451 __x->__parent_unsafe()->__right_ :
Howard Hinnant324bb032010-08-22 00:02:43 +0000452 __x->__parent_->__left_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000453 // continue;
454 }
455 else // __w has a red child
456 {
457 if (__w->__right_ == nullptr || __w->__right_->__is_black_)
458 {
459 // __w left child is non-null and red
460 __w->__left_->__is_black_ = true;
461 __w->__is_black_ = false;
462 __tree_right_rotate(__w);
463 // __w is known not to be root, so root hasn't changed
464 // reset sibling, and it still can't be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000465 __w = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000466 }
467 // __w has a right red child, left child may be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000468 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
469 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000470 __w->__right_->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000471 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000472 break;
473 }
474 }
475 else
476 {
477 if (!__w->__is_black_)
478 {
479 __w->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000480 __w->__parent_unsafe()->__is_black_ = false;
481 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000482 // __x is still valid
483 // reset __root only if necessary
484 if (__root == __w->__right_)
485 __root = __w;
486 // reset sibling, and it still can't be null
487 __w = __w->__right_->__left_;
488 }
489 // __w->__is_black_ is now true, __w may have null children
490 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
491 (__w->__right_ == nullptr || __w->__right_->__is_black_))
492 {
493 __w->__is_black_ = false;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000494 __x = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000495 // __x can no longer be null
496 if (!__x->__is_black_ || __x == __root)
497 {
498 __x->__is_black_ = true;
499 break;
500 }
501 // reset sibling, and it still can't be null
502 __w = __tree_is_left_child(__x) ?
Eric Fiselier7310ec82016-07-19 17:56:20 +0000503 __x->__parent_unsafe()->__right_ :
Howard Hinnant324bb032010-08-22 00:02:43 +0000504 __x->__parent_->__left_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000505 // continue;
506 }
507 else // __w has a red child
508 {
509 if (__w->__left_ == nullptr || __w->__left_->__is_black_)
510 {
511 // __w right child is non-null and red
512 __w->__right_->__is_black_ = true;
513 __w->__is_black_ = false;
514 __tree_left_rotate(__w);
515 // __w is known not to be root, so root hasn't changed
516 // reset sibling, and it still can't be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000517 __w = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000518 }
519 // __w has a left red child, right child may be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000520 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
521 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000522 __w->__left_->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000523 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000524 break;
525 }
526 }
527 }
528 }
529 }
530}
531
Eric Fiselier55263482016-02-20 05:28:30 +0000532// node traits
533
Eric Fiselierdb215062016-03-31 02:15:15 +0000534
535#ifndef _LIBCPP_CXX03_LANG
536template <class _Tp>
537struct __is_tree_value_type_imp : false_type {};
538
539template <class _Key, class _Value>
540struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {};
541
542template <class ..._Args>
543struct __is_tree_value_type : false_type {};
544
545template <class _One>
546struct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {};
547#endif
548
Eric Fiselier55263482016-02-20 05:28:30 +0000549template <class _Tp>
550struct __tree_key_value_types {
551 typedef _Tp key_type;
552 typedef _Tp __node_value_type;
553 typedef _Tp __container_value_type;
554 static const bool __is_map = false;
Eric Fiselierdb215062016-03-31 02:15:15 +0000555
556 _LIBCPP_INLINE_VISIBILITY
557 static key_type const& __get_key(_Tp const& __v) {
558 return __v;
559 }
560 _LIBCPP_INLINE_VISIBILITY
561 static __container_value_type const& __get_value(__node_value_type const& __v) {
562 return __v;
563 }
564 _LIBCPP_INLINE_VISIBILITY
565 static __container_value_type* __get_ptr(__node_value_type& __n) {
566 return _VSTD::addressof(__n);
567 }
568
569#ifndef _LIBCPP_CXX03_LANG
570 _LIBCPP_INLINE_VISIBILITY
571 static __container_value_type&& __move(__node_value_type& __v) {
572 return _VSTD::move(__v);
573 }
574#endif
Eric Fiselier55263482016-02-20 05:28:30 +0000575};
576
577template <class _Key, class _Tp>
578struct __tree_key_value_types<__value_type<_Key, _Tp> > {
579 typedef _Key key_type;
580 typedef _Tp mapped_type;
581 typedef __value_type<_Key, _Tp> __node_value_type;
582 typedef pair<const _Key, _Tp> __container_value_type;
583 typedef pair<_Key, _Tp> __nc_value_type;
584 typedef __container_value_type __map_value_type;
585 static const bool __is_map = true;
Eric Fiselierdb215062016-03-31 02:15:15 +0000586
587 _LIBCPP_INLINE_VISIBILITY
588 static key_type const&
589 __get_key(__node_value_type const& __t) {
590 return __t.__cc.first;
591 }
592
593 template <class _Up>
594 _LIBCPP_INLINE_VISIBILITY
595 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
596 key_type const&>::type
597 __get_key(_Up& __t) {
598 return __t.first;
599 }
600
601 _LIBCPP_INLINE_VISIBILITY
602 static __container_value_type const&
603 __get_value(__node_value_type const& __t) {
604 return __t.__cc;
605 }
606
607 template <class _Up>
608 _LIBCPP_INLINE_VISIBILITY
609 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
610 __container_value_type const&>::type
611 __get_value(_Up& __t) {
612 return __t;
613 }
614
615 _LIBCPP_INLINE_VISIBILITY
616 static __container_value_type* __get_ptr(__node_value_type& __n) {
617 return _VSTD::addressof(__n.__cc);
618 }
619
620#ifndef _LIBCPP_CXX03_LANG
621 _LIBCPP_INLINE_VISIBILITY
622 static __nc_value_type&& __move(__node_value_type& __v) {
623 return _VSTD::move(__v.__nc);
624 }
625#endif
Eric Fiselier55263482016-02-20 05:28:30 +0000626};
627
628template <class _VoidPtr>
629struct __tree_node_base_types {
630 typedef _VoidPtr __void_pointer;
631
632 typedef __tree_node_base<__void_pointer> __node_base_type;
633 typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
634 __node_base_pointer;
635
636 typedef __tree_end_node<__node_base_pointer> __end_node_type;
637 typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
638 __end_node_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000639#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
640 typedef __end_node_pointer __parent_pointer;
641#else
642 typedef typename conditional<
643 is_pointer<__end_node_pointer>::value,
644 __end_node_pointer,
645 __node_base_pointer>::type __parent_pointer;
646#endif
647
Eric Fiselier55263482016-02-20 05:28:30 +0000648private:
649 static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
650 "_VoidPtr does not point to unqualified void type");
651};
652
653template <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>,
654 bool = _KVTypes::__is_map>
655struct __tree_map_pointer_types {};
656
657template <class _Tp, class _AllocPtr, class _KVTypes>
658struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
659 typedef typename _KVTypes::__map_value_type _Mv;
660 typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
661 __map_value_type_pointer;
662 typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
663 __const_map_value_type_pointer;
664};
665
666template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
667struct __tree_node_types;
668
669template <class _NodePtr, class _Tp, class _VoidPtr>
670struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> >
671 : public __tree_node_base_types<_VoidPtr>,
672 __tree_key_value_types<_Tp>,
673 __tree_map_pointer_types<_Tp, _VoidPtr>
674{
675 typedef __tree_node_base_types<_VoidPtr> __base;
676 typedef __tree_key_value_types<_Tp> __key_base;
677 typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base;
678public:
679
680 typedef typename pointer_traits<_NodePtr>::element_type __node_type;
681 typedef _NodePtr __node_pointer;
682
683 typedef _Tp __node_value_type;
684 typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
685 __node_value_type_pointer;
686 typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
687 __const_node_value_type_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000688#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
689 typedef typename __base::__end_node_pointer __iter_pointer;
690#else
691 typedef typename conditional<
692 is_pointer<__node_pointer>::value,
693 typename __base::__end_node_pointer,
694 __node_pointer>::type __iter_pointer;
695#endif
Eric Fiselier55263482016-02-20 05:28:30 +0000696private:
697 static_assert(!is_const<__node_type>::value,
698 "_NodePtr should never be a pointer to const");
699 static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
700 _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
701};
702
703template <class _ValueTp, class _VoidPtr>
704struct __make_tree_node_types {
705 typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
706 _NodePtr;
707 typedef __tree_node_types<_NodePtr> type;
708};
709
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000710// node
711
712template <class _Pointer>
713class __tree_end_node
714{
715public:
716 typedef _Pointer pointer;
717 pointer __left_;
718
Howard Hinnant333f50d2010-09-21 20:16:37 +0000719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8b537682011-06-04 17:10:24 +0000720 __tree_end_node() _NOEXCEPT : __left_() {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000721};
722
723template <class _VoidPtr>
724class __tree_node_base
Eric Fiselier55263482016-02-20 05:28:30 +0000725 : public __tree_node_base_types<_VoidPtr>::__end_node_type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000726{
Eric Fiselier55263482016-02-20 05:28:30 +0000727 typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
728
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000729public:
Eric Fiselier55263482016-02-20 05:28:30 +0000730 typedef typename _NodeBaseTypes::__node_base_pointer pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000731 typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000732
Eric Fiselier7310ec82016-07-19 17:56:20 +0000733 pointer __right_;
734 __parent_pointer __parent_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000735 bool __is_black_;
736
Eric Fiselier7310ec82016-07-19 17:56:20 +0000737 _LIBCPP_INLINE_VISIBILITY
738 pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
739
740 _LIBCPP_INLINE_VISIBILITY
741 void __set_parent(pointer __p) {
742 __parent_ = static_cast<__parent_pointer>(__p);
743 }
744
Eric Fiselierdb215062016-03-31 02:15:15 +0000745private:
746 ~__tree_node_base() _LIBCPP_EQUAL_DELETE;
747 __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
748 __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000749};
750
751template <class _Tp, class _VoidPtr>
752class __tree_node
753 : public __tree_node_base<_VoidPtr>
754{
755public:
Eric Fiselier55263482016-02-20 05:28:30 +0000756 typedef _Tp __node_value_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000757
Eric Fiselier55263482016-02-20 05:28:30 +0000758 __node_value_type __value_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000759
Eric Fiselierdb215062016-03-31 02:15:15 +0000760private:
761 ~__tree_node() _LIBCPP_EQUAL_DELETE;
762 __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE;
763 __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000764};
765
Eric Fiselierdb215062016-03-31 02:15:15 +0000766
767template <class _Allocator>
768class __tree_node_destructor
769{
770 typedef _Allocator allocator_type;
771 typedef allocator_traits<allocator_type> __alloc_traits;
772
773public:
774 typedef typename __alloc_traits::pointer pointer;
775private:
776 typedef __tree_node_types<pointer> _NodeTypes;
777 allocator_type& __na_;
778
779 __tree_node_destructor& operator=(const __tree_node_destructor&);
780
781public:
782 bool __value_constructed;
783
784 _LIBCPP_INLINE_VISIBILITY
785 explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
786 : __na_(__na),
787 __value_constructed(__val)
788 {}
789
790 _LIBCPP_INLINE_VISIBILITY
791 void operator()(pointer __p) _NOEXCEPT
792 {
793 if (__value_constructed)
794 __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
795 if (__p)
796 __alloc_traits::deallocate(__na_, __p, 1);
797 }
798
799 template <class> friend class __map_node_destructor;
800};
801
802
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000803template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000804class _LIBCPP_TEMPLATE_VIS __tree_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000805{
Eric Fiselier55263482016-02-20 05:28:30 +0000806 typedef __tree_node_types<_NodePtr> _NodeTypes;
807 typedef _NodePtr __node_pointer;
808 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000809 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
810 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +0000811 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000812
Eric Fiselier7310ec82016-07-19 17:56:20 +0000813 __iter_pointer __ptr_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000814
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000815public:
Eric Fiselier55263482016-02-20 05:28:30 +0000816 typedef bidirectional_iterator_tag iterator_category;
817 typedef _Tp value_type;
818 typedef _DiffType difference_type;
819 typedef value_type& reference;
820 typedef typename _NodeTypes::__node_value_type_pointer pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000821
Marshall Clow051c8482013-08-08 21:52:50 +0000822 _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
823#if _LIBCPP_STD_VER > 11
824 : __ptr_(nullptr)
825#endif
826 {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000827
Eric Fiselier7310ec82016-07-19 17:56:20 +0000828 _LIBCPP_INLINE_VISIBILITY reference operator*() const
829 {return __get_np()->__value_;}
Howard Hinnant70342b92013-06-19 21:29:40 +0000830 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier7310ec82016-07-19 17:56:20 +0000831 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000832
Howard Hinnant333f50d2010-09-21 20:16:37 +0000833 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000834 __tree_iterator& operator++() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000835 __ptr_ = static_cast<__iter_pointer>(
836 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000837 return *this;
838 }
Howard Hinnant333f50d2010-09-21 20:16:37 +0000839 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000840 __tree_iterator operator++(int)
841 {__tree_iterator __t(*this); ++(*this); return __t;}
842
Howard Hinnant333f50d2010-09-21 20:16:37 +0000843 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000844 __tree_iterator& operator--() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000845 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
846 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000847 return *this;
848 }
Howard Hinnant333f50d2010-09-21 20:16:37 +0000849 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000850 __tree_iterator operator--(int)
851 {__tree_iterator __t(*this); --(*this); return __t;}
852
Howard Hinnant333f50d2010-09-21 20:16:37 +0000853 friend _LIBCPP_INLINE_VISIBILITY
854 bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000855 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000856 friend _LIBCPP_INLINE_VISIBILITY
857 bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000858 {return !(__x == __y);}
859
860private:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000861 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +0000862 explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Eric Fiselier7310ec82016-07-19 17:56:20 +0000863 _LIBCPP_INLINE_VISIBILITY
864 explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
865 _LIBCPP_INLINE_VISIBILITY
866 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000867 template <class, class, class> friend class __tree;
Eric Fiselierc3589a82017-01-04 23:56:00 +0000868 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
869 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
870 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
871 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
872 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
873 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000874};
875
Eric Fiselier55263482016-02-20 05:28:30 +0000876template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000877class _LIBCPP_TEMPLATE_VIS __tree_const_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000878{
Eric Fiselier55263482016-02-20 05:28:30 +0000879 typedef __tree_node_types<_NodePtr> _NodeTypes;
880 typedef typename _NodeTypes::__node_pointer __node_pointer;
881 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000882 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
883 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +0000884 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000885
Eric Fiselier7310ec82016-07-19 17:56:20 +0000886 __iter_pointer __ptr_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000887
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000888public:
Eric Fiselier55263482016-02-20 05:28:30 +0000889 typedef bidirectional_iterator_tag iterator_category;
890 typedef _Tp value_type;
891 typedef _DiffType difference_type;
892 typedef const value_type& reference;
893 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000894
Marshall Clow051c8482013-08-08 21:52:50 +0000895 _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
896#if _LIBCPP_STD_VER > 11
897 : __ptr_(nullptr)
898#endif
899 {}
900
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000901private:
Eric Fiselier55263482016-02-20 05:28:30 +0000902 typedef __tree_iterator<value_type, __node_pointer, difference_type>
903 __non_const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000904public:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000905 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +0000906 __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
907 : __ptr_(__p.__ptr_) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000908
Eric Fiselier7310ec82016-07-19 17:56:20 +0000909 _LIBCPP_INLINE_VISIBILITY reference operator*() const
910 {return __get_np()->__value_;}
Howard Hinnant70342b92013-06-19 21:29:40 +0000911 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier7310ec82016-07-19 17:56:20 +0000912 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000913
Howard Hinnant333f50d2010-09-21 20:16:37 +0000914 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000915 __tree_const_iterator& operator++() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000916 __ptr_ = static_cast<__iter_pointer>(
917 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000918 return *this;
919 }
920
Howard Hinnant333f50d2010-09-21 20:16:37 +0000921 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000922 __tree_const_iterator operator++(int)
923 {__tree_const_iterator __t(*this); ++(*this); return __t;}
924
Howard Hinnant333f50d2010-09-21 20:16:37 +0000925 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000926 __tree_const_iterator& operator--() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000927 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
928 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000929 return *this;
930 }
931
Howard Hinnant333f50d2010-09-21 20:16:37 +0000932 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000933 __tree_const_iterator operator--(int)
934 {__tree_const_iterator __t(*this); --(*this); return __t;}
935
Howard Hinnant333f50d2010-09-21 20:16:37 +0000936 friend _LIBCPP_INLINE_VISIBILITY
937 bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000938 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000939 friend _LIBCPP_INLINE_VISIBILITY
940 bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000941 {return !(__x == __y);}
942
943private:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000944 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +0000945 explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
946 : __ptr_(__p) {}
Eric Fiselier7310ec82016-07-19 17:56:20 +0000947 _LIBCPP_INLINE_VISIBILITY
948 explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
949 : __ptr_(__p) {}
950 _LIBCPP_INLINE_VISIBILITY
951 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
952
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000953 template <class, class, class> friend class __tree;
Eric Fiselierc3589a82017-01-04 23:56:00 +0000954 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
955 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
956 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
957 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
958 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000959
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000960};
961
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000962#ifndef _LIBCPP_CXX03_LANG
963template <class _Tp, class _Compare, class _Allocator>
964struct __diagnose_tree_helper {
965 static constexpr bool __trigger_diagnostics()
Eric Fiseliereaf29202017-01-13 22:42:53 +0000966 _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000967 "the specified comparator type does not provide a const call operator")
968 { return true; }
969};
970
971template <class _Key, class _Value, class _KeyComp, class _Alloc>
972struct __diagnose_tree_helper<
973 __value_type<_Key, _Value>,
974 __map_value_compare<_Key, __value_type<_Key, _Value>, _KeyComp>,
975 _Alloc
Eric Fiseliereaf29202017-01-13 22:42:53 +0000976> : __diagnose_tree_helper<_Key, _KeyComp, _Alloc>
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000977{
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000978};
Eric Fiseliereaf29202017-01-13 22:42:53 +0000979#endif // !_LIBCPP_CXX03_LANG
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000980
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000981template <class _Tp, class _Compare, class _Allocator>
982class __tree
983{
984public:
985 typedef _Tp value_type;
986 typedef _Compare value_compare;
987 typedef _Allocator allocator_type;
Eric Fiselier55263482016-02-20 05:28:30 +0000988
989private:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000990 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiselier55263482016-02-20 05:28:30 +0000991 typedef typename __make_tree_node_types<value_type,
992 typename __alloc_traits::void_pointer>::type
993 _NodeTypes;
Eric Fiselierdb215062016-03-31 02:15:15 +0000994 typedef typename _NodeTypes::key_type key_type;
Eric Fiselier55263482016-02-20 05:28:30 +0000995public:
996 typedef typename _NodeTypes::__node_value_type __node_value_type;
997 typedef typename _NodeTypes::__container_value_type __container_value_type;
998
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000999 typedef typename __alloc_traits::pointer pointer;
1000 typedef typename __alloc_traits::const_pointer const_pointer;
1001 typedef typename __alloc_traits::size_type size_type;
1002 typedef typename __alloc_traits::difference_type difference_type;
1003
Eric Fiselier55263482016-02-20 05:28:30 +00001004public:
1005 typedef typename _NodeTypes::__void_pointer __void_pointer;
Howard Hinnant70342b92013-06-19 21:29:40 +00001006
Eric Fiselier55263482016-02-20 05:28:30 +00001007 typedef typename _NodeTypes::__node_type __node;
1008 typedef typename _NodeTypes::__node_pointer __node_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +00001009
1010 typedef typename _NodeTypes::__node_base_type __node_base;
1011 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +00001012
1013 typedef typename _NodeTypes::__end_node_type __end_node_t;
1014 typedef typename _NodeTypes::__end_node_pointer __end_node_ptr;
Eric Fiselier55263482016-02-20 05:28:30 +00001015
Eric Fiselier7310ec82016-07-19 17:56:20 +00001016 typedef typename _NodeTypes::__parent_pointer __parent_pointer;
1017 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
1018
Marshall Clow66302c62015-04-07 05:21:38 +00001019 typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
Eric Fiselier55263482016-02-20 05:28:30 +00001020 typedef allocator_traits<__node_allocator> __node_traits;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001021
Eric Fiselier55263482016-02-20 05:28:30 +00001022private:
1023 // check for sane allocator pointer rebinding semantics. Rebinding the
1024 // allocator for a new pointer type should be exactly the same as rebinding
1025 // the pointer using 'pointer_traits'.
1026 static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1027 "Allocator does not rebind pointers in a sane manner.");
1028 typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1029 __node_base_allocator;
1030 typedef allocator_traits<__node_base_allocator> __node_base_traits;
1031 static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1032 "Allocator does not rebind pointers in a sane manner.");
1033
1034private:
Eric Fiselier7310ec82016-07-19 17:56:20 +00001035 __iter_pointer __begin_node_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001036 __compressed_pair<__end_node_t, __node_allocator> __pair1_;
1037 __compressed_pair<size_type, value_compare> __pair3_;
1038
1039public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001040 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001041 __iter_pointer __end_node() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001042 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001043 return static_cast<__iter_pointer>(
Eric Fiselier227b47c2016-02-20 07:12:17 +00001044 pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
1045 );
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001046 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001047 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001048 __iter_pointer __end_node() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001049 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001050 return static_cast<__iter_pointer>(
Eric Fiselier227b47c2016-02-20 07:12:17 +00001051 pointer_traits<__end_node_ptr>::pointer_to(
1052 const_cast<__end_node_t&>(__pair1_.first())
1053 )
1054 );
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001055 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001057 __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001058private:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001060 const __node_allocator& __node_alloc() const _NOEXCEPT
1061 {return __pair1_.second();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001062 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001063 __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001064 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001065 const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001066public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001067 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001068 allocator_type __alloc() const _NOEXCEPT
1069 {return allocator_type(__node_alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001070private:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001071 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001072 size_type& size() _NOEXCEPT {return __pair3_.first();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001073public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001074 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001075 const size_type& size() const _NOEXCEPT {return __pair3_.first();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001077 value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001078 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001079 const value_compare& value_comp() const _NOEXCEPT
1080 {return __pair3_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001081public:
Eric Fiselier227b47c2016-02-20 07:12:17 +00001082
Howard Hinnant333f50d2010-09-21 20:16:37 +00001083 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier227b47c2016-02-20 07:12:17 +00001084 __node_pointer __root() const _NOEXCEPT
1085 {return static_cast<__node_pointer>(__end_node()->__left_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001086
Eric Fiselier7310ec82016-07-19 17:56:20 +00001087 __node_base_pointer* __root_ptr() const _NOEXCEPT {
1088 return _VSTD::addressof(__end_node()->__left_);
1089 }
1090
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001091 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
Howard Hinnant70342b92013-06-19 21:29:40 +00001092 typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001093
Howard Hinnant7686add2011-06-04 14:31:57 +00001094 explicit __tree(const value_compare& __comp)
1095 _NOEXCEPT_(
1096 is_nothrow_default_constructible<__node_allocator>::value &&
1097 is_nothrow_copy_constructible<value_compare>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001098 explicit __tree(const allocator_type& __a);
1099 __tree(const value_compare& __comp, const allocator_type& __a);
1100 __tree(const __tree& __t);
1101 __tree& operator=(const __tree& __t);
1102 template <class _InputIterator>
1103 void __assign_unique(_InputIterator __first, _InputIterator __last);
1104 template <class _InputIterator>
1105 void __assign_multi(_InputIterator __first, _InputIterator __last);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001106#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant7686add2011-06-04 14:31:57 +00001107 __tree(__tree&& __t)
1108 _NOEXCEPT_(
1109 is_nothrow_move_constructible<__node_allocator>::value &&
1110 is_nothrow_move_constructible<value_compare>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001111 __tree(__tree&& __t, const allocator_type& __a);
Howard Hinnant7686add2011-06-04 14:31:57 +00001112 __tree& operator=(__tree&& __t)
1113 _NOEXCEPT_(
1114 __node_traits::propagate_on_container_move_assignment::value &&
1115 is_nothrow_move_assignable<value_compare>::value &&
1116 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001117#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001118
1119 ~__tree();
1120
Howard Hinnant333f50d2010-09-21 20:16:37 +00001121 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001122 iterator begin() _NOEXCEPT {return iterator(__begin_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001123 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001124 const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001125 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001126 iterator end() _NOEXCEPT {return iterator(__end_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001127 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001128 const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001129
Howard Hinnant333f50d2010-09-21 20:16:37 +00001130 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001131 size_type max_size() const _NOEXCEPT
Eric Fiselieref3060e2016-11-23 01:18:56 +00001132 {return std::min<size_type>(
1133 __node_traits::max_size(__node_alloc()),
1134 numeric_limits<difference_type >::max());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001135
Howard Hinnant7686add2011-06-04 14:31:57 +00001136 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001137
Howard Hinnant7686add2011-06-04 14:31:57 +00001138 void swap(__tree& __t)
Dimitry Andric1421cf02016-08-27 19:32:03 +00001139#if _LIBCPP_STD_VER <= 11
Howard Hinnant7686add2011-06-04 14:31:57 +00001140 _NOEXCEPT_(
Marshall Clow7d914d12015-07-13 20:04:56 +00001141 __is_nothrow_swappable<value_compare>::value
Marshall Clow7d914d12015-07-13 20:04:56 +00001142 && (!__node_traits::propagate_on_container_swap::value ||
1143 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow7d914d12015-07-13 20:04:56 +00001144 );
Dimitry Andric1421cf02016-08-27 19:32:03 +00001145#else
1146 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1147#endif
Eric Fiselierdb215062016-03-31 02:15:15 +00001148
1149#ifndef _LIBCPP_CXX03_LANG
1150 template <class _Key, class ..._Args>
1151 pair<iterator, bool>
1152 __emplace_unique_key_args(_Key const&, _Args&&... __args);
1153 template <class _Key, class ..._Args>
1154 iterator
1155 __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001156
1157 template <class... _Args>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001158 pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
Eric Fiselierdb215062016-03-31 02:15:15 +00001159
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001160 template <class... _Args>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001161 iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001162
Eric Fiselierdb215062016-03-31 02:15:15 +00001163 template <class... _Args>
1164 iterator __emplace_multi(_Args&&... __args);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001165
Eric Fiselierdb215062016-03-31 02:15:15 +00001166 template <class... _Args>
1167 iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001168
1169 template <class _Pp>
1170 _LIBCPP_INLINE_VISIBILITY
1171 pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1172 return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1173 __can_extract_key<_Pp, key_type>());
1174 }
1175
Eric Fiselierdc414cd2016-04-16 00:23:12 +00001176 template <class _First, class _Second>
1177 _LIBCPP_INLINE_VISIBILITY
1178 typename enable_if<
1179 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1180 pair<iterator, bool>
1181 >::type __emplace_unique(_First&& __f, _Second&& __s) {
1182 return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1183 _VSTD::forward<_Second>(__s));
1184 }
1185
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001186 template <class... _Args>
1187 _LIBCPP_INLINE_VISIBILITY
1188 pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1189 return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1190 }
1191
1192 template <class _Pp>
1193 _LIBCPP_INLINE_VISIBILITY
1194 pair<iterator, bool>
1195 __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1196 return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1197 }
1198
1199 template <class _Pp>
1200 _LIBCPP_INLINE_VISIBILITY
1201 pair<iterator, bool>
1202 __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1203 return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1204 }
1205
1206 template <class _Pp>
1207 _LIBCPP_INLINE_VISIBILITY
1208 pair<iterator, bool>
1209 __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1210 return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1211 }
1212
1213 template <class _Pp>
1214 _LIBCPP_INLINE_VISIBILITY
1215 iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1216 return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1217 __can_extract_key<_Pp, key_type>());
1218 }
1219
Eric Fiselierdc414cd2016-04-16 00:23:12 +00001220 template <class _First, class _Second>
1221 _LIBCPP_INLINE_VISIBILITY
1222 typename enable_if<
1223 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1224 iterator
1225 >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
1226 return __emplace_hint_unique_key_args(__p, __f,
1227 _VSTD::forward<_First>(__f),
1228 _VSTD::forward<_Second>(__s));
1229 }
1230
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001231 template <class... _Args>
1232 _LIBCPP_INLINE_VISIBILITY
1233 iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1234 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1235 }
1236
1237 template <class _Pp>
1238 _LIBCPP_INLINE_VISIBILITY
1239 iterator
1240 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1241 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
1242 }
1243
1244 template <class _Pp>
1245 _LIBCPP_INLINE_VISIBILITY
1246 iterator
1247 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1248 return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x));
1249 }
1250
1251 template <class _Pp>
1252 _LIBCPP_INLINE_VISIBILITY
1253 iterator
1254 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1255 return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x));
1256 }
1257
Eric Fiselierdb215062016-03-31 02:15:15 +00001258#else
1259 template <class _Key, class _Args>
1260 _LIBCPP_INLINE_VISIBILITY
1261 pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args);
1262 template <class _Key, class _Args>
1263 _LIBCPP_INLINE_VISIBILITY
1264 iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&);
Marshall Clow3426a862016-01-05 19:32:41 +00001265#endif
1266
Eric Fiselierdb215062016-03-31 02:15:15 +00001267 _LIBCPP_INLINE_VISIBILITY
1268 pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
1269 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
1270 }
1271
1272 _LIBCPP_INLINE_VISIBILITY
1273 iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
1274 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v);
1275 }
1276
1277#ifdef _LIBCPP_CXX03_LANG
1278 _LIBCPP_INLINE_VISIBILITY
1279 iterator __insert_multi(const __container_value_type& __v);
1280 _LIBCPP_INLINE_VISIBILITY
1281 iterator __insert_multi(const_iterator __p, const __container_value_type& __v);
1282#else
1283 _LIBCPP_INLINE_VISIBILITY
1284 pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
1285 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
1286 }
1287
1288 _LIBCPP_INLINE_VISIBILITY
1289 iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
1290 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__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 pair<iterator, bool> __insert_unique(_Vp&& __v) {
1300 return __emplace_unique(_VSTD::forward<_Vp>(__v));
1301 }
1302
1303 template <class _Vp, class = typename enable_if<
1304 !is_same<typename __unconstref<_Vp>::type,
1305 __container_value_type
1306 >::value
1307 >::type>
1308 _LIBCPP_INLINE_VISIBILITY
1309 iterator __insert_unique(const_iterator __p, _Vp&& __v) {
1310 return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
1311 }
1312
1313 _LIBCPP_INLINE_VISIBILITY
1314 iterator __insert_multi(__container_value_type&& __v) {
1315 return __emplace_multi(_VSTD::move(__v));
1316 }
1317
1318 _LIBCPP_INLINE_VISIBILITY
1319 iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
1320 return __emplace_hint_multi(__p, _VSTD::move(__v));
1321 }
1322
1323 template <class _Vp>
1324 _LIBCPP_INLINE_VISIBILITY
1325 iterator __insert_multi(_Vp&& __v) {
1326 return __emplace_multi(_VSTD::forward<_Vp>(__v));
1327 }
1328
1329 template <class _Vp>
1330 _LIBCPP_INLINE_VISIBILITY
1331 iterator __insert_multi(const_iterator __p, _Vp&& __v) {
1332 return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
1333 }
1334
1335#endif // !_LIBCPP_CXX03_LANG
1336
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001337 pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
1338 iterator __node_insert_unique(const_iterator __p,
1339 __node_pointer __nd);
1340
1341 iterator __node_insert_multi(__node_pointer __nd);
1342 iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1343
1344 iterator erase(const_iterator __p);
1345 iterator erase(const_iterator __f, const_iterator __l);
1346 template <class _Key>
1347 size_type __erase_unique(const _Key& __k);
1348 template <class _Key>
1349 size_type __erase_multi(const _Key& __k);
1350
Eric Fiselier7310ec82016-07-19 17:56:20 +00001351 void __insert_node_at(__parent_pointer __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001352 __node_base_pointer& __child,
1353 __node_base_pointer __new_node);
1354
1355 template <class _Key>
1356 iterator find(const _Key& __v);
1357 template <class _Key>
1358 const_iterator find(const _Key& __v) const;
1359
1360 template <class _Key>
1361 size_type __count_unique(const _Key& __k) const;
1362 template <class _Key>
1363 size_type __count_multi(const _Key& __k) const;
1364
1365 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001367 iterator lower_bound(const _Key& __v)
1368 {return __lower_bound(__v, __root(), __end_node());}
1369 template <class _Key>
1370 iterator __lower_bound(const _Key& __v,
1371 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001372 __iter_pointer __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001373 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001375 const_iterator lower_bound(const _Key& __v) const
1376 {return __lower_bound(__v, __root(), __end_node());}
1377 template <class _Key>
1378 const_iterator __lower_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00001379 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001380 __iter_pointer __result) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001381 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001383 iterator upper_bound(const _Key& __v)
1384 {return __upper_bound(__v, __root(), __end_node());}
1385 template <class _Key>
1386 iterator __upper_bound(const _Key& __v,
1387 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001388 __iter_pointer __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001389 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001391 const_iterator upper_bound(const _Key& __v) const
1392 {return __upper_bound(__v, __root(), __end_node());}
1393 template <class _Key>
1394 const_iterator __upper_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00001395 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001396 __iter_pointer __result) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001397 template <class _Key>
1398 pair<iterator, iterator>
1399 __equal_range_unique(const _Key& __k);
1400 template <class _Key>
1401 pair<const_iterator, const_iterator>
1402 __equal_range_unique(const _Key& __k) const;
1403
1404 template <class _Key>
1405 pair<iterator, iterator>
1406 __equal_range_multi(const _Key& __k);
1407 template <class _Key>
1408 pair<const_iterator, const_iterator>
1409 __equal_range_multi(const _Key& __k) const;
1410
Howard Hinnant99968442011-11-29 18:15:50 +00001411 typedef __tree_node_destructor<__node_allocator> _Dp;
1412 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001413
Howard Hinnant8b537682011-06-04 17:10:24 +00001414 __node_holder remove(const_iterator __p) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001415private:
Eric Fiselier7310ec82016-07-19 17:56:20 +00001416 __node_base_pointer&
1417 __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1418 __node_base_pointer&
1419 __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1420 __node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001421 __find_leaf(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001422 __parent_pointer& __parent, const key_type& __v);
Eric Fiselier856712b2017-01-05 06:06:18 +00001423 // FIXME: Make this function const qualified. Unfortunetly doing so
1424 // breaks existing code which uses non-const callable comparators.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001425 template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001426 __node_base_pointer&
1427 __find_equal(__parent_pointer& __parent, const _Key& __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001428 template <class _Key>
Eric Fiselier856712b2017-01-05 06:06:18 +00001429 _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1430 __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1431 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1432 }
1433 template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001434 __node_base_pointer&
1435 __find_equal(const_iterator __hint, __parent_pointer& __parent,
1436 __node_base_pointer& __dummy,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001437 const _Key& __v);
1438
Eric Fiselierdb215062016-03-31 02:15:15 +00001439#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001440 template <class ..._Args>
Eric Fiselierdb215062016-03-31 02:15:15 +00001441 __node_holder __construct_node(_Args&& ...__args);
1442#else
1443 __node_holder __construct_node(const __container_value_type& __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001444#endif
1445
Howard Hinnant7686add2011-06-04 14:31:57 +00001446 void destroy(__node_pointer __nd) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001447
Howard Hinnant333f50d2010-09-21 20:16:37 +00001448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001449 void __copy_assign_alloc(const __tree& __t)
1450 {__copy_assign_alloc(__t, integral_constant<bool,
1451 __node_traits::propagate_on_container_copy_assignment::value>());}
1452
Howard Hinnant333f50d2010-09-21 20:16:37 +00001453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001454 void __copy_assign_alloc(const __tree& __t, true_type)
Marshall Clow546498c2016-08-17 23:24:02 +00001455 {
1456 if (__node_alloc() != __t.__node_alloc())
1457 clear();
1458 __node_alloc() = __t.__node_alloc();
1459 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001460 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001461 void __copy_assign_alloc(const __tree&, false_type) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001462
1463 void __move_assign(__tree& __t, false_type);
Howard Hinnant7686add2011-06-04 14:31:57 +00001464 void __move_assign(__tree& __t, true_type)
1465 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1466 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001467
Howard Hinnant333f50d2010-09-21 20:16:37 +00001468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001469 void __move_assign_alloc(__tree& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001470 _NOEXCEPT_(
1471 !__node_traits::propagate_on_container_move_assignment::value ||
1472 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001473 {__move_assign_alloc(__t, integral_constant<bool,
1474 __node_traits::propagate_on_container_move_assignment::value>());}
1475
Howard Hinnant333f50d2010-09-21 20:16:37 +00001476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001477 void __move_assign_alloc(__tree& __t, true_type)
Howard Hinnant7686add2011-06-04 14:31:57 +00001478 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001479 {__node_alloc() = _VSTD::move(__t.__node_alloc());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001480 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001481 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001482
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001483 __node_pointer __detach();
1484 static __node_pointer __detach(__node_pointer);
Howard Hinnant70342b92013-06-19 21:29:40 +00001485
Eric Fiselierc3589a82017-01-04 23:56:00 +00001486 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1487 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001488};
1489
1490template <class _Tp, class _Compare, class _Allocator>
1491__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
Howard Hinnant7686add2011-06-04 14:31:57 +00001492 _NOEXCEPT_(
1493 is_nothrow_default_constructible<__node_allocator>::value &&
1494 is_nothrow_copy_constructible<value_compare>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001495 : __pair3_(0, __comp)
1496{
1497 __begin_node() = __end_node();
1498}
1499
1500template <class _Tp, class _Compare, class _Allocator>
1501__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001502 : __begin_node_(__iter_pointer()),
Eric Fiselier02bb4bd2015-07-18 23:56:04 +00001503 __pair1_(__node_allocator(__a)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001504 __pair3_(0)
1505{
1506 __begin_node() = __end_node();
1507}
1508
1509template <class _Tp, class _Compare, class _Allocator>
1510__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1511 const allocator_type& __a)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001512 : __begin_node_(__iter_pointer()),
Eric Fiselier02bb4bd2015-07-18 23:56:04 +00001513 __pair1_(__node_allocator(__a)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001514 __pair3_(0, __comp)
1515{
1516 __begin_node() = __end_node();
1517}
1518
1519// Precondition: size() != 0
1520template <class _Tp, class _Compare, class _Allocator>
1521typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1522__tree<_Tp, _Compare, _Allocator>::__detach()
1523{
Eric Fiselier7310ec82016-07-19 17:56:20 +00001524 __node_pointer __cache = static_cast<__node_pointer>(__begin_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001525 __begin_node() = __end_node();
1526 __end_node()->__left_->__parent_ = nullptr;
1527 __end_node()->__left_ = nullptr;
1528 size() = 0;
1529 // __cache->__left_ == nullptr
1530 if (__cache->__right_ != nullptr)
1531 __cache = static_cast<__node_pointer>(__cache->__right_);
1532 // __cache->__left_ == nullptr
1533 // __cache->__right_ == nullptr
1534 return __cache;
1535}
1536
1537// Precondition: __cache != nullptr
1538// __cache->left_ == nullptr
1539// __cache->right_ == nullptr
1540// This is no longer a red-black tree
1541template <class _Tp, class _Compare, class _Allocator>
1542typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1543__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
1544{
1545 if (__cache->__parent_ == nullptr)
1546 return nullptr;
Howard Hinnant70342b92013-06-19 21:29:40 +00001547 if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001548 {
1549 __cache->__parent_->__left_ = nullptr;
1550 __cache = static_cast<__node_pointer>(__cache->__parent_);
1551 if (__cache->__right_ == nullptr)
1552 return __cache;
1553 return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
1554 }
1555 // __cache is right child
Eric Fiselier7310ec82016-07-19 17:56:20 +00001556 __cache->__parent_unsafe()->__right_ = nullptr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001557 __cache = static_cast<__node_pointer>(__cache->__parent_);
1558 if (__cache->__left_ == nullptr)
1559 return __cache;
1560 return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
1561}
1562
1563template <class _Tp, class _Compare, class _Allocator>
1564__tree<_Tp, _Compare, _Allocator>&
1565__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1566{
1567 if (this != &__t)
1568 {
1569 value_comp() = __t.value_comp();
1570 __copy_assign_alloc(__t);
1571 __assign_multi(__t.begin(), __t.end());
1572 }
1573 return *this;
1574}
1575
1576template <class _Tp, class _Compare, class _Allocator>
1577template <class _InputIterator>
1578void
1579__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
1580{
Eric Fiselierdb215062016-03-31 02:15:15 +00001581 typedef iterator_traits<_InputIterator> _ITraits;
1582 typedef typename _ITraits::value_type _ItValueType;
1583 static_assert((is_same<_ItValueType, __container_value_type>::value),
1584 "__assign_unique may only be called with the containers value type");
1585
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001586 if (size() != 0)
1587 {
1588 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001589#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001590 try
1591 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001592#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001593 for (; __cache != nullptr && __first != __last; ++__first)
1594 {
1595 __cache->__value_ = *__first;
1596 __node_pointer __next = __detach(__cache);
1597 __node_insert_unique(__cache);
1598 __cache = __next;
1599 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001600#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001601 }
1602 catch (...)
1603 {
1604 while (__cache->__parent_ != nullptr)
1605 __cache = static_cast<__node_pointer>(__cache->__parent_);
1606 destroy(__cache);
1607 throw;
1608 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001609#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001610 if (__cache != nullptr)
1611 {
1612 while (__cache->__parent_ != nullptr)
1613 __cache = static_cast<__node_pointer>(__cache->__parent_);
1614 destroy(__cache);
1615 }
1616 }
1617 for (; __first != __last; ++__first)
1618 __insert_unique(*__first);
1619}
1620
1621template <class _Tp, class _Compare, class _Allocator>
1622template <class _InputIterator>
1623void
1624__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1625{
Eric Fiselierdb215062016-03-31 02:15:15 +00001626 typedef iterator_traits<_InputIterator> _ITraits;
1627 typedef typename _ITraits::value_type _ItValueType;
1628 static_assert((is_same<_ItValueType, __container_value_type>::value ||
1629 is_same<_ItValueType, __node_value_type>::value),
1630 "__assign_multi may only be called with the containers value type"
1631 " or the nodes value type");
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001632 if (size() != 0)
1633 {
1634 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001635#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001636 try
1637 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001638#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001639 for (; __cache != nullptr && __first != __last; ++__first)
1640 {
1641 __cache->__value_ = *__first;
1642 __node_pointer __next = __detach(__cache);
1643 __node_insert_multi(__cache);
1644 __cache = __next;
1645 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001646#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001647 }
1648 catch (...)
1649 {
1650 while (__cache->__parent_ != nullptr)
1651 __cache = static_cast<__node_pointer>(__cache->__parent_);
1652 destroy(__cache);
1653 throw;
1654 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001655#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001656 if (__cache != nullptr)
1657 {
1658 while (__cache->__parent_ != nullptr)
1659 __cache = static_cast<__node_pointer>(__cache->__parent_);
1660 destroy(__cache);
1661 }
1662 }
1663 for (; __first != __last; ++__first)
Eric Fiselierdb215062016-03-31 02:15:15 +00001664 __insert_multi(_NodeTypes::__get_value(*__first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001665}
1666
1667template <class _Tp, class _Compare, class _Allocator>
1668__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001669 : __begin_node_(__iter_pointer()),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001670 __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
1671 __pair3_(0, __t.value_comp())
1672{
1673 __begin_node() = __end_node();
1674}
1675
Howard Hinnant73d21a42010-09-04 23:28:19 +00001676#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001677
1678template <class _Tp, class _Compare, class _Allocator>
1679__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001680 _NOEXCEPT_(
1681 is_nothrow_move_constructible<__node_allocator>::value &&
1682 is_nothrow_move_constructible<value_compare>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001683 : __begin_node_(_VSTD::move(__t.__begin_node_)),
1684 __pair1_(_VSTD::move(__t.__pair1_)),
1685 __pair3_(_VSTD::move(__t.__pair3_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001686{
1687 if (size() == 0)
1688 __begin_node() = __end_node();
1689 else
1690 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001691 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001692 __t.__begin_node() = __t.__end_node();
1693 __t.__end_node()->__left_ = nullptr;
1694 __t.size() = 0;
1695 }
1696}
1697
1698template <class _Tp, class _Compare, class _Allocator>
1699__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1700 : __pair1_(__node_allocator(__a)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00001701 __pair3_(0, _VSTD::move(__t.value_comp()))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001702{
1703 if (__a == __t.__alloc())
1704 {
1705 if (__t.size() == 0)
1706 __begin_node() = __end_node();
1707 else
1708 {
1709 __begin_node() = __t.__begin_node();
1710 __end_node()->__left_ = __t.__end_node()->__left_;
Eric Fiselier7310ec82016-07-19 17:56:20 +00001711 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001712 size() = __t.size();
1713 __t.__begin_node() = __t.__end_node();
1714 __t.__end_node()->__left_ = nullptr;
1715 __t.size() = 0;
1716 }
1717 }
1718 else
1719 {
1720 __begin_node() = __end_node();
1721 }
1722}
1723
1724template <class _Tp, class _Compare, class _Allocator>
1725void
1726__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
Howard Hinnant7686add2011-06-04 14:31:57 +00001727 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1728 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001729{
1730 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1731 __begin_node_ = __t.__begin_node_;
1732 __pair1_.first() = __t.__pair1_.first();
1733 __move_assign_alloc(__t);
Howard Hinnant0949eed2011-06-30 21:18:19 +00001734 __pair3_ = _VSTD::move(__t.__pair3_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001735 if (size() == 0)
1736 __begin_node() = __end_node();
1737 else
1738 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001739 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001740 __t.__begin_node() = __t.__end_node();
1741 __t.__end_node()->__left_ = nullptr;
1742 __t.size() = 0;
1743 }
1744}
1745
1746template <class _Tp, class _Compare, class _Allocator>
1747void
1748__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1749{
1750 if (__node_alloc() == __t.__node_alloc())
1751 __move_assign(__t, true_type());
1752 else
1753 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001754 value_comp() = _VSTD::move(__t.value_comp());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001755 const_iterator __e = end();
1756 if (size() != 0)
1757 {
1758 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001759#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001760 try
1761 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001762#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001763 while (__cache != nullptr && __t.size() != 0)
1764 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001765 __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001766 __node_pointer __next = __detach(__cache);
1767 __node_insert_multi(__cache);
1768 __cache = __next;
1769 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001770#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001771 }
1772 catch (...)
1773 {
1774 while (__cache->__parent_ != nullptr)
1775 __cache = static_cast<__node_pointer>(__cache->__parent_);
1776 destroy(__cache);
1777 throw;
1778 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001779#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001780 if (__cache != nullptr)
1781 {
1782 while (__cache->__parent_ != nullptr)
1783 __cache = static_cast<__node_pointer>(__cache->__parent_);
1784 destroy(__cache);
1785 }
1786 }
1787 while (__t.size() != 0)
Eric Fiselierdb215062016-03-31 02:15:15 +00001788 __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001789 }
1790}
1791
1792template <class _Tp, class _Compare, class _Allocator>
1793__tree<_Tp, _Compare, _Allocator>&
1794__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001795 _NOEXCEPT_(
1796 __node_traits::propagate_on_container_move_assignment::value &&
1797 is_nothrow_move_assignable<value_compare>::value &&
1798 is_nothrow_move_assignable<__node_allocator>::value)
1799
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001800{
1801 __move_assign(__t, integral_constant<bool,
1802 __node_traits::propagate_on_container_move_assignment::value>());
1803 return *this;
1804}
1805
Howard Hinnant73d21a42010-09-04 23:28:19 +00001806#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001807
1808template <class _Tp, class _Compare, class _Allocator>
1809__tree<_Tp, _Compare, _Allocator>::~__tree()
1810{
Marshall Clow1a933122016-06-30 22:05:45 +00001811 static_assert((is_copy_constructible<value_compare>::value),
1812 "Comparator must be copy-constructible.");
Eric Fiselierebaf7da2017-01-13 22:02:08 +00001813#ifndef _LIBCPP_CXX03_LANG
1814 static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>::
1815 __trigger_diagnostics()), "");
1816#endif
1817 destroy(__root());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001818}
1819
1820template <class _Tp, class _Compare, class _Allocator>
1821void
Howard Hinnant7686add2011-06-04 14:31:57 +00001822__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001823{
1824 if (__nd != nullptr)
1825 {
1826 destroy(static_cast<__node_pointer>(__nd->__left_));
1827 destroy(static_cast<__node_pointer>(__nd->__right_));
1828 __node_allocator& __na = __node_alloc();
Eric Fiselierdb215062016-03-31 02:15:15 +00001829 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001830 __node_traits::deallocate(__na, __nd, 1);
1831 }
1832}
1833
1834template <class _Tp, class _Compare, class _Allocator>
1835void
1836__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
Dimitry Andric1421cf02016-08-27 19:32:03 +00001837#if _LIBCPP_STD_VER <= 11
Marshall Clow7d914d12015-07-13 20:04:56 +00001838 _NOEXCEPT_(
1839 __is_nothrow_swappable<value_compare>::value
Marshall Clow7d914d12015-07-13 20:04:56 +00001840 && (!__node_traits::propagate_on_container_swap::value ||
1841 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow7d914d12015-07-13 20:04:56 +00001842 )
Dimitry Andric1421cf02016-08-27 19:32:03 +00001843#else
1844 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1845#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001846{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001847 using _VSTD::swap;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001848 swap(__begin_node_, __t.__begin_node_);
1849 swap(__pair1_.first(), __t.__pair1_.first());
Marshall Clow7d914d12015-07-13 20:04:56 +00001850 __swap_allocator(__node_alloc(), __t.__node_alloc());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001851 __pair3_.swap(__t.__pair3_);
1852 if (size() == 0)
1853 __begin_node() = __end_node();
1854 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00001855 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001856 if (__t.size() == 0)
1857 __t.__begin_node() = __t.__end_node();
1858 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00001859 __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001860}
1861
1862template <class _Tp, class _Compare, class _Allocator>
1863void
Howard Hinnant7686add2011-06-04 14:31:57 +00001864__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001865{
1866 destroy(__root());
1867 size() = 0;
1868 __begin_node() = __end_node();
1869 __end_node()->__left_ = nullptr;
1870}
1871
1872// Find lower_bound place to insert
1873// Set __parent to parent of null leaf
1874// Return reference to null leaf
1875template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001876typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1877__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001878 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001879{
1880 __node_pointer __nd = __root();
1881 if (__nd != nullptr)
1882 {
1883 while (true)
1884 {
1885 if (value_comp()(__nd->__value_, __v))
1886 {
1887 if (__nd->__right_ != nullptr)
1888 __nd = static_cast<__node_pointer>(__nd->__right_);
1889 else
1890 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001891 __parent = static_cast<__parent_pointer>(__nd);
1892 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001893 }
1894 }
1895 else
1896 {
1897 if (__nd->__left_ != nullptr)
1898 __nd = static_cast<__node_pointer>(__nd->__left_);
1899 else
1900 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001901 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001902 return __parent->__left_;
1903 }
1904 }
1905 }
1906 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00001907 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001908 return __parent->__left_;
1909}
1910
1911// Find upper_bound place to insert
1912// Set __parent to parent of null leaf
1913// Return reference to null leaf
1914template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001915typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1916__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001917 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001918{
1919 __node_pointer __nd = __root();
1920 if (__nd != nullptr)
1921 {
1922 while (true)
1923 {
1924 if (value_comp()(__v, __nd->__value_))
1925 {
1926 if (__nd->__left_ != nullptr)
1927 __nd = static_cast<__node_pointer>(__nd->__left_);
1928 else
1929 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001930 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001931 return __parent->__left_;
1932 }
1933 }
1934 else
1935 {
1936 if (__nd->__right_ != nullptr)
1937 __nd = static_cast<__node_pointer>(__nd->__right_);
1938 else
1939 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001940 __parent = static_cast<__parent_pointer>(__nd);
1941 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001942 }
1943 }
1944 }
1945 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00001946 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001947 return __parent->__left_;
1948}
1949
1950// Find leaf place to insert closest to __hint
1951// First check prior to __hint.
1952// Next check after __hint.
1953// Next do O(log N) search.
1954// Set __parent to parent of null leaf
1955// Return reference to null leaf
1956template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001957typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001958__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001959 __parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001960 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001961{
1962 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1963 {
1964 // __v <= *__hint
1965 const_iterator __prior = __hint;
1966 if (__prior == begin() || !value_comp()(__v, *--__prior))
1967 {
1968 // *prev(__hint) <= __v <= *__hint
1969 if (__hint.__ptr_->__left_ == nullptr)
1970 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001971 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001972 return __parent->__left_;
1973 }
1974 else
1975 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001976 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
1977 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001978 }
1979 }
1980 // __v < *prev(__hint)
1981 return __find_leaf_high(__parent, __v);
1982 }
1983 // else __v > *__hint
1984 return __find_leaf_low(__parent, __v);
1985}
1986
1987// Find place to insert if __v doesn't exist
1988// Set __parent to parent of null leaf
1989// Return reference to null leaf
1990// If __v exists, set parent to node of __v and return reference to node of __v
1991template <class _Tp, class _Compare, class _Allocator>
1992template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001993typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1994__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001995 const _Key& __v)
1996{
1997 __node_pointer __nd = __root();
Eric Fiselier7310ec82016-07-19 17:56:20 +00001998 __node_base_pointer* __nd_ptr = __root_ptr();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001999 if (__nd != nullptr)
2000 {
2001 while (true)
2002 {
2003 if (value_comp()(__v, __nd->__value_))
2004 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002005 if (__nd->__left_ != nullptr) {
2006 __nd_ptr = _VSTD::addressof(__nd->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002007 __nd = static_cast<__node_pointer>(__nd->__left_);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002008 } else {
2009 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002010 return __parent->__left_;
2011 }
2012 }
2013 else if (value_comp()(__nd->__value_, __v))
2014 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002015 if (__nd->__right_ != nullptr) {
2016 __nd_ptr = _VSTD::addressof(__nd->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002017 __nd = static_cast<__node_pointer>(__nd->__right_);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002018 } else {
2019 __parent = static_cast<__parent_pointer>(__nd);
2020 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002021 }
2022 }
2023 else
2024 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002025 __parent = static_cast<__parent_pointer>(__nd);
2026 return *__nd_ptr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002027 }
2028 }
2029 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00002030 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002031 return __parent->__left_;
2032}
2033
2034// Find place to insert if __v doesn't exist
2035// First check prior to __hint.
2036// Next check after __hint.
2037// Next do O(log N) search.
2038// Set __parent to parent of null leaf
2039// Return reference to null leaf
2040// If __v exists, set parent to node of __v and return reference to node of __v
2041template <class _Tp, class _Compare, class _Allocator>
2042template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00002043typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002044__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002045 __parent_pointer& __parent,
2046 __node_base_pointer& __dummy,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002047 const _Key& __v)
2048{
2049 if (__hint == end() || value_comp()(__v, *__hint)) // check before
2050 {
2051 // __v < *__hint
2052 const_iterator __prior = __hint;
2053 if (__prior == begin() || value_comp()(*--__prior, __v))
2054 {
2055 // *prev(__hint) < __v < *__hint
2056 if (__hint.__ptr_->__left_ == nullptr)
2057 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002058 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002059 return __parent->__left_;
2060 }
2061 else
2062 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002063 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2064 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002065 }
2066 }
2067 // __v <= *prev(__hint)
2068 return __find_equal(__parent, __v);
2069 }
2070 else if (value_comp()(*__hint, __v)) // check after
2071 {
2072 // *__hint < __v
Howard Hinnant0949eed2011-06-30 21:18:19 +00002073 const_iterator __next = _VSTD::next(__hint);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002074 if (__next == end() || value_comp()(__v, *__next))
2075 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002076 // *__hint < __v < *_VSTD::next(__hint)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002077 if (__hint.__get_np()->__right_ == nullptr)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002078 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002079 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2080 return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002081 }
2082 else
2083 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002084 __parent = static_cast<__parent_pointer>(__next.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002085 return __parent->__left_;
2086 }
2087 }
2088 // *next(__hint) <= __v
2089 return __find_equal(__parent, __v);
2090 }
2091 // else __v == *__hint
Eric Fiselier7310ec82016-07-19 17:56:20 +00002092 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2093 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2094 return __dummy;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002095}
2096
2097template <class _Tp, class _Compare, class _Allocator>
2098void
Eric Fiselier7310ec82016-07-19 17:56:20 +00002099__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002100 __node_base_pointer& __child,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002101 __node_base_pointer __new_node)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002102{
2103 __new_node->__left_ = nullptr;
2104 __new_node->__right_ = nullptr;
2105 __new_node->__parent_ = __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002106 // __new_node->__is_black_ is initialized in __tree_balance_after_insert
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002107 __child = __new_node;
2108 if (__begin_node()->__left_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002109 __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002110 __tree_balance_after_insert(__end_node()->__left_, __child);
2111 ++size();
2112}
2113
Eric Fiselierdb215062016-03-31 02:15:15 +00002114#ifndef _LIBCPP_CXX03_LANG
2115template <class _Tp, class _Compare, class _Allocator>
2116template <class _Key, class... _Args>
2117pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2118__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
2119#else
2120template <class _Tp, class _Compare, class _Allocator>
2121template <class _Key, class _Args>
2122pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2123__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args)
2124#endif
2125{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002126 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002127 __node_base_pointer& __child = __find_equal(__parent, __k);
2128 __node_pointer __r = static_cast<__node_pointer>(__child);
2129 bool __inserted = false;
2130 if (__child == nullptr)
2131 {
2132#ifndef _LIBCPP_CXX03_LANG
2133 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2134#else
2135 __node_holder __h = __construct_node(__args);
2136#endif
2137 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2138 __r = __h.release();
2139 __inserted = true;
2140 }
2141 return pair<iterator, bool>(iterator(__r), __inserted);
2142}
2143
2144
2145#ifndef _LIBCPP_CXX03_LANG
2146template <class _Tp, class _Compare, class _Allocator>
2147template <class _Key, class... _Args>
2148typename __tree<_Tp, _Compare, _Allocator>::iterator
2149__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2150 const_iterator __p, _Key const& __k, _Args&&... __args)
2151#else
2152template <class _Tp, class _Compare, class _Allocator>
2153template <class _Key, class _Args>
2154typename __tree<_Tp, _Compare, _Allocator>::iterator
2155__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2156 const_iterator __p, _Key const& __k, _Args& __args)
2157#endif
2158{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002159 __parent_pointer __parent;
2160 __node_base_pointer __dummy;
2161 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
Eric Fiselierdb215062016-03-31 02:15:15 +00002162 __node_pointer __r = static_cast<__node_pointer>(__child);
2163 if (__child == nullptr)
2164 {
2165#ifndef _LIBCPP_CXX03_LANG
2166 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2167#else
2168 __node_holder __h = __construct_node(__args);
2169#endif
2170 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2171 __r = __h.release();
2172 }
2173 return iterator(__r);
2174}
2175
2176
2177#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002178
2179template <class _Tp, class _Compare, class _Allocator>
2180template <class ..._Args>
2181typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2182__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
2183{
Eric Fiselierdb215062016-03-31 02:15:15 +00002184 static_assert(!__is_tree_value_type<_Args...>::value,
2185 "Cannot construct from __value_type");
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002186 __node_allocator& __na = __node_alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00002187 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierdb215062016-03-31 02:15:15 +00002188 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002189 __h.get_deleter().__value_constructed = true;
2190 return __h;
2191}
2192
Eric Fiselierdb215062016-03-31 02:15:15 +00002193
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002194template <class _Tp, class _Compare, class _Allocator>
2195template <class... _Args>
2196pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00002197__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002198{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002199 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002200 __parent_pointer __parent;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002201 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
2202 __node_pointer __r = static_cast<__node_pointer>(__child);
2203 bool __inserted = false;
2204 if (__child == nullptr)
2205 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002206 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002207 __r = __h.release();
2208 __inserted = true;
2209 }
2210 return pair<iterator, bool>(iterator(__r), __inserted);
2211}
2212
2213template <class _Tp, class _Compare, class _Allocator>
2214template <class... _Args>
2215typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselier83c9dc12016-04-15 23:27:27 +00002216__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002217{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002218 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002219 __parent_pointer __parent;
2220 __node_base_pointer __dummy;
2221 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002222 __node_pointer __r = static_cast<__node_pointer>(__child);
2223 if (__child == nullptr)
2224 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002225 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002226 __r = __h.release();
2227 }
2228 return iterator(__r);
2229}
2230
2231template <class _Tp, class _Compare, class _Allocator>
2232template <class... _Args>
2233typename __tree<_Tp, _Compare, _Allocator>::iterator
2234__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
2235{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002236 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002237 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002238 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002239 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002240 return iterator(static_cast<__node_pointer>(__h.release()));
2241}
2242
2243template <class _Tp, class _Compare, class _Allocator>
2244template <class... _Args>
2245typename __tree<_Tp, _Compare, _Allocator>::iterator
2246__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
2247 _Args&&... __args)
2248{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002249 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002250 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002251 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002252 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002253 return iterator(static_cast<__node_pointer>(__h.release()));
2254}
2255
Howard Hinnant73d21a42010-09-04 23:28:19 +00002256
Eric Fiselierdb215062016-03-31 02:15:15 +00002257#else // _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002258
2259template <class _Tp, class _Compare, class _Allocator>
2260typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Eric Fiselierdb215062016-03-31 02:15:15 +00002261__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002262{
2263 __node_allocator& __na = __node_alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00002264 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierdb215062016-03-31 02:15:15 +00002265 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002266 __h.get_deleter().__value_constructed = true;
Dimitry Andric89663502015-08-19 06:43:33 +00002267 return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002268}
2269
Eric Fiselierdb215062016-03-31 02:15:15 +00002270#endif // _LIBCPP_CXX03_LANG
Howard Hinnantd0a2fbf2011-03-10 17:27:57 +00002271
Eric Fiselierdb215062016-03-31 02:15:15 +00002272#ifdef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002273template <class _Tp, class _Compare, class _Allocator>
2274typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierdb215062016-03-31 02:15:15 +00002275__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002276{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002277 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002278 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002279 __node_holder __h = __construct_node(__v);
Howard Hinnant70342b92013-06-19 21:29:40 +00002280 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002281 return iterator(__h.release());
2282}
2283
2284template <class _Tp, class _Compare, class _Allocator>
2285typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierdb215062016-03-31 02:15:15 +00002286__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002287{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002288 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002289 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002290 __node_holder __h = __construct_node(__v);
Howard Hinnant70342b92013-06-19 21:29:40 +00002291 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002292 return iterator(__h.release());
2293}
Eric Fiselierdb215062016-03-31 02:15:15 +00002294#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002295
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002296template <class _Tp, class _Compare, class _Allocator>
2297pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2298__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
2299{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002300 __parent_pointer __parent;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002301 __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
2302 __node_pointer __r = static_cast<__node_pointer>(__child);
2303 bool __inserted = false;
2304 if (__child == nullptr)
2305 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002306 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002307 __r = __nd;
2308 __inserted = true;
2309 }
2310 return pair<iterator, bool>(iterator(__r), __inserted);
2311}
2312
2313template <class _Tp, class _Compare, class _Allocator>
2314typename __tree<_Tp, _Compare, _Allocator>::iterator
2315__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
2316 __node_pointer __nd)
2317{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002318 __parent_pointer __parent;
2319 __node_base_pointer __dummy;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002320 __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
2321 __node_pointer __r = static_cast<__node_pointer>(__child);
2322 if (__child == nullptr)
2323 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002324 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002325 __r = __nd;
2326 }
2327 return iterator(__r);
2328}
2329
2330template <class _Tp, class _Compare, class _Allocator>
2331typename __tree<_Tp, _Compare, _Allocator>::iterator
2332__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
2333{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002334 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002335 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002336 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002337 return iterator(__nd);
2338}
2339
2340template <class _Tp, class _Compare, class _Allocator>
2341typename __tree<_Tp, _Compare, _Allocator>::iterator
2342__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
2343 __node_pointer __nd)
2344{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002345 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002346 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002347 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002348 return iterator(__nd);
2349}
2350
2351template <class _Tp, class _Compare, class _Allocator>
2352typename __tree<_Tp, _Compare, _Allocator>::iterator
2353__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
2354{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002355 __node_pointer __np = __p.__get_np();
2356 iterator __r(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002357 ++__r;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002358 if (__begin_node() == __p.__ptr_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002359 __begin_node() = __r.__ptr_;
2360 --size();
2361 __node_allocator& __na = __node_alloc();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002362 __tree_remove(__end_node()->__left_,
2363 static_cast<__node_base_pointer>(__np));
Eric Fiselierdb215062016-03-31 02:15:15 +00002364 __node_traits::destroy(__na, _NodeTypes::__get_ptr(
2365 const_cast<__node_value_type&>(*__p)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002366 __node_traits::deallocate(__na, __np, 1);
2367 return __r;
2368}
2369
2370template <class _Tp, class _Compare, class _Allocator>
2371typename __tree<_Tp, _Compare, _Allocator>::iterator
2372__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
2373{
2374 while (__f != __l)
2375 __f = erase(__f);
Howard Hinnant70342b92013-06-19 21:29:40 +00002376 return iterator(__l.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002377}
2378
2379template <class _Tp, class _Compare, class _Allocator>
2380template <class _Key>
2381typename __tree<_Tp, _Compare, _Allocator>::size_type
2382__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
2383{
2384 iterator __i = find(__k);
2385 if (__i == end())
2386 return 0;
2387 erase(__i);
2388 return 1;
2389}
2390
2391template <class _Tp, class _Compare, class _Allocator>
2392template <class _Key>
2393typename __tree<_Tp, _Compare, _Allocator>::size_type
2394__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
2395{
2396 pair<iterator, iterator> __p = __equal_range_multi(__k);
2397 size_type __r = 0;
2398 for (; __p.first != __p.second; ++__r)
2399 __p.first = erase(__p.first);
2400 return __r;
2401}
2402
2403template <class _Tp, class _Compare, class _Allocator>
2404template <class _Key>
2405typename __tree<_Tp, _Compare, _Allocator>::iterator
2406__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
2407{
2408 iterator __p = __lower_bound(__v, __root(), __end_node());
2409 if (__p != end() && !value_comp()(__v, *__p))
2410 return __p;
2411 return end();
2412}
2413
2414template <class _Tp, class _Compare, class _Allocator>
2415template <class _Key>
2416typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2417__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
2418{
2419 const_iterator __p = __lower_bound(__v, __root(), __end_node());
2420 if (__p != end() && !value_comp()(__v, *__p))
2421 return __p;
2422 return end();
2423}
2424
2425template <class _Tp, class _Compare, class _Allocator>
2426template <class _Key>
2427typename __tree<_Tp, _Compare, _Allocator>::size_type
2428__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
2429{
Eric Fiselier227b47c2016-02-20 07:12:17 +00002430 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002431 while (__rt != nullptr)
2432 {
2433 if (value_comp()(__k, __rt->__value_))
2434 {
Eric Fiselier227b47c2016-02-20 07:12:17 +00002435 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002436 }
2437 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002438 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002439 else
2440 return 1;
2441 }
2442 return 0;
2443}
2444
2445template <class _Tp, class _Compare, class _Allocator>
2446template <class _Key>
2447typename __tree<_Tp, _Compare, _Allocator>::size_type
2448__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
2449{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002450 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002451 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002452 while (__rt != nullptr)
2453 {
2454 if (value_comp()(__k, __rt->__value_))
2455 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002456 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002457 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002458 }
2459 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002460 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002461 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00002462 return _VSTD::distance(
Eric Fiselier7310ec82016-07-19 17:56:20 +00002463 __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiselier227b47c2016-02-20 07:12:17 +00002464 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002465 );
2466 }
2467 return 0;
2468}
2469
2470template <class _Tp, class _Compare, class _Allocator>
2471template <class _Key>
2472typename __tree<_Tp, _Compare, _Allocator>::iterator
2473__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2474 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002475 __iter_pointer __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002476{
2477 while (__root != nullptr)
2478 {
2479 if (!value_comp()(__root->__value_, __v))
2480 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002481 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002482 __root = static_cast<__node_pointer>(__root->__left_);
2483 }
2484 else
2485 __root = static_cast<__node_pointer>(__root->__right_);
2486 }
2487 return iterator(__result);
2488}
2489
2490template <class _Tp, class _Compare, class _Allocator>
2491template <class _Key>
2492typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2493__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00002494 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002495 __iter_pointer __result) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002496{
2497 while (__root != nullptr)
2498 {
2499 if (!value_comp()(__root->__value_, __v))
2500 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002501 __result = static_cast<__iter_pointer>(__root);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002502 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002503 }
2504 else
Eric Fiselier227b47c2016-02-20 07:12:17 +00002505 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002506 }
2507 return const_iterator(__result);
2508}
2509
2510template <class _Tp, class _Compare, class _Allocator>
2511template <class _Key>
2512typename __tree<_Tp, _Compare, _Allocator>::iterator
2513__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2514 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002515 __iter_pointer __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002516{
2517 while (__root != nullptr)
2518 {
2519 if (value_comp()(__v, __root->__value_))
2520 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002521 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002522 __root = static_cast<__node_pointer>(__root->__left_);
2523 }
2524 else
2525 __root = static_cast<__node_pointer>(__root->__right_);
2526 }
2527 return iterator(__result);
2528}
2529
2530template <class _Tp, class _Compare, class _Allocator>
2531template <class _Key>
2532typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2533__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00002534 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002535 __iter_pointer __result) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002536{
2537 while (__root != nullptr)
2538 {
2539 if (value_comp()(__v, __root->__value_))
2540 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002541 __result = static_cast<__iter_pointer>(__root);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002542 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002543 }
2544 else
Eric Fiselier227b47c2016-02-20 07:12:17 +00002545 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002546 }
2547 return const_iterator(__result);
2548}
2549
2550template <class _Tp, class _Compare, class _Allocator>
2551template <class _Key>
2552pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2553 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2554__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2555{
Howard Hinnant99968442011-11-29 18:15:50 +00002556 typedef pair<iterator, iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002557 __iter_pointer __result = __end_node();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002558 __node_pointer __rt = __root();
2559 while (__rt != nullptr)
2560 {
2561 if (value_comp()(__k, __rt->__value_))
2562 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002563 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002564 __rt = static_cast<__node_pointer>(__rt->__left_);
2565 }
2566 else if (value_comp()(__rt->__value_, __k))
2567 __rt = static_cast<__node_pointer>(__rt->__right_);
2568 else
Howard Hinnant99968442011-11-29 18:15:50 +00002569 return _Pp(iterator(__rt),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002570 iterator(
2571 __rt->__right_ != nullptr ?
Eric Fiselier7310ec82016-07-19 17:56:20 +00002572 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002573 : __result));
2574 }
Howard Hinnant99968442011-11-29 18:15:50 +00002575 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002576}
2577
2578template <class _Tp, class _Compare, class _Allocator>
2579template <class _Key>
2580pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2581 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2582__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2583{
Howard Hinnant99968442011-11-29 18:15:50 +00002584 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002585 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002586 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002587 while (__rt != nullptr)
2588 {
2589 if (value_comp()(__k, __rt->__value_))
2590 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002591 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002592 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002593 }
2594 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002595 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002596 else
Howard Hinnant99968442011-11-29 18:15:50 +00002597 return _Pp(const_iterator(__rt),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002598 const_iterator(
2599 __rt->__right_ != nullptr ?
Eric Fiselier7310ec82016-07-19 17:56:20 +00002600 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002601 : __result));
2602 }
Howard Hinnant99968442011-11-29 18:15:50 +00002603 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002604}
2605
2606template <class _Tp, class _Compare, class _Allocator>
2607template <class _Key>
2608pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2609 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2610__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2611{
Howard Hinnant99968442011-11-29 18:15:50 +00002612 typedef pair<iterator, iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002613 __iter_pointer __result = __end_node();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002614 __node_pointer __rt = __root();
2615 while (__rt != nullptr)
2616 {
2617 if (value_comp()(__k, __rt->__value_))
2618 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002619 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002620 __rt = static_cast<__node_pointer>(__rt->__left_);
2621 }
2622 else if (value_comp()(__rt->__value_, __k))
2623 __rt = static_cast<__node_pointer>(__rt->__right_);
2624 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002625 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002626 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2627 }
Howard Hinnant99968442011-11-29 18:15:50 +00002628 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002629}
2630
2631template <class _Tp, class _Compare, class _Allocator>
2632template <class _Key>
2633pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2634 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2635__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2636{
Howard Hinnant99968442011-11-29 18:15:50 +00002637 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002638 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002639 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002640 while (__rt != nullptr)
2641 {
2642 if (value_comp()(__k, __rt->__value_))
2643 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002644 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002645 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002646 }
2647 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002648 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002649 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002650 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiselier227b47c2016-02-20 07:12:17 +00002651 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002652 }
Howard Hinnant99968442011-11-29 18:15:50 +00002653 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002654}
2655
2656template <class _Tp, class _Compare, class _Allocator>
2657typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Howard Hinnant8b537682011-06-04 17:10:24 +00002658__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002659{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002660 __node_pointer __np = __p.__get_np();
2661 if (__begin_node() == __p.__ptr_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002662 {
2663 if (__np->__right_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002664 __begin_node() = static_cast<__iter_pointer>(__np->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002665 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002666 __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002667 }
2668 --size();
2669 __tree_remove(__end_node()->__left_,
2670 static_cast<__node_base_pointer>(__np));
Marshall Clow01c1c6f2015-01-28 19:54:25 +00002671 return __node_holder(__np, _Dp(__node_alloc(), true));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002672}
2673
Howard Hinnant7686add2011-06-04 14:31:57 +00002674template <class _Tp, class _Compare, class _Allocator>
2675inline _LIBCPP_INLINE_VISIBILITY
2676void
2677swap(__tree<_Tp, _Compare, _Allocator>& __x,
2678 __tree<_Tp, _Compare, _Allocator>& __y)
2679 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2680{
2681 __x.swap(__y);
2682}
2683
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002684_LIBCPP_END_NAMESPACE_STD
2685
2686#endif // _LIBCPP___TREE