blob: 6771589bbc6880bffba15cd8f9faeb3ceab000de [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
Eric Fiselierb1b1dcf2017-02-04 20:27:46 +000020#include <__undef_min_max>
21
Howard Hinnant08e17472011-10-17 20:05:10 +000022#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000023#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000024#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000025
26_LIBCPP_BEGIN_NAMESPACE_STD
27
Howard Hinnant2b1b2d42011-06-14 19:58:17 +000028template <class _Tp, class _Compare, class _Allocator> class __tree;
29template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +000030 class _LIBCPP_TEMPLATE_VIS __tree_iterator;
Howard Hinnant2b1b2d42011-06-14 19:58:17 +000031template <class _Tp, class _ConstNodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +000032 class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000033
Eric Fiselier55263482016-02-20 05:28:30 +000034template <class _Pointer> class __tree_end_node;
35template <class _VoidPtr> class __tree_node_base;
36template <class _Tp, class _VoidPtr> class __tree_node;
37
38#ifndef _LIBCPP_CXX03_LANG
39template <class _Key, class _Value>
40union __value_type;
41#else
42template <class _Key, class _Value>
43struct __value_type;
44#endif
45
Eric Fiselierebaf7da2017-01-13 22:02:08 +000046template <class _Key, class _CP, class _Compare,
47 bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
48class __map_value_compare;
49
Eric Fiselier55263482016-02-20 05:28:30 +000050template <class _Allocator> class __map_node_destructor;
Eric Fiselierc3589a82017-01-04 23:56:00 +000051template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
52template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiselier55263482016-02-20 05:28:30 +000053
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000054/*
55
56_NodePtr algorithms
57
58The algorithms taking _NodePtr are red black tree algorithms. Those
59algorithms taking a parameter named __root should assume that __root
60points to a proper red black tree (unless otherwise specified).
61
62Each algorithm herein assumes that __root->__parent_ points to a non-null
63structure which has a member __left_ which points back to __root. No other
64member is read or written to at __root->__parent_.
65
66__root->__parent_ will be referred to below (in comments only) as end_node.
67end_node->__left_ is an externably accessible lvalue for __root, and can be
68changed by node insertion and removal (without explicit reference to end_node).
69
70All nodes (with the exception of end_node), even the node referred to as
71__root, have a non-null __parent_ field.
72
73*/
74
75// Returns: true if __x is a left child of its parent, else false
76// Precondition: __x != nullptr.
77template <class _NodePtr>
Howard Hinnant333f50d2010-09-21 20:16:37 +000078inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000079bool
Howard Hinnant8b537682011-06-04 17:10:24 +000080__tree_is_left_child(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000081{
82 return __x == __x->__parent_->__left_;
83}
84
85// Determintes if the subtree rooted at __x is a proper red black subtree. If
86// __x is a proper subtree, returns the black height (null counts as 1). If
87// __x is an improper subtree, returns 0.
88template <class _NodePtr>
89unsigned
90__tree_sub_invariant(_NodePtr __x)
91{
92 if (__x == nullptr)
93 return 1;
94 // parent consistency checked by caller
95 // check __x->__left_ consistency
96 if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
97 return 0;
98 // check __x->__right_ consistency
99 if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
100 return 0;
101 // check __x->__left_ != __x->__right_ unless both are nullptr
102 if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
103 return 0;
104 // If this is red, neither child can be red
105 if (!__x->__is_black_)
106 {
107 if (__x->__left_ && !__x->__left_->__is_black_)
108 return 0;
109 if (__x->__right_ && !__x->__right_->__is_black_)
110 return 0;
111 }
112 unsigned __h = __tree_sub_invariant(__x->__left_);
113 if (__h == 0)
114 return 0; // invalid left subtree
115 if (__h != __tree_sub_invariant(__x->__right_))
116 return 0; // invalid or different height right subtree
117 return __h + __x->__is_black_; // return black height of this node
118}
119
120// Determintes if the red black tree rooted at __root is a proper red black tree.
121// __root == nullptr is a proper tree. Returns true is __root is a proper
122// red black tree, else returns false.
123template <class _NodePtr>
124bool
125__tree_invariant(_NodePtr __root)
126{
127 if (__root == nullptr)
128 return true;
129 // check __x->__parent_ consistency
130 if (__root->__parent_ == nullptr)
131 return false;
132 if (!__tree_is_left_child(__root))
133 return false;
134 // root must be black
135 if (!__root->__is_black_)
136 return false;
137 // do normal node checks
138 return __tree_sub_invariant(__root) != 0;
139}
140
141// Returns: pointer to the left-most node under __x.
142// Precondition: __x != nullptr.
143template <class _NodePtr>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000144inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000146__tree_min(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147{
148 while (__x->__left_ != nullptr)
149 __x = __x->__left_;
150 return __x;
151}
152
153// Returns: pointer to the right-most node under __x.
154// Precondition: __x != nullptr.
155template <class _NodePtr>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000156inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000157_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000158__tree_max(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000159{
160 while (__x->__right_ != nullptr)
161 __x = __x->__right_;
162 return __x;
163}
164
165// Returns: pointer to the next in-order node after __x.
166// Precondition: __x != nullptr.
167template <class _NodePtr>
168_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000169__tree_next(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000170{
171 if (__x->__right_ != nullptr)
172 return __tree_min(__x->__right_);
173 while (!__tree_is_left_child(__x))
Eric Fiselier7310ec82016-07-19 17:56:20 +0000174 __x = __x->__parent_unsafe();
175 return __x->__parent_unsafe();
176}
177
178template <class _EndNodePtr, class _NodePtr>
179inline _LIBCPP_INLINE_VISIBILITY
180_EndNodePtr
181__tree_next_iter(_NodePtr __x) _NOEXCEPT
182{
183 if (__x->__right_ != nullptr)
184 return static_cast<_EndNodePtr>(__tree_min(__x->__right_));
185 while (!__tree_is_left_child(__x))
186 __x = __x->__parent_unsafe();
187 return static_cast<_EndNodePtr>(__x->__parent_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000188}
189
190// Returns: pointer to the previous in-order node before __x.
191// Precondition: __x != nullptr.
Eric Fiselier7310ec82016-07-19 17:56:20 +0000192// Note: __x may be the end node.
193template <class _NodePtr, class _EndNodePtr>
194inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000195_NodePtr
Eric Fiselier7310ec82016-07-19 17:56:20 +0000196__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000197{
198 if (__x->__left_ != nullptr)
199 return __tree_max(__x->__left_);
Eric Fiselier7310ec82016-07-19 17:56:20 +0000200 _NodePtr __xx = static_cast<_NodePtr>(__x);
201 while (__tree_is_left_child(__xx))
202 __xx = __xx->__parent_unsafe();
203 return __xx->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000204}
205
206// Returns: pointer to a node which has no children
207// Precondition: __x != nullptr.
208template <class _NodePtr>
209_NodePtr
Howard Hinnant8b537682011-06-04 17:10:24 +0000210__tree_leaf(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000211{
212 while (true)
213 {
214 if (__x->__left_ != nullptr)
215 {
216 __x = __x->__left_;
217 continue;
218 }
219 if (__x->__right_ != nullptr)
220 {
221 __x = __x->__right_;
222 continue;
223 }
224 break;
225 }
226 return __x;
227}
228
229// Effects: Makes __x->__right_ the subtree root with __x as its left child
230// while preserving in-order order.
231// Precondition: __x->__right_ != nullptr
232template <class _NodePtr>
233void
Howard Hinnant8b537682011-06-04 17:10:24 +0000234__tree_left_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000235{
236 _NodePtr __y = __x->__right_;
237 __x->__right_ = __y->__left_;
238 if (__x->__right_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000239 __x->__right_->__set_parent(__x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000240 __y->__parent_ = __x->__parent_;
241 if (__tree_is_left_child(__x))
242 __x->__parent_->__left_ = __y;
243 else
Eric Fiselier7310ec82016-07-19 17:56:20 +0000244 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000245 __y->__left_ = __x;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000246 __x->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000247}
248
249// Effects: Makes __x->__left_ the subtree root with __x as its right child
250// while preserving in-order order.
251// Precondition: __x->__left_ != nullptr
252template <class _NodePtr>
253void
Howard Hinnant8b537682011-06-04 17:10:24 +0000254__tree_right_rotate(_NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000255{
256 _NodePtr __y = __x->__left_;
257 __x->__left_ = __y->__right_;
258 if (__x->__left_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000259 __x->__left_->__set_parent(__x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000260 __y->__parent_ = __x->__parent_;
261 if (__tree_is_left_child(__x))
262 __x->__parent_->__left_ = __y;
263 else
Eric Fiselier7310ec82016-07-19 17:56:20 +0000264 __x->__parent_unsafe()->__right_ = __y;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265 __y->__right_ = __x;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000266 __x->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000267}
268
269// Effects: Rebalances __root after attaching __x to a leaf.
270// Precondition: __root != nulptr && __x != nullptr.
271// __x has no children.
272// __x == __root or == a direct or indirect child of __root.
273// If __x were to be unlinked from __root (setting __root to
274// nullptr if __root == __x), __tree_invariant(__root) == true.
275// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_
276// may be different than the value passed in as __root.
277template <class _NodePtr>
278void
Howard Hinnant8b537682011-06-04 17:10:24 +0000279__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000280{
281 __x->__is_black_ = __x == __root;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000282 while (__x != __root && !__x->__parent_unsafe()->__is_black_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000283 {
284 // __x->__parent_ != __root because __x->__parent_->__is_black == false
Eric Fiselier7310ec82016-07-19 17:56:20 +0000285 if (__tree_is_left_child(__x->__parent_unsafe()))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000286 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000287 _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000288 if (__y != nullptr && !__y->__is_black_)
289 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000290 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000291 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000292 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000293 __x->__is_black_ = __x == __root;
294 __y->__is_black_ = true;
295 }
296 else
297 {
298 if (!__tree_is_left_child(__x))
299 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000300 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000301 __tree_left_rotate(__x);
302 }
Eric Fiselier7310ec82016-07-19 17:56:20 +0000303 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000304 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000305 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000306 __x->__is_black_ = false;
307 __tree_right_rotate(__x);
308 break;
309 }
310 }
311 else
312 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000313 _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000314 if (__y != nullptr && !__y->__is_black_)
315 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000316 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000318 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000319 __x->__is_black_ = __x == __root;
320 __y->__is_black_ = true;
321 }
322 else
323 {
324 if (__tree_is_left_child(__x))
325 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000326 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000327 __tree_right_rotate(__x);
328 }
Eric Fiselier7310ec82016-07-19 17:56:20 +0000329 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 __x->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000331 __x = __x->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000332 __x->__is_black_ = false;
333 __tree_left_rotate(__x);
334 break;
335 }
336 }
337 }
338}
339
340// Precondition: __root != nullptr && __z != nullptr.
341// __tree_invariant(__root) == true.
342// __z == __root or == a direct or indirect child of __root.
343// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed.
344// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
345// nor any of its children refer to __z. end_node->__left_
346// may be different than the value passed in as __root.
347template <class _NodePtr>
348void
Howard Hinnant8b537682011-06-04 17:10:24 +0000349__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000350{
351 // __z will be removed from the tree. Client still needs to destruct/deallocate it
352 // __y is either __z, or if __z has two children, __tree_next(__z).
353 // __y will have at most one child.
354 // __y will be the initial hole in the tree (make the hole at a leaf)
355 _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
356 __z : __tree_next(__z);
357 // __x is __y's possibly null single child
358 _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
359 // __w is __x's possibly null uncle (will become __x's sibling)
360 _NodePtr __w = nullptr;
361 // link __x to __y's parent, and find __w
362 if (__x != nullptr)
363 __x->__parent_ = __y->__parent_;
364 if (__tree_is_left_child(__y))
365 {
366 __y->__parent_->__left_ = __x;
367 if (__y != __root)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000368 __w = __y->__parent_unsafe()->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000369 else
370 __root = __x; // __w == nullptr
371 }
372 else
373 {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000374 __y->__parent_unsafe()->__right_ = __x;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000375 // __y can't be root if it is a right child
376 __w = __y->__parent_->__left_;
377 }
378 bool __removed_black = __y->__is_black_;
379 // If we didn't remove __z, do so now by splicing in __y for __z,
380 // but copy __z's color. This does not impact __x or __w.
381 if (__y != __z)
382 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000383 // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000384 __y->__parent_ = __z->__parent_;
385 if (__tree_is_left_child(__z))
386 __y->__parent_->__left_ = __y;
387 else
Eric Fiselier7310ec82016-07-19 17:56:20 +0000388 __y->__parent_unsafe()->__right_ = __y;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000389 __y->__left_ = __z->__left_;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000390 __y->__left_->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000391 __y->__right_ = __z->__right_;
392 if (__y->__right_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +0000393 __y->__right_->__set_parent(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000394 __y->__is_black_ = __z->__is_black_;
395 if (__root == __z)
396 __root = __y;
397 }
398 // There is no need to rebalance if we removed a red, or if we removed
399 // the last node.
400 if (__removed_black && __root != nullptr)
401 {
402 // Rebalance:
403 // __x has an implicit black color (transferred from the removed __y)
404 // associated with it, no matter what its color is.
405 // If __x is __root (in which case it can't be null), it is supposed
406 // to be black anyway, and if it is doubly black, then the double
407 // can just be ignored.
408 // If __x is red (in which case it can't be null), then it can absorb
409 // the implicit black just by setting its color to black.
410 // Since __y was black and only had one child (which __x points to), __x
411 // is either red with no children, else null, otherwise __y would have
412 // different black heights under left and right pointers.
413 // if (__x == __root || __x != nullptr && !__x->__is_black_)
414 if (__x != nullptr)
415 __x->__is_black_ = true;
416 else
417 {
418 // Else __x isn't root, and is "doubly black", even though it may
419 // be null. __w can not be null here, else the parent would
420 // see a black height >= 2 on the __x side and a black height
421 // of 1 on the __w side (__w must be a non-null black or a red
422 // with a non-null black child).
423 while (true)
424 {
425 if (!__tree_is_left_child(__w)) // if x is left child
426 {
427 if (!__w->__is_black_)
428 {
429 __w->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000430 __w->__parent_unsafe()->__is_black_ = false;
431 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432 // __x is still valid
433 // reset __root only if necessary
434 if (__root == __w->__left_)
435 __root = __w;
436 // reset sibling, and it still can't be null
437 __w = __w->__left_->__right_;
438 }
439 // __w->__is_black_ is now true, __w may have null children
440 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
441 (__w->__right_ == nullptr || __w->__right_->__is_black_))
442 {
443 __w->__is_black_ = false;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000444 __x = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000445 // __x can no longer be null
446 if (__x == __root || !__x->__is_black_)
447 {
448 __x->__is_black_ = true;
449 break;
450 }
451 // reset sibling, and it still can't be null
452 __w = __tree_is_left_child(__x) ?
Eric Fiselier7310ec82016-07-19 17:56:20 +0000453 __x->__parent_unsafe()->__right_ :
Howard Hinnant324bb032010-08-22 00:02:43 +0000454 __x->__parent_->__left_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000455 // continue;
456 }
457 else // __w has a red child
458 {
459 if (__w->__right_ == nullptr || __w->__right_->__is_black_)
460 {
461 // __w left child is non-null and red
462 __w->__left_->__is_black_ = true;
463 __w->__is_black_ = false;
464 __tree_right_rotate(__w);
465 // __w is known not to be root, so root hasn't changed
466 // reset sibling, and it still can't be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000467 __w = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000468 }
469 // __w has a right red child, left child may be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000470 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
471 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000472 __w->__right_->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000473 __tree_left_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000474 break;
475 }
476 }
477 else
478 {
479 if (!__w->__is_black_)
480 {
481 __w->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000482 __w->__parent_unsafe()->__is_black_ = false;
483 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000484 // __x is still valid
485 // reset __root only if necessary
486 if (__root == __w->__right_)
487 __root = __w;
488 // reset sibling, and it still can't be null
489 __w = __w->__right_->__left_;
490 }
491 // __w->__is_black_ is now true, __w may have null children
492 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
493 (__w->__right_ == nullptr || __w->__right_->__is_black_))
494 {
495 __w->__is_black_ = false;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000496 __x = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000497 // __x can no longer be null
498 if (!__x->__is_black_ || __x == __root)
499 {
500 __x->__is_black_ = true;
501 break;
502 }
503 // reset sibling, and it still can't be null
504 __w = __tree_is_left_child(__x) ?
Eric Fiselier7310ec82016-07-19 17:56:20 +0000505 __x->__parent_unsafe()->__right_ :
Howard Hinnant324bb032010-08-22 00:02:43 +0000506 __x->__parent_->__left_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000507 // continue;
508 }
509 else // __w has a red child
510 {
511 if (__w->__left_ == nullptr || __w->__left_->__is_black_)
512 {
513 // __w right child is non-null and red
514 __w->__right_->__is_black_ = true;
515 __w->__is_black_ = false;
516 __tree_left_rotate(__w);
517 // __w is known not to be root, so root hasn't changed
518 // reset sibling, and it still can't be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000519 __w = __w->__parent_unsafe();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000520 }
521 // __w has a left red child, right child may be null
Eric Fiselier7310ec82016-07-19 17:56:20 +0000522 __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
523 __w->__parent_unsafe()->__is_black_ = true;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000524 __w->__left_->__is_black_ = true;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000525 __tree_right_rotate(__w->__parent_unsafe());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000526 break;
527 }
528 }
529 }
530 }
531 }
532}
533
Eric Fiselier55263482016-02-20 05:28:30 +0000534// node traits
535
Eric Fiselierdb215062016-03-31 02:15:15 +0000536
537#ifndef _LIBCPP_CXX03_LANG
538template <class _Tp>
539struct __is_tree_value_type_imp : false_type {};
540
541template <class _Key, class _Value>
542struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {};
543
544template <class ..._Args>
545struct __is_tree_value_type : false_type {};
546
547template <class _One>
548struct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {};
549#endif
550
Eric Fiselier55263482016-02-20 05:28:30 +0000551template <class _Tp>
552struct __tree_key_value_types {
553 typedef _Tp key_type;
554 typedef _Tp __node_value_type;
555 typedef _Tp __container_value_type;
556 static const bool __is_map = false;
Eric Fiselierdb215062016-03-31 02:15:15 +0000557
558 _LIBCPP_INLINE_VISIBILITY
559 static key_type const& __get_key(_Tp const& __v) {
560 return __v;
561 }
562 _LIBCPP_INLINE_VISIBILITY
563 static __container_value_type const& __get_value(__node_value_type const& __v) {
564 return __v;
565 }
566 _LIBCPP_INLINE_VISIBILITY
567 static __container_value_type* __get_ptr(__node_value_type& __n) {
568 return _VSTD::addressof(__n);
569 }
570
571#ifndef _LIBCPP_CXX03_LANG
572 _LIBCPP_INLINE_VISIBILITY
573 static __container_value_type&& __move(__node_value_type& __v) {
574 return _VSTD::move(__v);
575 }
576#endif
Eric Fiselier55263482016-02-20 05:28:30 +0000577};
578
579template <class _Key, class _Tp>
580struct __tree_key_value_types<__value_type<_Key, _Tp> > {
581 typedef _Key key_type;
582 typedef _Tp mapped_type;
583 typedef __value_type<_Key, _Tp> __node_value_type;
584 typedef pair<const _Key, _Tp> __container_value_type;
585 typedef pair<_Key, _Tp> __nc_value_type;
586 typedef __container_value_type __map_value_type;
587 static const bool __is_map = true;
Eric Fiselierdb215062016-03-31 02:15:15 +0000588
589 _LIBCPP_INLINE_VISIBILITY
590 static key_type const&
591 __get_key(__node_value_type const& __t) {
592 return __t.__cc.first;
593 }
594
595 template <class _Up>
596 _LIBCPP_INLINE_VISIBILITY
597 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
598 key_type const&>::type
599 __get_key(_Up& __t) {
600 return __t.first;
601 }
602
603 _LIBCPP_INLINE_VISIBILITY
604 static __container_value_type const&
605 __get_value(__node_value_type const& __t) {
606 return __t.__cc;
607 }
608
609 template <class _Up>
610 _LIBCPP_INLINE_VISIBILITY
611 static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
612 __container_value_type const&>::type
613 __get_value(_Up& __t) {
614 return __t;
615 }
616
617 _LIBCPP_INLINE_VISIBILITY
618 static __container_value_type* __get_ptr(__node_value_type& __n) {
619 return _VSTD::addressof(__n.__cc);
620 }
621
622#ifndef _LIBCPP_CXX03_LANG
623 _LIBCPP_INLINE_VISIBILITY
624 static __nc_value_type&& __move(__node_value_type& __v) {
625 return _VSTD::move(__v.__nc);
626 }
627#endif
Eric Fiselier55263482016-02-20 05:28:30 +0000628};
629
630template <class _VoidPtr>
631struct __tree_node_base_types {
632 typedef _VoidPtr __void_pointer;
633
634 typedef __tree_node_base<__void_pointer> __node_base_type;
635 typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
636 __node_base_pointer;
637
638 typedef __tree_end_node<__node_base_pointer> __end_node_type;
639 typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
640 __end_node_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000641#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
642 typedef __end_node_pointer __parent_pointer;
643#else
644 typedef typename conditional<
645 is_pointer<__end_node_pointer>::value,
646 __end_node_pointer,
647 __node_base_pointer>::type __parent_pointer;
648#endif
649
Eric Fiselier55263482016-02-20 05:28:30 +0000650private:
651 static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
652 "_VoidPtr does not point to unqualified void type");
653};
654
655template <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>,
656 bool = _KVTypes::__is_map>
657struct __tree_map_pointer_types {};
658
659template <class _Tp, class _AllocPtr, class _KVTypes>
660struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
661 typedef typename _KVTypes::__map_value_type _Mv;
662 typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
663 __map_value_type_pointer;
664 typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
665 __const_map_value_type_pointer;
666};
667
668template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
669struct __tree_node_types;
670
671template <class _NodePtr, class _Tp, class _VoidPtr>
672struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> >
673 : public __tree_node_base_types<_VoidPtr>,
674 __tree_key_value_types<_Tp>,
675 __tree_map_pointer_types<_Tp, _VoidPtr>
676{
677 typedef __tree_node_base_types<_VoidPtr> __base;
678 typedef __tree_key_value_types<_Tp> __key_base;
679 typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base;
680public:
681
682 typedef typename pointer_traits<_NodePtr>::element_type __node_type;
683 typedef _NodePtr __node_pointer;
684
685 typedef _Tp __node_value_type;
686 typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
687 __node_value_type_pointer;
688 typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
689 __const_node_value_type_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000690#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
691 typedef typename __base::__end_node_pointer __iter_pointer;
692#else
693 typedef typename conditional<
694 is_pointer<__node_pointer>::value,
695 typename __base::__end_node_pointer,
696 __node_pointer>::type __iter_pointer;
697#endif
Eric Fiselier55263482016-02-20 05:28:30 +0000698private:
699 static_assert(!is_const<__node_type>::value,
700 "_NodePtr should never be a pointer to const");
701 static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
702 _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
703};
704
705template <class _ValueTp, class _VoidPtr>
706struct __make_tree_node_types {
707 typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
708 _NodePtr;
709 typedef __tree_node_types<_NodePtr> type;
710};
711
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000712// node
713
714template <class _Pointer>
715class __tree_end_node
716{
717public:
718 typedef _Pointer pointer;
719 pointer __left_;
720
Howard Hinnant333f50d2010-09-21 20:16:37 +0000721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8b537682011-06-04 17:10:24 +0000722 __tree_end_node() _NOEXCEPT : __left_() {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000723};
724
725template <class _VoidPtr>
726class __tree_node_base
Eric Fiselier55263482016-02-20 05:28:30 +0000727 : public __tree_node_base_types<_VoidPtr>::__end_node_type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000728{
Eric Fiselier55263482016-02-20 05:28:30 +0000729 typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
730
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000731public:
Eric Fiselier55263482016-02-20 05:28:30 +0000732 typedef typename _NodeBaseTypes::__node_base_pointer pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000733 typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000734
Eric Fiselier7310ec82016-07-19 17:56:20 +0000735 pointer __right_;
736 __parent_pointer __parent_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000737 bool __is_black_;
738
Eric Fiselier7310ec82016-07-19 17:56:20 +0000739 _LIBCPP_INLINE_VISIBILITY
740 pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
741
742 _LIBCPP_INLINE_VISIBILITY
743 void __set_parent(pointer __p) {
744 __parent_ = static_cast<__parent_pointer>(__p);
745 }
746
Eric Fiselierdb215062016-03-31 02:15:15 +0000747private:
748 ~__tree_node_base() _LIBCPP_EQUAL_DELETE;
749 __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
750 __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000751};
752
753template <class _Tp, class _VoidPtr>
754class __tree_node
755 : public __tree_node_base<_VoidPtr>
756{
757public:
Eric Fiselier55263482016-02-20 05:28:30 +0000758 typedef _Tp __node_value_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000759
Eric Fiselier55263482016-02-20 05:28:30 +0000760 __node_value_type __value_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000761
Eric Fiselierdb215062016-03-31 02:15:15 +0000762private:
763 ~__tree_node() _LIBCPP_EQUAL_DELETE;
764 __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE;
765 __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000766};
767
Eric Fiselierdb215062016-03-31 02:15:15 +0000768
769template <class _Allocator>
770class __tree_node_destructor
771{
772 typedef _Allocator allocator_type;
773 typedef allocator_traits<allocator_type> __alloc_traits;
774
775public:
776 typedef typename __alloc_traits::pointer pointer;
777private:
778 typedef __tree_node_types<pointer> _NodeTypes;
779 allocator_type& __na_;
780
781 __tree_node_destructor& operator=(const __tree_node_destructor&);
782
783public:
784 bool __value_constructed;
785
786 _LIBCPP_INLINE_VISIBILITY
787 explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
788 : __na_(__na),
789 __value_constructed(__val)
790 {}
791
792 _LIBCPP_INLINE_VISIBILITY
793 void operator()(pointer __p) _NOEXCEPT
794 {
795 if (__value_constructed)
796 __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
797 if (__p)
798 __alloc_traits::deallocate(__na_, __p, 1);
799 }
800
801 template <class> friend class __map_node_destructor;
802};
803
804
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000805template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000806class _LIBCPP_TEMPLATE_VIS __tree_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000807{
Eric Fiselier55263482016-02-20 05:28:30 +0000808 typedef __tree_node_types<_NodePtr> _NodeTypes;
809 typedef _NodePtr __node_pointer;
810 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000811 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
812 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +0000813 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000814
Eric Fiselier7310ec82016-07-19 17:56:20 +0000815 __iter_pointer __ptr_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000816
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000817public:
Eric Fiselier55263482016-02-20 05:28:30 +0000818 typedef bidirectional_iterator_tag iterator_category;
819 typedef _Tp value_type;
820 typedef _DiffType difference_type;
821 typedef value_type& reference;
822 typedef typename _NodeTypes::__node_value_type_pointer pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000823
Marshall Clow051c8482013-08-08 21:52:50 +0000824 _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
825#if _LIBCPP_STD_VER > 11
826 : __ptr_(nullptr)
827#endif
828 {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000829
Eric Fiselier7310ec82016-07-19 17:56:20 +0000830 _LIBCPP_INLINE_VISIBILITY reference operator*() const
831 {return __get_np()->__value_;}
Howard Hinnant70342b92013-06-19 21:29:40 +0000832 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier7310ec82016-07-19 17:56:20 +0000833 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000834
Howard Hinnant333f50d2010-09-21 20:16:37 +0000835 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000836 __tree_iterator& operator++() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000837 __ptr_ = static_cast<__iter_pointer>(
838 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000839 return *this;
840 }
Howard Hinnant333f50d2010-09-21 20:16:37 +0000841 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000842 __tree_iterator operator++(int)
843 {__tree_iterator __t(*this); ++(*this); return __t;}
844
Howard Hinnant333f50d2010-09-21 20:16:37 +0000845 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000846 __tree_iterator& operator--() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000847 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
848 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000849 return *this;
850 }
Howard Hinnant333f50d2010-09-21 20:16:37 +0000851 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000852 __tree_iterator operator--(int)
853 {__tree_iterator __t(*this); --(*this); return __t;}
854
Howard Hinnant333f50d2010-09-21 20:16:37 +0000855 friend _LIBCPP_INLINE_VISIBILITY
856 bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000857 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000858 friend _LIBCPP_INLINE_VISIBILITY
859 bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000860 {return !(__x == __y);}
861
862private:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000863 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +0000864 explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Eric Fiselier7310ec82016-07-19 17:56:20 +0000865 _LIBCPP_INLINE_VISIBILITY
866 explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
867 _LIBCPP_INLINE_VISIBILITY
868 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000869 template <class, class, class> friend class __tree;
Eric Fiselierc3589a82017-01-04 23:56:00 +0000870 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
871 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
872 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
873 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
874 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
875 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000876};
877
Eric Fiselier55263482016-02-20 05:28:30 +0000878template <class _Tp, class _NodePtr, class _DiffType>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000879class _LIBCPP_TEMPLATE_VIS __tree_const_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000880{
Eric Fiselier55263482016-02-20 05:28:30 +0000881 typedef __tree_node_types<_NodePtr> _NodeTypes;
882 typedef typename _NodeTypes::__node_pointer __node_pointer;
883 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000884 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
885 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +0000886 typedef pointer_traits<__node_pointer> __pointer_traits;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000887
Eric Fiselier7310ec82016-07-19 17:56:20 +0000888 __iter_pointer __ptr_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000889
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000890public:
Eric Fiselier55263482016-02-20 05:28:30 +0000891 typedef bidirectional_iterator_tag iterator_category;
892 typedef _Tp value_type;
893 typedef _DiffType difference_type;
894 typedef const value_type& reference;
895 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000896
Marshall Clow051c8482013-08-08 21:52:50 +0000897 _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
898#if _LIBCPP_STD_VER > 11
899 : __ptr_(nullptr)
900#endif
901 {}
902
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000903private:
Eric Fiselier55263482016-02-20 05:28:30 +0000904 typedef __tree_iterator<value_type, __node_pointer, difference_type>
905 __non_const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000906public:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000907 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +0000908 __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
909 : __ptr_(__p.__ptr_) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000910
Eric Fiselier7310ec82016-07-19 17:56:20 +0000911 _LIBCPP_INLINE_VISIBILITY reference operator*() const
912 {return __get_np()->__value_;}
Howard Hinnant70342b92013-06-19 21:29:40 +0000913 _LIBCPP_INLINE_VISIBILITY pointer operator->() const
Eric Fiselier7310ec82016-07-19 17:56:20 +0000914 {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000915
Howard Hinnant333f50d2010-09-21 20:16:37 +0000916 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000917 __tree_const_iterator& operator++() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000918 __ptr_ = static_cast<__iter_pointer>(
919 __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000920 return *this;
921 }
922
Howard Hinnant333f50d2010-09-21 20:16:37 +0000923 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000924 __tree_const_iterator operator++(int)
925 {__tree_const_iterator __t(*this); ++(*this); return __t;}
926
Howard Hinnant333f50d2010-09-21 20:16:37 +0000927 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000928 __tree_const_iterator& operator--() {
Eric Fiselier7310ec82016-07-19 17:56:20 +0000929 __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>(
930 static_cast<__end_node_pointer>(__ptr_)));
Eric Fiselier9c8e6632015-03-03 20:10:01 +0000931 return *this;
932 }
933
Howard Hinnant333f50d2010-09-21 20:16:37 +0000934 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000935 __tree_const_iterator operator--(int)
936 {__tree_const_iterator __t(*this); --(*this); return __t;}
937
Howard Hinnant333f50d2010-09-21 20:16:37 +0000938 friend _LIBCPP_INLINE_VISIBILITY
939 bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000940 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000941 friend _LIBCPP_INLINE_VISIBILITY
942 bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000943 {return !(__x == __y);}
944
945private:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000946 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +0000947 explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
948 : __ptr_(__p) {}
Eric Fiselier7310ec82016-07-19 17:56:20 +0000949 _LIBCPP_INLINE_VISIBILITY
950 explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
951 : __ptr_(__p) {}
952 _LIBCPP_INLINE_VISIBILITY
953 __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
954
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000955 template <class, class, class> friend class __tree;
Eric Fiselierc3589a82017-01-04 23:56:00 +0000956 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
957 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
958 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
959 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
960 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
Eric Fiselier7310ec82016-07-19 17:56:20 +0000961
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000962};
963
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000964#ifndef _LIBCPP_CXX03_LANG
965template <class _Tp, class _Compare, class _Allocator>
966struct __diagnose_tree_helper {
967 static constexpr bool __trigger_diagnostics()
Eric Fiseliereaf29202017-01-13 22:42:53 +0000968 _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000969 "the specified comparator type does not provide a const call operator")
970 { return true; }
971};
972
973template <class _Key, class _Value, class _KeyComp, class _Alloc>
974struct __diagnose_tree_helper<
975 __value_type<_Key, _Value>,
976 __map_value_compare<_Key, __value_type<_Key, _Value>, _KeyComp>,
977 _Alloc
Eric Fiseliereaf29202017-01-13 22:42:53 +0000978> : __diagnose_tree_helper<_Key, _KeyComp, _Alloc>
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000979{
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000980};
Eric Fiseliereaf29202017-01-13 22:42:53 +0000981#endif // !_LIBCPP_CXX03_LANG
Eric Fiselierebaf7da2017-01-13 22:02:08 +0000982
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000983template <class _Tp, class _Compare, class _Allocator>
984class __tree
985{
986public:
987 typedef _Tp value_type;
988 typedef _Compare value_compare;
989 typedef _Allocator allocator_type;
Eric Fiselier55263482016-02-20 05:28:30 +0000990
991private:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000992 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiselier55263482016-02-20 05:28:30 +0000993 typedef typename __make_tree_node_types<value_type,
994 typename __alloc_traits::void_pointer>::type
995 _NodeTypes;
Eric Fiselierdb215062016-03-31 02:15:15 +0000996 typedef typename _NodeTypes::key_type key_type;
Eric Fiselier55263482016-02-20 05:28:30 +0000997public:
998 typedef typename _NodeTypes::__node_value_type __node_value_type;
999 typedef typename _NodeTypes::__container_value_type __container_value_type;
1000
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001001 typedef typename __alloc_traits::pointer pointer;
1002 typedef typename __alloc_traits::const_pointer const_pointer;
1003 typedef typename __alloc_traits::size_type size_type;
1004 typedef typename __alloc_traits::difference_type difference_type;
1005
Eric Fiselier55263482016-02-20 05:28:30 +00001006public:
1007 typedef typename _NodeTypes::__void_pointer __void_pointer;
Howard Hinnant70342b92013-06-19 21:29:40 +00001008
Eric Fiselier55263482016-02-20 05:28:30 +00001009 typedef typename _NodeTypes::__node_type __node;
1010 typedef typename _NodeTypes::__node_pointer __node_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +00001011
1012 typedef typename _NodeTypes::__node_base_type __node_base;
1013 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
Eric Fiselier55263482016-02-20 05:28:30 +00001014
1015 typedef typename _NodeTypes::__end_node_type __end_node_t;
1016 typedef typename _NodeTypes::__end_node_pointer __end_node_ptr;
Eric Fiselier55263482016-02-20 05:28:30 +00001017
Eric Fiselier7310ec82016-07-19 17:56:20 +00001018 typedef typename _NodeTypes::__parent_pointer __parent_pointer;
1019 typedef typename _NodeTypes::__iter_pointer __iter_pointer;
1020
Marshall Clow66302c62015-04-07 05:21:38 +00001021 typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
Eric Fiselier55263482016-02-20 05:28:30 +00001022 typedef allocator_traits<__node_allocator> __node_traits;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001023
Eric Fiselier55263482016-02-20 05:28:30 +00001024private:
1025 // check for sane allocator pointer rebinding semantics. Rebinding the
1026 // allocator for a new pointer type should be exactly the same as rebinding
1027 // the pointer using 'pointer_traits'.
1028 static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
1029 "Allocator does not rebind pointers in a sane manner.");
1030 typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
1031 __node_base_allocator;
1032 typedef allocator_traits<__node_base_allocator> __node_base_traits;
1033 static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
1034 "Allocator does not rebind pointers in a sane manner.");
1035
1036private:
Eric Fiselier7310ec82016-07-19 17:56:20 +00001037 __iter_pointer __begin_node_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001038 __compressed_pair<__end_node_t, __node_allocator> __pair1_;
1039 __compressed_pair<size_type, value_compare> __pair3_;
1040
1041public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001042 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001043 __iter_pointer __end_node() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001044 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001045 return static_cast<__iter_pointer>(
Eric Fiselier227b47c2016-02-20 07:12:17 +00001046 pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
1047 );
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001048 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001049 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001050 __iter_pointer __end_node() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001051 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001052 return static_cast<__iter_pointer>(
Eric Fiselier227b47c2016-02-20 07:12:17 +00001053 pointer_traits<__end_node_ptr>::pointer_to(
1054 const_cast<__end_node_t&>(__pair1_.first())
1055 )
1056 );
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001057 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001059 __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001060private:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001062 const __node_allocator& __node_alloc() const _NOEXCEPT
1063 {return __pair1_.second();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001064 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001065 __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001066 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7310ec82016-07-19 17:56:20 +00001067 const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001068public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001070 allocator_type __alloc() const _NOEXCEPT
1071 {return allocator_type(__node_alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001072private:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001074 size_type& size() _NOEXCEPT {return __pair3_.first();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001075public:
Howard Hinnant333f50d2010-09-21 20:16:37 +00001076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001077 const size_type& size() const _NOEXCEPT {return __pair3_.first();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001078 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001079 value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001080 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001081 const value_compare& value_comp() const _NOEXCEPT
1082 {return __pair3_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001083public:
Eric Fiselier227b47c2016-02-20 07:12:17 +00001084
Howard Hinnant333f50d2010-09-21 20:16:37 +00001085 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier227b47c2016-02-20 07:12:17 +00001086 __node_pointer __root() const _NOEXCEPT
1087 {return static_cast<__node_pointer>(__end_node()->__left_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001088
Eric Fiselier7310ec82016-07-19 17:56:20 +00001089 __node_base_pointer* __root_ptr() const _NOEXCEPT {
1090 return _VSTD::addressof(__end_node()->__left_);
1091 }
1092
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001093 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
Howard Hinnant70342b92013-06-19 21:29:40 +00001094 typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001095
Howard Hinnant7686add2011-06-04 14:31:57 +00001096 explicit __tree(const value_compare& __comp)
1097 _NOEXCEPT_(
1098 is_nothrow_default_constructible<__node_allocator>::value &&
1099 is_nothrow_copy_constructible<value_compare>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001100 explicit __tree(const allocator_type& __a);
1101 __tree(const value_compare& __comp, const allocator_type& __a);
1102 __tree(const __tree& __t);
1103 __tree& operator=(const __tree& __t);
1104 template <class _InputIterator>
1105 void __assign_unique(_InputIterator __first, _InputIterator __last);
1106 template <class _InputIterator>
1107 void __assign_multi(_InputIterator __first, _InputIterator __last);
Eric Fiselier5875c1d2017-04-19 01:23:04 +00001108#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant7686add2011-06-04 14:31:57 +00001109 __tree(__tree&& __t)
1110 _NOEXCEPT_(
1111 is_nothrow_move_constructible<__node_allocator>::value &&
1112 is_nothrow_move_constructible<value_compare>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001113 __tree(__tree&& __t, const allocator_type& __a);
Howard Hinnant7686add2011-06-04 14:31:57 +00001114 __tree& operator=(__tree&& __t)
1115 _NOEXCEPT_(
1116 __node_traits::propagate_on_container_move_assignment::value &&
1117 is_nothrow_move_assignable<value_compare>::value &&
1118 is_nothrow_move_assignable<__node_allocator>::value);
Eric Fiselier5875c1d2017-04-19 01:23:04 +00001119#endif // _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001120
1121 ~__tree();
1122
Howard Hinnant333f50d2010-09-21 20:16:37 +00001123 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001124 iterator begin() _NOEXCEPT {return iterator(__begin_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001125 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001126 const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001127 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001128 iterator end() _NOEXCEPT {return iterator(__end_node());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001129 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001130 const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001131
Howard Hinnant333f50d2010-09-21 20:16:37 +00001132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7686add2011-06-04 14:31:57 +00001133 size_type max_size() const _NOEXCEPT
Eric Fiselieref3060e2016-11-23 01:18:56 +00001134 {return std::min<size_type>(
1135 __node_traits::max_size(__node_alloc()),
1136 numeric_limits<difference_type >::max());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001137
Howard Hinnant7686add2011-06-04 14:31:57 +00001138 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001139
Howard Hinnant7686add2011-06-04 14:31:57 +00001140 void swap(__tree& __t)
Dimitry Andric1421cf02016-08-27 19:32:03 +00001141#if _LIBCPP_STD_VER <= 11
Howard Hinnant7686add2011-06-04 14:31:57 +00001142 _NOEXCEPT_(
Marshall Clow7d914d12015-07-13 20:04:56 +00001143 __is_nothrow_swappable<value_compare>::value
Marshall Clow7d914d12015-07-13 20:04:56 +00001144 && (!__node_traits::propagate_on_container_swap::value ||
1145 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow7d914d12015-07-13 20:04:56 +00001146 );
Dimitry Andric1421cf02016-08-27 19:32:03 +00001147#else
1148 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
1149#endif
Eric Fiselierdb215062016-03-31 02:15:15 +00001150
1151#ifndef _LIBCPP_CXX03_LANG
1152 template <class _Key, class ..._Args>
1153 pair<iterator, bool>
1154 __emplace_unique_key_args(_Key const&, _Args&&... __args);
1155 template <class _Key, class ..._Args>
1156 iterator
1157 __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001158
1159 template <class... _Args>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001160 pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
Eric Fiselierdb215062016-03-31 02:15:15 +00001161
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001162 template <class... _Args>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001163 iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001164
Eric Fiselierdb215062016-03-31 02:15:15 +00001165 template <class... _Args>
1166 iterator __emplace_multi(_Args&&... __args);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001167
Eric Fiselierdb215062016-03-31 02:15:15 +00001168 template <class... _Args>
1169 iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001170
1171 template <class _Pp>
1172 _LIBCPP_INLINE_VISIBILITY
1173 pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1174 return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1175 __can_extract_key<_Pp, key_type>());
1176 }
1177
Eric Fiselierdc414cd2016-04-16 00:23:12 +00001178 template <class _First, class _Second>
1179 _LIBCPP_INLINE_VISIBILITY
1180 typename enable_if<
1181 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1182 pair<iterator, bool>
1183 >::type __emplace_unique(_First&& __f, _Second&& __s) {
1184 return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1185 _VSTD::forward<_Second>(__s));
1186 }
1187
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001188 template <class... _Args>
1189 _LIBCPP_INLINE_VISIBILITY
1190 pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1191 return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1192 }
1193
1194 template <class _Pp>
1195 _LIBCPP_INLINE_VISIBILITY
1196 pair<iterator, bool>
1197 __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1198 return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1199 }
1200
1201 template <class _Pp>
1202 _LIBCPP_INLINE_VISIBILITY
1203 pair<iterator, bool>
1204 __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1205 return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1206 }
1207
1208 template <class _Pp>
1209 _LIBCPP_INLINE_VISIBILITY
1210 pair<iterator, bool>
1211 __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1212 return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1213 }
1214
1215 template <class _Pp>
1216 _LIBCPP_INLINE_VISIBILITY
1217 iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
1218 return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
1219 __can_extract_key<_Pp, key_type>());
1220 }
1221
Eric Fiselierdc414cd2016-04-16 00:23:12 +00001222 template <class _First, class _Second>
1223 _LIBCPP_INLINE_VISIBILITY
1224 typename enable_if<
1225 __can_extract_map_key<_First, key_type, __container_value_type>::value,
1226 iterator
1227 >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
1228 return __emplace_hint_unique_key_args(__p, __f,
1229 _VSTD::forward<_First>(__f),
1230 _VSTD::forward<_Second>(__s));
1231 }
1232
Eric Fiselier83c9dc12016-04-15 23:27:27 +00001233 template <class... _Args>
1234 _LIBCPP_INLINE_VISIBILITY
1235 iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1236 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
1237 }
1238
1239 template <class _Pp>
1240 _LIBCPP_INLINE_VISIBILITY
1241 iterator
1242 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1243 return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
1244 }
1245
1246 template <class _Pp>
1247 _LIBCPP_INLINE_VISIBILITY
1248 iterator
1249 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1250 return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x));
1251 }
1252
1253 template <class _Pp>
1254 _LIBCPP_INLINE_VISIBILITY
1255 iterator
1256 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1257 return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x));
1258 }
1259
Eric Fiselierdb215062016-03-31 02:15:15 +00001260#else
1261 template <class _Key, class _Args>
1262 _LIBCPP_INLINE_VISIBILITY
1263 pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args);
1264 template <class _Key, class _Args>
1265 _LIBCPP_INLINE_VISIBILITY
1266 iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&);
Marshall Clow3426a862016-01-05 19:32:41 +00001267#endif
1268
Eric Fiselierdb215062016-03-31 02:15:15 +00001269 _LIBCPP_INLINE_VISIBILITY
1270 pair<iterator, bool> __insert_unique(const __container_value_type& __v) {
1271 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v);
1272 }
1273
1274 _LIBCPP_INLINE_VISIBILITY
1275 iterator __insert_unique(const_iterator __p, const __container_value_type& __v) {
1276 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v);
1277 }
1278
1279#ifdef _LIBCPP_CXX03_LANG
1280 _LIBCPP_INLINE_VISIBILITY
1281 iterator __insert_multi(const __container_value_type& __v);
1282 _LIBCPP_INLINE_VISIBILITY
1283 iterator __insert_multi(const_iterator __p, const __container_value_type& __v);
1284#else
1285 _LIBCPP_INLINE_VISIBILITY
1286 pair<iterator, bool> __insert_unique(__container_value_type&& __v) {
1287 return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v));
1288 }
1289
1290 _LIBCPP_INLINE_VISIBILITY
1291 iterator __insert_unique(const_iterator __p, __container_value_type&& __v) {
1292 return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v));
1293 }
1294
1295 template <class _Vp, class = typename enable_if<
1296 !is_same<typename __unconstref<_Vp>::type,
1297 __container_value_type
1298 >::value
1299 >::type>
1300 _LIBCPP_INLINE_VISIBILITY
1301 pair<iterator, bool> __insert_unique(_Vp&& __v) {
1302 return __emplace_unique(_VSTD::forward<_Vp>(__v));
1303 }
1304
1305 template <class _Vp, class = typename enable_if<
1306 !is_same<typename __unconstref<_Vp>::type,
1307 __container_value_type
1308 >::value
1309 >::type>
1310 _LIBCPP_INLINE_VISIBILITY
1311 iterator __insert_unique(const_iterator __p, _Vp&& __v) {
1312 return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
1313 }
1314
1315 _LIBCPP_INLINE_VISIBILITY
1316 iterator __insert_multi(__container_value_type&& __v) {
1317 return __emplace_multi(_VSTD::move(__v));
1318 }
1319
1320 _LIBCPP_INLINE_VISIBILITY
1321 iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
1322 return __emplace_hint_multi(__p, _VSTD::move(__v));
1323 }
1324
1325 template <class _Vp>
1326 _LIBCPP_INLINE_VISIBILITY
1327 iterator __insert_multi(_Vp&& __v) {
1328 return __emplace_multi(_VSTD::forward<_Vp>(__v));
1329 }
1330
1331 template <class _Vp>
1332 _LIBCPP_INLINE_VISIBILITY
1333 iterator __insert_multi(const_iterator __p, _Vp&& __v) {
1334 return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v));
1335 }
1336
1337#endif // !_LIBCPP_CXX03_LANG
1338
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001339 pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
1340 iterator __node_insert_unique(const_iterator __p,
1341 __node_pointer __nd);
1342
1343 iterator __node_insert_multi(__node_pointer __nd);
1344 iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1345
1346 iterator erase(const_iterator __p);
1347 iterator erase(const_iterator __f, const_iterator __l);
1348 template <class _Key>
1349 size_type __erase_unique(const _Key& __k);
1350 template <class _Key>
1351 size_type __erase_multi(const _Key& __k);
1352
Eric Fiselier7310ec82016-07-19 17:56:20 +00001353 void __insert_node_at(__parent_pointer __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001354 __node_base_pointer& __child,
1355 __node_base_pointer __new_node);
1356
1357 template <class _Key>
1358 iterator find(const _Key& __v);
1359 template <class _Key>
1360 const_iterator find(const _Key& __v) const;
1361
1362 template <class _Key>
1363 size_type __count_unique(const _Key& __k) const;
1364 template <class _Key>
1365 size_type __count_multi(const _Key& __k) const;
1366
1367 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001369 iterator lower_bound(const _Key& __v)
1370 {return __lower_bound(__v, __root(), __end_node());}
1371 template <class _Key>
1372 iterator __lower_bound(const _Key& __v,
1373 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001374 __iter_pointer __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001375 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001376 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001377 const_iterator lower_bound(const _Key& __v) const
1378 {return __lower_bound(__v, __root(), __end_node());}
1379 template <class _Key>
1380 const_iterator __lower_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00001381 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001382 __iter_pointer __result) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001383 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001385 iterator upper_bound(const _Key& __v)
1386 {return __upper_bound(__v, __root(), __end_node());}
1387 template <class _Key>
1388 iterator __upper_bound(const _Key& __v,
1389 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001390 __iter_pointer __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001391 template <class _Key>
Howard Hinnant333f50d2010-09-21 20:16:37 +00001392 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001393 const_iterator upper_bound(const _Key& __v) const
1394 {return __upper_bound(__v, __root(), __end_node());}
1395 template <class _Key>
1396 const_iterator __upper_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00001397 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001398 __iter_pointer __result) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001399 template <class _Key>
1400 pair<iterator, iterator>
1401 __equal_range_unique(const _Key& __k);
1402 template <class _Key>
1403 pair<const_iterator, const_iterator>
1404 __equal_range_unique(const _Key& __k) const;
1405
1406 template <class _Key>
1407 pair<iterator, iterator>
1408 __equal_range_multi(const _Key& __k);
1409 template <class _Key>
1410 pair<const_iterator, const_iterator>
1411 __equal_range_multi(const _Key& __k) const;
1412
Howard Hinnant99968442011-11-29 18:15:50 +00001413 typedef __tree_node_destructor<__node_allocator> _Dp;
1414 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001415
Howard Hinnant8b537682011-06-04 17:10:24 +00001416 __node_holder remove(const_iterator __p) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001417private:
Eric Fiselier7310ec82016-07-19 17:56:20 +00001418 __node_base_pointer&
1419 __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
1420 __node_base_pointer&
1421 __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
1422 __node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001423 __find_leaf(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001424 __parent_pointer& __parent, const key_type& __v);
Eric Fiselier856712b2017-01-05 06:06:18 +00001425 // FIXME: Make this function const qualified. Unfortunetly doing so
1426 // breaks existing code which uses non-const callable comparators.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001427 template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001428 __node_base_pointer&
1429 __find_equal(__parent_pointer& __parent, const _Key& __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001430 template <class _Key>
Eric Fiselier856712b2017-01-05 06:06:18 +00001431 _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
1432 __find_equal(__parent_pointer& __parent, const _Key& __v) const {
1433 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1434 }
1435 template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001436 __node_base_pointer&
1437 __find_equal(const_iterator __hint, __parent_pointer& __parent,
1438 __node_base_pointer& __dummy,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001439 const _Key& __v);
1440
Eric Fiselierdb215062016-03-31 02:15:15 +00001441#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001442 template <class ..._Args>
Eric Fiselierdb215062016-03-31 02:15:15 +00001443 __node_holder __construct_node(_Args&& ...__args);
1444#else
1445 __node_holder __construct_node(const __container_value_type& __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001446#endif
1447
Howard Hinnant7686add2011-06-04 14:31:57 +00001448 void destroy(__node_pointer __nd) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001449
Howard Hinnant333f50d2010-09-21 20:16:37 +00001450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001451 void __copy_assign_alloc(const __tree& __t)
1452 {__copy_assign_alloc(__t, integral_constant<bool,
1453 __node_traits::propagate_on_container_copy_assignment::value>());}
1454
Howard Hinnant333f50d2010-09-21 20:16:37 +00001455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001456 void __copy_assign_alloc(const __tree& __t, true_type)
Marshall Clow546498c2016-08-17 23:24:02 +00001457 {
1458 if (__node_alloc() != __t.__node_alloc())
1459 clear();
1460 __node_alloc() = __t.__node_alloc();
1461 }
Howard Hinnant333f50d2010-09-21 20:16:37 +00001462 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001463 void __copy_assign_alloc(const __tree&, false_type) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001464
1465 void __move_assign(__tree& __t, false_type);
Howard Hinnant7686add2011-06-04 14:31:57 +00001466 void __move_assign(__tree& __t, true_type)
1467 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1468 is_nothrow_move_assignable<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001469
Howard Hinnant333f50d2010-09-21 20:16:37 +00001470 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001471 void __move_assign_alloc(__tree& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001472 _NOEXCEPT_(
1473 !__node_traits::propagate_on_container_move_assignment::value ||
1474 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001475 {__move_assign_alloc(__t, integral_constant<bool,
1476 __node_traits::propagate_on_container_move_assignment::value>());}
1477
Howard Hinnant333f50d2010-09-21 20:16:37 +00001478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001479 void __move_assign_alloc(__tree& __t, true_type)
Howard Hinnant7686add2011-06-04 14:31:57 +00001480 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001481 {__node_alloc() = _VSTD::move(__t.__node_alloc());}
Howard Hinnant333f50d2010-09-21 20:16:37 +00001482 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001483 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001484
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001485 __node_pointer __detach();
1486 static __node_pointer __detach(__node_pointer);
Howard Hinnant70342b92013-06-19 21:29:40 +00001487
Eric Fiselierc3589a82017-01-04 23:56:00 +00001488 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1489 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001490};
1491
1492template <class _Tp, class _Compare, class _Allocator>
1493__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
Howard Hinnant7686add2011-06-04 14:31:57 +00001494 _NOEXCEPT_(
1495 is_nothrow_default_constructible<__node_allocator>::value &&
1496 is_nothrow_copy_constructible<value_compare>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001497 : __pair3_(0, __comp)
1498{
1499 __begin_node() = __end_node();
1500}
1501
1502template <class _Tp, class _Compare, class _Allocator>
1503__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001504 : __begin_node_(__iter_pointer()),
Eric Fiselier161ccc12017-04-13 00:34:24 +00001505 __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001506 __pair3_(0)
1507{
1508 __begin_node() = __end_node();
1509}
1510
1511template <class _Tp, class _Compare, class _Allocator>
1512__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1513 const allocator_type& __a)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001514 : __begin_node_(__iter_pointer()),
Eric Fiselier161ccc12017-04-13 00:34:24 +00001515 __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001516 __pair3_(0, __comp)
1517{
1518 __begin_node() = __end_node();
1519}
1520
1521// Precondition: size() != 0
1522template <class _Tp, class _Compare, class _Allocator>
1523typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1524__tree<_Tp, _Compare, _Allocator>::__detach()
1525{
Eric Fiselier7310ec82016-07-19 17:56:20 +00001526 __node_pointer __cache = static_cast<__node_pointer>(__begin_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001527 __begin_node() = __end_node();
1528 __end_node()->__left_->__parent_ = nullptr;
1529 __end_node()->__left_ = nullptr;
1530 size() = 0;
1531 // __cache->__left_ == nullptr
1532 if (__cache->__right_ != nullptr)
1533 __cache = static_cast<__node_pointer>(__cache->__right_);
1534 // __cache->__left_ == nullptr
1535 // __cache->__right_ == nullptr
1536 return __cache;
1537}
1538
1539// Precondition: __cache != nullptr
1540// __cache->left_ == nullptr
1541// __cache->right_ == nullptr
1542// This is no longer a red-black tree
1543template <class _Tp, class _Compare, class _Allocator>
1544typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1545__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
1546{
1547 if (__cache->__parent_ == nullptr)
1548 return nullptr;
Howard Hinnant70342b92013-06-19 21:29:40 +00001549 if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001550 {
1551 __cache->__parent_->__left_ = nullptr;
1552 __cache = static_cast<__node_pointer>(__cache->__parent_);
1553 if (__cache->__right_ == nullptr)
1554 return __cache;
1555 return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
1556 }
1557 // __cache is right child
Eric Fiselier7310ec82016-07-19 17:56:20 +00001558 __cache->__parent_unsafe()->__right_ = nullptr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001559 __cache = static_cast<__node_pointer>(__cache->__parent_);
1560 if (__cache->__left_ == nullptr)
1561 return __cache;
1562 return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
1563}
1564
1565template <class _Tp, class _Compare, class _Allocator>
1566__tree<_Tp, _Compare, _Allocator>&
1567__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1568{
1569 if (this != &__t)
1570 {
1571 value_comp() = __t.value_comp();
1572 __copy_assign_alloc(__t);
1573 __assign_multi(__t.begin(), __t.end());
1574 }
1575 return *this;
1576}
1577
1578template <class _Tp, class _Compare, class _Allocator>
1579template <class _InputIterator>
1580void
1581__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
1582{
Eric Fiselierdb215062016-03-31 02:15:15 +00001583 typedef iterator_traits<_InputIterator> _ITraits;
1584 typedef typename _ITraits::value_type _ItValueType;
1585 static_assert((is_same<_ItValueType, __container_value_type>::value),
1586 "__assign_unique may only be called with the containers value type");
1587
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001588 if (size() != 0)
1589 {
1590 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001591#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001592 try
1593 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001594#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001595 for (; __cache != nullptr && __first != __last; ++__first)
1596 {
1597 __cache->__value_ = *__first;
1598 __node_pointer __next = __detach(__cache);
1599 __node_insert_unique(__cache);
1600 __cache = __next;
1601 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001602#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001603 }
1604 catch (...)
1605 {
1606 while (__cache->__parent_ != nullptr)
1607 __cache = static_cast<__node_pointer>(__cache->__parent_);
1608 destroy(__cache);
1609 throw;
1610 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001611#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001612 if (__cache != nullptr)
1613 {
1614 while (__cache->__parent_ != nullptr)
1615 __cache = static_cast<__node_pointer>(__cache->__parent_);
1616 destroy(__cache);
1617 }
1618 }
1619 for (; __first != __last; ++__first)
1620 __insert_unique(*__first);
1621}
1622
1623template <class _Tp, class _Compare, class _Allocator>
1624template <class _InputIterator>
1625void
1626__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1627{
Eric Fiselierdb215062016-03-31 02:15:15 +00001628 typedef iterator_traits<_InputIterator> _ITraits;
1629 typedef typename _ITraits::value_type _ItValueType;
1630 static_assert((is_same<_ItValueType, __container_value_type>::value ||
1631 is_same<_ItValueType, __node_value_type>::value),
1632 "__assign_multi may only be called with the containers value type"
1633 " or the nodes value type");
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001634 if (size() != 0)
1635 {
1636 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001637#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001638 try
1639 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001640#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001641 for (; __cache != nullptr && __first != __last; ++__first)
1642 {
1643 __cache->__value_ = *__first;
1644 __node_pointer __next = __detach(__cache);
1645 __node_insert_multi(__cache);
1646 __cache = __next;
1647 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001648#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001649 }
1650 catch (...)
1651 {
1652 while (__cache->__parent_ != nullptr)
1653 __cache = static_cast<__node_pointer>(__cache->__parent_);
1654 destroy(__cache);
1655 throw;
1656 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001657#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001658 if (__cache != nullptr)
1659 {
1660 while (__cache->__parent_ != nullptr)
1661 __cache = static_cast<__node_pointer>(__cache->__parent_);
1662 destroy(__cache);
1663 }
1664 }
1665 for (; __first != __last; ++__first)
Eric Fiselierdb215062016-03-31 02:15:15 +00001666 __insert_multi(_NodeTypes::__get_value(*__first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001667}
1668
1669template <class _Tp, class _Compare, class _Allocator>
1670__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
Eric Fiselier7310ec82016-07-19 17:56:20 +00001671 : __begin_node_(__iter_pointer()),
Eric Fiselier161ccc12017-04-13 00:34:24 +00001672 __pair1_(__second_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001673 __pair3_(0, __t.value_comp())
1674{
1675 __begin_node() = __end_node();
1676}
1677
Eric Fiselier5875c1d2017-04-19 01:23:04 +00001678#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001679
1680template <class _Tp, class _Compare, class _Allocator>
1681__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001682 _NOEXCEPT_(
1683 is_nothrow_move_constructible<__node_allocator>::value &&
1684 is_nothrow_move_constructible<value_compare>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001685 : __begin_node_(_VSTD::move(__t.__begin_node_)),
1686 __pair1_(_VSTD::move(__t.__pair1_)),
1687 __pair3_(_VSTD::move(__t.__pair3_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001688{
1689 if (size() == 0)
1690 __begin_node() = __end_node();
1691 else
1692 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001693 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001694 __t.__begin_node() = __t.__end_node();
1695 __t.__end_node()->__left_ = nullptr;
1696 __t.size() = 0;
1697 }
1698}
1699
1700template <class _Tp, class _Compare, class _Allocator>
1701__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
Eric Fiselier161ccc12017-04-13 00:34:24 +00001702 : __pair1_(__second_tag(), __node_allocator(__a)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00001703 __pair3_(0, _VSTD::move(__t.value_comp()))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001704{
1705 if (__a == __t.__alloc())
1706 {
1707 if (__t.size() == 0)
1708 __begin_node() = __end_node();
1709 else
1710 {
1711 __begin_node() = __t.__begin_node();
1712 __end_node()->__left_ = __t.__end_node()->__left_;
Eric Fiselier7310ec82016-07-19 17:56:20 +00001713 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001714 size() = __t.size();
1715 __t.__begin_node() = __t.__end_node();
1716 __t.__end_node()->__left_ = nullptr;
1717 __t.size() = 0;
1718 }
1719 }
1720 else
1721 {
1722 __begin_node() = __end_node();
1723 }
1724}
1725
1726template <class _Tp, class _Compare, class _Allocator>
1727void
1728__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
Howard Hinnant7686add2011-06-04 14:31:57 +00001729 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1730 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001731{
1732 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1733 __begin_node_ = __t.__begin_node_;
1734 __pair1_.first() = __t.__pair1_.first();
1735 __move_assign_alloc(__t);
Howard Hinnant0949eed2011-06-30 21:18:19 +00001736 __pair3_ = _VSTD::move(__t.__pair3_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001737 if (size() == 0)
1738 __begin_node() = __end_node();
1739 else
1740 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001741 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001742 __t.__begin_node() = __t.__end_node();
1743 __t.__end_node()->__left_ = nullptr;
1744 __t.size() = 0;
1745 }
1746}
1747
1748template <class _Tp, class _Compare, class _Allocator>
1749void
1750__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1751{
1752 if (__node_alloc() == __t.__node_alloc())
1753 __move_assign(__t, true_type());
1754 else
1755 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001756 value_comp() = _VSTD::move(__t.value_comp());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001757 const_iterator __e = end();
1758 if (size() != 0)
1759 {
1760 __node_pointer __cache = __detach();
Howard Hinnantd4444702010-08-11 17:04:31 +00001761#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001762 try
1763 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001764#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001765 while (__cache != nullptr && __t.size() != 0)
1766 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001767 __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001768 __node_pointer __next = __detach(__cache);
1769 __node_insert_multi(__cache);
1770 __cache = __next;
1771 }
Howard Hinnantd4444702010-08-11 17:04:31 +00001772#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001773 }
1774 catch (...)
1775 {
1776 while (__cache->__parent_ != nullptr)
1777 __cache = static_cast<__node_pointer>(__cache->__parent_);
1778 destroy(__cache);
1779 throw;
1780 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001781#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001782 if (__cache != nullptr)
1783 {
1784 while (__cache->__parent_ != nullptr)
1785 __cache = static_cast<__node_pointer>(__cache->__parent_);
1786 destroy(__cache);
1787 }
1788 }
1789 while (__t.size() != 0)
Eric Fiselierdb215062016-03-31 02:15:15 +00001790 __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001791 }
1792}
1793
1794template <class _Tp, class _Compare, class _Allocator>
1795__tree<_Tp, _Compare, _Allocator>&
1796__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
Howard Hinnant7686add2011-06-04 14:31:57 +00001797 _NOEXCEPT_(
1798 __node_traits::propagate_on_container_move_assignment::value &&
1799 is_nothrow_move_assignable<value_compare>::value &&
1800 is_nothrow_move_assignable<__node_allocator>::value)
1801
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001802{
1803 __move_assign(__t, integral_constant<bool,
1804 __node_traits::propagate_on_container_move_assignment::value>());
1805 return *this;
1806}
1807
Eric Fiselier5875c1d2017-04-19 01:23:04 +00001808#endif // _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001809
1810template <class _Tp, class _Compare, class _Allocator>
1811__tree<_Tp, _Compare, _Allocator>::~__tree()
1812{
Marshall Clow1a933122016-06-30 22:05:45 +00001813 static_assert((is_copy_constructible<value_compare>::value),
1814 "Comparator must be copy-constructible.");
Eric Fiselierebaf7da2017-01-13 22:02:08 +00001815#ifndef _LIBCPP_CXX03_LANG
1816 static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>::
1817 __trigger_diagnostics()), "");
1818#endif
1819 destroy(__root());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001820}
1821
1822template <class _Tp, class _Compare, class _Allocator>
1823void
Howard Hinnant7686add2011-06-04 14:31:57 +00001824__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001825{
1826 if (__nd != nullptr)
1827 {
1828 destroy(static_cast<__node_pointer>(__nd->__left_));
1829 destroy(static_cast<__node_pointer>(__nd->__right_));
1830 __node_allocator& __na = __node_alloc();
Eric Fiselierdb215062016-03-31 02:15:15 +00001831 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001832 __node_traits::deallocate(__na, __nd, 1);
1833 }
1834}
1835
1836template <class _Tp, class _Compare, class _Allocator>
1837void
1838__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
Dimitry Andric1421cf02016-08-27 19:32:03 +00001839#if _LIBCPP_STD_VER <= 11
Marshall Clow7d914d12015-07-13 20:04:56 +00001840 _NOEXCEPT_(
1841 __is_nothrow_swappable<value_compare>::value
Marshall Clow7d914d12015-07-13 20:04:56 +00001842 && (!__node_traits::propagate_on_container_swap::value ||
1843 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow7d914d12015-07-13 20:04:56 +00001844 )
Dimitry Andric1421cf02016-08-27 19:32:03 +00001845#else
1846 _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
1847#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001848{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001849 using _VSTD::swap;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001850 swap(__begin_node_, __t.__begin_node_);
1851 swap(__pair1_.first(), __t.__pair1_.first());
Marshall Clow7d914d12015-07-13 20:04:56 +00001852 __swap_allocator(__node_alloc(), __t.__node_alloc());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001853 __pair3_.swap(__t.__pair3_);
1854 if (size() == 0)
1855 __begin_node() = __end_node();
1856 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00001857 __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001858 if (__t.size() == 0)
1859 __t.__begin_node() = __t.__end_node();
1860 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00001861 __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001862}
1863
1864template <class _Tp, class _Compare, class _Allocator>
1865void
Howard Hinnant7686add2011-06-04 14:31:57 +00001866__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001867{
1868 destroy(__root());
1869 size() = 0;
1870 __begin_node() = __end_node();
1871 __end_node()->__left_ = nullptr;
1872}
1873
1874// Find lower_bound place to insert
1875// Set __parent to parent of null leaf
1876// Return reference to null leaf
1877template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001878typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1879__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001880 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001881{
1882 __node_pointer __nd = __root();
1883 if (__nd != nullptr)
1884 {
1885 while (true)
1886 {
1887 if (value_comp()(__nd->__value_, __v))
1888 {
1889 if (__nd->__right_ != nullptr)
1890 __nd = static_cast<__node_pointer>(__nd->__right_);
1891 else
1892 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001893 __parent = static_cast<__parent_pointer>(__nd);
1894 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001895 }
1896 }
1897 else
1898 {
1899 if (__nd->__left_ != nullptr)
1900 __nd = static_cast<__node_pointer>(__nd->__left_);
1901 else
1902 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001903 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001904 return __parent->__left_;
1905 }
1906 }
1907 }
1908 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00001909 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001910 return __parent->__left_;
1911}
1912
1913// Find upper_bound place to insert
1914// Set __parent to parent of null leaf
1915// Return reference to null leaf
1916template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001917typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1918__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001919 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001920{
1921 __node_pointer __nd = __root();
1922 if (__nd != nullptr)
1923 {
1924 while (true)
1925 {
1926 if (value_comp()(__v, __nd->__value_))
1927 {
1928 if (__nd->__left_ != nullptr)
1929 __nd = static_cast<__node_pointer>(__nd->__left_);
1930 else
1931 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001932 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001933 return __parent->__left_;
1934 }
1935 }
1936 else
1937 {
1938 if (__nd->__right_ != nullptr)
1939 __nd = static_cast<__node_pointer>(__nd->__right_);
1940 else
1941 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001942 __parent = static_cast<__parent_pointer>(__nd);
1943 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001944 }
1945 }
1946 }
1947 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00001948 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001949 return __parent->__left_;
1950}
1951
1952// Find leaf place to insert closest to __hint
1953// First check prior to __hint.
1954// Next check after __hint.
1955// Next do O(log N) search.
1956// Set __parent to parent of null leaf
1957// Return reference to null leaf
1958template <class _Tp, class _Compare, class _Allocator>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001959typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001960__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00001961 __parent_pointer& __parent,
Eric Fiselierdb215062016-03-31 02:15:15 +00001962 const key_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001963{
1964 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1965 {
1966 // __v <= *__hint
1967 const_iterator __prior = __hint;
1968 if (__prior == begin() || !value_comp()(__v, *--__prior))
1969 {
1970 // *prev(__hint) <= __v <= *__hint
1971 if (__hint.__ptr_->__left_ == nullptr)
1972 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001973 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001974 return __parent->__left_;
1975 }
1976 else
1977 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00001978 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
1979 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001980 }
1981 }
1982 // __v < *prev(__hint)
1983 return __find_leaf_high(__parent, __v);
1984 }
1985 // else __v > *__hint
1986 return __find_leaf_low(__parent, __v);
1987}
1988
1989// Find place to insert if __v doesn't exist
1990// Set __parent to parent of null leaf
1991// Return reference to null leaf
1992// If __v exists, set parent to node of __v and return reference to node of __v
1993template <class _Tp, class _Compare, class _Allocator>
1994template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00001995typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1996__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001997 const _Key& __v)
1998{
1999 __node_pointer __nd = __root();
Eric Fiselier7310ec82016-07-19 17:56:20 +00002000 __node_base_pointer* __nd_ptr = __root_ptr();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002001 if (__nd != nullptr)
2002 {
2003 while (true)
2004 {
2005 if (value_comp()(__v, __nd->__value_))
2006 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002007 if (__nd->__left_ != nullptr) {
2008 __nd_ptr = _VSTD::addressof(__nd->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002009 __nd = static_cast<__node_pointer>(__nd->__left_);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002010 } else {
2011 __parent = static_cast<__parent_pointer>(__nd);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002012 return __parent->__left_;
2013 }
2014 }
2015 else if (value_comp()(__nd->__value_, __v))
2016 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002017 if (__nd->__right_ != nullptr) {
2018 __nd_ptr = _VSTD::addressof(__nd->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002019 __nd = static_cast<__node_pointer>(__nd->__right_);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002020 } else {
2021 __parent = static_cast<__parent_pointer>(__nd);
2022 return __nd->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002023 }
2024 }
2025 else
2026 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002027 __parent = static_cast<__parent_pointer>(__nd);
2028 return *__nd_ptr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002029 }
2030 }
2031 }
Eric Fiselier7310ec82016-07-19 17:56:20 +00002032 __parent = static_cast<__parent_pointer>(__end_node());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002033 return __parent->__left_;
2034}
2035
2036// Find place to insert if __v doesn't exist
2037// First check prior to __hint.
2038// Next check after __hint.
2039// Next do O(log N) search.
2040// Set __parent to parent of null leaf
2041// Return reference to null leaf
2042// If __v exists, set parent to node of __v and return reference to node of __v
2043template <class _Tp, class _Compare, class _Allocator>
2044template <class _Key>
Eric Fiselier7310ec82016-07-19 17:56:20 +00002045typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002046__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002047 __parent_pointer& __parent,
2048 __node_base_pointer& __dummy,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002049 const _Key& __v)
2050{
2051 if (__hint == end() || value_comp()(__v, *__hint)) // check before
2052 {
2053 // __v < *__hint
2054 const_iterator __prior = __hint;
2055 if (__prior == begin() || value_comp()(*--__prior, __v))
2056 {
2057 // *prev(__hint) < __v < *__hint
2058 if (__hint.__ptr_->__left_ == nullptr)
2059 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002060 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002061 return __parent->__left_;
2062 }
2063 else
2064 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002065 __parent = static_cast<__parent_pointer>(__prior.__ptr_);
2066 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002067 }
2068 }
2069 // __v <= *prev(__hint)
2070 return __find_equal(__parent, __v);
2071 }
2072 else if (value_comp()(*__hint, __v)) // check after
2073 {
2074 // *__hint < __v
Howard Hinnant0949eed2011-06-30 21:18:19 +00002075 const_iterator __next = _VSTD::next(__hint);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002076 if (__next == end() || value_comp()(__v, *__next))
2077 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002078 // *__hint < __v < *_VSTD::next(__hint)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002079 if (__hint.__get_np()->__right_ == nullptr)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002080 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002081 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2082 return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002083 }
2084 else
2085 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002086 __parent = static_cast<__parent_pointer>(__next.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002087 return __parent->__left_;
2088 }
2089 }
2090 // *next(__hint) <= __v
2091 return __find_equal(__parent, __v);
2092 }
2093 // else __v == *__hint
Eric Fiselier7310ec82016-07-19 17:56:20 +00002094 __parent = static_cast<__parent_pointer>(__hint.__ptr_);
2095 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
2096 return __dummy;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002097}
2098
2099template <class _Tp, class _Compare, class _Allocator>
2100void
Eric Fiselier7310ec82016-07-19 17:56:20 +00002101__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002102 __node_base_pointer& __child,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002103 __node_base_pointer __new_node)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002104{
2105 __new_node->__left_ = nullptr;
2106 __new_node->__right_ = nullptr;
2107 __new_node->__parent_ = __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002108 // __new_node->__is_black_ is initialized in __tree_balance_after_insert
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002109 __child = __new_node;
2110 if (__begin_node()->__left_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002111 __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002112 __tree_balance_after_insert(__end_node()->__left_, __child);
2113 ++size();
2114}
2115
Eric Fiselierdb215062016-03-31 02:15:15 +00002116#ifndef _LIBCPP_CXX03_LANG
2117template <class _Tp, class _Compare, class _Allocator>
2118template <class _Key, class... _Args>
2119pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2120__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
2121#else
2122template <class _Tp, class _Compare, class _Allocator>
2123template <class _Key, class _Args>
2124pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2125__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args)
2126#endif
2127{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002128 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002129 __node_base_pointer& __child = __find_equal(__parent, __k);
2130 __node_pointer __r = static_cast<__node_pointer>(__child);
2131 bool __inserted = false;
2132 if (__child == nullptr)
2133 {
2134#ifndef _LIBCPP_CXX03_LANG
2135 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2136#else
2137 __node_holder __h = __construct_node(__args);
2138#endif
2139 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2140 __r = __h.release();
2141 __inserted = true;
2142 }
2143 return pair<iterator, bool>(iterator(__r), __inserted);
2144}
2145
2146
2147#ifndef _LIBCPP_CXX03_LANG
2148template <class _Tp, class _Compare, class _Allocator>
2149template <class _Key, class... _Args>
2150typename __tree<_Tp, _Compare, _Allocator>::iterator
2151__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2152 const_iterator __p, _Key const& __k, _Args&&... __args)
2153#else
2154template <class _Tp, class _Compare, class _Allocator>
2155template <class _Key, class _Args>
2156typename __tree<_Tp, _Compare, _Allocator>::iterator
2157__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
2158 const_iterator __p, _Key const& __k, _Args& __args)
2159#endif
2160{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002161 __parent_pointer __parent;
2162 __node_base_pointer __dummy;
2163 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
Eric Fiselierdb215062016-03-31 02:15:15 +00002164 __node_pointer __r = static_cast<__node_pointer>(__child);
2165 if (__child == nullptr)
2166 {
2167#ifndef _LIBCPP_CXX03_LANG
2168 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2169#else
2170 __node_holder __h = __construct_node(__args);
2171#endif
2172 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
2173 __r = __h.release();
2174 }
2175 return iterator(__r);
2176}
2177
2178
2179#ifndef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002180
2181template <class _Tp, class _Compare, class _Allocator>
2182template <class ..._Args>
2183typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2184__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
2185{
Eric Fiselierdb215062016-03-31 02:15:15 +00002186 static_assert(!__is_tree_value_type<_Args...>::value,
2187 "Cannot construct from __value_type");
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002188 __node_allocator& __na = __node_alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00002189 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierdb215062016-03-31 02:15:15 +00002190 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002191 __h.get_deleter().__value_constructed = true;
2192 return __h;
2193}
2194
Eric Fiselierdb215062016-03-31 02:15:15 +00002195
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002196template <class _Tp, class _Compare, class _Allocator>
2197template <class... _Args>
2198pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
Eric Fiselier83c9dc12016-04-15 23:27:27 +00002199__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002200{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002201 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002202 __parent_pointer __parent;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002203 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
2204 __node_pointer __r = static_cast<__node_pointer>(__child);
2205 bool __inserted = false;
2206 if (__child == nullptr)
2207 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002208 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002209 __r = __h.release();
2210 __inserted = true;
2211 }
2212 return pair<iterator, bool>(iterator(__r), __inserted);
2213}
2214
2215template <class _Tp, class _Compare, class _Allocator>
2216template <class... _Args>
2217typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselier83c9dc12016-04-15 23:27:27 +00002218__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002219{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002220 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002221 __parent_pointer __parent;
2222 __node_base_pointer __dummy;
2223 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002224 __node_pointer __r = static_cast<__node_pointer>(__child);
2225 if (__child == nullptr)
2226 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002227 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002228 __r = __h.release();
2229 }
2230 return iterator(__r);
2231}
2232
2233template <class _Tp, class _Compare, class _Allocator>
2234template <class... _Args>
2235typename __tree<_Tp, _Compare, _Allocator>::iterator
2236__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
2237{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002238 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002239 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002240 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002241 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002242 return iterator(static_cast<__node_pointer>(__h.release()));
2243}
2244
2245template <class _Tp, class _Compare, class _Allocator>
2246template <class... _Args>
2247typename __tree<_Tp, _Compare, _Allocator>::iterator
2248__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
2249 _Args&&... __args)
2250{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002251 __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
Eric Fiselier7310ec82016-07-19 17:56:20 +00002252 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002253 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002254 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002255 return iterator(static_cast<__node_pointer>(__h.release()));
2256}
2257
Howard Hinnant73d21a42010-09-04 23:28:19 +00002258
Eric Fiselierdb215062016-03-31 02:15:15 +00002259#else // _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002260
2261template <class _Tp, class _Compare, class _Allocator>
2262typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Eric Fiselierdb215062016-03-31 02:15:15 +00002263__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002264{
2265 __node_allocator& __na = __node_alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00002266 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Eric Fiselierdb215062016-03-31 02:15:15 +00002267 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002268 __h.get_deleter().__value_constructed = true;
Dimitry Andric89663502015-08-19 06:43:33 +00002269 return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002270}
2271
Eric Fiselierdb215062016-03-31 02:15:15 +00002272#endif // _LIBCPP_CXX03_LANG
Howard Hinnantd0a2fbf2011-03-10 17:27:57 +00002273
Eric Fiselierdb215062016-03-31 02:15:15 +00002274#ifdef _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002275template <class _Tp, class _Compare, class _Allocator>
2276typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierdb215062016-03-31 02:15:15 +00002277__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002278{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002279 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002280 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002281 __node_holder __h = __construct_node(__v);
Howard Hinnant70342b92013-06-19 21:29:40 +00002282 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002283 return iterator(__h.release());
2284}
2285
2286template <class _Tp, class _Compare, class _Allocator>
2287typename __tree<_Tp, _Compare, _Allocator>::iterator
Eric Fiselierdb215062016-03-31 02:15:15 +00002288__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002289{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002290 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002291 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002292 __node_holder __h = __construct_node(__v);
Howard Hinnant70342b92013-06-19 21:29:40 +00002293 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002294 return iterator(__h.release());
2295}
Eric Fiselierdb215062016-03-31 02:15:15 +00002296#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002297
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002298template <class _Tp, class _Compare, class _Allocator>
2299pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
2300__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
2301{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002302 __parent_pointer __parent;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002303 __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
2304 __node_pointer __r = static_cast<__node_pointer>(__child);
2305 bool __inserted = false;
2306 if (__child == nullptr)
2307 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002308 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002309 __r = __nd;
2310 __inserted = true;
2311 }
2312 return pair<iterator, bool>(iterator(__r), __inserted);
2313}
2314
2315template <class _Tp, class _Compare, class _Allocator>
2316typename __tree<_Tp, _Compare, _Allocator>::iterator
2317__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
2318 __node_pointer __nd)
2319{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002320 __parent_pointer __parent;
2321 __node_base_pointer __dummy;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002322 __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
2323 __node_pointer __r = static_cast<__node_pointer>(__child);
2324 if (__child == nullptr)
2325 {
Howard Hinnant70342b92013-06-19 21:29:40 +00002326 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002327 __r = __nd;
2328 }
2329 return iterator(__r);
2330}
2331
2332template <class _Tp, class _Compare, class _Allocator>
2333typename __tree<_Tp, _Compare, _Allocator>::iterator
2334__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
2335{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002336 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002337 __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002338 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002339 return iterator(__nd);
2340}
2341
2342template <class _Tp, class _Compare, class _Allocator>
2343typename __tree<_Tp, _Compare, _Allocator>::iterator
2344__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
2345 __node_pointer __nd)
2346{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002347 __parent_pointer __parent;
Eric Fiselierdb215062016-03-31 02:15:15 +00002348 __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
Howard Hinnant70342b92013-06-19 21:29:40 +00002349 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002350 return iterator(__nd);
2351}
2352
2353template <class _Tp, class _Compare, class _Allocator>
2354typename __tree<_Tp, _Compare, _Allocator>::iterator
2355__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
2356{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002357 __node_pointer __np = __p.__get_np();
2358 iterator __r(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002359 ++__r;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002360 if (__begin_node() == __p.__ptr_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002361 __begin_node() = __r.__ptr_;
2362 --size();
2363 __node_allocator& __na = __node_alloc();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002364 __tree_remove(__end_node()->__left_,
2365 static_cast<__node_base_pointer>(__np));
Eric Fiselierdb215062016-03-31 02:15:15 +00002366 __node_traits::destroy(__na, _NodeTypes::__get_ptr(
2367 const_cast<__node_value_type&>(*__p)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002368 __node_traits::deallocate(__na, __np, 1);
2369 return __r;
2370}
2371
2372template <class _Tp, class _Compare, class _Allocator>
2373typename __tree<_Tp, _Compare, _Allocator>::iterator
2374__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
2375{
2376 while (__f != __l)
2377 __f = erase(__f);
Howard Hinnant70342b92013-06-19 21:29:40 +00002378 return iterator(__l.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002379}
2380
2381template <class _Tp, class _Compare, class _Allocator>
2382template <class _Key>
2383typename __tree<_Tp, _Compare, _Allocator>::size_type
2384__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
2385{
2386 iterator __i = find(__k);
2387 if (__i == end())
2388 return 0;
2389 erase(__i);
2390 return 1;
2391}
2392
2393template <class _Tp, class _Compare, class _Allocator>
2394template <class _Key>
2395typename __tree<_Tp, _Compare, _Allocator>::size_type
2396__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
2397{
2398 pair<iterator, iterator> __p = __equal_range_multi(__k);
2399 size_type __r = 0;
2400 for (; __p.first != __p.second; ++__r)
2401 __p.first = erase(__p.first);
2402 return __r;
2403}
2404
2405template <class _Tp, class _Compare, class _Allocator>
2406template <class _Key>
2407typename __tree<_Tp, _Compare, _Allocator>::iterator
2408__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
2409{
2410 iterator __p = __lower_bound(__v, __root(), __end_node());
2411 if (__p != end() && !value_comp()(__v, *__p))
2412 return __p;
2413 return end();
2414}
2415
2416template <class _Tp, class _Compare, class _Allocator>
2417template <class _Key>
2418typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2419__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
2420{
2421 const_iterator __p = __lower_bound(__v, __root(), __end_node());
2422 if (__p != end() && !value_comp()(__v, *__p))
2423 return __p;
2424 return end();
2425}
2426
2427template <class _Tp, class _Compare, class _Allocator>
2428template <class _Key>
2429typename __tree<_Tp, _Compare, _Allocator>::size_type
2430__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
2431{
Eric Fiselier227b47c2016-02-20 07:12:17 +00002432 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002433 while (__rt != nullptr)
2434 {
2435 if (value_comp()(__k, __rt->__value_))
2436 {
Eric Fiselier227b47c2016-02-20 07:12:17 +00002437 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002438 }
2439 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002440 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002441 else
2442 return 1;
2443 }
2444 return 0;
2445}
2446
2447template <class _Tp, class _Compare, class _Allocator>
2448template <class _Key>
2449typename __tree<_Tp, _Compare, _Allocator>::size_type
2450__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
2451{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002452 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002453 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002454 while (__rt != nullptr)
2455 {
2456 if (value_comp()(__k, __rt->__value_))
2457 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002458 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002459 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002460 }
2461 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002462 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002463 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00002464 return _VSTD::distance(
Eric Fiselier7310ec82016-07-19 17:56:20 +00002465 __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiselier227b47c2016-02-20 07:12:17 +00002466 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002467 );
2468 }
2469 return 0;
2470}
2471
2472template <class _Tp, class _Compare, class _Allocator>
2473template <class _Key>
2474typename __tree<_Tp, _Compare, _Allocator>::iterator
2475__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2476 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002477 __iter_pointer __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002478{
2479 while (__root != nullptr)
2480 {
2481 if (!value_comp()(__root->__value_, __v))
2482 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002483 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002484 __root = static_cast<__node_pointer>(__root->__left_);
2485 }
2486 else
2487 __root = static_cast<__node_pointer>(__root->__right_);
2488 }
2489 return iterator(__result);
2490}
2491
2492template <class _Tp, class _Compare, class _Allocator>
2493template <class _Key>
2494typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2495__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00002496 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002497 __iter_pointer __result) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002498{
2499 while (__root != nullptr)
2500 {
2501 if (!value_comp()(__root->__value_, __v))
2502 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002503 __result = static_cast<__iter_pointer>(__root);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002504 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002505 }
2506 else
Eric Fiselier227b47c2016-02-20 07:12:17 +00002507 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002508 }
2509 return const_iterator(__result);
2510}
2511
2512template <class _Tp, class _Compare, class _Allocator>
2513template <class _Key>
2514typename __tree<_Tp, _Compare, _Allocator>::iterator
2515__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2516 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002517 __iter_pointer __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002518{
2519 while (__root != nullptr)
2520 {
2521 if (value_comp()(__v, __root->__value_))
2522 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002523 __result = static_cast<__iter_pointer>(__root);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002524 __root = static_cast<__node_pointer>(__root->__left_);
2525 }
2526 else
2527 __root = static_cast<__node_pointer>(__root->__right_);
2528 }
2529 return iterator(__result);
2530}
2531
2532template <class _Tp, class _Compare, class _Allocator>
2533template <class _Key>
2534typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2535__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
Eric Fiselier227b47c2016-02-20 07:12:17 +00002536 __node_pointer __root,
Eric Fiselier7310ec82016-07-19 17:56:20 +00002537 __iter_pointer __result) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002538{
2539 while (__root != nullptr)
2540 {
2541 if (value_comp()(__v, __root->__value_))
2542 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002543 __result = static_cast<__iter_pointer>(__root);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002544 __root = static_cast<__node_pointer>(__root->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002545 }
2546 else
Eric Fiselier227b47c2016-02-20 07:12:17 +00002547 __root = static_cast<__node_pointer>(__root->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002548 }
2549 return const_iterator(__result);
2550}
2551
2552template <class _Tp, class _Compare, class _Allocator>
2553template <class _Key>
2554pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2555 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2556__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2557{
Howard Hinnant99968442011-11-29 18:15:50 +00002558 typedef pair<iterator, iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002559 __iter_pointer __result = __end_node();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002560 __node_pointer __rt = __root();
2561 while (__rt != nullptr)
2562 {
2563 if (value_comp()(__k, __rt->__value_))
2564 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002565 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002566 __rt = static_cast<__node_pointer>(__rt->__left_);
2567 }
2568 else if (value_comp()(__rt->__value_, __k))
2569 __rt = static_cast<__node_pointer>(__rt->__right_);
2570 else
Howard Hinnant99968442011-11-29 18:15:50 +00002571 return _Pp(iterator(__rt),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002572 iterator(
2573 __rt->__right_ != nullptr ?
Eric Fiselier7310ec82016-07-19 17:56:20 +00002574 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002575 : __result));
2576 }
Howard Hinnant99968442011-11-29 18:15:50 +00002577 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002578}
2579
2580template <class _Tp, class _Compare, class _Allocator>
2581template <class _Key>
2582pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2583 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2584__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2585{
Howard Hinnant99968442011-11-29 18:15:50 +00002586 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002587 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002588 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002589 while (__rt != nullptr)
2590 {
2591 if (value_comp()(__k, __rt->__value_))
2592 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002593 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002594 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002595 }
2596 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002597 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002598 else
Howard Hinnant99968442011-11-29 18:15:50 +00002599 return _Pp(const_iterator(__rt),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002600 const_iterator(
2601 __rt->__right_ != nullptr ?
Eric Fiselier7310ec82016-07-19 17:56:20 +00002602 static_cast<__iter_pointer>(__tree_min(__rt->__right_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002603 : __result));
2604 }
Howard Hinnant99968442011-11-29 18:15:50 +00002605 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002606}
2607
2608template <class _Tp, class _Compare, class _Allocator>
2609template <class _Key>
2610pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2611 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2612__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2613{
Howard Hinnant99968442011-11-29 18:15:50 +00002614 typedef pair<iterator, iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002615 __iter_pointer __result = __end_node();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002616 __node_pointer __rt = __root();
2617 while (__rt != nullptr)
2618 {
2619 if (value_comp()(__k, __rt->__value_))
2620 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002621 __result = static_cast<__iter_pointer>(__rt);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002622 __rt = static_cast<__node_pointer>(__rt->__left_);
2623 }
2624 else if (value_comp()(__rt->__value_, __k))
2625 __rt = static_cast<__node_pointer>(__rt->__right_);
2626 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002627 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002628 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2629 }
Howard Hinnant99968442011-11-29 18:15:50 +00002630 return _Pp(iterator(__result), iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002631}
2632
2633template <class _Tp, class _Compare, class _Allocator>
2634template <class _Key>
2635pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2636 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2637__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2638{
Howard Hinnant99968442011-11-29 18:15:50 +00002639 typedef pair<const_iterator, const_iterator> _Pp;
Eric Fiselier7310ec82016-07-19 17:56:20 +00002640 __iter_pointer __result = __end_node();
Eric Fiselier227b47c2016-02-20 07:12:17 +00002641 __node_pointer __rt = __root();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002642 while (__rt != nullptr)
2643 {
2644 if (value_comp()(__k, __rt->__value_))
2645 {
Eric Fiselier7310ec82016-07-19 17:56:20 +00002646 __result = static_cast<__iter_pointer>(__rt);
Eric Fiselier227b47c2016-02-20 07:12:17 +00002647 __rt = static_cast<__node_pointer>(__rt->__left_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002648 }
2649 else if (value_comp()(__rt->__value_, __k))
Eric Fiselier227b47c2016-02-20 07:12:17 +00002650 __rt = static_cast<__node_pointer>(__rt->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002651 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002652 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
Eric Fiselier227b47c2016-02-20 07:12:17 +00002653 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002654 }
Howard Hinnant99968442011-11-29 18:15:50 +00002655 return _Pp(const_iterator(__result), const_iterator(__result));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002656}
2657
2658template <class _Tp, class _Compare, class _Allocator>
2659typename __tree<_Tp, _Compare, _Allocator>::__node_holder
Howard Hinnant8b537682011-06-04 17:10:24 +00002660__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002661{
Eric Fiselier7310ec82016-07-19 17:56:20 +00002662 __node_pointer __np = __p.__get_np();
2663 if (__begin_node() == __p.__ptr_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002664 {
2665 if (__np->__right_ != nullptr)
Eric Fiselier7310ec82016-07-19 17:56:20 +00002666 __begin_node() = static_cast<__iter_pointer>(__np->__right_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002667 else
Eric Fiselier7310ec82016-07-19 17:56:20 +00002668 __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002669 }
2670 --size();
2671 __tree_remove(__end_node()->__left_,
2672 static_cast<__node_base_pointer>(__np));
Marshall Clow01c1c6f2015-01-28 19:54:25 +00002673 return __node_holder(__np, _Dp(__node_alloc(), true));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002674}
2675
Howard Hinnant7686add2011-06-04 14:31:57 +00002676template <class _Tp, class _Compare, class _Allocator>
2677inline _LIBCPP_INLINE_VISIBILITY
2678void
2679swap(__tree<_Tp, _Compare, _Allocator>& __x,
2680 __tree<_Tp, _Compare, _Allocator>& __y)
2681 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2682{
2683 __x.swap(__y);
2684}
2685
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002686_LIBCPP_END_NAMESPACE_STD
2687
2688#endif // _LIBCPP___TREE