blob: 8f8efc26bae7380279fb763b5764c2ee17638ee0 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
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
20#pragma GCC system_header
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class, class, class> class __tree;
25template <class, class, class> class __tree_iterator;
26template <class, class, class> class __tree_const_iterator;
27template <class, class, class, class> class map;
28template <class, class, class, class> class multimap;
29template <class, class, class> class set;
30template <class, class, class> class multiset;
31
32/*
33
34_NodePtr algorithms
35
36The algorithms taking _NodePtr are red black tree algorithms. Those
37algorithms taking a parameter named __root should assume that __root
38points to a proper red black tree (unless otherwise specified).
39
40Each algorithm herein assumes that __root->__parent_ points to a non-null
41structure which has a member __left_ which points back to __root. No other
42member is read or written to at __root->__parent_.
43
44__root->__parent_ will be referred to below (in comments only) as end_node.
45end_node->__left_ is an externably accessible lvalue for __root, and can be
46changed by node insertion and removal (without explicit reference to end_node).
47
48All nodes (with the exception of end_node), even the node referred to as
49__root, have a non-null __parent_ field.
50
51*/
52
53// Returns: true if __x is a left child of its parent, else false
54// Precondition: __x != nullptr.
55template <class _NodePtr>
56inline
57bool
58__tree_is_left_child(_NodePtr __x)
59{
60 return __x == __x->__parent_->__left_;
61}
62
63// Determintes if the subtree rooted at __x is a proper red black subtree. If
64// __x is a proper subtree, returns the black height (null counts as 1). If
65// __x is an improper subtree, returns 0.
66template <class _NodePtr>
67unsigned
68__tree_sub_invariant(_NodePtr __x)
69{
70 if (__x == nullptr)
71 return 1;
72 // parent consistency checked by caller
73 // check __x->__left_ consistency
74 if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
75 return 0;
76 // check __x->__right_ consistency
77 if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
78 return 0;
79 // check __x->__left_ != __x->__right_ unless both are nullptr
80 if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
81 return 0;
82 // If this is red, neither child can be red
83 if (!__x->__is_black_)
84 {
85 if (__x->__left_ && !__x->__left_->__is_black_)
86 return 0;
87 if (__x->__right_ && !__x->__right_->__is_black_)
88 return 0;
89 }
90 unsigned __h = __tree_sub_invariant(__x->__left_);
91 if (__h == 0)
92 return 0; // invalid left subtree
93 if (__h != __tree_sub_invariant(__x->__right_))
94 return 0; // invalid or different height right subtree
95 return __h + __x->__is_black_; // return black height of this node
96}
97
98// Determintes if the red black tree rooted at __root is a proper red black tree.
99// __root == nullptr is a proper tree. Returns true is __root is a proper
100// red black tree, else returns false.
101template <class _NodePtr>
102bool
103__tree_invariant(_NodePtr __root)
104{
105 if (__root == nullptr)
106 return true;
107 // check __x->__parent_ consistency
108 if (__root->__parent_ == nullptr)
109 return false;
110 if (!__tree_is_left_child(__root))
111 return false;
112 // root must be black
113 if (!__root->__is_black_)
114 return false;
115 // do normal node checks
116 return __tree_sub_invariant(__root) != 0;
117}
118
119// Returns: pointer to the left-most node under __x.
120// Precondition: __x != nullptr.
121template <class _NodePtr>
122inline
123_NodePtr
124__tree_min(_NodePtr __x)
125{
126 while (__x->__left_ != nullptr)
127 __x = __x->__left_;
128 return __x;
129}
130
131// Returns: pointer to the right-most node under __x.
132// Precondition: __x != nullptr.
133template <class _NodePtr>
134inline
135_NodePtr
136__tree_max(_NodePtr __x)
137{
138 while (__x->__right_ != nullptr)
139 __x = __x->__right_;
140 return __x;
141}
142
143// Returns: pointer to the next in-order node after __x.
144// Precondition: __x != nullptr.
145template <class _NodePtr>
146_NodePtr
147__tree_next(_NodePtr __x)
148{
149 if (__x->__right_ != nullptr)
150 return __tree_min(__x->__right_);
151 while (!__tree_is_left_child(__x))
152 __x = __x->__parent_;
153 return __x->__parent_;
154}
155
156// Returns: pointer to the previous in-order node before __x.
157// Precondition: __x != nullptr.
158template <class _NodePtr>
159_NodePtr
160__tree_prev(_NodePtr __x)
161{
162 if (__x->__left_ != nullptr)
163 return __tree_max(__x->__left_);
164 while (__tree_is_left_child(__x))
165 __x = __x->__parent_;
166 return __x->__parent_;
167}
168
169// Returns: pointer to a node which has no children
170// Precondition: __x != nullptr.
171template <class _NodePtr>
172_NodePtr
173__tree_leaf(_NodePtr __x)
174{
175 while (true)
176 {
177 if (__x->__left_ != nullptr)
178 {
179 __x = __x->__left_;
180 continue;
181 }
182 if (__x->__right_ != nullptr)
183 {
184 __x = __x->__right_;
185 continue;
186 }
187 break;
188 }
189 return __x;
190}
191
192// Effects: Makes __x->__right_ the subtree root with __x as its left child
193// while preserving in-order order.
194// Precondition: __x->__right_ != nullptr
195template <class _NodePtr>
196void
197__tree_left_rotate(_NodePtr __x)
198{
199 _NodePtr __y = __x->__right_;
200 __x->__right_ = __y->__left_;
201 if (__x->__right_ != nullptr)
202 __x->__right_->__parent_ = __x;
203 __y->__parent_ = __x->__parent_;
204 if (__tree_is_left_child(__x))
205 __x->__parent_->__left_ = __y;
206 else
207 __x->__parent_->__right_ = __y;
208 __y->__left_ = __x;
209 __x->__parent_ = __y;
210}
211
212// Effects: Makes __x->__left_ the subtree root with __x as its right child
213// while preserving in-order order.
214// Precondition: __x->__left_ != nullptr
215template <class _NodePtr>
216void
217__tree_right_rotate(_NodePtr __x)
218{
219 _NodePtr __y = __x->__left_;
220 __x->__left_ = __y->__right_;
221 if (__x->__left_ != nullptr)
222 __x->__left_->__parent_ = __x;
223 __y->__parent_ = __x->__parent_;
224 if (__tree_is_left_child(__x))
225 __x->__parent_->__left_ = __y;
226 else
227 __x->__parent_->__right_ = __y;
228 __y->__right_ = __x;
229 __x->__parent_ = __y;
230}
231
232// Effects: Rebalances __root after attaching __x to a leaf.
233// Precondition: __root != nulptr && __x != nullptr.
234// __x has no children.
235// __x == __root or == a direct or indirect child of __root.
236// If __x were to be unlinked from __root (setting __root to
237// nullptr if __root == __x), __tree_invariant(__root) == true.
238// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_
239// may be different than the value passed in as __root.
240template <class _NodePtr>
241void
242__tree_balance_after_insert(_NodePtr __root, _NodePtr __x)
243{
244 __x->__is_black_ = __x == __root;
245 while (__x != __root && !__x->__parent_->__is_black_)
246 {
247 // __x->__parent_ != __root because __x->__parent_->__is_black == false
248 if (__tree_is_left_child(__x->__parent_))
249 {
250 _NodePtr __y = __x->__parent_->__parent_->__right_;
251 if (__y != nullptr && !__y->__is_black_)
252 {
253 __x = __x->__parent_;
254 __x->__is_black_ = true;
255 __x = __x->__parent_;
256 __x->__is_black_ = __x == __root;
257 __y->__is_black_ = true;
258 }
259 else
260 {
261 if (!__tree_is_left_child(__x))
262 {
263 __x = __x->__parent_;
264 __tree_left_rotate(__x);
265 }
266 __x = __x->__parent_;
267 __x->__is_black_ = true;
268 __x = __x->__parent_;
269 __x->__is_black_ = false;
270 __tree_right_rotate(__x);
271 break;
272 }
273 }
274 else
275 {
276 _NodePtr __y = __x->__parent_->__parent_->__left_;
277 if (__y != nullptr && !__y->__is_black_)
278 {
279 __x = __x->__parent_;
280 __x->__is_black_ = true;
281 __x = __x->__parent_;
282 __x->__is_black_ = __x == __root;
283 __y->__is_black_ = true;
284 }
285 else
286 {
287 if (__tree_is_left_child(__x))
288 {
289 __x = __x->__parent_;
290 __tree_right_rotate(__x);
291 }
292 __x = __x->__parent_;
293 __x->__is_black_ = true;
294 __x = __x->__parent_;
295 __x->__is_black_ = false;
296 __tree_left_rotate(__x);
297 break;
298 }
299 }
300 }
301}
302
303// Precondition: __root != nullptr && __z != nullptr.
304// __tree_invariant(__root) == true.
305// __z == __root or == a direct or indirect child of __root.
306// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed.
307// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
308// nor any of its children refer to __z. end_node->__left_
309// may be different than the value passed in as __root.
310template <class _NodePtr>
311void
312__tree_remove(_NodePtr __root, _NodePtr __z)
313{
314 // __z will be removed from the tree. Client still needs to destruct/deallocate it
315 // __y is either __z, or if __z has two children, __tree_next(__z).
316 // __y will have at most one child.
317 // __y will be the initial hole in the tree (make the hole at a leaf)
318 _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
319 __z : __tree_next(__z);
320 // __x is __y's possibly null single child
321 _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
322 // __w is __x's possibly null uncle (will become __x's sibling)
323 _NodePtr __w = nullptr;
324 // link __x to __y's parent, and find __w
325 if (__x != nullptr)
326 __x->__parent_ = __y->__parent_;
327 if (__tree_is_left_child(__y))
328 {
329 __y->__parent_->__left_ = __x;
330 if (__y != __root)
331 __w = __y->__parent_->__right_;
332 else
333 __root = __x; // __w == nullptr
334 }
335 else
336 {
337 __y->__parent_->__right_ = __x;
338 // __y can't be root if it is a right child
339 __w = __y->__parent_->__left_;
340 }
341 bool __removed_black = __y->__is_black_;
342 // If we didn't remove __z, do so now by splicing in __y for __z,
343 // but copy __z's color. This does not impact __x or __w.
344 if (__y != __z)
345 {
346 // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
347 __y->__parent_ = __z->__parent_;
348 if (__tree_is_left_child(__z))
349 __y->__parent_->__left_ = __y;
350 else
351 __y->__parent_->__right_ = __y;
352 __y->__left_ = __z->__left_;
353 __y->__left_->__parent_ = __y;
354 __y->__right_ = __z->__right_;
355 if (__y->__right_ != nullptr)
356 __y->__right_->__parent_ = __y;
357 __y->__is_black_ = __z->__is_black_;
358 if (__root == __z)
359 __root = __y;
360 }
361 // There is no need to rebalance if we removed a red, or if we removed
362 // the last node.
363 if (__removed_black && __root != nullptr)
364 {
365 // Rebalance:
366 // __x has an implicit black color (transferred from the removed __y)
367 // associated with it, no matter what its color is.
368 // If __x is __root (in which case it can't be null), it is supposed
369 // to be black anyway, and if it is doubly black, then the double
370 // can just be ignored.
371 // If __x is red (in which case it can't be null), then it can absorb
372 // the implicit black just by setting its color to black.
373 // Since __y was black and only had one child (which __x points to), __x
374 // is either red with no children, else null, otherwise __y would have
375 // different black heights under left and right pointers.
376 // if (__x == __root || __x != nullptr && !__x->__is_black_)
377 if (__x != nullptr)
378 __x->__is_black_ = true;
379 else
380 {
381 // Else __x isn't root, and is "doubly black", even though it may
382 // be null. __w can not be null here, else the parent would
383 // see a black height >= 2 on the __x side and a black height
384 // of 1 on the __w side (__w must be a non-null black or a red
385 // with a non-null black child).
386 while (true)
387 {
388 if (!__tree_is_left_child(__w)) // if x is left child
389 {
390 if (!__w->__is_black_)
391 {
392 __w->__is_black_ = true;
393 __w->__parent_->__is_black_ = false;
394 __tree_left_rotate(__w->__parent_);
395 // __x is still valid
396 // reset __root only if necessary
397 if (__root == __w->__left_)
398 __root = __w;
399 // reset sibling, and it still can't be null
400 __w = __w->__left_->__right_;
401 }
402 // __w->__is_black_ is now true, __w may have null children
403 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
404 (__w->__right_ == nullptr || __w->__right_->__is_black_))
405 {
406 __w->__is_black_ = false;
407 __x = __w->__parent_;
408 // __x can no longer be null
409 if (__x == __root || !__x->__is_black_)
410 {
411 __x->__is_black_ = true;
412 break;
413 }
414 // reset sibling, and it still can't be null
415 __w = __tree_is_left_child(__x) ?
416 __x->__parent_->__right_ :
417 __x->__parent_->__left_;
418 // continue;
419 }
420 else // __w has a red child
421 {
422 if (__w->__right_ == nullptr || __w->__right_->__is_black_)
423 {
424 // __w left child is non-null and red
425 __w->__left_->__is_black_ = true;
426 __w->__is_black_ = false;
427 __tree_right_rotate(__w);
428 // __w is known not to be root, so root hasn't changed
429 // reset sibling, and it still can't be null
430 __w = __w->__parent_;
431 }
432 // __w has a right red child, left child may be null
433 __w->__is_black_ = __w->__parent_->__is_black_;
434 __w->__parent_->__is_black_ = true;
435 __w->__right_->__is_black_ = true;
436 __tree_left_rotate(__w->__parent_);
437 break;
438 }
439 }
440 else
441 {
442 if (!__w->__is_black_)
443 {
444 __w->__is_black_ = true;
445 __w->__parent_->__is_black_ = false;
446 __tree_right_rotate(__w->__parent_);
447 // __x is still valid
448 // reset __root only if necessary
449 if (__root == __w->__right_)
450 __root = __w;
451 // reset sibling, and it still can't be null
452 __w = __w->__right_->__left_;
453 }
454 // __w->__is_black_ is now true, __w may have null children
455 if ((__w->__left_ == nullptr || __w->__left_->__is_black_) &&
456 (__w->__right_ == nullptr || __w->__right_->__is_black_))
457 {
458 __w->__is_black_ = false;
459 __x = __w->__parent_;
460 // __x can no longer be null
461 if (!__x->__is_black_ || __x == __root)
462 {
463 __x->__is_black_ = true;
464 break;
465 }
466 // reset sibling, and it still can't be null
467 __w = __tree_is_left_child(__x) ?
468 __x->__parent_->__right_ :
469 __x->__parent_->__left_;
470 // continue;
471 }
472 else // __w has a red child
473 {
474 if (__w->__left_ == nullptr || __w->__left_->__is_black_)
475 {
476 // __w right child is non-null and red
477 __w->__right_->__is_black_ = true;
478 __w->__is_black_ = false;
479 __tree_left_rotate(__w);
480 // __w is known not to be root, so root hasn't changed
481 // reset sibling, and it still can't be null
482 __w = __w->__parent_;
483 }
484 // __w has a left red child, right child may be null
485 __w->__is_black_ = __w->__parent_->__is_black_;
486 __w->__parent_->__is_black_ = true;
487 __w->__left_->__is_black_ = true;
488 __tree_right_rotate(__w->__parent_);
489 break;
490 }
491 }
492 }
493 }
494 }
495}
496
497template <class> class __map_node_destructor;
498
499
500template <class _Allocator>
501class __tree_node_destructor
502{
503 typedef _Allocator allocator_type;
504 typedef allocator_traits<allocator_type> __alloc_traits;
505 typedef typename __alloc_traits::value_type::value_type value_type;
506public:
507 typedef typename __alloc_traits::pointer pointer;
508private:
509
510 allocator_type& __na_;
511
512 __tree_node_destructor& operator=(const __tree_node_destructor&);
513
514public:
515 bool __value_constructed;
516
517 explicit __tree_node_destructor(allocator_type& __na)
518 : __na_(__na),
519 __value_constructed(false)
520 {}
521
522 void operator()(pointer __p)
523 {
524 if (__value_constructed)
525 __alloc_traits::destroy(__na_, addressof(__p->__value_));
526 if (__p)
527 __alloc_traits::deallocate(__na_, __p, 1);
528 }
529
530 template <class> friend class __map_node_destructor;
531};
532
533// node
534
535template <class _Pointer>
536class __tree_end_node
537{
538public:
539 typedef _Pointer pointer;
540 pointer __left_;
541
542 __tree_end_node() : __left_() {}
543};
544
545template <class _VoidPtr>
546class __tree_node_base
547 : public __tree_end_node
548 <
549 typename pointer_traits<_VoidPtr>::template
550#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
551 rebind<__tree_node_base<_VoidPtr> >
552#else
553 rebind<__tree_node_base<_VoidPtr> >::other
554#endif
555 >
556{
557 __tree_node_base(const __tree_node_base&);
558 __tree_node_base& operator=(const __tree_node_base&);
559public:
560 typedef typename pointer_traits<_VoidPtr>::template
561#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
562 rebind<__tree_node_base>
563#else
564 rebind<__tree_node_base>::other
565#endif
566 pointer;
567 typedef typename pointer_traits<_VoidPtr>::template
568#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
569 rebind<const __tree_node_base>
570#else
571 rebind<const __tree_node_base>::other
572#endif
573 const_pointer;
574 typedef __tree_end_node<pointer> base;
575
576 pointer __right_;
577 pointer __parent_;
578 bool __is_black_;
579
580 __tree_node_base() : __right_(), __parent_(), __is_black_(false) {}
581};
582
583template <class _Tp, class _VoidPtr>
584class __tree_node
585 : public __tree_node_base<_VoidPtr>
586{
587public:
588 typedef __tree_node_base<_VoidPtr> base;
589 typedef _Tp value_type;
590
591 value_type __value_;
592
593#ifdef _LIBCPP_MOVE
594 template <class ..._Args>
595 explicit __tree_node(_Args&& ...__args)
596 : __value_(_STD::forward<_Args>(__args)...) {}
597#else
598 explicit __tree_node(const value_type& __v)
599 : __value_(__v) {}
600#endif
601};
602
603template <class> class __map_iterator;
604template <class> class __map_const_iterator;
605
606template <class _Tp, class _NodePtr, class _DiffType>
607class __tree_iterator
608{
609 typedef _NodePtr __node_pointer;
610 typedef typename pointer_traits<__node_pointer>::element_type __node;
611 typedef typename __node::base __node_base;
612 typedef typename __node_base::pointer __node_base_pointer;
613
614 __node_pointer __ptr_;
615
616 typedef pointer_traits<__node_pointer> __pointer_traits;
617public:
618 typedef bidirectional_iterator_tag iterator_category;
619 typedef _Tp value_type;
620 typedef _DiffType difference_type;
621 typedef value_type& reference;
622 typedef typename pointer_traits<__node_pointer>::template
623#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
624 rebind<value_type>
625#else
626 rebind<value_type>::other
627#endif
628 pointer;
629
630 __tree_iterator() {}
631
632 reference operator*() const {return __ptr_->__value_;}
633 pointer operator->() const {return &__ptr_->__value_;}
634
635 __tree_iterator& operator++()
636 {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
637 return *this;}
638 __tree_iterator operator++(int)
639 {__tree_iterator __t(*this); ++(*this); return __t;}
640
641 __tree_iterator& operator--()
642 {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
643 return *this;}
644 __tree_iterator operator--(int)
645 {__tree_iterator __t(*this); --(*this); return __t;}
646
647 friend bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
648 {return __x.__ptr_ == __y.__ptr_;}
649 friend bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
650 {return !(__x == __y);}
651
652private:
653 explicit __tree_iterator(__node_pointer __p) : __ptr_(__p) {}
654 template <class, class, class> friend class __tree;
655 template <class, class, class> friend class __tree_const_iterator;
656 template <class> friend class __map_iterator;
657 template <class, class, class, class> friend class map;
658 template <class, class, class, class> friend class multimap;
659 template <class, class, class> friend class set;
660 template <class, class, class> friend class multiset;
661};
662
663template <class _Tp, class _ConstNodePtr, class _DiffType>
664class __tree_const_iterator
665{
666 typedef _ConstNodePtr __node_pointer;
667 typedef typename pointer_traits<__node_pointer>::element_type __node;
668 typedef const typename __node::base __node_base;
669 typedef typename pointer_traits<__node_pointer>::template
670#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
671 rebind<__node_base>
672#else
673 rebind<__node_base>::other
674#endif
675 __node_base_pointer;
676
677 __node_pointer __ptr_;
678
679 typedef pointer_traits<__node_pointer> __pointer_traits;
680public:
681 typedef bidirectional_iterator_tag iterator_category;
682 typedef _Tp value_type;
683 typedef _DiffType difference_type;
684 typedef const value_type& reference;
685 typedef typename pointer_traits<__node_pointer>::template
686#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
687 rebind<const value_type>
688#else
689 rebind<const value_type>::other
690#endif
691 pointer;
692
693 __tree_const_iterator() {}
694private:
695 typedef typename remove_const<__node>::type __non_const_node;
696 typedef typename pointer_traits<__node_pointer>::template
697#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
698 rebind<__non_const_node>
699#else
700 rebind<__non_const_node>::other
701#endif
702 __non_const_node_pointer;
703 typedef __tree_iterator<value_type, __non_const_node_pointer, difference_type>
704 __non_const_iterator;
705public:
706 __tree_const_iterator(__non_const_iterator __p) : __ptr_(__p.__ptr_) {}
707
708 reference operator*() const {return __ptr_->__value_;}
709 pointer operator->() const {return &__ptr_->__value_;}
710
711 __tree_const_iterator& operator++()
712 {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
713 return *this;}
714 __tree_const_iterator operator++(int)
715 {__tree_const_iterator __t(*this); ++(*this); return __t;}
716
717 __tree_const_iterator& operator--()
718 {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
719 return *this;}
720 __tree_const_iterator operator--(int)
721 {__tree_const_iterator __t(*this); --(*this); return __t;}
722
723 friend bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
724 {return __x.__ptr_ == __y.__ptr_;}
725 friend bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
726 {return !(__x == __y);}
727
728private:
729 explicit __tree_const_iterator(__node_pointer __p) : __ptr_(__p) {}
730 template <class, class, class> friend class __tree;
731 template <class, class, class, class> friend class map;
732 template <class, class, class, class> friend class multimap;
733 template <class, class, class> friend class set;
734 template <class, class, class> friend class multiset;
735 template <class> friend class __map_const_iterator;
736};
737
738template <class _Tp, class _Compare, class _Allocator>
739class __tree
740{
741public:
742 typedef _Tp value_type;
743 typedef _Compare value_compare;
744 typedef _Allocator allocator_type;
745 typedef allocator_traits<allocator_type> __alloc_traits;
746 typedef typename __alloc_traits::pointer pointer;
747 typedef typename __alloc_traits::const_pointer const_pointer;
748 typedef typename __alloc_traits::size_type size_type;
749 typedef typename __alloc_traits::difference_type difference_type;
750
751 typedef __tree_node<value_type, typename __alloc_traits::void_pointer> __node;
752 typedef typename __alloc_traits::template
753#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
754 rebind_alloc<__node>
755#else
756 rebind_alloc<__node>::other
757#endif
758 __node_allocator;
759 typedef allocator_traits<__node_allocator> __node_traits;
760 typedef typename __node_traits::pointer __node_pointer;
761 typedef typename __node_traits::const_pointer __node_const_pointer;
762 typedef typename __node::base::pointer __node_base_pointer;
763 typedef typename __node::base::const_pointer __node_base_const_pointer;
764private:
765 typedef typename __node::base::base __end_node_t;
766 typedef typename pointer_traits<__node_pointer>::template
767#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
768 rebind<__end_node_t>
769#else
770 rebind<__end_node_t>::other
771#endif
772 __end_node_ptr;
773 typedef typename pointer_traits<__node_pointer>::template
774#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
775 rebind<const __end_node_t>
776#else
777 rebind<const __end_node_t>::other
778#endif
779 __end_node_const_ptr;
780
781 __node_pointer __begin_node_;
782 __compressed_pair<__end_node_t, __node_allocator> __pair1_;
783 __compressed_pair<size_type, value_compare> __pair3_;
784
785public:
786 __node_pointer __end_node()
787 {
788 return static_cast<__node_pointer>
789 (
790 pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
791 );
792 }
793 __node_const_pointer __end_node() const
794 {
795 return static_cast<__node_const_pointer>
796 (
797 pointer_traits<__end_node_const_ptr>::pointer_to(__pair1_.first())
798 );
799 }
800 __node_allocator& __node_alloc() {return __pair1_.second();}
801private:
802 const __node_allocator& __node_alloc() const {return __pair1_.second();}
803 __node_pointer& __begin_node() {return __begin_node_;}
804 const __node_pointer& __begin_node() const {return __begin_node_;}
805public:
806 allocator_type __alloc() const {return allocator_type(__node_alloc());}
807private:
808 size_type& size() {return __pair3_.first();}
809public:
810 const size_type& size() const {return __pair3_.first();}
811 value_compare& value_comp() {return __pair3_.second();}
812 const value_compare& value_comp() const {return __pair3_.second();}
813public:
814 __node_pointer __root()
815 {return static_cast<__node_pointer> (__end_node()->__left_);}
816 __node_const_pointer __root() const
817 {return static_cast<__node_const_pointer>(__end_node()->__left_);}
818
819 typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator;
820 typedef __tree_const_iterator<value_type, __node_const_pointer, difference_type> const_iterator;
821
822 explicit __tree(const value_compare& __comp);
823 explicit __tree(const allocator_type& __a);
824 __tree(const value_compare& __comp, const allocator_type& __a);
825 __tree(const __tree& __t);
826 __tree& operator=(const __tree& __t);
827 template <class _InputIterator>
828 void __assign_unique(_InputIterator __first, _InputIterator __last);
829 template <class _InputIterator>
830 void __assign_multi(_InputIterator __first, _InputIterator __last);
831#ifdef _LIBCPP_MOVE
832 __tree(__tree&& __t);
833 __tree(__tree&& __t, const allocator_type& __a);
834 __tree& operator=(__tree&& __t);
835#endif
836
837 ~__tree();
838
839 iterator begin() {return iterator(__begin_node());}
840 const_iterator begin() const {return const_iterator(__begin_node());}
841 iterator end() {return iterator(__end_node());}
842 const_iterator end() const {return const_iterator(__end_node());}
843
844 size_type max_size() const {return __node_traits::max_size(__node_alloc());}
845
846 void clear();
847
848 void swap(__tree& __t);
849
850#ifdef _LIBCPP_MOVE
851 template <class... _Args>
852 pair<iterator, bool>
853 __emplace_unique(_Args&&... __args);
854 template <class... _Args>
855 iterator
856 __emplace_multi(_Args&&... __args);
857
858 template <class... _Args>
859 iterator
860 __emplace_hint_unique(const_iterator __p, _Args&&... __args);
861 template <class... _Args>
862 iterator
863 __emplace_hint_multi(const_iterator __p, _Args&&... __args);
864
865 template <class _V>
866 pair<iterator, bool> __insert_unique(_V&& __v);
867 template <class _V>
868 iterator __insert_unique(const_iterator __p, _V&& __v);
869 template <class _V>
870 iterator __insert_multi(_V&& __v);
871 template <class _V>
872 iterator __insert_multi(const_iterator __p, _V&& __v);
873#else
874
875 pair<iterator, bool> __insert_unique(const value_type& __v);
876 iterator __insert_unique(const_iterator __p, const value_type& __v);
877 iterator __insert_multi(const value_type& __v);
878 iterator __insert_multi(const_iterator __p, const value_type& __v);
879#endif
880
881 pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
882 iterator __node_insert_unique(const_iterator __p,
883 __node_pointer __nd);
884
885 iterator __node_insert_multi(__node_pointer __nd);
886 iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
887
888 iterator erase(const_iterator __p);
889 iterator erase(const_iterator __f, const_iterator __l);
890 template <class _Key>
891 size_type __erase_unique(const _Key& __k);
892 template <class _Key>
893 size_type __erase_multi(const _Key& __k);
894
895 void __insert_node_at(__node_base_pointer __parent,
896 __node_base_pointer& __child,
897 __node_base_pointer __new_node);
898
899 template <class _Key>
900 iterator find(const _Key& __v);
901 template <class _Key>
902 const_iterator find(const _Key& __v) const;
903
904 template <class _Key>
905 size_type __count_unique(const _Key& __k) const;
906 template <class _Key>
907 size_type __count_multi(const _Key& __k) const;
908
909 template <class _Key>
910 iterator lower_bound(const _Key& __v)
911 {return __lower_bound(__v, __root(), __end_node());}
912 template <class _Key>
913 iterator __lower_bound(const _Key& __v,
914 __node_pointer __root,
915 __node_pointer __result);
916 template <class _Key>
917 const_iterator lower_bound(const _Key& __v) const
918 {return __lower_bound(__v, __root(), __end_node());}
919 template <class _Key>
920 const_iterator __lower_bound(const _Key& __v,
921 __node_const_pointer __root,
922 __node_const_pointer __result) const;
923 template <class _Key>
924 iterator upper_bound(const _Key& __v)
925 {return __upper_bound(__v, __root(), __end_node());}
926 template <class _Key>
927 iterator __upper_bound(const _Key& __v,
928 __node_pointer __root,
929 __node_pointer __result);
930 template <class _Key>
931 const_iterator upper_bound(const _Key& __v) const
932 {return __upper_bound(__v, __root(), __end_node());}
933 template <class _Key>
934 const_iterator __upper_bound(const _Key& __v,
935 __node_const_pointer __root,
936 __node_const_pointer __result) const;
937 template <class _Key>
938 pair<iterator, iterator>
939 __equal_range_unique(const _Key& __k);
940 template <class _Key>
941 pair<const_iterator, const_iterator>
942 __equal_range_unique(const _Key& __k) const;
943
944 template <class _Key>
945 pair<iterator, iterator>
946 __equal_range_multi(const _Key& __k);
947 template <class _Key>
948 pair<const_iterator, const_iterator>
949 __equal_range_multi(const _Key& __k) const;
950
951 typedef __tree_node_destructor<__node_allocator> _D;
952 typedef unique_ptr<__node, _D> __node_holder;
953
954 __node_holder remove(const_iterator __p);
955private:
956 typename __node::base::pointer&
957 __find_leaf_low(typename __node::base::pointer& __parent, const value_type& __v);
958 typename __node::base::pointer&
959 __find_leaf_high(typename __node::base::pointer& __parent, const value_type& __v);
960 typename __node::base::pointer&
961 __find_leaf(const_iterator __hint,
962 typename __node::base::pointer& __parent, const value_type& __v);
963 template <class _Key>
964 typename __node::base::pointer&
965 __find_equal(typename __node::base::pointer& __parent, const _Key& __v);
966 template <class _Key>
967 typename __node::base::pointer&
968 __find_equal(const_iterator __hint, typename __node::base::pointer& __parent,
969 const _Key& __v);
970
971#ifdef _LIBCPP_MOVE
972 template <class ..._Args>
973 __node_holder __construct_node(_Args&& ...__args);
974#else
975 __node_holder __construct_node(const value_type& __v);
976#endif
977
978 void destroy(__node_pointer __nd);
979
980 void __copy_assign_alloc(const __tree& __t)
981 {__copy_assign_alloc(__t, integral_constant<bool,
982 __node_traits::propagate_on_container_copy_assignment::value>());}
983
984 void __copy_assign_alloc(const __tree& __t, true_type)
985 {__node_alloc() = __t.__node_alloc();}
986 void __copy_assign_alloc(const __tree& __t, false_type) {}
987
988 void __move_assign(__tree& __t, false_type);
989 void __move_assign(__tree& __t, true_type);
990
991 void __move_assign_alloc(__tree& __t)
992 {__move_assign_alloc(__t, integral_constant<bool,
993 __node_traits::propagate_on_container_move_assignment::value>());}
994
995 void __move_assign_alloc(__tree& __t, true_type)
996 {__node_alloc() = _STD::move(__t.__node_alloc());}
997 void __move_assign_alloc(__tree& __t, false_type) {}
998
999 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
1000 {__swap_alloc(__x, __y, integral_constant<bool,
1001 __node_traits::propagate_on_container_swap::value>());}
1002 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
1003 {
1004 using _STD::swap;
1005 swap(__x, __y);
1006 }
1007 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
1008 {}
1009
1010 __node_pointer __detach();
1011 static __node_pointer __detach(__node_pointer);
1012};
1013
1014template <class _Tp, class _Compare, class _Allocator>
1015__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
1016 : __pair3_(0, __comp)
1017{
1018 __begin_node() = __end_node();
1019}
1020
1021template <class _Tp, class _Compare, class _Allocator>
1022__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
1023 : __pair1_(__node_allocator(__a)),
1024 __begin_node_(__node_pointer()),
1025 __pair3_(0)
1026{
1027 __begin_node() = __end_node();
1028}
1029
1030template <class _Tp, class _Compare, class _Allocator>
1031__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
1032 const allocator_type& __a)
1033 : __pair1_(__node_allocator(__a)),
1034 __begin_node_(__node_pointer()),
1035 __pair3_(0, __comp)
1036{
1037 __begin_node() = __end_node();
1038}
1039
1040// Precondition: size() != 0
1041template <class _Tp, class _Compare, class _Allocator>
1042typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1043__tree<_Tp, _Compare, _Allocator>::__detach()
1044{
1045 __node_pointer __cache = __begin_node();
1046 __begin_node() = __end_node();
1047 __end_node()->__left_->__parent_ = nullptr;
1048 __end_node()->__left_ = nullptr;
1049 size() = 0;
1050 // __cache->__left_ == nullptr
1051 if (__cache->__right_ != nullptr)
1052 __cache = static_cast<__node_pointer>(__cache->__right_);
1053 // __cache->__left_ == nullptr
1054 // __cache->__right_ == nullptr
1055 return __cache;
1056}
1057
1058// Precondition: __cache != nullptr
1059// __cache->left_ == nullptr
1060// __cache->right_ == nullptr
1061// This is no longer a red-black tree
1062template <class _Tp, class _Compare, class _Allocator>
1063typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1064__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
1065{
1066 if (__cache->__parent_ == nullptr)
1067 return nullptr;
1068 if (__tree_is_left_child(__cache))
1069 {
1070 __cache->__parent_->__left_ = nullptr;
1071 __cache = static_cast<__node_pointer>(__cache->__parent_);
1072 if (__cache->__right_ == nullptr)
1073 return __cache;
1074 return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
1075 }
1076 // __cache is right child
1077 __cache->__parent_->__right_ = nullptr;
1078 __cache = static_cast<__node_pointer>(__cache->__parent_);
1079 if (__cache->__left_ == nullptr)
1080 return __cache;
1081 return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
1082}
1083
1084template <class _Tp, class _Compare, class _Allocator>
1085__tree<_Tp, _Compare, _Allocator>&
1086__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
1087{
1088 if (this != &__t)
1089 {
1090 value_comp() = __t.value_comp();
1091 __copy_assign_alloc(__t);
1092 __assign_multi(__t.begin(), __t.end());
1093 }
1094 return *this;
1095}
1096
1097template <class _Tp, class _Compare, class _Allocator>
1098template <class _InputIterator>
1099void
1100__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
1101{
1102 if (size() != 0)
1103 {
1104 __node_pointer __cache = __detach();
1105 try
1106 {
1107 for (; __cache != nullptr && __first != __last; ++__first)
1108 {
1109 __cache->__value_ = *__first;
1110 __node_pointer __next = __detach(__cache);
1111 __node_insert_unique(__cache);
1112 __cache = __next;
1113 }
1114 }
1115 catch (...)
1116 {
1117 while (__cache->__parent_ != nullptr)
1118 __cache = static_cast<__node_pointer>(__cache->__parent_);
1119 destroy(__cache);
1120 throw;
1121 }
1122 if (__cache != nullptr)
1123 {
1124 while (__cache->__parent_ != nullptr)
1125 __cache = static_cast<__node_pointer>(__cache->__parent_);
1126 destroy(__cache);
1127 }
1128 }
1129 for (; __first != __last; ++__first)
1130 __insert_unique(*__first);
1131}
1132
1133template <class _Tp, class _Compare, class _Allocator>
1134template <class _InputIterator>
1135void
1136__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1137{
1138 if (size() != 0)
1139 {
1140 __node_pointer __cache = __detach();
1141 try
1142 {
1143 for (; __cache != nullptr && __first != __last; ++__first)
1144 {
1145 __cache->__value_ = *__first;
1146 __node_pointer __next = __detach(__cache);
1147 __node_insert_multi(__cache);
1148 __cache = __next;
1149 }
1150 }
1151 catch (...)
1152 {
1153 while (__cache->__parent_ != nullptr)
1154 __cache = static_cast<__node_pointer>(__cache->__parent_);
1155 destroy(__cache);
1156 throw;
1157 }
1158 if (__cache != nullptr)
1159 {
1160 while (__cache->__parent_ != nullptr)
1161 __cache = static_cast<__node_pointer>(__cache->__parent_);
1162 destroy(__cache);
1163 }
1164 }
1165 for (; __first != __last; ++__first)
1166 __insert_multi(*__first);
1167}
1168
1169template <class _Tp, class _Compare, class _Allocator>
1170__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
1171 : __begin_node_(__node_pointer()),
1172 __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
1173 __pair3_(0, __t.value_comp())
1174{
1175 __begin_node() = __end_node();
1176}
1177
1178#ifdef _LIBCPP_MOVE
1179
1180template <class _Tp, class _Compare, class _Allocator>
1181__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
1182 : __begin_node_(_STD::move(__t.__begin_node_)),
1183 __pair1_(_STD::move(__t.__pair1_)),
1184 __pair3_(_STD::move(__t.__pair3_))
1185{
1186 if (size() == 0)
1187 __begin_node() = __end_node();
1188 else
1189 {
1190 __end_node()->__left_->__parent_ = __end_node();
1191 __t.__begin_node() = __t.__end_node();
1192 __t.__end_node()->__left_ = nullptr;
1193 __t.size() = 0;
1194 }
1195}
1196
1197template <class _Tp, class _Compare, class _Allocator>
1198__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1199 : __pair1_(__node_allocator(__a)),
1200 __pair3_(0, _STD::move(__t.value_comp()))
1201{
1202 if (__a == __t.__alloc())
1203 {
1204 if (__t.size() == 0)
1205 __begin_node() = __end_node();
1206 else
1207 {
1208 __begin_node() = __t.__begin_node();
1209 __end_node()->__left_ = __t.__end_node()->__left_;
1210 __end_node()->__left_->__parent_ = __end_node();
1211 size() = __t.size();
1212 __t.__begin_node() = __t.__end_node();
1213 __t.__end_node()->__left_ = nullptr;
1214 __t.size() = 0;
1215 }
1216 }
1217 else
1218 {
1219 __begin_node() = __end_node();
1220 }
1221}
1222
1223template <class _Tp, class _Compare, class _Allocator>
1224void
1225__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
1226{
1227 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1228 __begin_node_ = __t.__begin_node_;
1229 __pair1_.first() = __t.__pair1_.first();
1230 __move_assign_alloc(__t);
1231 __pair3_ = _STD::move(__t.__pair3_);
1232 if (size() == 0)
1233 __begin_node() = __end_node();
1234 else
1235 {
1236 __end_node()->__left_->__parent_ = __end_node();
1237 __t.__begin_node() = __t.__end_node();
1238 __t.__end_node()->__left_ = nullptr;
1239 __t.size() = 0;
1240 }
1241}
1242
1243template <class _Tp, class _Compare, class _Allocator>
1244void
1245__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1246{
1247 if (__node_alloc() == __t.__node_alloc())
1248 __move_assign(__t, true_type());
1249 else
1250 {
1251 value_comp() = _STD::move(__t.value_comp());
1252 const_iterator __e = end();
1253 if (size() != 0)
1254 {
1255 __node_pointer __cache = __detach();
1256 try
1257 {
1258 while (__cache != nullptr && __t.size() != 0)
1259 {
1260 __cache->__value_ = _STD::move(__t.remove(__t.begin())->__value_);
1261 __node_pointer __next = __detach(__cache);
1262 __node_insert_multi(__cache);
1263 __cache = __next;
1264 }
1265 }
1266 catch (...)
1267 {
1268 while (__cache->__parent_ != nullptr)
1269 __cache = static_cast<__node_pointer>(__cache->__parent_);
1270 destroy(__cache);
1271 throw;
1272 }
1273 if (__cache != nullptr)
1274 {
1275 while (__cache->__parent_ != nullptr)
1276 __cache = static_cast<__node_pointer>(__cache->__parent_);
1277 destroy(__cache);
1278 }
1279 }
1280 while (__t.size() != 0)
1281 __insert_multi(__e, _STD::move(__t.remove(__t.begin())->__value_));
1282 }
1283}
1284
1285template <class _Tp, class _Compare, class _Allocator>
1286__tree<_Tp, _Compare, _Allocator>&
1287__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
1288{
1289 __move_assign(__t, integral_constant<bool,
1290 __node_traits::propagate_on_container_move_assignment::value>());
1291 return *this;
1292}
1293
1294#endif
1295
1296template <class _Tp, class _Compare, class _Allocator>
1297__tree<_Tp, _Compare, _Allocator>::~__tree()
1298{
1299 destroy(__root());
1300}
1301
1302template <class _Tp, class _Compare, class _Allocator>
1303void
1304__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd)
1305{
1306 if (__nd != nullptr)
1307 {
1308 destroy(static_cast<__node_pointer>(__nd->__left_));
1309 destroy(static_cast<__node_pointer>(__nd->__right_));
1310 __node_allocator& __na = __node_alloc();
1311 __node_traits::destroy(__na, addressof(__nd->__value_));
1312 __node_traits::deallocate(__na, __nd, 1);
1313 }
1314}
1315
1316template <class _Tp, class _Compare, class _Allocator>
1317void
1318__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
1319{
1320 using _STD::swap;
1321 swap(__begin_node_, __t.__begin_node_);
1322 swap(__pair1_.first(), __t.__pair1_.first());
1323 __swap_alloc(__node_alloc(), __t.__node_alloc());
1324 __pair3_.swap(__t.__pair3_);
1325 if (size() == 0)
1326 __begin_node() = __end_node();
1327 else
1328 __end_node()->__left_->__parent_ = __end_node();
1329 if (__t.size() == 0)
1330 __t.__begin_node() = __t.__end_node();
1331 else
1332 __t.__end_node()->__left_->__parent_ = __t.__end_node();
1333}
1334
1335template <class _Tp, class _Compare, class _Allocator>
1336void
1337__tree<_Tp, _Compare, _Allocator>::clear()
1338{
1339 destroy(__root());
1340 size() = 0;
1341 __begin_node() = __end_node();
1342 __end_node()->__left_ = nullptr;
1343}
1344
1345// Find lower_bound place to insert
1346// Set __parent to parent of null leaf
1347// Return reference to null leaf
1348template <class _Tp, class _Compare, class _Allocator>
1349typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1350__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node::base::pointer& __parent,
1351 const value_type& __v)
1352{
1353 __node_pointer __nd = __root();
1354 if (__nd != nullptr)
1355 {
1356 while (true)
1357 {
1358 if (value_comp()(__nd->__value_, __v))
1359 {
1360 if (__nd->__right_ != nullptr)
1361 __nd = static_cast<__node_pointer>(__nd->__right_);
1362 else
1363 {
1364 __parent = __nd;
1365 return __parent->__right_;
1366 }
1367 }
1368 else
1369 {
1370 if (__nd->__left_ != nullptr)
1371 __nd = static_cast<__node_pointer>(__nd->__left_);
1372 else
1373 {
1374 __parent = __nd;
1375 return __parent->__left_;
1376 }
1377 }
1378 }
1379 }
1380 __parent = __end_node();
1381 return __parent->__left_;
1382}
1383
1384// Find upper_bound place to insert
1385// Set __parent to parent of null leaf
1386// Return reference to null leaf
1387template <class _Tp, class _Compare, class _Allocator>
1388typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1389__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node::base::pointer& __parent,
1390 const value_type& __v)
1391{
1392 __node_pointer __nd = __root();
1393 if (__nd != nullptr)
1394 {
1395 while (true)
1396 {
1397 if (value_comp()(__v, __nd->__value_))
1398 {
1399 if (__nd->__left_ != nullptr)
1400 __nd = static_cast<__node_pointer>(__nd->__left_);
1401 else
1402 {
1403 __parent = __nd;
1404 return __parent->__left_;
1405 }
1406 }
1407 else
1408 {
1409 if (__nd->__right_ != nullptr)
1410 __nd = static_cast<__node_pointer>(__nd->__right_);
1411 else
1412 {
1413 __parent = __nd;
1414 return __parent->__right_;
1415 }
1416 }
1417 }
1418 }
1419 __parent = __end_node();
1420 return __parent->__left_;
1421}
1422
1423// Find leaf place to insert closest to __hint
1424// First check prior to __hint.
1425// Next check after __hint.
1426// Next do O(log N) search.
1427// Set __parent to parent of null leaf
1428// Return reference to null leaf
1429template <class _Tp, class _Compare, class _Allocator>
1430typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1431__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
1432 typename __node::base::pointer& __parent,
1433 const value_type& __v)
1434{
1435 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1436 {
1437 // __v <= *__hint
1438 const_iterator __prior = __hint;
1439 if (__prior == begin() || !value_comp()(__v, *--__prior))
1440 {
1441 // *prev(__hint) <= __v <= *__hint
1442 if (__hint.__ptr_->__left_ == nullptr)
1443 {
1444 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1445 return __parent->__left_;
1446 }
1447 else
1448 {
1449 __parent = const_cast<__node_pointer&>(__prior.__ptr_);
1450 return __parent->__right_;
1451 }
1452 }
1453 // __v < *prev(__hint)
1454 return __find_leaf_high(__parent, __v);
1455 }
1456 // else __v > *__hint
1457 return __find_leaf_low(__parent, __v);
1458}
1459
1460// Find place to insert if __v doesn't exist
1461// Set __parent to parent of null leaf
1462// Return reference to null leaf
1463// If __v exists, set parent to node of __v and return reference to node of __v
1464template <class _Tp, class _Compare, class _Allocator>
1465template <class _Key>
1466typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1467__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node::base::pointer& __parent,
1468 const _Key& __v)
1469{
1470 __node_pointer __nd = __root();
1471 if (__nd != nullptr)
1472 {
1473 while (true)
1474 {
1475 if (value_comp()(__v, __nd->__value_))
1476 {
1477 if (__nd->__left_ != nullptr)
1478 __nd = static_cast<__node_pointer>(__nd->__left_);
1479 else
1480 {
1481 __parent = __nd;
1482 return __parent->__left_;
1483 }
1484 }
1485 else if (value_comp()(__nd->__value_, __v))
1486 {
1487 if (__nd->__right_ != nullptr)
1488 __nd = static_cast<__node_pointer>(__nd->__right_);
1489 else
1490 {
1491 __parent = __nd;
1492 return __parent->__right_;
1493 }
1494 }
1495 else
1496 {
1497 __parent = __nd;
1498 return __parent;
1499 }
1500 }
1501 }
1502 __parent = __end_node();
1503 return __parent->__left_;
1504}
1505
1506// Find place to insert if __v doesn't exist
1507// First check prior to __hint.
1508// Next check after __hint.
1509// Next do O(log N) search.
1510// Set __parent to parent of null leaf
1511// Return reference to null leaf
1512// If __v exists, set parent to node of __v and return reference to node of __v
1513template <class _Tp, class _Compare, class _Allocator>
1514template <class _Key>
1515typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1516__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
1517 typename __node::base::pointer& __parent,
1518 const _Key& __v)
1519{
1520 if (__hint == end() || value_comp()(__v, *__hint)) // check before
1521 {
1522 // __v < *__hint
1523 const_iterator __prior = __hint;
1524 if (__prior == begin() || value_comp()(*--__prior, __v))
1525 {
1526 // *prev(__hint) < __v < *__hint
1527 if (__hint.__ptr_->__left_ == nullptr)
1528 {
1529 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1530 return __parent->__left_;
1531 }
1532 else
1533 {
1534 __parent = const_cast<__node_pointer&>(__prior.__ptr_);
1535 return __parent->__right_;
1536 }
1537 }
1538 // __v <= *prev(__hint)
1539 return __find_equal(__parent, __v);
1540 }
1541 else if (value_comp()(*__hint, __v)) // check after
1542 {
1543 // *__hint < __v
1544 const_iterator __next = _STD::next(__hint);
1545 if (__next == end() || value_comp()(__v, *__next))
1546 {
1547 // *__hint < __v < *next(__hint)
1548 if (__hint.__ptr_->__right_ == nullptr)
1549 {
1550 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1551 return __parent->__right_;
1552 }
1553 else
1554 {
1555 __parent = const_cast<__node_pointer&>(__next.__ptr_);
1556 return __parent->__left_;
1557 }
1558 }
1559 // *next(__hint) <= __v
1560 return __find_equal(__parent, __v);
1561 }
1562 // else __v == *__hint
1563 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1564 return __parent;
1565}
1566
1567template <class _Tp, class _Compare, class _Allocator>
1568void
1569__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent,
1570 __node_base_pointer& __child,
1571 __node_base_pointer __new_node)
1572{
1573 __new_node->__left_ = nullptr;
1574 __new_node->__right_ = nullptr;
1575 __new_node->__parent_ = __parent;
1576 __child = __new_node;
1577 if (__begin_node()->__left_ != nullptr)
1578 __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_);
1579 __tree_balance_after_insert(__end_node()->__left_, __child);
1580 ++size();
1581}
1582
1583#ifdef _LIBCPP_MOVE
1584
1585template <class _Tp, class _Compare, class _Allocator>
1586template <class ..._Args>
1587typename __tree<_Tp, _Compare, _Allocator>::__node_holder
1588__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
1589{
1590 __node_allocator& __na = __node_alloc();
1591 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
1592 __node_traits::construct(__na, addressof(__h->__value_), _STD::forward<_Args>(__args)...);
1593 __h.get_deleter().__value_constructed = true;
1594 return __h;
1595}
1596
1597template <class _Tp, class _Compare, class _Allocator>
1598template <class... _Args>
1599pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1600__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args)
1601{
1602 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1603 __node_base_pointer __parent;
1604 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
1605 __node_pointer __r = static_cast<__node_pointer>(__child);
1606 bool __inserted = false;
1607 if (__child == nullptr)
1608 {
1609 __insert_node_at(__parent, __child, __h.get());
1610 __r = __h.release();
1611 __inserted = true;
1612 }
1613 return pair<iterator, bool>(iterator(__r), __inserted);
1614}
1615
1616template <class _Tp, class _Compare, class _Allocator>
1617template <class... _Args>
1618typename __tree<_Tp, _Compare, _Allocator>::iterator
1619__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args)
1620{
1621 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1622 __node_base_pointer __parent;
1623 __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_);
1624 __node_pointer __r = static_cast<__node_pointer>(__child);
1625 if (__child == nullptr)
1626 {
1627 __insert_node_at(__parent, __child, __h.get());
1628 __r = __h.release();
1629 }
1630 return iterator(__r);
1631}
1632
1633template <class _Tp, class _Compare, class _Allocator>
1634template <class... _Args>
1635typename __tree<_Tp, _Compare, _Allocator>::iterator
1636__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
1637{
1638 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1639 __node_base_pointer __parent;
1640 __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
1641 __insert_node_at(__parent, __child, __h.get());
1642 return iterator(static_cast<__node_pointer>(__h.release()));
1643}
1644
1645template <class _Tp, class _Compare, class _Allocator>
1646template <class... _Args>
1647typename __tree<_Tp, _Compare, _Allocator>::iterator
1648__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
1649 _Args&&... __args)
1650{
1651 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1652 __node_base_pointer __parent;
1653 __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
1654 __insert_node_at(__parent, __child, __h.get());
1655 return iterator(static_cast<__node_pointer>(__h.release()));
1656}
1657
1658template <class _Tp, class _Compare, class _Allocator>
1659template <class _V>
1660pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1661__tree<_Tp, _Compare, _Allocator>::__insert_unique(_V&& __v)
1662{
1663 __node_base_pointer __parent;
1664 __node_base_pointer& __child = __find_equal(__parent, __v);
1665 __node_pointer __r = static_cast<__node_pointer>(__child);
1666 bool __inserted = false;
1667 if (__child == nullptr)
1668 {
1669 __node_holder __h = __construct_node(_STD::forward<_V>(__v));
1670 __insert_node_at(__parent, __child, __h.get());
1671 __r = __h.release();
1672 __inserted = true;
1673 }
1674 return pair<iterator, bool>(iterator(__r), __inserted);
1675}
1676
1677template <class _Tp, class _Compare, class _Allocator>
1678template <class _V>
1679typename __tree<_Tp, _Compare, _Allocator>::iterator
1680__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _V&& __v)
1681{
1682 __node_base_pointer __parent;
1683 __node_base_pointer& __child = __find_equal(__p, __parent, __v);
1684 __node_pointer __r = static_cast<__node_pointer>(__child);
1685 if (__child == nullptr)
1686 {
1687 __node_holder __h = __construct_node(_STD::forward<_V>(__v));
1688 __insert_node_at(__parent, __child, __h.get());
1689 __r = __h.release();
1690 }
1691 return iterator(__r);
1692}
1693
1694template <class _Tp, class _Compare, class _Allocator>
1695template <class _V>
1696typename __tree<_Tp, _Compare, _Allocator>::iterator
1697__tree<_Tp, _Compare, _Allocator>::__insert_multi(_V&& __v)
1698{
1699 __node_holder __h = __construct_node(_STD::forward<_V>(__v));
1700 __node_base_pointer __parent;
1701 __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
1702 __insert_node_at(__parent, __child, __h.get());
1703 return iterator(__h.release());
1704}
1705
1706template <class _Tp, class _Compare, class _Allocator>
1707template <class _V>
1708typename __tree<_Tp, _Compare, _Allocator>::iterator
1709__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _V&& __v)
1710{
1711 __node_holder __h = __construct_node(_STD::forward<_V>(__v));
1712 __node_base_pointer __parent;
1713 __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
1714 __insert_node_at(__parent, __child, __h.get());
1715 return iterator(__h.release());
1716}
1717
1718#else
1719
1720template <class _Tp, class _Compare, class _Allocator>
1721typename __tree<_Tp, _Compare, _Allocator>::__node_holder
1722__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v)
1723{
1724 __node_allocator& __na = __node_alloc();
1725 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
1726 __node_traits::construct(__na, addressof(__h->__value_), __v);
1727 __h.get_deleter().__value_constructed = true;
1728 return _STD::move(__h);
1729}
1730
1731template <class _Tp, class _Compare, class _Allocator>
1732pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1733__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v)
1734{
1735 __node_base_pointer __parent;
1736 __node_base_pointer& __child = __find_equal(__parent, __v);
1737 __node_pointer __r = static_cast<__node_pointer>(__child);
1738 bool __inserted = false;
1739 if (__child == nullptr)
1740 {
1741 __node_holder __h = __construct_node(__v);
1742 __insert_node_at(__parent, __child, __h.get());
1743 __r = __h.release();
1744 __inserted = true;
1745 }
1746 return pair<iterator, bool>(iterator(__r), __inserted);
1747}
1748
1749template <class _Tp, class _Compare, class _Allocator>
1750typename __tree<_Tp, _Compare, _Allocator>::iterator
1751__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v)
1752{
1753 __node_base_pointer __parent;
1754 __node_base_pointer& __child = __find_equal(__p, __parent, __v);
1755 __node_pointer __r = static_cast<__node_pointer>(__child);
1756 if (__child == nullptr)
1757 {
1758 __node_holder __h = __construct_node(__v);
1759 __insert_node_at(__parent, __child, __h.get());
1760 __r = __h.release();
1761 }
1762 return iterator(__r);
1763}
1764
1765template <class _Tp, class _Compare, class _Allocator>
1766typename __tree<_Tp, _Compare, _Allocator>::iterator
1767__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v)
1768{
1769 __node_base_pointer __parent;
1770 __node_base_pointer& __child = __find_leaf_high(__parent, __v);
1771 __node_holder __h = __construct_node(__v);
1772 __insert_node_at(__parent, __child, __h.get());
1773 return iterator(__h.release());
1774}
1775
1776template <class _Tp, class _Compare, class _Allocator>
1777typename __tree<_Tp, _Compare, _Allocator>::iterator
1778__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v)
1779{
1780 __node_base_pointer __parent;
1781 __node_base_pointer& __child = __find_leaf(__p, __parent, __v);
1782 __node_holder __h = __construct_node(__v);
1783 __insert_node_at(__parent, __child, __h.get());
1784 return iterator(__h.release());
1785}
1786
1787#endif
1788
1789template <class _Tp, class _Compare, class _Allocator>
1790pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1791__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
1792{
1793 __node_base_pointer __parent;
1794 __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
1795 __node_pointer __r = static_cast<__node_pointer>(__child);
1796 bool __inserted = false;
1797 if (__child == nullptr)
1798 {
1799 __insert_node_at(__parent, __child, __nd);
1800 __r = __nd;
1801 __inserted = true;
1802 }
1803 return pair<iterator, bool>(iterator(__r), __inserted);
1804}
1805
1806template <class _Tp, class _Compare, class _Allocator>
1807typename __tree<_Tp, _Compare, _Allocator>::iterator
1808__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
1809 __node_pointer __nd)
1810{
1811 __node_base_pointer __parent;
1812 __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
1813 __node_pointer __r = static_cast<__node_pointer>(__child);
1814 if (__child == nullptr)
1815 {
1816 __insert_node_at(__parent, __child, __nd);
1817 __r = __nd;
1818 }
1819 return iterator(__r);
1820}
1821
1822template <class _Tp, class _Compare, class _Allocator>
1823typename __tree<_Tp, _Compare, _Allocator>::iterator
1824__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
1825{
1826 __node_base_pointer __parent;
1827 __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
1828 __insert_node_at(__parent, __child, __nd);
1829 return iterator(__nd);
1830}
1831
1832template <class _Tp, class _Compare, class _Allocator>
1833typename __tree<_Tp, _Compare, _Allocator>::iterator
1834__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
1835 __node_pointer __nd)
1836{
1837 __node_base_pointer __parent;
1838 __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
1839 __insert_node_at(__parent, __child, __nd);
1840 return iterator(__nd);
1841}
1842
1843template <class _Tp, class _Compare, class _Allocator>
1844typename __tree<_Tp, _Compare, _Allocator>::iterator
1845__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
1846{
1847 __node_pointer __np = const_cast<__node_pointer>(__p.__ptr_);
1848 iterator __r(__np);
1849 ++__r;
1850 if (__begin_node() == __np)
1851 __begin_node() = __r.__ptr_;
1852 --size();
1853 __node_allocator& __na = __node_alloc();
1854 __node_traits::destroy(__na, const_cast<value_type*>(addressof(*__p)));
1855 __tree_remove(__end_node()->__left_,
1856 static_cast<__node_base_pointer>(__np));
1857 __node_traits::deallocate(__na, __np, 1);
1858 return __r;
1859}
1860
1861template <class _Tp, class _Compare, class _Allocator>
1862typename __tree<_Tp, _Compare, _Allocator>::iterator
1863__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
1864{
1865 while (__f != __l)
1866 __f = erase(__f);
1867 return iterator(const_cast<__node_pointer>(__l.__ptr_));
1868}
1869
1870template <class _Tp, class _Compare, class _Allocator>
1871template <class _Key>
1872typename __tree<_Tp, _Compare, _Allocator>::size_type
1873__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
1874{
1875 iterator __i = find(__k);
1876 if (__i == end())
1877 return 0;
1878 erase(__i);
1879 return 1;
1880}
1881
1882template <class _Tp, class _Compare, class _Allocator>
1883template <class _Key>
1884typename __tree<_Tp, _Compare, _Allocator>::size_type
1885__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
1886{
1887 pair<iterator, iterator> __p = __equal_range_multi(__k);
1888 size_type __r = 0;
1889 for (; __p.first != __p.second; ++__r)
1890 __p.first = erase(__p.first);
1891 return __r;
1892}
1893
1894template <class _Tp, class _Compare, class _Allocator>
1895template <class _Key>
1896typename __tree<_Tp, _Compare, _Allocator>::iterator
1897__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
1898{
1899 iterator __p = __lower_bound(__v, __root(), __end_node());
1900 if (__p != end() && !value_comp()(__v, *__p))
1901 return __p;
1902 return end();
1903}
1904
1905template <class _Tp, class _Compare, class _Allocator>
1906template <class _Key>
1907typename __tree<_Tp, _Compare, _Allocator>::const_iterator
1908__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
1909{
1910 const_iterator __p = __lower_bound(__v, __root(), __end_node());
1911 if (__p != end() && !value_comp()(__v, *__p))
1912 return __p;
1913 return end();
1914}
1915
1916template <class _Tp, class _Compare, class _Allocator>
1917template <class _Key>
1918typename __tree<_Tp, _Compare, _Allocator>::size_type
1919__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
1920{
1921 __node_const_pointer __result = __end_node();
1922 __node_const_pointer __rt = __root();
1923 while (__rt != nullptr)
1924 {
1925 if (value_comp()(__k, __rt->__value_))
1926 {
1927 __result = __rt;
1928 __rt = static_cast<__node_const_pointer>(__rt->__left_);
1929 }
1930 else if (value_comp()(__rt->__value_, __k))
1931 __rt = static_cast<__node_const_pointer>(__rt->__right_);
1932 else
1933 return 1;
1934 }
1935 return 0;
1936}
1937
1938template <class _Tp, class _Compare, class _Allocator>
1939template <class _Key>
1940typename __tree<_Tp, _Compare, _Allocator>::size_type
1941__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
1942{
1943 typedef pair<const_iterator, const_iterator> _P;
1944 __node_const_pointer __result = __end_node();
1945 __node_const_pointer __rt = __root();
1946 while (__rt != nullptr)
1947 {
1948 if (value_comp()(__k, __rt->__value_))
1949 {
1950 __result = __rt;
1951 __rt = static_cast<__node_const_pointer>(__rt->__left_);
1952 }
1953 else if (value_comp()(__rt->__value_, __k))
1954 __rt = static_cast<__node_const_pointer>(__rt->__right_);
1955 else
1956 return _STD::distance(
1957 __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
1958 __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)
1959 );
1960 }
1961 return 0;
1962}
1963
1964template <class _Tp, class _Compare, class _Allocator>
1965template <class _Key>
1966typename __tree<_Tp, _Compare, _Allocator>::iterator
1967__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
1968 __node_pointer __root,
1969 __node_pointer __result)
1970{
1971 while (__root != nullptr)
1972 {
1973 if (!value_comp()(__root->__value_, __v))
1974 {
1975 __result = __root;
1976 __root = static_cast<__node_pointer>(__root->__left_);
1977 }
1978 else
1979 __root = static_cast<__node_pointer>(__root->__right_);
1980 }
1981 return iterator(__result);
1982}
1983
1984template <class _Tp, class _Compare, class _Allocator>
1985template <class _Key>
1986typename __tree<_Tp, _Compare, _Allocator>::const_iterator
1987__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
1988 __node_const_pointer __root,
1989 __node_const_pointer __result) const
1990{
1991 while (__root != nullptr)
1992 {
1993 if (!value_comp()(__root->__value_, __v))
1994 {
1995 __result = __root;
1996 __root = static_cast<__node_const_pointer>(__root->__left_);
1997 }
1998 else
1999 __root = static_cast<__node_const_pointer>(__root->__right_);
2000 }
2001 return const_iterator(__result);
2002}
2003
2004template <class _Tp, class _Compare, class _Allocator>
2005template <class _Key>
2006typename __tree<_Tp, _Compare, _Allocator>::iterator
2007__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2008 __node_pointer __root,
2009 __node_pointer __result)
2010{
2011 while (__root != nullptr)
2012 {
2013 if (value_comp()(__v, __root->__value_))
2014 {
2015 __result = __root;
2016 __root = static_cast<__node_pointer>(__root->__left_);
2017 }
2018 else
2019 __root = static_cast<__node_pointer>(__root->__right_);
2020 }
2021 return iterator(__result);
2022}
2023
2024template <class _Tp, class _Compare, class _Allocator>
2025template <class _Key>
2026typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2027__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2028 __node_const_pointer __root,
2029 __node_const_pointer __result) const
2030{
2031 while (__root != nullptr)
2032 {
2033 if (value_comp()(__v, __root->__value_))
2034 {
2035 __result = __root;
2036 __root = static_cast<__node_const_pointer>(__root->__left_);
2037 }
2038 else
2039 __root = static_cast<__node_const_pointer>(__root->__right_);
2040 }
2041 return const_iterator(__result);
2042}
2043
2044template <class _Tp, class _Compare, class _Allocator>
2045template <class _Key>
2046pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2047 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2048__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2049{
2050 typedef pair<iterator, iterator> _P;
2051 __node_pointer __result = __end_node();
2052 __node_pointer __rt = __root();
2053 while (__rt != nullptr)
2054 {
2055 if (value_comp()(__k, __rt->__value_))
2056 {
2057 __result = __rt;
2058 __rt = static_cast<__node_pointer>(__rt->__left_);
2059 }
2060 else if (value_comp()(__rt->__value_, __k))
2061 __rt = static_cast<__node_pointer>(__rt->__right_);
2062 else
2063 return _P(iterator(__rt),
2064 iterator(
2065 __rt->__right_ != nullptr ?
2066 static_cast<__node_pointer>(__tree_min(__rt->__right_))
2067 : __result));
2068 }
2069 return _P(iterator(__result), iterator(__result));
2070}
2071
2072template <class _Tp, class _Compare, class _Allocator>
2073template <class _Key>
2074pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2075 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2076__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2077{
2078 typedef pair<const_iterator, const_iterator> _P;
2079 __node_const_pointer __result = __end_node();
2080 __node_const_pointer __rt = __root();
2081 while (__rt != nullptr)
2082 {
2083 if (value_comp()(__k, __rt->__value_))
2084 {
2085 __result = __rt;
2086 __rt = static_cast<__node_const_pointer>(__rt->__left_);
2087 }
2088 else if (value_comp()(__rt->__value_, __k))
2089 __rt = static_cast<__node_const_pointer>(__rt->__right_);
2090 else
2091 return _P(const_iterator(__rt),
2092 const_iterator(
2093 __rt->__right_ != nullptr ?
2094 static_cast<__node_const_pointer>(__tree_min(__rt->__right_))
2095 : __result));
2096 }
2097 return _P(const_iterator(__result), const_iterator(__result));
2098}
2099
2100template <class _Tp, class _Compare, class _Allocator>
2101template <class _Key>
2102pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2103 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2104__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2105{
2106 typedef pair<iterator, iterator> _P;
2107 __node_pointer __result = __end_node();
2108 __node_pointer __rt = __root();
2109 while (__rt != nullptr)
2110 {
2111 if (value_comp()(__k, __rt->__value_))
2112 {
2113 __result = __rt;
2114 __rt = static_cast<__node_pointer>(__rt->__left_);
2115 }
2116 else if (value_comp()(__rt->__value_, __k))
2117 __rt = static_cast<__node_pointer>(__rt->__right_);
2118 else
2119 return _P(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
2120 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2121 }
2122 return _P(iterator(__result), iterator(__result));
2123}
2124
2125template <class _Tp, class _Compare, class _Allocator>
2126template <class _Key>
2127pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2128 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2129__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2130{
2131 typedef pair<const_iterator, const_iterator> _P;
2132 __node_const_pointer __result = __end_node();
2133 __node_const_pointer __rt = __root();
2134 while (__rt != nullptr)
2135 {
2136 if (value_comp()(__k, __rt->__value_))
2137 {
2138 __result = __rt;
2139 __rt = static_cast<__node_const_pointer>(__rt->__left_);
2140 }
2141 else if (value_comp()(__rt->__value_, __k))
2142 __rt = static_cast<__node_const_pointer>(__rt->__right_);
2143 else
2144 return _P(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
2145 __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result));
2146 }
2147 return _P(const_iterator(__result), const_iterator(__result));
2148}
2149
2150template <class _Tp, class _Compare, class _Allocator>
2151typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2152__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p)
2153{
2154 __node_pointer __np = const_cast<__node_pointer>(__p.__ptr_);
2155 if (__begin_node() == __np)
2156 {
2157 if (__np->__right_ != nullptr)
2158 __begin_node() = static_cast<__node_pointer>(__np->__right_);
2159 else
2160 __begin_node() = static_cast<__node_pointer>(__np->__parent_);
2161 }
2162 --size();
2163 __tree_remove(__end_node()->__left_,
2164 static_cast<__node_base_pointer>(__np));
2165 return __node_holder(__np, _D(__node_alloc()));
2166}
2167
2168_LIBCPP_END_NAMESPACE_STD
2169
2170#endif // _LIBCPP___TREE