blob: 18363dc5378d7a5e6ed75494b1305128ef5315d5 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
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();
Howard Hinnant72f73582010-08-11 17:04:31 +00001105#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001106 try
1107 {
Howard Hinnant72f73582010-08-11 17:04:31 +00001108#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001109 for (; __cache != nullptr && __first != __last; ++__first)
1110 {
1111 __cache->__value_ = *__first;
1112 __node_pointer __next = __detach(__cache);
1113 __node_insert_unique(__cache);
1114 __cache = __next;
1115 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001116#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001117 }
1118 catch (...)
1119 {
1120 while (__cache->__parent_ != nullptr)
1121 __cache = static_cast<__node_pointer>(__cache->__parent_);
1122 destroy(__cache);
1123 throw;
1124 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001125#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001126 if (__cache != nullptr)
1127 {
1128 while (__cache->__parent_ != nullptr)
1129 __cache = static_cast<__node_pointer>(__cache->__parent_);
1130 destroy(__cache);
1131 }
1132 }
1133 for (; __first != __last; ++__first)
1134 __insert_unique(*__first);
1135}
1136
1137template <class _Tp, class _Compare, class _Allocator>
1138template <class _InputIterator>
1139void
1140__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
1141{
1142 if (size() != 0)
1143 {
1144 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001145#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001146 try
1147 {
Howard Hinnant72f73582010-08-11 17:04:31 +00001148#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001149 for (; __cache != nullptr && __first != __last; ++__first)
1150 {
1151 __cache->__value_ = *__first;
1152 __node_pointer __next = __detach(__cache);
1153 __node_insert_multi(__cache);
1154 __cache = __next;
1155 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001156#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001157 }
1158 catch (...)
1159 {
1160 while (__cache->__parent_ != nullptr)
1161 __cache = static_cast<__node_pointer>(__cache->__parent_);
1162 destroy(__cache);
1163 throw;
1164 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001165#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001166 if (__cache != nullptr)
1167 {
1168 while (__cache->__parent_ != nullptr)
1169 __cache = static_cast<__node_pointer>(__cache->__parent_);
1170 destroy(__cache);
1171 }
1172 }
1173 for (; __first != __last; ++__first)
1174 __insert_multi(*__first);
1175}
1176
1177template <class _Tp, class _Compare, class _Allocator>
1178__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
1179 : __begin_node_(__node_pointer()),
1180 __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
1181 __pair3_(0, __t.value_comp())
1182{
1183 __begin_node() = __end_node();
1184}
1185
1186#ifdef _LIBCPP_MOVE
1187
1188template <class _Tp, class _Compare, class _Allocator>
1189__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
1190 : __begin_node_(_STD::move(__t.__begin_node_)),
1191 __pair1_(_STD::move(__t.__pair1_)),
1192 __pair3_(_STD::move(__t.__pair3_))
1193{
1194 if (size() == 0)
1195 __begin_node() = __end_node();
1196 else
1197 {
1198 __end_node()->__left_->__parent_ = __end_node();
1199 __t.__begin_node() = __t.__end_node();
1200 __t.__end_node()->__left_ = nullptr;
1201 __t.size() = 0;
1202 }
1203}
1204
1205template <class _Tp, class _Compare, class _Allocator>
1206__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1207 : __pair1_(__node_allocator(__a)),
1208 __pair3_(0, _STD::move(__t.value_comp()))
1209{
1210 if (__a == __t.__alloc())
1211 {
1212 if (__t.size() == 0)
1213 __begin_node() = __end_node();
1214 else
1215 {
1216 __begin_node() = __t.__begin_node();
1217 __end_node()->__left_ = __t.__end_node()->__left_;
1218 __end_node()->__left_->__parent_ = __end_node();
1219 size() = __t.size();
1220 __t.__begin_node() = __t.__end_node();
1221 __t.__end_node()->__left_ = nullptr;
1222 __t.size() = 0;
1223 }
1224 }
1225 else
1226 {
1227 __begin_node() = __end_node();
1228 }
1229}
1230
1231template <class _Tp, class _Compare, class _Allocator>
1232void
1233__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
1234{
1235 destroy(static_cast<__node_pointer>(__end_node()->__left_));
1236 __begin_node_ = __t.__begin_node_;
1237 __pair1_.first() = __t.__pair1_.first();
1238 __move_assign_alloc(__t);
1239 __pair3_ = _STD::move(__t.__pair3_);
1240 if (size() == 0)
1241 __begin_node() = __end_node();
1242 else
1243 {
1244 __end_node()->__left_->__parent_ = __end_node();
1245 __t.__begin_node() = __t.__end_node();
1246 __t.__end_node()->__left_ = nullptr;
1247 __t.size() = 0;
1248 }
1249}
1250
1251template <class _Tp, class _Compare, class _Allocator>
1252void
1253__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
1254{
1255 if (__node_alloc() == __t.__node_alloc())
1256 __move_assign(__t, true_type());
1257 else
1258 {
1259 value_comp() = _STD::move(__t.value_comp());
1260 const_iterator __e = end();
1261 if (size() != 0)
1262 {
1263 __node_pointer __cache = __detach();
Howard Hinnant72f73582010-08-11 17:04:31 +00001264#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001265 try
1266 {
Howard Hinnant72f73582010-08-11 17:04:31 +00001267#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001268 while (__cache != nullptr && __t.size() != 0)
1269 {
1270 __cache->__value_ = _STD::move(__t.remove(__t.begin())->__value_);
1271 __node_pointer __next = __detach(__cache);
1272 __node_insert_multi(__cache);
1273 __cache = __next;
1274 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001275#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001276 }
1277 catch (...)
1278 {
1279 while (__cache->__parent_ != nullptr)
1280 __cache = static_cast<__node_pointer>(__cache->__parent_);
1281 destroy(__cache);
1282 throw;
1283 }
Howard Hinnant72f73582010-08-11 17:04:31 +00001284#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001285 if (__cache != nullptr)
1286 {
1287 while (__cache->__parent_ != nullptr)
1288 __cache = static_cast<__node_pointer>(__cache->__parent_);
1289 destroy(__cache);
1290 }
1291 }
1292 while (__t.size() != 0)
1293 __insert_multi(__e, _STD::move(__t.remove(__t.begin())->__value_));
1294 }
1295}
1296
1297template <class _Tp, class _Compare, class _Allocator>
1298__tree<_Tp, _Compare, _Allocator>&
1299__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
1300{
1301 __move_assign(__t, integral_constant<bool,
1302 __node_traits::propagate_on_container_move_assignment::value>());
1303 return *this;
1304}
1305
1306#endif
1307
1308template <class _Tp, class _Compare, class _Allocator>
1309__tree<_Tp, _Compare, _Allocator>::~__tree()
1310{
1311 destroy(__root());
1312}
1313
1314template <class _Tp, class _Compare, class _Allocator>
1315void
1316__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd)
1317{
1318 if (__nd != nullptr)
1319 {
1320 destroy(static_cast<__node_pointer>(__nd->__left_));
1321 destroy(static_cast<__node_pointer>(__nd->__right_));
1322 __node_allocator& __na = __node_alloc();
1323 __node_traits::destroy(__na, addressof(__nd->__value_));
1324 __node_traits::deallocate(__na, __nd, 1);
1325 }
1326}
1327
1328template <class _Tp, class _Compare, class _Allocator>
1329void
1330__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
1331{
1332 using _STD::swap;
1333 swap(__begin_node_, __t.__begin_node_);
1334 swap(__pair1_.first(), __t.__pair1_.first());
1335 __swap_alloc(__node_alloc(), __t.__node_alloc());
1336 __pair3_.swap(__t.__pair3_);
1337 if (size() == 0)
1338 __begin_node() = __end_node();
1339 else
1340 __end_node()->__left_->__parent_ = __end_node();
1341 if (__t.size() == 0)
1342 __t.__begin_node() = __t.__end_node();
1343 else
1344 __t.__end_node()->__left_->__parent_ = __t.__end_node();
1345}
1346
1347template <class _Tp, class _Compare, class _Allocator>
1348void
1349__tree<_Tp, _Compare, _Allocator>::clear()
1350{
1351 destroy(__root());
1352 size() = 0;
1353 __begin_node() = __end_node();
1354 __end_node()->__left_ = nullptr;
1355}
1356
1357// Find lower_bound place to insert
1358// Set __parent to parent of null leaf
1359// Return reference to null leaf
1360template <class _Tp, class _Compare, class _Allocator>
1361typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1362__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node::base::pointer& __parent,
1363 const value_type& __v)
1364{
1365 __node_pointer __nd = __root();
1366 if (__nd != nullptr)
1367 {
1368 while (true)
1369 {
1370 if (value_comp()(__nd->__value_, __v))
1371 {
1372 if (__nd->__right_ != nullptr)
1373 __nd = static_cast<__node_pointer>(__nd->__right_);
1374 else
1375 {
1376 __parent = __nd;
1377 return __parent->__right_;
1378 }
1379 }
1380 else
1381 {
1382 if (__nd->__left_ != nullptr)
1383 __nd = static_cast<__node_pointer>(__nd->__left_);
1384 else
1385 {
1386 __parent = __nd;
1387 return __parent->__left_;
1388 }
1389 }
1390 }
1391 }
1392 __parent = __end_node();
1393 return __parent->__left_;
1394}
1395
1396// Find upper_bound place to insert
1397// Set __parent to parent of null leaf
1398// Return reference to null leaf
1399template <class _Tp, class _Compare, class _Allocator>
1400typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1401__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node::base::pointer& __parent,
1402 const value_type& __v)
1403{
1404 __node_pointer __nd = __root();
1405 if (__nd != nullptr)
1406 {
1407 while (true)
1408 {
1409 if (value_comp()(__v, __nd->__value_))
1410 {
1411 if (__nd->__left_ != nullptr)
1412 __nd = static_cast<__node_pointer>(__nd->__left_);
1413 else
1414 {
1415 __parent = __nd;
1416 return __parent->__left_;
1417 }
1418 }
1419 else
1420 {
1421 if (__nd->__right_ != nullptr)
1422 __nd = static_cast<__node_pointer>(__nd->__right_);
1423 else
1424 {
1425 __parent = __nd;
1426 return __parent->__right_;
1427 }
1428 }
1429 }
1430 }
1431 __parent = __end_node();
1432 return __parent->__left_;
1433}
1434
1435// Find leaf place to insert closest to __hint
1436// First check prior to __hint.
1437// Next check after __hint.
1438// Next do O(log N) search.
1439// Set __parent to parent of null leaf
1440// Return reference to null leaf
1441template <class _Tp, class _Compare, class _Allocator>
1442typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1443__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
1444 typename __node::base::pointer& __parent,
1445 const value_type& __v)
1446{
1447 if (__hint == end() || !value_comp()(*__hint, __v)) // check before
1448 {
1449 // __v <= *__hint
1450 const_iterator __prior = __hint;
1451 if (__prior == begin() || !value_comp()(__v, *--__prior))
1452 {
1453 // *prev(__hint) <= __v <= *__hint
1454 if (__hint.__ptr_->__left_ == nullptr)
1455 {
1456 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1457 return __parent->__left_;
1458 }
1459 else
1460 {
1461 __parent = const_cast<__node_pointer&>(__prior.__ptr_);
1462 return __parent->__right_;
1463 }
1464 }
1465 // __v < *prev(__hint)
1466 return __find_leaf_high(__parent, __v);
1467 }
1468 // else __v > *__hint
1469 return __find_leaf_low(__parent, __v);
1470}
1471
1472// Find place to insert if __v doesn't exist
1473// Set __parent to parent of null leaf
1474// Return reference to null leaf
1475// If __v exists, set parent to node of __v and return reference to node of __v
1476template <class _Tp, class _Compare, class _Allocator>
1477template <class _Key>
1478typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1479__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node::base::pointer& __parent,
1480 const _Key& __v)
1481{
1482 __node_pointer __nd = __root();
1483 if (__nd != nullptr)
1484 {
1485 while (true)
1486 {
1487 if (value_comp()(__v, __nd->__value_))
1488 {
1489 if (__nd->__left_ != nullptr)
1490 __nd = static_cast<__node_pointer>(__nd->__left_);
1491 else
1492 {
1493 __parent = __nd;
1494 return __parent->__left_;
1495 }
1496 }
1497 else if (value_comp()(__nd->__value_, __v))
1498 {
1499 if (__nd->__right_ != nullptr)
1500 __nd = static_cast<__node_pointer>(__nd->__right_);
1501 else
1502 {
1503 __parent = __nd;
1504 return __parent->__right_;
1505 }
1506 }
1507 else
1508 {
1509 __parent = __nd;
1510 return __parent;
1511 }
1512 }
1513 }
1514 __parent = __end_node();
1515 return __parent->__left_;
1516}
1517
1518// Find place to insert if __v doesn't exist
1519// First check prior to __hint.
1520// Next check after __hint.
1521// Next do O(log N) search.
1522// Set __parent to parent of null leaf
1523// Return reference to null leaf
1524// If __v exists, set parent to node of __v and return reference to node of __v
1525template <class _Tp, class _Compare, class _Allocator>
1526template <class _Key>
1527typename __tree<_Tp, _Compare, _Allocator>::__node::base::pointer&
1528__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
1529 typename __node::base::pointer& __parent,
1530 const _Key& __v)
1531{
1532 if (__hint == end() || value_comp()(__v, *__hint)) // check before
1533 {
1534 // __v < *__hint
1535 const_iterator __prior = __hint;
1536 if (__prior == begin() || value_comp()(*--__prior, __v))
1537 {
1538 // *prev(__hint) < __v < *__hint
1539 if (__hint.__ptr_->__left_ == nullptr)
1540 {
1541 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1542 return __parent->__left_;
1543 }
1544 else
1545 {
1546 __parent = const_cast<__node_pointer&>(__prior.__ptr_);
1547 return __parent->__right_;
1548 }
1549 }
1550 // __v <= *prev(__hint)
1551 return __find_equal(__parent, __v);
1552 }
1553 else if (value_comp()(*__hint, __v)) // check after
1554 {
1555 // *__hint < __v
1556 const_iterator __next = _STD::next(__hint);
1557 if (__next == end() || value_comp()(__v, *__next))
1558 {
1559 // *__hint < __v < *next(__hint)
1560 if (__hint.__ptr_->__right_ == nullptr)
1561 {
1562 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1563 return __parent->__right_;
1564 }
1565 else
1566 {
1567 __parent = const_cast<__node_pointer&>(__next.__ptr_);
1568 return __parent->__left_;
1569 }
1570 }
1571 // *next(__hint) <= __v
1572 return __find_equal(__parent, __v);
1573 }
1574 // else __v == *__hint
1575 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1576 return __parent;
1577}
1578
1579template <class _Tp, class _Compare, class _Allocator>
1580void
1581__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent,
1582 __node_base_pointer& __child,
1583 __node_base_pointer __new_node)
1584{
1585 __new_node->__left_ = nullptr;
1586 __new_node->__right_ = nullptr;
1587 __new_node->__parent_ = __parent;
1588 __child = __new_node;
1589 if (__begin_node()->__left_ != nullptr)
1590 __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_);
1591 __tree_balance_after_insert(__end_node()->__left_, __child);
1592 ++size();
1593}
1594
1595#ifdef _LIBCPP_MOVE
1596
1597template <class _Tp, class _Compare, class _Allocator>
1598template <class ..._Args>
1599typename __tree<_Tp, _Compare, _Allocator>::__node_holder
1600__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
1601{
1602 __node_allocator& __na = __node_alloc();
1603 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
1604 __node_traits::construct(__na, addressof(__h->__value_), _STD::forward<_Args>(__args)...);
1605 __h.get_deleter().__value_constructed = true;
1606 return __h;
1607}
1608
1609template <class _Tp, class _Compare, class _Allocator>
1610template <class... _Args>
1611pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1612__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args)
1613{
1614 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1615 __node_base_pointer __parent;
1616 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
1617 __node_pointer __r = static_cast<__node_pointer>(__child);
1618 bool __inserted = false;
1619 if (__child == nullptr)
1620 {
1621 __insert_node_at(__parent, __child, __h.get());
1622 __r = __h.release();
1623 __inserted = true;
1624 }
1625 return pair<iterator, bool>(iterator(__r), __inserted);
1626}
1627
1628template <class _Tp, class _Compare, class _Allocator>
1629template <class... _Args>
1630typename __tree<_Tp, _Compare, _Allocator>::iterator
1631__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args)
1632{
1633 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1634 __node_base_pointer __parent;
1635 __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_);
1636 __node_pointer __r = static_cast<__node_pointer>(__child);
1637 if (__child == nullptr)
1638 {
1639 __insert_node_at(__parent, __child, __h.get());
1640 __r = __h.release();
1641 }
1642 return iterator(__r);
1643}
1644
1645template <class _Tp, class _Compare, class _Allocator>
1646template <class... _Args>
1647typename __tree<_Tp, _Compare, _Allocator>::iterator
1648__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
1649{
1650 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1651 __node_base_pointer __parent;
1652 __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
1653 __insert_node_at(__parent, __child, __h.get());
1654 return iterator(static_cast<__node_pointer>(__h.release()));
1655}
1656
1657template <class _Tp, class _Compare, class _Allocator>
1658template <class... _Args>
1659typename __tree<_Tp, _Compare, _Allocator>::iterator
1660__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
1661 _Args&&... __args)
1662{
1663 __node_holder __h = __construct_node(_STD::forward<_Args>(__args)...);
1664 __node_base_pointer __parent;
1665 __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
1666 __insert_node_at(__parent, __child, __h.get());
1667 return iterator(static_cast<__node_pointer>(__h.release()));
1668}
1669
1670template <class _Tp, class _Compare, class _Allocator>
1671template <class _V>
1672pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1673__tree<_Tp, _Compare, _Allocator>::__insert_unique(_V&& __v)
1674{
1675 __node_base_pointer __parent;
1676 __node_base_pointer& __child = __find_equal(__parent, __v);
1677 __node_pointer __r = static_cast<__node_pointer>(__child);
1678 bool __inserted = false;
1679 if (__child == nullptr)
1680 {
1681 __node_holder __h = __construct_node(_STD::forward<_V>(__v));
1682 __insert_node_at(__parent, __child, __h.get());
1683 __r = __h.release();
1684 __inserted = true;
1685 }
1686 return pair<iterator, bool>(iterator(__r), __inserted);
1687}
1688
1689template <class _Tp, class _Compare, class _Allocator>
1690template <class _V>
1691typename __tree<_Tp, _Compare, _Allocator>::iterator
1692__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _V&& __v)
1693{
1694 __node_base_pointer __parent;
1695 __node_base_pointer& __child = __find_equal(__p, __parent, __v);
1696 __node_pointer __r = static_cast<__node_pointer>(__child);
1697 if (__child == nullptr)
1698 {
1699 __node_holder __h = __construct_node(_STD::forward<_V>(__v));
1700 __insert_node_at(__parent, __child, __h.get());
1701 __r = __h.release();
1702 }
1703 return iterator(__r);
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(_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_high(__parent, __h->__value_);
1714 __insert_node_at(__parent, __child, __h.get());
1715 return iterator(__h.release());
1716}
1717
1718template <class _Tp, class _Compare, class _Allocator>
1719template <class _V>
1720typename __tree<_Tp, _Compare, _Allocator>::iterator
1721__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _V&& __v)
1722{
1723 __node_holder __h = __construct_node(_STD::forward<_V>(__v));
1724 __node_base_pointer __parent;
1725 __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
1726 __insert_node_at(__parent, __child, __h.get());
1727 return iterator(__h.release());
1728}
1729
1730#else
1731
1732template <class _Tp, class _Compare, class _Allocator>
1733typename __tree<_Tp, _Compare, _Allocator>::__node_holder
1734__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v)
1735{
1736 __node_allocator& __na = __node_alloc();
1737 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
1738 __node_traits::construct(__na, addressof(__h->__value_), __v);
1739 __h.get_deleter().__value_constructed = true;
1740 return _STD::move(__h);
1741}
1742
1743template <class _Tp, class _Compare, class _Allocator>
1744pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1745__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v)
1746{
1747 __node_base_pointer __parent;
1748 __node_base_pointer& __child = __find_equal(__parent, __v);
1749 __node_pointer __r = static_cast<__node_pointer>(__child);
1750 bool __inserted = false;
1751 if (__child == nullptr)
1752 {
1753 __node_holder __h = __construct_node(__v);
1754 __insert_node_at(__parent, __child, __h.get());
1755 __r = __h.release();
1756 __inserted = true;
1757 }
1758 return pair<iterator, bool>(iterator(__r), __inserted);
1759}
1760
1761template <class _Tp, class _Compare, class _Allocator>
1762typename __tree<_Tp, _Compare, _Allocator>::iterator
1763__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v)
1764{
1765 __node_base_pointer __parent;
1766 __node_base_pointer& __child = __find_equal(__p, __parent, __v);
1767 __node_pointer __r = static_cast<__node_pointer>(__child);
1768 if (__child == nullptr)
1769 {
1770 __node_holder __h = __construct_node(__v);
1771 __insert_node_at(__parent, __child, __h.get());
1772 __r = __h.release();
1773 }
1774 return iterator(__r);
1775}
1776
1777template <class _Tp, class _Compare, class _Allocator>
1778typename __tree<_Tp, _Compare, _Allocator>::iterator
1779__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v)
1780{
1781 __node_base_pointer __parent;
1782 __node_base_pointer& __child = __find_leaf_high(__parent, __v);
1783 __node_holder __h = __construct_node(__v);
1784 __insert_node_at(__parent, __child, __h.get());
1785 return iterator(__h.release());
1786}
1787
1788template <class _Tp, class _Compare, class _Allocator>
1789typename __tree<_Tp, _Compare, _Allocator>::iterator
1790__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v)
1791{
1792 __node_base_pointer __parent;
1793 __node_base_pointer& __child = __find_leaf(__p, __parent, __v);
1794 __node_holder __h = __construct_node(__v);
1795 __insert_node_at(__parent, __child, __h.get());
1796 return iterator(__h.release());
1797}
1798
1799#endif
1800
1801template <class _Tp, class _Compare, class _Allocator>
1802pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1803__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
1804{
1805 __node_base_pointer __parent;
1806 __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
1807 __node_pointer __r = static_cast<__node_pointer>(__child);
1808 bool __inserted = false;
1809 if (__child == nullptr)
1810 {
1811 __insert_node_at(__parent, __child, __nd);
1812 __r = __nd;
1813 __inserted = true;
1814 }
1815 return pair<iterator, bool>(iterator(__r), __inserted);
1816}
1817
1818template <class _Tp, class _Compare, class _Allocator>
1819typename __tree<_Tp, _Compare, _Allocator>::iterator
1820__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
1821 __node_pointer __nd)
1822{
1823 __node_base_pointer __parent;
1824 __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
1825 __node_pointer __r = static_cast<__node_pointer>(__child);
1826 if (__child == nullptr)
1827 {
1828 __insert_node_at(__parent, __child, __nd);
1829 __r = __nd;
1830 }
1831 return iterator(__r);
1832}
1833
1834template <class _Tp, class _Compare, class _Allocator>
1835typename __tree<_Tp, _Compare, _Allocator>::iterator
1836__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
1837{
1838 __node_base_pointer __parent;
1839 __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
1840 __insert_node_at(__parent, __child, __nd);
1841 return iterator(__nd);
1842}
1843
1844template <class _Tp, class _Compare, class _Allocator>
1845typename __tree<_Tp, _Compare, _Allocator>::iterator
1846__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
1847 __node_pointer __nd)
1848{
1849 __node_base_pointer __parent;
1850 __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
1851 __insert_node_at(__parent, __child, __nd);
1852 return iterator(__nd);
1853}
1854
1855template <class _Tp, class _Compare, class _Allocator>
1856typename __tree<_Tp, _Compare, _Allocator>::iterator
1857__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
1858{
1859 __node_pointer __np = const_cast<__node_pointer>(__p.__ptr_);
1860 iterator __r(__np);
1861 ++__r;
1862 if (__begin_node() == __np)
1863 __begin_node() = __r.__ptr_;
1864 --size();
1865 __node_allocator& __na = __node_alloc();
1866 __node_traits::destroy(__na, const_cast<value_type*>(addressof(*__p)));
1867 __tree_remove(__end_node()->__left_,
1868 static_cast<__node_base_pointer>(__np));
1869 __node_traits::deallocate(__na, __np, 1);
1870 return __r;
1871}
1872
1873template <class _Tp, class _Compare, class _Allocator>
1874typename __tree<_Tp, _Compare, _Allocator>::iterator
1875__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
1876{
1877 while (__f != __l)
1878 __f = erase(__f);
1879 return iterator(const_cast<__node_pointer>(__l.__ptr_));
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_unique(const _Key& __k)
1886{
1887 iterator __i = find(__k);
1888 if (__i == end())
1889 return 0;
1890 erase(__i);
1891 return 1;
1892}
1893
1894template <class _Tp, class _Compare, class _Allocator>
1895template <class _Key>
1896typename __tree<_Tp, _Compare, _Allocator>::size_type
1897__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
1898{
1899 pair<iterator, iterator> __p = __equal_range_multi(__k);
1900 size_type __r = 0;
1901 for (; __p.first != __p.second; ++__r)
1902 __p.first = erase(__p.first);
1903 return __r;
1904}
1905
1906template <class _Tp, class _Compare, class _Allocator>
1907template <class _Key>
1908typename __tree<_Tp, _Compare, _Allocator>::iterator
1909__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
1910{
1911 iterator __p = __lower_bound(__v, __root(), __end_node());
1912 if (__p != end() && !value_comp()(__v, *__p))
1913 return __p;
1914 return end();
1915}
1916
1917template <class _Tp, class _Compare, class _Allocator>
1918template <class _Key>
1919typename __tree<_Tp, _Compare, _Allocator>::const_iterator
1920__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
1921{
1922 const_iterator __p = __lower_bound(__v, __root(), __end_node());
1923 if (__p != end() && !value_comp()(__v, *__p))
1924 return __p;
1925 return end();
1926}
1927
1928template <class _Tp, class _Compare, class _Allocator>
1929template <class _Key>
1930typename __tree<_Tp, _Compare, _Allocator>::size_type
1931__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
1932{
1933 __node_const_pointer __result = __end_node();
1934 __node_const_pointer __rt = __root();
1935 while (__rt != nullptr)
1936 {
1937 if (value_comp()(__k, __rt->__value_))
1938 {
1939 __result = __rt;
1940 __rt = static_cast<__node_const_pointer>(__rt->__left_);
1941 }
1942 else if (value_comp()(__rt->__value_, __k))
1943 __rt = static_cast<__node_const_pointer>(__rt->__right_);
1944 else
1945 return 1;
1946 }
1947 return 0;
1948}
1949
1950template <class _Tp, class _Compare, class _Allocator>
1951template <class _Key>
1952typename __tree<_Tp, _Compare, _Allocator>::size_type
1953__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
1954{
1955 typedef pair<const_iterator, const_iterator> _P;
1956 __node_const_pointer __result = __end_node();
1957 __node_const_pointer __rt = __root();
1958 while (__rt != nullptr)
1959 {
1960 if (value_comp()(__k, __rt->__value_))
1961 {
1962 __result = __rt;
1963 __rt = static_cast<__node_const_pointer>(__rt->__left_);
1964 }
1965 else if (value_comp()(__rt->__value_, __k))
1966 __rt = static_cast<__node_const_pointer>(__rt->__right_);
1967 else
1968 return _STD::distance(
1969 __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
1970 __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)
1971 );
1972 }
1973 return 0;
1974}
1975
1976template <class _Tp, class _Compare, class _Allocator>
1977template <class _Key>
1978typename __tree<_Tp, _Compare, _Allocator>::iterator
1979__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
1980 __node_pointer __root,
1981 __node_pointer __result)
1982{
1983 while (__root != nullptr)
1984 {
1985 if (!value_comp()(__root->__value_, __v))
1986 {
1987 __result = __root;
1988 __root = static_cast<__node_pointer>(__root->__left_);
1989 }
1990 else
1991 __root = static_cast<__node_pointer>(__root->__right_);
1992 }
1993 return iterator(__result);
1994}
1995
1996template <class _Tp, class _Compare, class _Allocator>
1997template <class _Key>
1998typename __tree<_Tp, _Compare, _Allocator>::const_iterator
1999__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
2000 __node_const_pointer __root,
2001 __node_const_pointer __result) const
2002{
2003 while (__root != nullptr)
2004 {
2005 if (!value_comp()(__root->__value_, __v))
2006 {
2007 __result = __root;
2008 __root = static_cast<__node_const_pointer>(__root->__left_);
2009 }
2010 else
2011 __root = static_cast<__node_const_pointer>(__root->__right_);
2012 }
2013 return const_iterator(__result);
2014}
2015
2016template <class _Tp, class _Compare, class _Allocator>
2017template <class _Key>
2018typename __tree<_Tp, _Compare, _Allocator>::iterator
2019__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2020 __node_pointer __root,
2021 __node_pointer __result)
2022{
2023 while (__root != nullptr)
2024 {
2025 if (value_comp()(__v, __root->__value_))
2026 {
2027 __result = __root;
2028 __root = static_cast<__node_pointer>(__root->__left_);
2029 }
2030 else
2031 __root = static_cast<__node_pointer>(__root->__right_);
2032 }
2033 return iterator(__result);
2034}
2035
2036template <class _Tp, class _Compare, class _Allocator>
2037template <class _Key>
2038typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2039__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
2040 __node_const_pointer __root,
2041 __node_const_pointer __result) const
2042{
2043 while (__root != nullptr)
2044 {
2045 if (value_comp()(__v, __root->__value_))
2046 {
2047 __result = __root;
2048 __root = static_cast<__node_const_pointer>(__root->__left_);
2049 }
2050 else
2051 __root = static_cast<__node_const_pointer>(__root->__right_);
2052 }
2053 return const_iterator(__result);
2054}
2055
2056template <class _Tp, class _Compare, class _Allocator>
2057template <class _Key>
2058pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2059 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2060__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
2061{
2062 typedef pair<iterator, iterator> _P;
2063 __node_pointer __result = __end_node();
2064 __node_pointer __rt = __root();
2065 while (__rt != nullptr)
2066 {
2067 if (value_comp()(__k, __rt->__value_))
2068 {
2069 __result = __rt;
2070 __rt = static_cast<__node_pointer>(__rt->__left_);
2071 }
2072 else if (value_comp()(__rt->__value_, __k))
2073 __rt = static_cast<__node_pointer>(__rt->__right_);
2074 else
2075 return _P(iterator(__rt),
2076 iterator(
2077 __rt->__right_ != nullptr ?
2078 static_cast<__node_pointer>(__tree_min(__rt->__right_))
2079 : __result));
2080 }
2081 return _P(iterator(__result), iterator(__result));
2082}
2083
2084template <class _Tp, class _Compare, class _Allocator>
2085template <class _Key>
2086pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2087 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2088__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
2089{
2090 typedef pair<const_iterator, const_iterator> _P;
2091 __node_const_pointer __result = __end_node();
2092 __node_const_pointer __rt = __root();
2093 while (__rt != nullptr)
2094 {
2095 if (value_comp()(__k, __rt->__value_))
2096 {
2097 __result = __rt;
2098 __rt = static_cast<__node_const_pointer>(__rt->__left_);
2099 }
2100 else if (value_comp()(__rt->__value_, __k))
2101 __rt = static_cast<__node_const_pointer>(__rt->__right_);
2102 else
2103 return _P(const_iterator(__rt),
2104 const_iterator(
2105 __rt->__right_ != nullptr ?
2106 static_cast<__node_const_pointer>(__tree_min(__rt->__right_))
2107 : __result));
2108 }
2109 return _P(const_iterator(__result), const_iterator(__result));
2110}
2111
2112template <class _Tp, class _Compare, class _Allocator>
2113template <class _Key>
2114pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
2115 typename __tree<_Tp, _Compare, _Allocator>::iterator>
2116__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
2117{
2118 typedef pair<iterator, iterator> _P;
2119 __node_pointer __result = __end_node();
2120 __node_pointer __rt = __root();
2121 while (__rt != nullptr)
2122 {
2123 if (value_comp()(__k, __rt->__value_))
2124 {
2125 __result = __rt;
2126 __rt = static_cast<__node_pointer>(__rt->__left_);
2127 }
2128 else if (value_comp()(__rt->__value_, __k))
2129 __rt = static_cast<__node_pointer>(__rt->__right_);
2130 else
2131 return _P(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
2132 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2133 }
2134 return _P(iterator(__result), iterator(__result));
2135}
2136
2137template <class _Tp, class _Compare, class _Allocator>
2138template <class _Key>
2139pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
2140 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
2141__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
2142{
2143 typedef pair<const_iterator, const_iterator> _P;
2144 __node_const_pointer __result = __end_node();
2145 __node_const_pointer __rt = __root();
2146 while (__rt != nullptr)
2147 {
2148 if (value_comp()(__k, __rt->__value_))
2149 {
2150 __result = __rt;
2151 __rt = static_cast<__node_const_pointer>(__rt->__left_);
2152 }
2153 else if (value_comp()(__rt->__value_, __k))
2154 __rt = static_cast<__node_const_pointer>(__rt->__right_);
2155 else
2156 return _P(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
2157 __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result));
2158 }
2159 return _P(const_iterator(__result), const_iterator(__result));
2160}
2161
2162template <class _Tp, class _Compare, class _Allocator>
2163typename __tree<_Tp, _Compare, _Allocator>::__node_holder
2164__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p)
2165{
2166 __node_pointer __np = const_cast<__node_pointer>(__p.__ptr_);
2167 if (__begin_node() == __np)
2168 {
2169 if (__np->__right_ != nullptr)
2170 __begin_node() = static_cast<__node_pointer>(__np->__right_);
2171 else
2172 __begin_node() = static_cast<__node_pointer>(__np->__parent_);
2173 }
2174 --size();
2175 __tree_remove(__end_node()->__left_,
2176 static_cast<__node_base_pointer>(__np));
2177 return __node_holder(__np, _D(__node_alloc()));
2178}
2179
2180_LIBCPP_END_NAMESPACE_STD
2181
2182#endif // _LIBCPP___TREE