blob: 3bc020734110fd315b1834befde71e68aa7618d4 [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()
966 _LIBCPP_DIAGNOSE_WARNING(!__is_const_comparable<_Compare, _Tp>::value,
967 "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
976>
977{
978 static constexpr bool __trigger_diagnostics()
979 _LIBCPP_DIAGNOSE_WARNING(!__is_const_comparable<_KeyComp, _Key>::value,
980 "the specified comparator type does not provide a const call operator")
981 { return true; }
982};
983
984#endif
985
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000986template <class _Tp, class _Compare, class _Allocator>
987class __tree
988{
989public:
990 typedef _Tp value_type;
991 typedef _Compare value_compare;
992 typedef _Allocator allocator_type;
Eric Fiselier55263482016-02-20 05:28:30 +0000993
994private:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000995 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiselier55263482016-02-20 05:28:30 +0000996 typedef typename __make_tree_node_types<value_type,
997 typename __alloc_traits::void_pointer>::type
998 _NodeTypes;
Eric Fiselierdb215062016-03-31 02:15:15 +0000999 typedef typename _NodeTypes::key_type key_type;
Eric Fiselier55263482016-02-20 05:28:30 +00001000public:
1001 typedef typename _NodeTypes::__node_value_type __node_value_type;
1002 typedef typename _NodeTypes::__container_value_type __container_value_type;
1003
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001004 typedef typename __alloc_traits::pointer pointer;
1005 typedef typename __alloc_traits::const_pointer const_pointer;
1006 typedef typename __alloc_traits::size_type size_type;
1007 typedef typename __alloc_traits::difference_type difference_type;
1008
Eric Fiselier55263482016-02-20 05:28:30 +00001009public:
1010 typedef typename _NodeTypes::__void_pointer __void_pointer;
Howard Hinnant70342b92013-06-19 21:29:40 +00001011
Eric Fiselier55263482016-02-20 05:28:30 +00001012 typedef typename _NodeTypes::__node_type __node;
1013 typedef typename _NodeTypes::__node_pointer __node_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +00001014
1015 typedef typename _NodeTypes::__node_base_type __node_base;
1016 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +00001017
1018 typedef typename _NodeTypes::__end_node_type __end_node_t;
1019 typedef typename _NodeTypes::__end_node_pointer __end_node_ptr;
Eric Fiselier55263482016-02-20 05:28:30 +00001020
Eric Fiselier7310ec82016-07-19 17:56:20 +00001021 typedef typename _NodeTypes::__parent_pointer __parent_pointer;
1022 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
1023
Marshall Clow66302c62015-04-07 05:21:38 +00001024 typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
Eric Fiselier55263482016-02-20 05:28:30 +00001025 typedef allocator_traits<__node_allocator> __node_traits;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001026
Eric Fiselier55263482016-02-20 05:28:30 +00001027private:
1028 // check for sane allocator pointer rebinding semantics. Rebinding the
1029 // allocator for a new pointer type should be exactly the same as rebinding
1030 // the pointer using 'pointer_traits'.
1031 static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1032 "Allocator does not rebind pointers in a sane manner.");
1033 typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1034 __node_base_allocator;
1035 typedef allocator_traits<__node_base_allocator> __node_base_traits;
1036 static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1037 "Allocator does not rebind pointers in a sane manner.");
1038
1039private:
Eric Fiselier7310ec82016-07-19 17:56:20 +00001040 __iter_pointer __begin_node_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001041 __compressed_pair<__end_node_t, __node_allocator> __pair1_;
1042 __compressed_pair<size_type, value_compare> __pair3_;
1043
1044public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001045 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001046 __iter_pointer __end_node() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001047 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001048 return static_cast<__iter_pointer>(
Eric Fiselier227b47c2016-02-20 07:12:17 +00001049 pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
1050 );
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001051 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001052 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001053 __iter_pointer __end_node() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001054 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001055 return static_cast<__iter_pointer>(
Eric Fiselier227b47c2016-02-20 07:12:17 +00001056 pointer_traits<__end_node_ptr>::pointer_to(
1057 const_cast<__end_node_t&>(__pair1_.first())
1058 )
1059 );
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001060 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001062 __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001063private:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001065 const __node_allocator& __node_alloc() const _NOEXCEPT
1066 {return __pair1_.second();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001067 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001068 __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001069 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001070 const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001071public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001072 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001073 allocator_type __alloc() const _NOEXCEPT
1074 {return allocator_type(__node_alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001075private:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001077 size_type& size() _NOEXCEPT {return __pair3_.first();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001078public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001079 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001080 const size_type& size() const _NOEXCEPT {return __pair3_.first();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001081 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001082 value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001083 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001084 const value_compare& value_comp() const _NOEXCEPT
1085 {return __pair3_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001086public:
Eric Fiselier227b47c2016-02-20 07:12:17 +00001087
Howard Hinnant333f50d2010-09-21 20:16:37 +00001088 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier227b47c2016-02-20 07:12:17 +00001089 __node_pointer __root() const _NOEXCEPT
1090 {return static_cast<__node_pointer>(__end_node()->__left_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001091
Eric Fiselier7310ec82016-07-19 17:56:20 +00001092 __node_base_pointer* __root_ptr() const _NOEXCEPT {
1093 return _VSTD::addressof(__end_node()->__left_);
1094 }
1095
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001096 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
Howard Hinnant70342b92013-06-19 21:29:40 +00001097 typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001098
Howard Hinnant7686add2011-06-04 14:31:57 +00001099 explicit __tree(const value_compare& __comp)
1100 _NOEXCEPT_(
1101 is_nothrow_default_constructible<__node_allocator>::value &&
1102 is_nothrow_copy_constructible<value_compare>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001103 explicit __tree(const allocator_type& __a);
1104 __tree(const value_compare& __comp, const allocator_type& __a);
1105 __tree(const __tree& __t);
1106 __tree& operator=(const __tree& __t);
1107 template <class _InputIterator>
1108 void __assign_unique(_InputIterator __first, _InputIterator __last);
1109 template <class _InputIterator>
1110 void __assign_multi(_InputIterator __first, _InputIterator __last);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001111#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant7686add2011-06-04 14:31:57 +00001112 __tree(__tree&& __t)
1113 _NOEXCEPT_(
1114 is_nothrow_move_constructible<__node_allocator>::value &&
1115 is_nothrow_move_constructible<value_compare>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001116 __tree(__tree&& __t, const allocator_type& __a);
Howard Hinnant7686add2011-06-04 14:31:57 +00001117 __tree& operator=(__tree&& __t)
1118 _NOEXCEPT_(
1119 __node_traits::propagate_on_container_move_assignment::value &&
1120 is_nothrow_move_assignable<value_compare>::value &&
1121 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001122#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001123
1124 ~__tree();
1125
Howard Hinnant333f50d2010-09-21 20:16:37 +00001126 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001127 iterator begin() _NOEXCEPT {return iterator(__begin_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001128 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001129 const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001130 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001131 iterator end() _NOEXCEPT {return iterator(__end_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001133 const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001134
Howard Hinnant333f50d2010-09-21 20:16:37 +00001135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001136 size_type max_size() const _NOEXCEPT
Eric Fiselieref3060e2016-11-23 01:18:56 +00001137 {return std::min<size_type>(
1138 __node_traits::max_size(__node_alloc()),
1139 numeric_limits<difference_type >::max());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001140
Howard Hinnant7686add2011-06-04 14:31:57 +00001141 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001142
Howard Hinnant7686add2011-06-04 14:31:57 +00001143 void swap(__tree& __t)
Dimitry Andric1421cf02016-08-27 19:32:03 +00001144#if _LIBCPP_STD_VER <= 11
Howard Hinnant7686add2011-06-04 14:31:57 +00001145 _NOEXCEPT_(
Marshall Clow7d914d12015-07-13 20:04:56 +00001146 __is_nothrow_swappable<value_compare>::value
Marshall Clow7d914d12015-07-13 20:04:56 +00001147 && (!__node_traits::propagate_on_container_swap::value ||
1148 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow7d914d12015-07-13 20:04:56 +00001149 );
Dimitry Andric1421cf02016-08-27 19:32:03 +00001150#else
1151 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1152#endif
Eric Fiselierdb215062016-03-31 02:15:15 +00001153
1154#ifndef _LIBCPP_CXX03_LANG
1155 template <class _Key, class ..._Args>
1156 pair<iterator, bool>
1157 __emplace_unique_key_args(_Key const&, _Args&&... __args);
1158 template <class _Key, class ..._Args>
1159 iterator
1160 __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001161
1162 template <class... _Args>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001163 pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
Eric Fiselierdb215062016-03-31 02:15:15 +00001164
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001165 template <class... _Args>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001166 iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001167
Eric Fiselierdb215062016-03-31 02:15:15 +00001168 template <class... _Args>
1169 iterator __emplace_multi(_Args&&... __args);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001170
Eric Fiselierdb215062016-03-31 02:15:15 +00001171 template <class... _Args>
1172 iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001173
1174 template <class _Pp>
1175 _LIBCPP_INLINE_VISIBILITY
1176 pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1177 return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1178 __can_extract_key<_Pp, key_type>());
1179 }
1180
Eric Fiselierdc414cd2016-04-16 00:23:12 +00001181 template <class _First, class _Second>
1182 _LIBCPP_INLINE_VISIBILITY
1183 typename enable_if<
1184 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1185 pair<iterator, bool>
1186 >::type __emplace_unique(_First&& __f, _Second&& __s) {
1187 return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1188 _VSTD::forward<_Second>(__s));
1189 }
1190
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001191 template <class... _Args>
1192 _LIBCPP_INLINE_VISIBILITY
1193 pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1194 return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1195 }
1196
1197 template <class _Pp>
1198 _LIBCPP_INLINE_VISIBILITY
1199 pair<iterator, bool>
1200 __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1201 return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1202 }
1203
1204 template <class _Pp>
1205 _LIBCPP_INLINE_VISIBILITY
1206 pair<iterator, bool>
1207 __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1208 return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1209 }
1210
1211 template <class _Pp>
1212 _LIBCPP_INLINE_VISIBILITY
1213 pair<iterator, bool>
1214 __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1215 return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1216 }
1217
1218 template <class _Pp>
1219 _LIBCPP_INLINE_VISIBILITY
1220 iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1221 return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1222 __can_extract_key<_Pp, key_type>());
1223 }
1224
Eric Fiselierdc414cd2016-04-16 00:23:12 +00001225 template <class _First, class _Second>
1226 _LIBCPP_INLINE_VISIBILITY
1227 typename enable_if<
1228 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1229 iterator
1230 >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
1231 return __emplace_hint_unique_key_args(__p, __f,
1232 _VSTD::forward<_First>(__f),
1233 _VSTD::forward<_Second>(__s));
1234 }
1235
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001236 template <class... _Args>
1237 _LIBCPP_INLINE_VISIBILITY
1238 iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1239 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1240 }
1241
1242 template <class _Pp>
1243 _LIBCPP_INLINE_VISIBILITY
1244 iterator
1245 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1246 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
1247 }
1248
1249 template <class _Pp>
1250 _LIBCPP_INLINE_VISIBILITY
1251 iterator
1252 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1253 return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x));
1254 }
1255
1256 template <class _Pp>
1257 _LIBCPP_INLINE_VISIBILITY
1258 iterator
1259 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1260 return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x));
1261 }
1262
Eric Fiselierdb215062016-03-31 02:15:15 +00001263#else
1264 template <class _Key, class _Args>
1265 _LIBCPP_INLINE_VISIBILITY
1266 pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args);
1267 template <class _Key, class _Args>
1268 _LIBCPP_INLINE_VISIBILITY
1269 iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&);
Marshall Clow3426a862016-01-05 19:32:41 +00001270#endif
1271
Eric Fiselierdb215062016-03-31 02:15:15 +00001272 _LIBCPP_INLINE_VISIBILITY
1273 pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
1274 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
1275 }
1276
1277 _LIBCPP_INLINE_VISIBILITY
1278 iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
1279 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v);
1280 }
1281
1282#ifdef _LIBCPP_CXX03_LANG
1283 _LIBCPP_INLINE_VISIBILITY
1284 iterator __insert_multi(const __container_value_type& __v);
1285 _LIBCPP_INLINE_VISIBILITY
1286 iterator __insert_multi(const_iterator __p, const __container_value_type& __v);
1287#else
1288 _LIBCPP_INLINE_VISIBILITY
1289 pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
1290 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
1291 }
1292
1293 _LIBCPP_INLINE_VISIBILITY
1294 iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
1295 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v));
1296 }
1297
1298 template <class _Vp, class = typename enable_if<
1299 !is_same<typename __unconstref<_Vp>::type,
1300 __container_value_type
1301 >::value
1302 >::type>
1303 _LIBCPP_INLINE_VISIBILITY
1304 pair<iterator, bool> __insert_unique(_Vp&& __v) {
1305 return __emplace_unique(_VSTD::forward<_Vp>(__v));
1306 }
1307
1308 template <class _Vp, class = typename enable_if<
1309 !is_same<typename __unconstref<_Vp>::type,
1310 __container_value_type
1311 >::value
1312 >::type>
1313 _LIBCPP_INLINE_VISIBILITY
1314 iterator __insert_unique(const_iterator __p, _Vp&& __v) {
1315 return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
1316 }
1317
1318 _LIBCPP_INLINE_VISIBILITY
1319 iterator __insert_multi(__container_value_type&& __v) {
1320 return __emplace_multi(_VSTD::move(__v));
1321 }
1322
1323 _LIBCPP_INLINE_VISIBILITY
1324 iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
1325 return __emplace_hint_multi(__p, _VSTD::move(__v));
1326 }
1327
1328 template <class _Vp>
1329 _LIBCPP_INLINE_VISIBILITY
1330 iterator __insert_multi(_Vp&& __v) {
1331 return __emplace_multi(_VSTD::forward<_Vp>(__v));
1332 }
1333
1334 template <class _Vp>
1335 _LIBCPP_INLINE_VISIBILITY
1336 iterator __insert_multi(const_iterator __p, _Vp&& __v) {
1337 return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
1338 }
1339
1340#endif // !_LIBCPP_CXX03_LANG
1341
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001342 pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
1343 iterator __node_insert_unique(const_iterator __p,
1344 __node_pointer __nd);
1345
1346 iterator __node_insert_multi(__node_pointer __nd);
1347 iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1348
1349 iterator erase(const_iterator __p);
1350 iterator erase(const_iterator __f, const_iterator __l);
1351 template <class _Key>
1352 size_type __erase_unique(const _Key& __k);
1353 template <class _Key>
1354 size_type __erase_multi(const _Key& __k);
1355
Eric Fiselier7310ec82016-07-19 17:56:20 +00001356 void __insert_node_at(__parent_pointer __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001357 __node_base_pointer& __child,
1358 __node_base_pointer __new_node);
1359
1360 template <class _Key>
1361 iterator find(const _Key& __v);
1362 template <class _Key>
1363 const_iterator find(const _Key& __v) const;
1364
1365 template <class _Key>
1366 size_type __count_unique(const _Key& __k) const;
1367 template <class _Key>
1368 size_type __count_multi(const _Key& __k) const;
1369
1370 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001372 iterator lower_bound(const _Key& __v)
1373 {return __lower_bound(__v, __root(), __end_node());}
1374 template <class _Key>
1375 iterator __lower_bound(const _Key& __v,
1376 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001377 __iter_pointer __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001378 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001379 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001380 const_iterator lower_bound(const _Key& __v) const
1381 {return __lower_bound(__v, __root(), __end_node());}
1382 template <class _Key>
1383 const_iterator __lower_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00001384 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001385 __iter_pointer __result) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001386 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001388 iterator upper_bound(const _Key& __v)
1389 {return __upper_bound(__v, __root(), __end_node());}
1390 template <class _Key>
1391 iterator __upper_bound(const _Key& __v,
1392 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001393 __iter_pointer __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001394 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001396 const_iterator upper_bound(const _Key& __v) const
1397 {return __upper_bound(__v, __root(), __end_node());}
1398 template <class _Key>
1399 const_iterator __upper_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00001400 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001401 __iter_pointer __result) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001402 template <class _Key>
1403 pair<iterator, iterator>
1404 __equal_range_unique(const _Key& __k);
1405 template <class _Key>
1406 pair<const_iterator, const_iterator>
1407 __equal_range_unique(const _Key& __k) const;
1408
1409 template <class _Key>
1410 pair<iterator, iterator>
1411 __equal_range_multi(const _Key& __k);
1412 template <class _Key>
1413 pair<const_iterator, const_iterator>
1414 __equal_range_multi(const _Key& __k) const;
1415
Howard Hinnant99968442011-11-29 18:15:50 +00001416 typedef __tree_node_destructor<__node_allocator> _Dp;
1417 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001418
Howard Hinnant8b537682011-06-04 17:10:24 +00001419 __node_holder remove(const_iterator __p) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001420private:
Eric Fiselier7310ec82016-07-19 17:56:20 +00001421 __node_base_pointer&
1422 __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1423 __node_base_pointer&
1424 __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1425 __node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001426 __find_leaf(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001427 __parent_pointer& __parent, const key_type& __v);
Eric Fiselier856712b2017-01-05 06:06:18 +00001428 // FIXME: Make this function const qualified. Unfortunetly doing so
1429 // breaks existing code which uses non-const callable comparators.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001430 template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001431 __node_base_pointer&
1432 __find_equal(__parent_pointer& __parent, const _Key& __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001433 template <class _Key>
Eric Fiselier856712b2017-01-05 06:06:18 +00001434 _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1435 __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1436 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1437 }
1438 template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001439 __node_base_pointer&
1440 __find_equal(const_iterator __hint, __parent_pointer& __parent,
1441 __node_base_pointer& __dummy,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001442 const _Key& __v);
1443
Eric Fiselierdb215062016-03-31 02:15:15 +00001444#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001445 template <class ..._Args>
Eric Fiselierdb215062016-03-31 02:15:15 +00001446 __node_holder __construct_node(_Args&& ...__args);
1447#else
1448 __node_holder __construct_node(const __container_value_type& __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001449#endif
1450
Howard Hinnant7686add2011-06-04 14:31:57 +00001451 void destroy(__node_pointer __nd) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001452
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)
1455 {__copy_assign_alloc(__t, integral_constant<bool,
1456 __node_traits::propagate_on_container_copy_assignment::value>());}
1457
Howard Hinnant333f50d2010-09-21 20:16:37 +00001458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001459 void __copy_assign_alloc(const __tree& __t, true_type)
Marshall Clow546498c2016-08-17 23:24:02 +00001460 {
1461 if (__node_alloc() != __t.__node_alloc())
1462 clear();
1463 __node_alloc() = __t.__node_alloc();
1464 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001465 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001466 void __copy_assign_alloc(const __tree&, false_type) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001467
1468 void __move_assign(__tree& __t, false_type);
Howard Hinnant7686add2011-06-04 14:31:57 +00001469 void __move_assign(__tree& __t, true_type)
1470 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1471 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001472
Howard Hinnant333f50d2010-09-21 20:16:37 +00001473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001474 void __move_assign_alloc(__tree& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001475 _NOEXCEPT_(
1476 !__node_traits::propagate_on_container_move_assignment::value ||
1477 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001478 {__move_assign_alloc(__t, integral_constant<bool,
1479 __node_traits::propagate_on_container_move_assignment::value>());}
1480
Howard Hinnant333f50d2010-09-21 20:16:37 +00001481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001482 void __move_assign_alloc(__tree& __t, true_type)
Howard Hinnant7686add2011-06-04 14:31:57 +00001483 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001484 {__node_alloc() = _VSTD::move(__t.__node_alloc());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001485 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001486 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001487
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001488 __node_pointer __detach();
1489 static __node_pointer __detach(__node_pointer);
Howard Hinnant70342b92013-06-19 21:29:40 +00001490
Eric Fiselierc3589a82017-01-04 23:56:00 +00001491 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1492 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001493};
1494
1495template <class _Tp, class _Compare, class _Allocator>
1496__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
Howard Hinnant7686add2011-06-04 14:31:57 +00001497 _NOEXCEPT_(
1498 is_nothrow_default_constructible<__node_allocator>::value &&
1499 is_nothrow_copy_constructible<value_compare>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001500 : __pair3_(0, __comp)
1501{
1502 __begin_node() = __end_node();
1503}
1504
1505template <class _Tp, class _Compare, class _Allocator>
1506__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001507 : __begin_node_(__iter_pointer()),
Eric Fiselier02bb4bd2015-07-18 23:56:04 +00001508 __pair1_(__node_allocator(__a)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001509 __pair3_(0)
1510{
1511 __begin_node() = __end_node();
1512}
1513
1514template <class _Tp, class _Compare, class _Allocator>
1515__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1516 const allocator_type& __a)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001517 : __begin_node_(__iter_pointer()),
Eric Fiselier02bb4bd2015-07-18 23:56:04 +00001518 __pair1_(__node_allocator(__a)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001519 __pair3_(0, __comp)
1520{
1521 __begin_node() = __end_node();
1522}
1523
1524// Precondition: size() != 0
1525template <class _Tp, class _Compare, class _Allocator>
1526typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1527__tree<_Tp, _Compare, _Allocator>::__detach()
1528{
Eric Fiselier7310ec82016-07-19 17:56:20 +00001529 __node_pointer __cache = static_cast<__node_pointer>(__begin_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001530 __begin_node() = __end_node();
1531 __end_node()->__left_->__parent_ = nullptr;
1532 __end_node()->__left_ = nullptr;
1533 size() = 0;
1534 // __cache->__left_ == nullptr
1535 if (__cache->__right_ != nullptr)
1536 __cache = static_cast<__node_pointer>(__cache->__right_);
1537 // __cache->__left_ == nullptr
1538 // __cache->__right_ == nullptr
1539 return __cache;
1540}
1541
1542// Precondition: __cache != nullptr
1543// __cache->left_ == nullptr
1544// __cache->right_ == nullptr
1545// This is no longer a red-black tree
1546template <class _Tp, class _Compare, class _Allocator>
1547typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1548__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
1549{
1550 if (__cache->__parent_ == nullptr)
1551 return nullptr;
Howard Hinnant70342b92013-06-19 21:29:40 +00001552 if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001553 {
1554 __cache->__parent_->__left_ = nullptr;
1555 __cache = static_cast<__node_pointer>(__cache->__parent_);
1556 if (__cache->__right_ == nullptr)
1557 return __cache;
1558 return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
1559 }
1560 // __cache is right child
Eric Fiselier7310ec82016-07-19 17:56:20 +00001561 __cache->__parent_unsafe()->__right_ = nullptr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001562 __cache = static_cast<__node_pointer>(__cache->__parent_);
1563 if (__cache->__left_ == nullptr)
1564 return __cache;
1565 return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
1566}
1567
1568template <class _Tp, class _Compare, class _Allocator>
1569__tree<_Tp, _Compare, _Allocator>&
1570__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1571{
1572 if (this != &__t)
1573 {
1574 value_comp() = __t.value_comp();
1575 __copy_assign_alloc(__t);
1576 __assign_multi(__t.begin(), __t.end());
1577 }
1578 return *this;
1579}
1580
1581template <class _Tp, class _Compare, class _Allocator>
1582template <class _InputIterator>
1583void
1584__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
1585{
Eric Fiselierdb215062016-03-31 02:15:15 +00001586 typedef iterator_traits<_InputIterator> _ITraits;
1587 typedef typename _ITraits::value_type _ItValueType;
1588 static_assert((is_same<_ItValueType, __container_value_type>::value),
1589 "__assign_unique may only be called with the containers value type");
1590
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001591 if (size() != 0)
1592 {
1593 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001594#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001595 try
1596 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001597#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001598 for (; __cache != nullptr && __first != __last; ++__first)
1599 {
1600 __cache->__value_ = *__first;
1601 __node_pointer __next = __detach(__cache);
1602 __node_insert_unique(__cache);
1603 __cache = __next;
1604 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001605#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001606 }
1607 catch (...)
1608 {
1609 while (__cache->__parent_ != nullptr)
1610 __cache = static_cast<__node_pointer>(__cache->__parent_);
1611 destroy(__cache);
1612 throw;
1613 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001614#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001615 if (__cache != nullptr)
1616 {
1617 while (__cache->__parent_ != nullptr)
1618 __cache = static_cast<__node_pointer>(__cache->__parent_);
1619 destroy(__cache);
1620 }
1621 }
1622 for (; __first != __last; ++__first)
1623 __insert_unique(*__first);
1624}
1625
1626template <class _Tp, class _Compare, class _Allocator>
1627template <class _InputIterator>
1628void
1629__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1630{
Eric Fiselierdb215062016-03-31 02:15:15 +00001631 typedef iterator_traits<_InputIterator> _ITraits;
1632 typedef typename _ITraits::value_type _ItValueType;
1633 static_assert((is_same<_ItValueType, __container_value_type>::value ||
1634 is_same<_ItValueType, __node_value_type>::value),
1635 "__assign_multi may only be called with the containers value type"
1636 " or the nodes value type");
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001637 if (size() != 0)
1638 {
1639 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001640#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001641 try
1642 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001643#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001644 for (; __cache != nullptr && __first != __last; ++__first)
1645 {
1646 __cache->__value_ = *__first;
1647 __node_pointer __next = __detach(__cache);
1648 __node_insert_multi(__cache);
1649 __cache = __next;
1650 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001651#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001652 }
1653 catch (...)
1654 {
1655 while (__cache->__parent_ != nullptr)
1656 __cache = static_cast<__node_pointer>(__cache->__parent_);
1657 destroy(__cache);
1658 throw;
1659 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001660#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001661 if (__cache != nullptr)
1662 {
1663 while (__cache->__parent_ != nullptr)
1664 __cache = static_cast<__node_pointer>(__cache->__parent_);
1665 destroy(__cache);
1666 }
1667 }
1668 for (; __first != __last; ++__first)
Eric Fiselierdb215062016-03-31 02:15:15 +00001669 __insert_multi(_NodeTypes::__get_value(*__first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001670}
1671
1672template <class _Tp, class _Compare, class _Allocator>
1673__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001674 : __begin_node_(__iter_pointer()),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001675 __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
1676 __pair3_(0, __t.value_comp())
1677{
1678 __begin_node() = __end_node();
1679}
1680
Howard Hinnant73d21a42010-09-04 23:28:19 +00001681#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001682
1683template <class _Tp, class _Compare, class _Allocator>
1684__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001685 _NOEXCEPT_(
1686 is_nothrow_move_constructible<__node_allocator>::value &&
1687 is_nothrow_move_constructible<value_compare>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001688 : __begin_node_(_VSTD::move(__t.__begin_node_)),
1689 __pair1_(_VSTD::move(__t.__pair1_)),
1690 __pair3_(_VSTD::move(__t.__pair3_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001691{
1692 if (size() == 0)
1693 __begin_node() = __end_node();
1694 else
1695 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001696 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001697 __t.__begin_node() = __t.__end_node();
1698 __t.__end_node()->__left_ = nullptr;
1699 __t.size() = 0;
1700 }
1701}
1702
1703template <class _Tp, class _Compare, class _Allocator>
1704__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1705 : __pair1_(__node_allocator(__a)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00001706 __pair3_(0, _VSTD::move(__t.value_comp()))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001707{
1708 if (__a == __t.__alloc())
1709 {
1710 if (__t.size() == 0)
1711 __begin_node() = __end_node();
1712 else
1713 {
1714 __begin_node() = __t.__begin_node();
1715 __end_node()->__left_ = __t.__end_node()->__left_;
Eric Fiselier7310ec82016-07-19 17:56:20 +00001716 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001717 size() = __t.size();
1718 __t.__begin_node() = __t.__end_node();
1719 __t.__end_node()->__left_ = nullptr;
1720 __t.size() = 0;
1721 }
1722 }
1723 else
1724 {
1725 __begin_node() = __end_node();
1726 }
1727}
1728
1729template <class _Tp, class _Compare, class _Allocator>
1730void
1731__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
Howard Hinnant7686add2011-06-04 14:31:57 +00001732 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1733 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001734{
1735 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1736 __begin_node_ = __t.__begin_node_;
1737 __pair1_.first() = __t.__pair1_.first();
1738 __move_assign_alloc(__t);
Howard Hinnant0949eed2011-06-30 21:18:19 +00001739 __pair3_ = _VSTD::move(__t.__pair3_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001740 if (size() == 0)
1741 __begin_node() = __end_node();
1742 else
1743 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001744 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001745 __t.__begin_node() = __t.__end_node();
1746 __t.__end_node()->__left_ = nullptr;
1747 __t.size() = 0;
1748 }
1749}
1750
1751template <class _Tp, class _Compare, class _Allocator>
1752void
1753__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1754{
1755 if (__node_alloc() == __t.__node_alloc())
1756 __move_assign(__t, true_type());
1757 else
1758 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001759 value_comp() = _VSTD::move(__t.value_comp());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001760 const_iterator __e = end();
1761 if (size() != 0)
1762 {
1763 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001764#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001765 try
1766 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001767#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001768 while (__cache != nullptr && __t.size() != 0)
1769 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001770 __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001771 __node_pointer __next = __detach(__cache);
1772 __node_insert_multi(__cache);
1773 __cache = __next;
1774 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001775#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001776 }
1777 catch (...)
1778 {
1779 while (__cache->__parent_ != nullptr)
1780 __cache = static_cast<__node_pointer>(__cache->__parent_);
1781 destroy(__cache);
1782 throw;
1783 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001784#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001785 if (__cache != nullptr)
1786 {
1787 while (__cache->__parent_ != nullptr)
1788 __cache = static_cast<__node_pointer>(__cache->__parent_);
1789 destroy(__cache);
1790 }
1791 }
1792 while (__t.size() != 0)
Eric Fiselierdb215062016-03-31 02:15:15 +00001793 __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001794 }
1795}
1796
1797template <class _Tp, class _Compare, class _Allocator>
1798__tree<_Tp, _Compare, _Allocator>&
1799__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001800 _NOEXCEPT_(
1801 __node_traits::propagate_on_container_move_assignment::value &&
1802 is_nothrow_move_assignable<value_compare>::value &&
1803 is_nothrow_move_assignable<__node_allocator>::value)
1804
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001805{
1806 __move_assign(__t, integral_constant<bool,
1807 __node_traits::propagate_on_container_move_assignment::value>());
1808 return *this;
1809}
1810
Howard Hinnant73d21a42010-09-04 23:28:19 +00001811#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001812
1813template <class _Tp, class _Compare, class _Allocator>
1814__tree<_Tp, _Compare, _Allocator>::~__tree()
1815{
Marshall Clow1a933122016-06-30 22:05:45 +00001816 static_assert((is_copy_constructible<value_compare>::value),
1817 "Comparator must be copy-constructible.");
Eric Fiselierebaf7da2017-01-13 22:02:08 +00001818#ifndef _LIBCPP_CXX03_LANG
1819 static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>::
1820 __trigger_diagnostics()), "");
1821#endif
1822 destroy(__root());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001823}
1824
1825template <class _Tp, class _Compare, class _Allocator>
1826void
Howard Hinnant7686add2011-06-04 14:31:57 +00001827__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001828{
1829 if (__nd != nullptr)
1830 {
1831 destroy(static_cast<__node_pointer>(__nd->__left_));
1832 destroy(static_cast<__node_pointer>(__nd->__right_));
1833 __node_allocator& __na = __node_alloc();
Eric Fiselierdb215062016-03-31 02:15:15 +00001834 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001835 __node_traits::deallocate(__na, __nd, 1);
1836 }
1837}
1838
1839template <class _Tp, class _Compare, class _Allocator>
1840void
1841__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
Dimitry Andric1421cf02016-08-27 19:32:03 +00001842#if _LIBCPP_STD_VER <= 11
Marshall Clow7d914d12015-07-13 20:04:56 +00001843 _NOEXCEPT_(
1844 __is_nothrow_swappable<value_compare>::value
Marshall Clow7d914d12015-07-13 20:04:56 +00001845 && (!__node_traits::propagate_on_container_swap::value ||
1846 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow7d914d12015-07-13 20:04:56 +00001847 )
Dimitry Andric1421cf02016-08-27 19:32:03 +00001848#else
1849 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1850#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001851{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001852 using _VSTD::swap;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001853 swap(__begin_node_, __t.__begin_node_);
1854 swap(__pair1_.first(), __t.__pair1_.first());
Marshall Clow7d914d12015-07-13 20:04:56 +00001855 __swap_allocator(__node_alloc(), __t.__node_alloc());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001856 __pair3_.swap(__t.__pair3_);
1857 if (size() == 0)
1858 __begin_node() = __end_node();
1859 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00001860 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001861 if (__t.size() == 0)
1862 __t.__begin_node() = __t.__end_node();
1863 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00001864 __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001865}
1866
1867template <class _Tp, class _Compare, class _Allocator>
1868void
Howard Hinnant7686add2011-06-04 14:31:57 +00001869__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001870{
1871 destroy(__root());
1872 size() = 0;
1873 __begin_node() = __end_node();
1874 __end_node()->__left_ = nullptr;
1875}
1876
1877// Find lower_bound place to insert
1878// Set __parent to parent of null leaf
1879// Return reference to null leaf
1880template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001881typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1882__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001883 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001884{
1885 __node_pointer __nd = __root();
1886 if (__nd != nullptr)
1887 {
1888 while (true)
1889 {
1890 if (value_comp()(__nd->__value_, __v))
1891 {
1892 if (__nd->__right_ != nullptr)
1893 __nd = static_cast<__node_pointer>(__nd->__right_);
1894 else
1895 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001896 __parent = static_cast<__parent_pointer>(__nd);
1897 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001898 }
1899 }
1900 else
1901 {
1902 if (__nd->__left_ != nullptr)
1903 __nd = static_cast<__node_pointer>(__nd->__left_);
1904 else
1905 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001906 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001907 return __parent->__left_;
1908 }
1909 }
1910 }
1911 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00001912 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001913 return __parent->__left_;
1914}
1915
1916// Find upper_bound place to insert
1917// Set __parent to parent of null leaf
1918// Return reference to null leaf
1919template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001920typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1921__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001922 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001923{
1924 __node_pointer __nd = __root();
1925 if (__nd != nullptr)
1926 {
1927 while (true)
1928 {
1929 if (value_comp()(__v, __nd->__value_))
1930 {
1931 if (__nd->__left_ != nullptr)
1932 __nd = static_cast<__node_pointer>(__nd->__left_);
1933 else
1934 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001935 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001936 return __parent->__left_;
1937 }
1938 }
1939 else
1940 {
1941 if (__nd->__right_ != nullptr)
1942 __nd = static_cast<__node_pointer>(__nd->__right_);
1943 else
1944 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001945 __parent = static_cast<__parent_pointer>(__nd);
1946 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001947 }
1948 }
1949 }
1950 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00001951 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001952 return __parent->__left_;
1953}
1954
1955// Find leaf place to insert closest to __hint
1956// First check prior to __hint.
1957// Next check after __hint.
1958// Next do O(log N) search.
1959// Set __parent to parent of null leaf
1960// Return reference to null leaf
1961template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001962typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001963__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001964 __parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001965 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001966{
1967 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1968 {
1969 // __v <= *__hint
1970 const_iterator __prior = __hint;
1971 if (__prior == begin() || !value_comp()(__v, *--__prior))
1972 {
1973 // *prev(__hint) <= __v <= *__hint
1974 if (__hint.__ptr_->__left_ == nullptr)
1975 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001976 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001977 return __parent->__left_;
1978 }
1979 else
1980 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001981 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
1982 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001983 }
1984 }
1985 // __v < *prev(__hint)
1986 return __find_leaf_high(__parent, __v);
1987 }
1988 // else __v > *__hint
1989 return __find_leaf_low(__parent, __v);
1990}
1991
1992// Find place to insert if __v doesn't exist
1993// Set __parent to parent of null leaf
1994// Return reference to null leaf
1995// If __v exists, set parent to node of __v and return reference to node of __v
1996template <class _Tp, class _Compare, class _Allocator>
1997template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001998typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1999__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002000 const _Key& __v)
2001{
2002 __node_pointer __nd = __root();
Eric Fiselier7310ec82016-07-19 17:56:20 +00002003 __node_base_pointer* __nd_ptr = __root_ptr();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002004 if (__nd != nullptr)
2005 {
2006 while (true)
2007 {
2008 if (value_comp()(__v, __nd->__value_))
2009 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002010 if (__nd->__left_ != nullptr) {
2011 __nd_ptr = _VSTD::addressof(__nd->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002012 __nd = static_cast<__node_pointer>(__nd->__left_);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002013 } else {
2014 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002015 return __parent->__left_;
2016 }
2017 }
2018 else if (value_comp()(__nd->__value_, __v))
2019 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002020 if (__nd->__right_ != nullptr) {
2021 __nd_ptr = _VSTD::addressof(__nd->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002022 __nd = static_cast<__node_pointer>(__nd->__right_);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002023 } else {
2024 __parent = static_cast<__parent_pointer>(__nd);
2025 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002026 }
2027 }
2028 else
2029 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002030 __parent = static_cast<__parent_pointer>(__nd);
2031 return *__nd_ptr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002032 }
2033 }
2034 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00002035 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002036 return __parent->__left_;
2037}
2038
2039// Find place to insert if __v doesn't exist
2040// First check prior to __hint.
2041// Next check after __hint.
2042// Next do O(log N) search.
2043// Set __parent to parent of null leaf
2044// Return reference to null leaf
2045// If __v exists, set parent to node of __v and return reference to node of __v
2046template <class _Tp, class _Compare, class _Allocator>
2047template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00002048typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002049__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002050 __parent_pointer& __parent,
2051 __node_base_pointer& __dummy,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002052 const _Key& __v)
2053{
2054 if (__hint == end() || value_comp()(__v, *__hint)) // check before
2055 {
2056 // __v < *__hint
2057 const_iterator __prior = __hint;
2058 if (__prior == begin() || value_comp()(*--__prior, __v))
2059 {
2060 // *prev(__hint) < __v < *__hint
2061 if (__hint.__ptr_->__left_ == nullptr)
2062 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002063 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002064 return __parent->__left_;
2065 }
2066 else
2067 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002068 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2069 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002070 }
2071 }
2072 // __v <= *prev(__hint)
2073 return __find_equal(__parent, __v);
2074 }
2075 else if (value_comp()(*__hint, __v)) // check after
2076 {
2077 // *__hint < __v
Howard Hinnant0949eed2011-06-30 21:18:19 +00002078 const_iterator __next = _VSTD::next(__hint);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002079 if (__next == end() || value_comp()(__v, *__next))
2080 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002081 // *__hint < __v < *_VSTD::next(__hint)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002082 if (__hint.__get_np()->__right_ == nullptr)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002083 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002084 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2085 return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002086 }
2087 else
2088 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002089 __parent = static_cast<__parent_pointer>(__next.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002090 return __parent->__left_;
2091 }
2092 }
2093 // *next(__hint) <= __v
2094 return __find_equal(__parent, __v);
2095 }
2096 // else __v == *__hint
Eric Fiselier7310ec82016-07-19 17:56:20 +00002097 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2098 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2099 return __dummy;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002100}
2101
2102template <class _Tp, class _Compare, class _Allocator>
2103void
Eric Fiselier7310ec82016-07-19 17:56:20 +00002104__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002105 __node_base_pointer& __child,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002106 __node_base_pointer __new_node)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002107{
2108 __new_node->__left_ = nullptr;
2109 __new_node->__right_ = nullptr;
2110 __new_node->__parent_ = __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002111 // __new_node->__is_black_ is initialized in __tree_balance_after_insert
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002112 __child = __new_node;
2113 if (__begin_node()->__left_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002114 __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002115 __tree_balance_after_insert(__end_node()->__left_, __child);
2116 ++size();
2117}
2118
Eric Fiselierdb215062016-03-31 02:15:15 +00002119#ifndef _LIBCPP_CXX03_LANG
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#else
2125template <class _Tp, class _Compare, class _Allocator>
2126template <class _Key, class _Args>
2127pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2128__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args)
2129#endif
2130{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002131 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002132 __node_base_pointer& __child = __find_equal(__parent, __k);
2133 __node_pointer __r = static_cast<__node_pointer>(__child);
2134 bool __inserted = false;
2135 if (__child == nullptr)
2136 {
2137#ifndef _LIBCPP_CXX03_LANG
2138 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2139#else
2140 __node_holder __h = __construct_node(__args);
2141#endif
2142 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2143 __r = __h.release();
2144 __inserted = true;
2145 }
2146 return pair<iterator, bool>(iterator(__r), __inserted);
2147}
2148
2149
2150#ifndef _LIBCPP_CXX03_LANG
2151template <class _Tp, class _Compare, class _Allocator>
2152template <class _Key, class... _Args>
2153typename __tree<_Tp, _Compare, _Allocator>::iterator
2154__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2155 const_iterator __p, _Key const& __k, _Args&&... __args)
2156#else
2157template <class _Tp, class _Compare, class _Allocator>
2158template <class _Key, class _Args>
2159typename __tree<_Tp, _Compare, _Allocator>::iterator
2160__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2161 const_iterator __p, _Key const& __k, _Args& __args)
2162#endif
2163{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002164 __parent_pointer __parent;
2165 __node_base_pointer __dummy;
2166 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
Eric Fiselierdb215062016-03-31 02:15:15 +00002167 __node_pointer __r = static_cast<__node_pointer>(__child);
2168 if (__child == nullptr)
2169 {
2170#ifndef _LIBCPP_CXX03_LANG
2171 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2172#else
2173 __node_holder __h = __construct_node(__args);
2174#endif
2175 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2176 __r = __h.release();
2177 }
2178 return iterator(__r);
2179}
2180
2181
2182#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002183
2184template <class _Tp, class _Compare, class _Allocator>
2185template <class ..._Args>
2186typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2187__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
2188{
Eric Fiselierdb215062016-03-31 02:15:15 +00002189 static_assert(!__is_tree_value_type<_Args...>::value,
2190 "Cannot construct from __value_type");
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002191 __node_allocator& __na = __node_alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00002192 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierdb215062016-03-31 02:15:15 +00002193 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002194 __h.get_deleter().__value_constructed = true;
2195 return __h;
2196}
2197
Eric Fiselierdb215062016-03-31 02:15:15 +00002198
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002199template <class _Tp, class _Compare, class _Allocator>
2200template <class... _Args>
2201pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00002202__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002203{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002204 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002205 __parent_pointer __parent;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002206 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
2207 __node_pointer __r = static_cast<__node_pointer>(__child);
2208 bool __inserted = false;
2209 if (__child == nullptr)
2210 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002211 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002212 __r = __h.release();
2213 __inserted = true;
2214 }
2215 return pair<iterator, bool>(iterator(__r), __inserted);
2216}
2217
2218template <class _Tp, class _Compare, class _Allocator>
2219template <class... _Args>
2220typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselier83c9dc12016-04-15 23:27:27 +00002221__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002222{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002223 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002224 __parent_pointer __parent;
2225 __node_base_pointer __dummy;
2226 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002227 __node_pointer __r = static_cast<__node_pointer>(__child);
2228 if (__child == nullptr)
2229 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002230 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002231 __r = __h.release();
2232 }
2233 return iterator(__r);
2234}
2235
2236template <class _Tp, class _Compare, class _Allocator>
2237template <class... _Args>
2238typename __tree<_Tp, _Compare, _Allocator>::iterator
2239__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
2240{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002241 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002242 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002243 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002244 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002245 return iterator(static_cast<__node_pointer>(__h.release()));
2246}
2247
2248template <class _Tp, class _Compare, class _Allocator>
2249template <class... _Args>
2250typename __tree<_Tp, _Compare, _Allocator>::iterator
2251__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
2252 _Args&&... __args)
2253{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002254 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002255 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002256 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002257 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002258 return iterator(static_cast<__node_pointer>(__h.release()));
2259}
2260
Howard Hinnant73d21a42010-09-04 23:28:19 +00002261
Eric Fiselierdb215062016-03-31 02:15:15 +00002262#else // _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002263
2264template <class _Tp, class _Compare, class _Allocator>
2265typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Eric Fiselierdb215062016-03-31 02:15:15 +00002266__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002267{
2268 __node_allocator& __na = __node_alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00002269 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierdb215062016-03-31 02:15:15 +00002270 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002271 __h.get_deleter().__value_constructed = true;
Dimitry Andric89663502015-08-19 06:43:33 +00002272 return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002273}
2274
Eric Fiselierdb215062016-03-31 02:15:15 +00002275#endif // _LIBCPP_CXX03_LANG
Howard Hinnantd0a2fbf2011-03-10 17:27:57 +00002276
Eric Fiselierdb215062016-03-31 02:15:15 +00002277#ifdef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002278template <class _Tp, class _Compare, class _Allocator>
2279typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierdb215062016-03-31 02:15:15 +00002280__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002281{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002282 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002283 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002284 __node_holder __h = __construct_node(__v);
Howard Hinnant70342b92013-06-19 21:29:40 +00002285 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002286 return iterator(__h.release());
2287}
2288
2289template <class _Tp, class _Compare, class _Allocator>
2290typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierdb215062016-03-31 02:15:15 +00002291__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002292{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002293 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002294 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002295 __node_holder __h = __construct_node(__v);
Howard Hinnant70342b92013-06-19 21:29:40 +00002296 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002297 return iterator(__h.release());
2298}
Eric Fiselierdb215062016-03-31 02:15:15 +00002299#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002300
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002301template <class _Tp, class _Compare, class _Allocator>
2302pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2303__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
2304{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002305 __parent_pointer __parent;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002306 __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
2307 __node_pointer __r = static_cast<__node_pointer>(__child);
2308 bool __inserted = false;
2309 if (__child == nullptr)
2310 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002311 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002312 __r = __nd;
2313 __inserted = true;
2314 }
2315 return pair<iterator, bool>(iterator(__r), __inserted);
2316}
2317
2318template <class _Tp, class _Compare, class _Allocator>
2319typename __tree<_Tp, _Compare, _Allocator>::iterator
2320__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
2321 __node_pointer __nd)
2322{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002323 __parent_pointer __parent;
2324 __node_base_pointer __dummy;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002325 __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
2326 __node_pointer __r = static_cast<__node_pointer>(__child);
2327 if (__child == nullptr)
2328 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002329 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002330 __r = __nd;
2331 }
2332 return iterator(__r);
2333}
2334
2335template <class _Tp, class _Compare, class _Allocator>
2336typename __tree<_Tp, _Compare, _Allocator>::iterator
2337__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
2338{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002339 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002340 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002341 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002342 return iterator(__nd);
2343}
2344
2345template <class _Tp, class _Compare, class _Allocator>
2346typename __tree<_Tp, _Compare, _Allocator>::iterator
2347__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
2348 __node_pointer __nd)
2349{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002350 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002351 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002352 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002353 return iterator(__nd);
2354}
2355
2356template <class _Tp, class _Compare, class _Allocator>
2357typename __tree<_Tp, _Compare, _Allocator>::iterator
2358__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
2359{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002360 __node_pointer __np = __p.__get_np();
2361 iterator __r(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002362 ++__r;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002363 if (__begin_node() == __p.__ptr_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002364 __begin_node() = __r.__ptr_;
2365 --size();
2366 __node_allocator& __na = __node_alloc();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002367 __tree_remove(__end_node()->__left_,
2368 static_cast<__node_base_pointer>(__np));
Eric Fiselierdb215062016-03-31 02:15:15 +00002369 __node_traits::destroy(__na, _NodeTypes::__get_ptr(
2370 const_cast<__node_value_type&>(*__p)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002371 __node_traits::deallocate(__na, __np, 1);
2372 return __r;
2373}
2374
2375template <class _Tp, class _Compare, class _Allocator>
2376typename __tree<_Tp, _Compare, _Allocator>::iterator
2377__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
2378{
2379 while (__f != __l)
2380 __f = erase(__f);
Howard Hinnant70342b92013-06-19 21:29:40 +00002381 return iterator(__l.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002382}
2383
2384template <class _Tp, class _Compare, class _Allocator>
2385template <class _Key>
2386typename __tree<_Tp, _Compare, _Allocator>::size_type
2387__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
2388{
2389 iterator __i = find(__k);
2390 if (__i == end())
2391 return 0;
2392 erase(__i);
2393 return 1;
2394}
2395
2396template <class _Tp, class _Compare, class _Allocator>
2397template <class _Key>
2398typename __tree<_Tp, _Compare, _Allocator>::size_type
2399__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
2400{
2401 pair<iterator, iterator> __p = __equal_range_multi(__k);
2402 size_type __r = 0;
2403 for (; __p.first != __p.second; ++__r)
2404 __p.first = erase(__p.first);
2405 return __r;
2406}
2407
2408template <class _Tp, class _Compare, class _Allocator>
2409template <class _Key>
2410typename __tree<_Tp, _Compare, _Allocator>::iterator
2411__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
2412{
2413 iterator __p = __lower_bound(__v, __root(), __end_node());
2414 if (__p != end() && !value_comp()(__v, *__p))
2415 return __p;
2416 return end();
2417}
2418
2419template <class _Tp, class _Compare, class _Allocator>
2420template <class _Key>
2421typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2422__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
2423{
2424 const_iterator __p = __lower_bound(__v, __root(), __end_node());
2425 if (__p != end() && !value_comp()(__v, *__p))
2426 return __p;
2427 return end();
2428}
2429
2430template <class _Tp, class _Compare, class _Allocator>
2431template <class _Key>
2432typename __tree<_Tp, _Compare, _Allocator>::size_type
2433__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
2434{
Eric Fiselier227b47c2016-02-20 07:12:17 +00002435 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002436 while (__rt != nullptr)
2437 {
2438 if (value_comp()(__k, __rt->__value_))
2439 {
Eric Fiselier227b47c2016-02-20 07:12:17 +00002440 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002441 }
2442 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002443 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002444 else
2445 return 1;
2446 }
2447 return 0;
2448}
2449
2450template <class _Tp, class _Compare, class _Allocator>
2451template <class _Key>
2452typename __tree<_Tp, _Compare, _Allocator>::size_type
2453__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
2454{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002455 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002456 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002457 while (__rt != nullptr)
2458 {
2459 if (value_comp()(__k, __rt->__value_))
2460 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002461 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002462 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002463 }
2464 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002465 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002466 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00002467 return _VSTD::distance(
Eric Fiselier7310ec82016-07-19 17:56:20 +00002468 __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiselier227b47c2016-02-20 07:12:17 +00002469 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002470 );
2471 }
2472 return 0;
2473}
2474
2475template <class _Tp, class _Compare, class _Allocator>
2476template <class _Key>
2477typename __tree<_Tp, _Compare, _Allocator>::iterator
2478__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2479 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002480 __iter_pointer __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002481{
2482 while (__root != nullptr)
2483 {
2484 if (!value_comp()(__root->__value_, __v))
2485 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002486 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002487 __root = static_cast<__node_pointer>(__root->__left_);
2488 }
2489 else
2490 __root = static_cast<__node_pointer>(__root->__right_);
2491 }
2492 return iterator(__result);
2493}
2494
2495template <class _Tp, class _Compare, class _Allocator>
2496template <class _Key>
2497typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2498__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00002499 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002500 __iter_pointer __result) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002501{
2502 while (__root != nullptr)
2503 {
2504 if (!value_comp()(__root->__value_, __v))
2505 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002506 __result = static_cast<__iter_pointer>(__root);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002507 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002508 }
2509 else
Eric Fiselier227b47c2016-02-20 07:12:17 +00002510 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002511 }
2512 return const_iterator(__result);
2513}
2514
2515template <class _Tp, class _Compare, class _Allocator>
2516template <class _Key>
2517typename __tree<_Tp, _Compare, _Allocator>::iterator
2518__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2519 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002520 __iter_pointer __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002521{
2522 while (__root != nullptr)
2523 {
2524 if (value_comp()(__v, __root->__value_))
2525 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002526 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002527 __root = static_cast<__node_pointer>(__root->__left_);
2528 }
2529 else
2530 __root = static_cast<__node_pointer>(__root->__right_);
2531 }
2532 return iterator(__result);
2533}
2534
2535template <class _Tp, class _Compare, class _Allocator>
2536template <class _Key>
2537typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2538__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00002539 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002540 __iter_pointer __result) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002541{
2542 while (__root != nullptr)
2543 {
2544 if (value_comp()(__v, __root->__value_))
2545 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002546 __result = static_cast<__iter_pointer>(__root);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002547 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002548 }
2549 else
Eric Fiselier227b47c2016-02-20 07:12:17 +00002550 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002551 }
2552 return const_iterator(__result);
2553}
2554
2555template <class _Tp, class _Compare, class _Allocator>
2556template <class _Key>
2557pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2558 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2559__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2560{
Howard Hinnant99968442011-11-29 18:15:50 +00002561 typedef pair<iterator, iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002562 __iter_pointer __result = __end_node();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002563 __node_pointer __rt = __root();
2564 while (__rt != nullptr)
2565 {
2566 if (value_comp()(__k, __rt->__value_))
2567 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002568 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002569 __rt = static_cast<__node_pointer>(__rt->__left_);
2570 }
2571 else if (value_comp()(__rt->__value_, __k))
2572 __rt = static_cast<__node_pointer>(__rt->__right_);
2573 else
Howard Hinnant99968442011-11-29 18:15:50 +00002574 return _Pp(iterator(__rt),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002575 iterator(
2576 __rt->__right_ != nullptr ?
Eric Fiselier7310ec82016-07-19 17:56:20 +00002577 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002578 : __result));
2579 }
Howard Hinnant99968442011-11-29 18:15:50 +00002580 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002581}
2582
2583template <class _Tp, class _Compare, class _Allocator>
2584template <class _Key>
2585pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2586 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2587__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2588{
Howard Hinnant99968442011-11-29 18:15:50 +00002589 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002590 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002591 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002592 while (__rt != nullptr)
2593 {
2594 if (value_comp()(__k, __rt->__value_))
2595 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002596 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002597 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002598 }
2599 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002600 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002601 else
Howard Hinnant99968442011-11-29 18:15:50 +00002602 return _Pp(const_iterator(__rt),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002603 const_iterator(
2604 __rt->__right_ != nullptr ?
Eric Fiselier7310ec82016-07-19 17:56:20 +00002605 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002606 : __result));
2607 }
Howard Hinnant99968442011-11-29 18:15:50 +00002608 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002609}
2610
2611template <class _Tp, class _Compare, class _Allocator>
2612template <class _Key>
2613pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2614 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2615__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2616{
Howard Hinnant99968442011-11-29 18:15:50 +00002617 typedef pair<iterator, iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002618 __iter_pointer __result = __end_node();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002619 __node_pointer __rt = __root();
2620 while (__rt != nullptr)
2621 {
2622 if (value_comp()(__k, __rt->__value_))
2623 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002624 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002625 __rt = static_cast<__node_pointer>(__rt->__left_);
2626 }
2627 else if (value_comp()(__rt->__value_, __k))
2628 __rt = static_cast<__node_pointer>(__rt->__right_);
2629 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002630 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002631 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2632 }
Howard Hinnant99968442011-11-29 18:15:50 +00002633 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002634}
2635
2636template <class _Tp, class _Compare, class _Allocator>
2637template <class _Key>
2638pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2639 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2640__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2641{
Howard Hinnant99968442011-11-29 18:15:50 +00002642 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002643 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002644 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002645 while (__rt != nullptr)
2646 {
2647 if (value_comp()(__k, __rt->__value_))
2648 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002649 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002650 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002651 }
2652 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002653 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002654 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002655 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiselier227b47c2016-02-20 07:12:17 +00002656 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002657 }
Howard Hinnant99968442011-11-29 18:15:50 +00002658 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002659}
2660
2661template <class _Tp, class _Compare, class _Allocator>
2662typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Howard Hinnant8b537682011-06-04 17:10:24 +00002663__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002664{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002665 __node_pointer __np = __p.__get_np();
2666 if (__begin_node() == __p.__ptr_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002667 {
2668 if (__np->__right_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002669 __begin_node() = static_cast<__iter_pointer>(__np->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002670 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002671 __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002672 }
2673 --size();
2674 __tree_remove(__end_node()->__left_,
2675 static_cast<__node_base_pointer>(__np));
Marshall Clow01c1c6f2015-01-28 19:54:25 +00002676 return __node_holder(__np, _Dp(__node_alloc(), true));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002677}
2678
Howard Hinnant7686add2011-06-04 14:31:57 +00002679template <class _Tp, class _Compare, class _Allocator>
2680inline _LIBCPP_INLINE_VISIBILITY
2681void
2682swap(__tree<_Tp, _Compare, _Allocator>& __x,
2683 __tree<_Tp, _Compare, _Allocator>& __y)
2684 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2685{
2686 __x.swap(__y);
2687}
2688
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002689_LIBCPP_END_NAMESPACE_STD
2690
2691#endif // _LIBCPP___TREE