]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/bits/stl_tree.h
re PR libstdc++/29988 (More stl_tree.h enhancements: improving operator=)
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / stl_tree.h
1 // RB tree implementation -*- C++ -*-
2
3 // Copyright (C) 2001-2014 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /*
26 *
27 * Copyright (c) 1996,1997
28 * Silicon Graphics Computer Systems, Inc.
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Silicon Graphics makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1994
40 * Hewlett-Packard Company
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Hewlett-Packard Company makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 *
50 *
51 */
52
53 /** @file bits/stl_tree.h
54 * This is an internal header file, included by other library headers.
55 * Do not attempt to use it directly. @headername{map,set}
56 */
57
58 #ifndef _STL_TREE_H
59 #define _STL_TREE_H 1
60
61 #pragma GCC system_header
62
63 #include <bits/stl_algobase.h>
64 #include <bits/allocator.h>
65 #include <bits/stl_function.h>
66 #include <bits/cpp_type_traits.h>
67 #include <ext/alloc_traits.h>
68 #if __cplusplus >= 201103L
69 #include <ext/aligned_buffer.h>
70 #endif
71
72 namespace std _GLIBCXX_VISIBILITY(default)
73 {
74 _GLIBCXX_BEGIN_NAMESPACE_VERSION
75
76 // Red-black tree class, designed for use in implementing STL
77 // associative containers (set, multiset, map, and multimap). The
78 // insertion and deletion algorithms are based on those in Cormen,
79 // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
80 // 1990), except that
81 //
82 // (1) the header cell is maintained with links not only to the root
83 // but also to the leftmost node of the tree, to enable constant
84 // time begin(), and to the rightmost node of the tree, to enable
85 // linear time performance when used with the generic set algorithms
86 // (set_union, etc.)
87 //
88 // (2) when a node being deleted has two children its successor node
89 // is relinked into its place, rather than copied, so that the only
90 // iterators invalidated are those referring to the deleted node.
91
92 enum _Rb_tree_color { _S_red = false, _S_black = true };
93
94 struct _Rb_tree_node_base
95 {
96 typedef _Rb_tree_node_base* _Base_ptr;
97 typedef const _Rb_tree_node_base* _Const_Base_ptr;
98
99 _Rb_tree_color _M_color;
100 _Base_ptr _M_parent;
101 _Base_ptr _M_left;
102 _Base_ptr _M_right;
103
104 static _Base_ptr
105 _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
106 {
107 while (__x->_M_left != 0) __x = __x->_M_left;
108 return __x;
109 }
110
111 static _Const_Base_ptr
112 _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
113 {
114 while (__x->_M_left != 0) __x = __x->_M_left;
115 return __x;
116 }
117
118 static _Base_ptr
119 _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
120 {
121 while (__x->_M_right != 0) __x = __x->_M_right;
122 return __x;
123 }
124
125 static _Const_Base_ptr
126 _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
127 {
128 while (__x->_M_right != 0) __x = __x->_M_right;
129 return __x;
130 }
131 };
132
133 template<typename _Val>
134 struct _Rb_tree_node : public _Rb_tree_node_base
135 {
136 typedef _Rb_tree_node<_Val>* _Link_type;
137
138 #if __cplusplus < 201103L
139 _Val _M_value_field;
140
141 _Val*
142 _M_valptr()
143 { return std::__addressof(_M_value_field); }
144
145 const _Val*
146 _M_valptr() const
147 { return std::__addressof(_M_value_field); }
148 #else
149 __gnu_cxx::__aligned_buffer<_Val> _M_storage;
150
151 _Val*
152 _M_valptr()
153 { return _M_storage._M_ptr(); }
154
155 const _Val*
156 _M_valptr() const
157 { return _M_storage._M_ptr(); }
158 #endif
159 };
160
161 _GLIBCXX_PURE _Rb_tree_node_base*
162 _Rb_tree_increment(_Rb_tree_node_base* __x) throw ();
163
164 _GLIBCXX_PURE const _Rb_tree_node_base*
165 _Rb_tree_increment(const _Rb_tree_node_base* __x) throw ();
166
167 _GLIBCXX_PURE _Rb_tree_node_base*
168 _Rb_tree_decrement(_Rb_tree_node_base* __x) throw ();
169
170 _GLIBCXX_PURE const _Rb_tree_node_base*
171 _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw ();
172
173 template<typename _Tp>
174 struct _Rb_tree_iterator
175 {
176 typedef _Tp value_type;
177 typedef _Tp& reference;
178 typedef _Tp* pointer;
179
180 typedef bidirectional_iterator_tag iterator_category;
181 typedef ptrdiff_t difference_type;
182
183 typedef _Rb_tree_iterator<_Tp> _Self;
184 typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
185 typedef _Rb_tree_node<_Tp>* _Link_type;
186
187 _Rb_tree_iterator() _GLIBCXX_NOEXCEPT
188 : _M_node() { }
189
190 explicit
191 _Rb_tree_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT
192 : _M_node(__x) { }
193
194 reference
195 operator*() const _GLIBCXX_NOEXCEPT
196 { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
197
198 pointer
199 operator->() const _GLIBCXX_NOEXCEPT
200 { return static_cast<_Link_type> (_M_node)->_M_valptr(); }
201
202 _Self&
203 operator++() _GLIBCXX_NOEXCEPT
204 {
205 _M_node = _Rb_tree_increment(_M_node);
206 return *this;
207 }
208
209 _Self
210 operator++(int) _GLIBCXX_NOEXCEPT
211 {
212 _Self __tmp = *this;
213 _M_node = _Rb_tree_increment(_M_node);
214 return __tmp;
215 }
216
217 _Self&
218 operator--() _GLIBCXX_NOEXCEPT
219 {
220 _M_node = _Rb_tree_decrement(_M_node);
221 return *this;
222 }
223
224 _Self
225 operator--(int) _GLIBCXX_NOEXCEPT
226 {
227 _Self __tmp = *this;
228 _M_node = _Rb_tree_decrement(_M_node);
229 return __tmp;
230 }
231
232 bool
233 operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
234 { return _M_node == __x._M_node; }
235
236 bool
237 operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
238 { return _M_node != __x._M_node; }
239
240 _Base_ptr _M_node;
241 };
242
243 template<typename _Tp>
244 struct _Rb_tree_const_iterator
245 {
246 typedef _Tp value_type;
247 typedef const _Tp& reference;
248 typedef const _Tp* pointer;
249
250 typedef _Rb_tree_iterator<_Tp> iterator;
251
252 typedef bidirectional_iterator_tag iterator_category;
253 typedef ptrdiff_t difference_type;
254
255 typedef _Rb_tree_const_iterator<_Tp> _Self;
256 typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
257 typedef const _Rb_tree_node<_Tp>* _Link_type;
258
259 _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT
260 : _M_node() { }
261
262 explicit
263 _Rb_tree_const_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT
264 : _M_node(__x) { }
265
266 _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT
267 : _M_node(__it._M_node) { }
268
269 iterator
270 _M_const_cast() const _GLIBCXX_NOEXCEPT
271 { return iterator(static_cast<typename iterator::_Link_type>
272 (const_cast<typename iterator::_Base_ptr>(_M_node))); }
273
274 reference
275 operator*() const _GLIBCXX_NOEXCEPT
276 { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
277
278 pointer
279 operator->() const _GLIBCXX_NOEXCEPT
280 { return static_cast<_Link_type>(_M_node)->_M_valptr(); }
281
282 _Self&
283 operator++() _GLIBCXX_NOEXCEPT
284 {
285 _M_node = _Rb_tree_increment(_M_node);
286 return *this;
287 }
288
289 _Self
290 operator++(int) _GLIBCXX_NOEXCEPT
291 {
292 _Self __tmp = *this;
293 _M_node = _Rb_tree_increment(_M_node);
294 return __tmp;
295 }
296
297 _Self&
298 operator--() _GLIBCXX_NOEXCEPT
299 {
300 _M_node = _Rb_tree_decrement(_M_node);
301 return *this;
302 }
303
304 _Self
305 operator--(int) _GLIBCXX_NOEXCEPT
306 {
307 _Self __tmp = *this;
308 _M_node = _Rb_tree_decrement(_M_node);
309 return __tmp;
310 }
311
312 bool
313 operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
314 { return _M_node == __x._M_node; }
315
316 bool
317 operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
318 { return _M_node != __x._M_node; }
319
320 _Base_ptr _M_node;
321 };
322
323 template<typename _Val>
324 inline bool
325 operator==(const _Rb_tree_iterator<_Val>& __x,
326 const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
327 { return __x._M_node == __y._M_node; }
328
329 template<typename _Val>
330 inline bool
331 operator!=(const _Rb_tree_iterator<_Val>& __x,
332 const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
333 { return __x._M_node != __y._M_node; }
334
335 void
336 _Rb_tree_insert_and_rebalance(const bool __insert_left,
337 _Rb_tree_node_base* __x,
338 _Rb_tree_node_base* __p,
339 _Rb_tree_node_base& __header) throw ();
340
341 _Rb_tree_node_base*
342 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
343 _Rb_tree_node_base& __header) throw ();
344
345
346 template<typename _Key, typename _Val, typename _KeyOfValue,
347 typename _Compare, typename _Alloc = allocator<_Val> >
348 class _Rb_tree
349 {
350 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
351 rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
352
353 typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
354
355 protected:
356 typedef _Rb_tree_node_base* _Base_ptr;
357 typedef const _Rb_tree_node_base* _Const_Base_ptr;
358 typedef _Rb_tree_node<_Val>* _Link_type;
359 typedef const _Rb_tree_node<_Val>* _Const_Link_type;
360
361 private:
362 // Functor recycling a pool of nodes and using allocation once the pool is
363 // empty.
364 struct _Reuse_or_alloc_node
365 {
366 _Reuse_or_alloc_node(const _Rb_tree_node_base& __header,
367 _Rb_tree& __t)
368 : _M_root(__header._M_parent), _M_nodes(__header._M_right), _M_t(__t)
369 {
370 if (_M_root)
371 _M_root->_M_parent = 0;
372 else
373 _M_nodes = 0;
374 }
375
376 #if __cplusplus >= 201103L
377 _Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete;
378 #endif
379
380 ~_Reuse_or_alloc_node()
381 { _M_t._M_erase(static_cast<_Link_type>(_M_root)); }
382
383 template<typename _Arg>
384 _Link_type
385 #if __cplusplus < 201103L
386 operator()(const _Arg& __arg)
387 #else
388 operator()(_Arg&& __arg)
389 #endif
390 {
391 _Link_type __node = static_cast<_Link_type>(_M_extract());
392 if (__node)
393 {
394 _M_t._M_destroy_node(__node);
395 _M_t._M_construct_node(__node, _GLIBCXX_FORWARD(_Arg, __arg));
396 return __node;
397 }
398
399 return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg));
400 }
401
402 private:
403 _Base_ptr
404 _M_extract()
405 {
406 if (!_M_nodes)
407 return _M_nodes;
408
409 _Base_ptr __node = _M_nodes;
410 _M_nodes = _M_nodes->_M_parent;
411 if (_M_nodes)
412 {
413 if (_M_nodes->_M_right == __node)
414 {
415 _M_nodes->_M_right = 0;
416
417 if (_M_nodes->_M_left)
418 {
419 _M_nodes = _M_nodes->_M_left;
420
421 while (_M_nodes->_M_right)
422 _M_nodes = _M_nodes->_M_right;
423 }
424 }
425 else // __node is on the left.
426 _M_nodes->_M_left = 0;
427 }
428 else
429 _M_root = 0;
430
431 return __node;
432 }
433
434 _Base_ptr _M_root;
435 _Base_ptr _M_nodes;
436 _Rb_tree& _M_t;
437 };
438
439 // Functor similar to the previous one but without any pool of node to
440 // recycle.
441 struct _Alloc_node
442 {
443 _Alloc_node(_Rb_tree& __t)
444 : _M_t(__t) { }
445
446 template<typename _Arg>
447 _Link_type
448 #if __cplusplus < 201103L
449 operator()(const _Arg& __arg) const
450 #else
451 operator()(_Arg&& __arg) const
452 #endif
453 { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); }
454
455 private:
456 _Rb_tree& _M_t;
457 };
458
459 public:
460 typedef _Key key_type;
461 typedef _Val value_type;
462 typedef value_type* pointer;
463 typedef const value_type* const_pointer;
464 typedef value_type& reference;
465 typedef const value_type& const_reference;
466 typedef size_t size_type;
467 typedef ptrdiff_t difference_type;
468 typedef _Alloc allocator_type;
469
470 _Node_allocator&
471 _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
472 { return *static_cast<_Node_allocator*>(&this->_M_impl); }
473
474 const _Node_allocator&
475 _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
476 { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
477
478 allocator_type
479 get_allocator() const _GLIBCXX_NOEXCEPT
480 { return allocator_type(_M_get_Node_allocator()); }
481
482 protected:
483 _Link_type
484 _M_get_node()
485 { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
486
487 void
488 _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT
489 { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
490
491 #if __cplusplus < 201103L
492 void
493 _M_construct_node(_Link_type __node, const value_type& __x)
494 {
495 __try
496 { get_allocator().construct(__node->_M_valptr(), __x); }
497 __catch(...)
498 {
499 _M_put_node(__node);
500 __throw_exception_again;
501 }
502 }
503
504 _Link_type
505 _M_create_node(const value_type& __x)
506 {
507 _Link_type __tmp = _M_get_node();
508 _M_construct_node(__tmp, __x);
509 return __tmp;
510 }
511
512 void
513 _M_destroy_node(_Link_type __p)
514 { get_allocator().destroy(__p->_M_valptr()); }
515 #else
516 template<typename... _Args>
517 void
518 _M_construct_node(_Link_type __node, _Args&&... __args)
519 {
520 __try
521 {
522 ::new(__node) _Rb_tree_node<_Val>;
523 _Alloc_traits::construct(_M_get_Node_allocator(),
524 __node->_M_valptr(),
525 std::forward<_Args>(__args)...);
526 }
527 __catch(...)
528 {
529 __node->~_Rb_tree_node<_Val>();
530 _M_put_node(__node);
531 __throw_exception_again;
532 }
533 }
534
535 template<typename... _Args>
536 _Link_type
537 _M_create_node(_Args&&... __args)
538 {
539 _Link_type __tmp = _M_get_node();
540 _M_construct_node(__tmp, std::forward<_Args>(__args)...);
541 return __tmp;
542 }
543
544 void
545 _M_destroy_node(_Link_type __p) noexcept
546 {
547 _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
548 __p->~_Rb_tree_node<_Val>();
549 }
550 #endif
551
552 void
553 _M_drop_node(_Link_type __p) _GLIBCXX_NOEXCEPT
554 {
555 _M_destroy_node(__p);
556 _M_put_node(__p);
557 }
558
559 template<typename _NodeGen>
560 _Link_type
561 _M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen)
562 {
563 _Link_type __tmp = __node_gen(*__x->_M_valptr());
564 __tmp->_M_color = __x->_M_color;
565 __tmp->_M_left = 0;
566 __tmp->_M_right = 0;
567 return __tmp;
568 }
569
570 protected:
571 // Unused _Is_pod_comparator is kept as it is part of mangled name.
572 template<typename _Key_compare,
573 bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
574 struct _Rb_tree_impl : public _Node_allocator
575 {
576 _Key_compare _M_key_compare;
577 _Rb_tree_node_base _M_header;
578 size_type _M_node_count; // Keeps track of size of tree.
579
580 _Rb_tree_impl()
581 : _Node_allocator(), _M_key_compare(), _M_header(),
582 _M_node_count(0)
583 { _M_initialize(); }
584
585 _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
586 : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
587 _M_node_count(0)
588 { _M_initialize(); }
589
590 #if __cplusplus >= 201103L
591 _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
592 : _Node_allocator(std::move(__a)), _M_key_compare(__comp),
593 _M_header(), _M_node_count(0)
594 { _M_initialize(); }
595 #endif
596
597 void
598 _M_reset()
599 {
600 this->_M_header._M_parent = 0;
601 this->_M_header._M_left = &this->_M_header;
602 this->_M_header._M_right = &this->_M_header;
603 this->_M_node_count = 0;
604 }
605
606 private:
607 void
608 _M_initialize()
609 {
610 this->_M_header._M_color = _S_red;
611 this->_M_header._M_parent = 0;
612 this->_M_header._M_left = &this->_M_header;
613 this->_M_header._M_right = &this->_M_header;
614 }
615 };
616
617 _Rb_tree_impl<_Compare> _M_impl;
618
619 protected:
620 _Base_ptr&
621 _M_root() _GLIBCXX_NOEXCEPT
622 { return this->_M_impl._M_header._M_parent; }
623
624 _Const_Base_ptr
625 _M_root() const _GLIBCXX_NOEXCEPT
626 { return this->_M_impl._M_header._M_parent; }
627
628 _Base_ptr&
629 _M_leftmost() _GLIBCXX_NOEXCEPT
630 { return this->_M_impl._M_header._M_left; }
631
632 _Const_Base_ptr
633 _M_leftmost() const _GLIBCXX_NOEXCEPT
634 { return this->_M_impl._M_header._M_left; }
635
636 _Base_ptr&
637 _M_rightmost() _GLIBCXX_NOEXCEPT
638 { return this->_M_impl._M_header._M_right; }
639
640 _Const_Base_ptr
641 _M_rightmost() const _GLIBCXX_NOEXCEPT
642 { return this->_M_impl._M_header._M_right; }
643
644 _Link_type
645 _M_begin() _GLIBCXX_NOEXCEPT
646 { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
647
648 _Const_Link_type
649 _M_begin() const _GLIBCXX_NOEXCEPT
650 {
651 return static_cast<_Const_Link_type>
652 (this->_M_impl._M_header._M_parent);
653 }
654
655 _Link_type
656 _M_end() _GLIBCXX_NOEXCEPT
657 { return reinterpret_cast<_Link_type>(&this->_M_impl._M_header); }
658
659 _Const_Link_type
660 _M_end() const _GLIBCXX_NOEXCEPT
661 { return reinterpret_cast<_Const_Link_type>(&this->_M_impl._M_header); }
662
663 static const_reference
664 _S_value(_Const_Link_type __x)
665 { return *__x->_M_valptr(); }
666
667 static const _Key&
668 _S_key(_Const_Link_type __x)
669 { return _KeyOfValue()(_S_value(__x)); }
670
671 static _Link_type
672 _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT
673 { return static_cast<_Link_type>(__x->_M_left); }
674
675 static _Const_Link_type
676 _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
677 { return static_cast<_Const_Link_type>(__x->_M_left); }
678
679 static _Link_type
680 _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT
681 { return static_cast<_Link_type>(__x->_M_right); }
682
683 static _Const_Link_type
684 _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
685 { return static_cast<_Const_Link_type>(__x->_M_right); }
686
687 static const_reference
688 _S_value(_Const_Base_ptr __x)
689 { return *static_cast<_Const_Link_type>(__x)->_M_valptr(); }
690
691 static const _Key&
692 _S_key(_Const_Base_ptr __x)
693 { return _KeyOfValue()(_S_value(__x)); }
694
695 static _Base_ptr
696 _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
697 { return _Rb_tree_node_base::_S_minimum(__x); }
698
699 static _Const_Base_ptr
700 _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
701 { return _Rb_tree_node_base::_S_minimum(__x); }
702
703 static _Base_ptr
704 _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
705 { return _Rb_tree_node_base::_S_maximum(__x); }
706
707 static _Const_Base_ptr
708 _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
709 { return _Rb_tree_node_base::_S_maximum(__x); }
710
711 public:
712 typedef _Rb_tree_iterator<value_type> iterator;
713 typedef _Rb_tree_const_iterator<value_type> const_iterator;
714
715 typedef std::reverse_iterator<iterator> reverse_iterator;
716 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
717
718 private:
719 pair<_Base_ptr, _Base_ptr>
720 _M_get_insert_unique_pos(const key_type& __k);
721
722 pair<_Base_ptr, _Base_ptr>
723 _M_get_insert_equal_pos(const key_type& __k);
724
725 pair<_Base_ptr, _Base_ptr>
726 _M_get_insert_hint_unique_pos(const_iterator __pos,
727 const key_type& __k);
728
729 pair<_Base_ptr, _Base_ptr>
730 _M_get_insert_hint_equal_pos(const_iterator __pos,
731 const key_type& __k);
732
733 #if __cplusplus >= 201103L
734 template<typename _Arg, typename _NodeGen>
735 iterator
736 _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v, _NodeGen&);
737
738 iterator
739 _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
740
741 template<typename _Arg>
742 iterator
743 _M_insert_lower(_Base_ptr __y, _Arg&& __v);
744
745 template<typename _Arg>
746 iterator
747 _M_insert_equal_lower(_Arg&& __x);
748
749 iterator
750 _M_insert_lower_node(_Base_ptr __p, _Link_type __z);
751
752 iterator
753 _M_insert_equal_lower_node(_Link_type __z);
754 #else
755 template<typename _NodeGen>
756 iterator
757 _M_insert_(_Base_ptr __x, _Base_ptr __y,
758 const value_type& __v, _NodeGen&);
759
760 // _GLIBCXX_RESOLVE_LIB_DEFECTS
761 // 233. Insertion hints in associative containers.
762 iterator
763 _M_insert_lower(_Base_ptr __y, const value_type& __v);
764
765 iterator
766 _M_insert_equal_lower(const value_type& __x);
767 #endif
768
769 template<typename _NodeGen>
770 _Link_type
771 _M_copy(_Const_Link_type __x, _Link_type __p, _NodeGen&);
772
773 _Link_type
774 _M_copy(_Const_Link_type __x, _Link_type __p)
775 {
776 _Alloc_node __an(*this);
777 return _M_copy(__x, __p, __an);
778 }
779
780 void
781 _M_erase(_Link_type __x);
782
783 iterator
784 _M_lower_bound(_Link_type __x, _Link_type __y,
785 const _Key& __k);
786
787 const_iterator
788 _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
789 const _Key& __k) const;
790
791 iterator
792 _M_upper_bound(_Link_type __x, _Link_type __y,
793 const _Key& __k);
794
795 const_iterator
796 _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
797 const _Key& __k) const;
798
799 public:
800 // allocation/deallocation
801 _Rb_tree() { }
802
803 _Rb_tree(const _Compare& __comp,
804 const allocator_type& __a = allocator_type())
805 : _M_impl(__comp, _Node_allocator(__a)) { }
806
807 _Rb_tree(const _Rb_tree& __x)
808 : _M_impl(__x._M_impl._M_key_compare,
809 _Alloc_traits::_S_select_on_copy(__x._M_get_Node_allocator()))
810 {
811 if (__x._M_root() != 0)
812 {
813 _M_root() = _M_copy(__x._M_begin(), _M_end());
814 _M_leftmost() = _S_minimum(_M_root());
815 _M_rightmost() = _S_maximum(_M_root());
816 _M_impl._M_node_count = __x._M_impl._M_node_count;
817 }
818 }
819
820 #if __cplusplus >= 201103L
821 _Rb_tree(const allocator_type& __a)
822 : _M_impl(_Compare(), _Node_allocator(__a))
823 { }
824
825 _Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
826 : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
827 {
828 if (__x._M_root() != nullptr)
829 {
830 _M_root() = _M_copy(__x._M_begin(), _M_end());
831 _M_leftmost() = _S_minimum(_M_root());
832 _M_rightmost() = _S_maximum(_M_root());
833 _M_impl._M_node_count = __x._M_impl._M_node_count;
834 }
835 }
836
837 _Rb_tree(_Rb_tree&& __x)
838 : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
839 {
840 if (__x._M_root() != 0)
841 _M_move_data(__x, std::true_type());
842 }
843
844 _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
845 : _Rb_tree(std::move(__x), _Node_allocator(__a))
846 { }
847
848 _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a);
849 #endif
850
851 ~_Rb_tree() _GLIBCXX_NOEXCEPT
852 { _M_erase(_M_begin()); }
853
854 _Rb_tree&
855 operator=(const _Rb_tree& __x);
856
857 // Accessors.
858 _Compare
859 key_comp() const
860 { return _M_impl._M_key_compare; }
861
862 iterator
863 begin() _GLIBCXX_NOEXCEPT
864 {
865 return iterator(static_cast<_Link_type>
866 (this->_M_impl._M_header._M_left));
867 }
868
869 const_iterator
870 begin() const _GLIBCXX_NOEXCEPT
871 {
872 return const_iterator(static_cast<_Const_Link_type>
873 (this->_M_impl._M_header._M_left));
874 }
875
876 iterator
877 end() _GLIBCXX_NOEXCEPT
878 { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }
879
880 const_iterator
881 end() const _GLIBCXX_NOEXCEPT
882 {
883 return const_iterator(static_cast<_Const_Link_type>
884 (&this->_M_impl._M_header));
885 }
886
887 reverse_iterator
888 rbegin() _GLIBCXX_NOEXCEPT
889 { return reverse_iterator(end()); }
890
891 const_reverse_iterator
892 rbegin() const _GLIBCXX_NOEXCEPT
893 { return const_reverse_iterator(end()); }
894
895 reverse_iterator
896 rend() _GLIBCXX_NOEXCEPT
897 { return reverse_iterator(begin()); }
898
899 const_reverse_iterator
900 rend() const _GLIBCXX_NOEXCEPT
901 { return const_reverse_iterator(begin()); }
902
903 bool
904 empty() const _GLIBCXX_NOEXCEPT
905 { return _M_impl._M_node_count == 0; }
906
907 size_type
908 size() const _GLIBCXX_NOEXCEPT
909 { return _M_impl._M_node_count; }
910
911 size_type
912 max_size() const _GLIBCXX_NOEXCEPT
913 { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
914
915 void
916 #if __cplusplus >= 201103L
917 swap(_Rb_tree& __t) noexcept(_Alloc_traits::_S_nothrow_swap());
918 #else
919 swap(_Rb_tree& __t);
920 #endif
921
922 // Insert/erase.
923 #if __cplusplus >= 201103L
924 template<typename _Arg>
925 pair<iterator, bool>
926 _M_insert_unique(_Arg&& __x);
927
928 template<typename _Arg>
929 iterator
930 _M_insert_equal(_Arg&& __x);
931
932 template<typename _Arg, typename _NodeGen>
933 iterator
934 _M_insert_unique_(const_iterator __pos, _Arg&& __x, _NodeGen&);
935
936 template<typename _Arg>
937 iterator
938 _M_insert_unique_(const_iterator __pos, _Arg&& __x)
939 {
940 _Alloc_node __an(*this);
941 return _M_insert_unique_(__pos, std::forward<_Arg>(__x), __an);
942 }
943
944 template<typename _Arg, typename _NodeGen>
945 iterator
946 _M_insert_equal_(const_iterator __pos, _Arg&& __x, _NodeGen&);
947
948 template<typename _Arg>
949 iterator
950 _M_insert_equal_(const_iterator __pos, _Arg&& __x)
951 {
952 _Alloc_node __an(*this);
953 return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an);
954 }
955
956 template<typename... _Args>
957 pair<iterator, bool>
958 _M_emplace_unique(_Args&&... __args);
959
960 template<typename... _Args>
961 iterator
962 _M_emplace_equal(_Args&&... __args);
963
964 template<typename... _Args>
965 iterator
966 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args);
967
968 template<typename... _Args>
969 iterator
970 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args);
971 #else
972 pair<iterator, bool>
973 _M_insert_unique(const value_type& __x);
974
975 iterator
976 _M_insert_equal(const value_type& __x);
977
978 template<typename _NodeGen>
979 iterator
980 _M_insert_unique_(const_iterator __pos, const value_type& __x,
981 _NodeGen&);
982
983 iterator
984 _M_insert_unique_(const_iterator __pos, const value_type& __x)
985 {
986 _Alloc_node __an(*this);
987 return _M_insert_unique_(__pos, __x, __an);
988 }
989
990 template<typename _NodeGen>
991 iterator
992 _M_insert_equal_(const_iterator __pos, const value_type& __x,
993 _NodeGen&);
994 iterator
995 _M_insert_equal_(const_iterator __pos, const value_type& __x)
996 {
997 _Alloc_node __an(*this);
998 return _M_insert_equal_(__pos, __x, __an);
999 }
1000 #endif
1001
1002 template<typename _InputIterator>
1003 void
1004 _M_insert_unique(_InputIterator __first, _InputIterator __last);
1005
1006 template<typename _InputIterator>
1007 void
1008 _M_insert_equal(_InputIterator __first, _InputIterator __last);
1009
1010 private:
1011 void
1012 _M_erase_aux(const_iterator __position);
1013
1014 void
1015 _M_erase_aux(const_iterator __first, const_iterator __last);
1016
1017 public:
1018 #if __cplusplus >= 201103L
1019 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1020 // DR 130. Associative erase should return an iterator.
1021 _GLIBCXX_ABI_TAG_CXX11
1022 iterator
1023 erase(const_iterator __position)
1024 {
1025 const_iterator __result = __position;
1026 ++__result;
1027 _M_erase_aux(__position);
1028 return __result._M_const_cast();
1029 }
1030
1031 // LWG 2059.
1032 _GLIBCXX_ABI_TAG_CXX11
1033 iterator
1034 erase(iterator __position)
1035 {
1036 iterator __result = __position;
1037 ++__result;
1038 _M_erase_aux(__position);
1039 return __result;
1040 }
1041 #else
1042 void
1043 erase(iterator __position)
1044 { _M_erase_aux(__position); }
1045
1046 void
1047 erase(const_iterator __position)
1048 { _M_erase_aux(__position); }
1049 #endif
1050 size_type
1051 erase(const key_type& __x);
1052
1053 #if __cplusplus >= 201103L
1054 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1055 // DR 130. Associative erase should return an iterator.
1056 _GLIBCXX_ABI_TAG_CXX11
1057 iterator
1058 erase(const_iterator __first, const_iterator __last)
1059 {
1060 _M_erase_aux(__first, __last);
1061 return __last._M_const_cast();
1062 }
1063 #else
1064 void
1065 erase(iterator __first, iterator __last)
1066 { _M_erase_aux(__first, __last); }
1067
1068 void
1069 erase(const_iterator __first, const_iterator __last)
1070 { _M_erase_aux(__first, __last); }
1071 #endif
1072 void
1073 erase(const key_type* __first, const key_type* __last);
1074
1075 void
1076 clear() _GLIBCXX_NOEXCEPT
1077 {
1078 _M_erase(_M_begin());
1079 _M_impl._M_reset();
1080 }
1081
1082 // Set operations.
1083 iterator
1084 find(const key_type& __k);
1085
1086 const_iterator
1087 find(const key_type& __k) const;
1088
1089 size_type
1090 count(const key_type& __k) const;
1091
1092 iterator
1093 lower_bound(const key_type& __k)
1094 { return _M_lower_bound(_M_begin(), _M_end(), __k); }
1095
1096 const_iterator
1097 lower_bound(const key_type& __k) const
1098 { return _M_lower_bound(_M_begin(), _M_end(), __k); }
1099
1100 iterator
1101 upper_bound(const key_type& __k)
1102 { return _M_upper_bound(_M_begin(), _M_end(), __k); }
1103
1104 const_iterator
1105 upper_bound(const key_type& __k) const
1106 { return _M_upper_bound(_M_begin(), _M_end(), __k); }
1107
1108 pair<iterator, iterator>
1109 equal_range(const key_type& __k);
1110
1111 pair<const_iterator, const_iterator>
1112 equal_range(const key_type& __k) const;
1113
1114 // Debugging.
1115 bool
1116 __rb_verify() const;
1117
1118 #if __cplusplus >= 201103L
1119 _Rb_tree&
1120 operator=(_Rb_tree&&) noexcept(_Alloc_traits::_S_nothrow_move());
1121
1122 template<typename _Iterator>
1123 void
1124 _M_assign_unique(_Iterator, _Iterator);
1125
1126 template<typename _Iterator>
1127 void
1128 _M_assign_equal(_Iterator, _Iterator);
1129
1130 private:
1131 // Move elements from container with equal allocator.
1132 void
1133 _M_move_data(_Rb_tree&, std::true_type);
1134
1135 // Move elements from container with possibly non-equal allocator,
1136 // which might result in a copy not a move.
1137 void
1138 _M_move_data(_Rb_tree&, std::false_type);
1139 #endif
1140 };
1141
1142 template<typename _Key, typename _Val, typename _KeyOfValue,
1143 typename _Compare, typename _Alloc>
1144 inline bool
1145 operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1146 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1147 {
1148 return __x.size() == __y.size()
1149 && std::equal(__x.begin(), __x.end(), __y.begin());
1150 }
1151
1152 template<typename _Key, typename _Val, typename _KeyOfValue,
1153 typename _Compare, typename _Alloc>
1154 inline bool
1155 operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1156 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1157 {
1158 return std::lexicographical_compare(__x.begin(), __x.end(),
1159 __y.begin(), __y.end());
1160 }
1161
1162 template<typename _Key, typename _Val, typename _KeyOfValue,
1163 typename _Compare, typename _Alloc>
1164 inline bool
1165 operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1166 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1167 { return !(__x == __y); }
1168
1169 template<typename _Key, typename _Val, typename _KeyOfValue,
1170 typename _Compare, typename _Alloc>
1171 inline bool
1172 operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1173 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1174 { return __y < __x; }
1175
1176 template<typename _Key, typename _Val, typename _KeyOfValue,
1177 typename _Compare, typename _Alloc>
1178 inline bool
1179 operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1180 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1181 { return !(__y < __x); }
1182
1183 template<typename _Key, typename _Val, typename _KeyOfValue,
1184 typename _Compare, typename _Alloc>
1185 inline bool
1186 operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1187 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1188 { return !(__x < __y); }
1189
1190 template<typename _Key, typename _Val, typename _KeyOfValue,
1191 typename _Compare, typename _Alloc>
1192 inline void
1193 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1194 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1195 { __x.swap(__y); }
1196
1197 #if __cplusplus >= 201103L
1198 template<typename _Key, typename _Val, typename _KeyOfValue,
1199 typename _Compare, typename _Alloc>
1200 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1201 _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
1202 : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
1203 {
1204 using __eq = integral_constant<bool, _Alloc_traits::_S_always_equal()>;
1205 if (__x._M_root() != nullptr)
1206 _M_move_data(__x, __eq());
1207 }
1208
1209 template<typename _Key, typename _Val, typename _KeyOfValue,
1210 typename _Compare, typename _Alloc>
1211 void
1212 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1213 _M_move_data(_Rb_tree& __x, std::true_type)
1214 {
1215 _M_root() = __x._M_root();
1216 _M_leftmost() = __x._M_leftmost();
1217 _M_rightmost() = __x._M_rightmost();
1218 _M_root()->_M_parent = _M_end();
1219
1220 __x._M_root() = 0;
1221 __x._M_leftmost() = __x._M_end();
1222 __x._M_rightmost() = __x._M_end();
1223
1224 this->_M_impl._M_node_count = __x._M_impl._M_node_count;
1225 __x._M_impl._M_node_count = 0;
1226 }
1227
1228 template<typename _Key, typename _Val, typename _KeyOfValue,
1229 typename _Compare, typename _Alloc>
1230 void
1231 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1232 _M_move_data(_Rb_tree& __x, std::false_type)
1233 {
1234 if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
1235 _M_move_data(__x, std::true_type());
1236 else
1237 {
1238 _Alloc_node __an(*this);
1239 auto __lbd =
1240 [&__an](const value_type& __cval)
1241 {
1242 auto& __val = const_cast<value_type&>(__cval);
1243 return __an(std::move_if_noexcept(__val));
1244 };
1245 _M_root() = _M_copy(__x._M_begin(), _M_end(), __lbd);
1246 _M_leftmost() = _S_minimum(_M_root());
1247 _M_rightmost() = _S_maximum(_M_root());
1248 _M_impl._M_node_count = __x._M_impl._M_node_count;
1249 }
1250 }
1251
1252 template<typename _Key, typename _Val, typename _KeyOfValue,
1253 typename _Compare, typename _Alloc>
1254 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
1255 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1256 operator=(_Rb_tree&& __x)
1257 noexcept(_Alloc_traits::_S_nothrow_move())
1258 {
1259 _M_impl._M_key_compare = __x._M_impl._M_key_compare;
1260 if (_Alloc_traits::_S_propagate_on_move_assign()
1261 || _Alloc_traits::_S_always_equal()
1262 || _M_get_Node_allocator() == __x._M_get_Node_allocator())
1263 {
1264 clear();
1265 if (__x._M_root() != nullptr)
1266 _M_move_data(__x, std::true_type());
1267 std::__alloc_on_move(_M_get_Node_allocator(),
1268 __x._M_get_Node_allocator());
1269 return *this;
1270 }
1271
1272 // Try to move each node reusing existing nodes and copying __x nodes
1273 // structure.
1274 _Reuse_or_alloc_node __roan(_M_impl._M_header, *this);
1275 _M_impl._M_reset();
1276 if (__x._M_root() != nullptr)
1277 {
1278 auto __lbd =
1279 [&__roan](const value_type& __cval)
1280 {
1281 auto& __val = const_cast<value_type&>(__cval);
1282 return __roan(std::move_if_noexcept(__val));
1283 };
1284 _M_root() = _M_copy(__x._M_begin(), _M_end(), __lbd);
1285 _M_leftmost() = _S_minimum(_M_root());
1286 _M_rightmost() = _S_maximum(_M_root());
1287 _M_impl._M_node_count = __x._M_impl._M_node_count;
1288 __x.clear();
1289 }
1290 return *this;
1291 }
1292
1293 template<typename _Key, typename _Val, typename _KeyOfValue,
1294 typename _Compare, typename _Alloc>
1295 template<typename _Iterator>
1296 void
1297 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1298 _M_assign_unique(_Iterator __first, _Iterator __last)
1299 {
1300 _Reuse_or_alloc_node __roan(this->_M_impl._M_header, *this);
1301 _M_impl._M_reset();
1302 for (; __first != __last; ++__first)
1303 _M_insert_unique_(end(), *__first, __roan);
1304 }
1305
1306 template<typename _Key, typename _Val, typename _KeyOfValue,
1307 typename _Compare, typename _Alloc>
1308 template<typename _Iterator>
1309 void
1310 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1311 _M_assign_equal(_Iterator __first, _Iterator __last)
1312 {
1313 _Reuse_or_alloc_node __roan(this->_M_impl._M_header, *this);
1314 _M_impl._M_reset();
1315 for (; __first != __last; ++__first)
1316 _M_insert_equal_(end(), *__first, __roan);
1317 }
1318 #endif
1319
1320 template<typename _Key, typename _Val, typename _KeyOfValue,
1321 typename _Compare, typename _Alloc>
1322 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
1323 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1324 operator=(const _Rb_tree& __x)
1325 {
1326 if (this != &__x)
1327 {
1328 // Note that _Key may be a constant type.
1329 #if __cplusplus >= 201103L
1330 if (_Alloc_traits::_S_propagate_on_copy_assign())
1331 {
1332 auto& __this_alloc = this->_M_get_Node_allocator();
1333 auto& __that_alloc = __x._M_get_Node_allocator();
1334 if (!_Alloc_traits::_S_always_equal()
1335 && __this_alloc != __that_alloc)
1336 {
1337 // Replacement allocator cannot free existing storage, we need
1338 // to erase nodes first.
1339 clear();
1340 std::__alloc_on_copy(__this_alloc, __that_alloc);
1341 }
1342 }
1343 #endif
1344
1345 _Reuse_or_alloc_node __roan(this->_M_impl._M_header, *this);
1346 _M_impl._M_reset();
1347 _M_impl._M_key_compare = __x._M_impl._M_key_compare;
1348 if (__x._M_root() != 0)
1349 {
1350 _M_root() = _M_copy(__x._M_begin(), _M_end(), __roan);
1351 _M_leftmost() = _S_minimum(_M_root());
1352 _M_rightmost() = _S_maximum(_M_root());
1353 _M_impl._M_node_count = __x._M_impl._M_node_count;
1354 }
1355 }
1356
1357 return *this;
1358 }
1359
1360 template<typename _Key, typename _Val, typename _KeyOfValue,
1361 typename _Compare, typename _Alloc>
1362 #if __cplusplus >= 201103L
1363 template<typename _Arg, typename _NodeGen>
1364 #else
1365 template<typename _NodeGen>
1366 #endif
1367 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1368 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1369 _M_insert_(_Base_ptr __x, _Base_ptr __p,
1370 #if __cplusplus >= 201103L
1371 _Arg&& __v,
1372 #else
1373 const _Val& __v,
1374 #endif
1375 _NodeGen& __node_gen)
1376 {
1377 bool __insert_left = (__x != 0 || __p == _M_end()
1378 || _M_impl._M_key_compare(_KeyOfValue()(__v),
1379 _S_key(__p)));
1380
1381 _Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v));
1382
1383 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1384 this->_M_impl._M_header);
1385 ++_M_impl._M_node_count;
1386 return iterator(__z);
1387 }
1388
1389 template<typename _Key, typename _Val, typename _KeyOfValue,
1390 typename _Compare, typename _Alloc>
1391 #if __cplusplus >= 201103L
1392 template<typename _Arg>
1393 #endif
1394 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1395 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1396 #if __cplusplus >= 201103L
1397 _M_insert_lower(_Base_ptr __p, _Arg&& __v)
1398 #else
1399 _M_insert_lower(_Base_ptr __p, const _Val& __v)
1400 #endif
1401 {
1402 bool __insert_left = (__p == _M_end()
1403 || !_M_impl._M_key_compare(_S_key(__p),
1404 _KeyOfValue()(__v)));
1405
1406 _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
1407
1408 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1409 this->_M_impl._M_header);
1410 ++_M_impl._M_node_count;
1411 return iterator(__z);
1412 }
1413
1414 template<typename _Key, typename _Val, typename _KeyOfValue,
1415 typename _Compare, typename _Alloc>
1416 #if __cplusplus >= 201103L
1417 template<typename _Arg>
1418 #endif
1419 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1420 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1421 #if __cplusplus >= 201103L
1422 _M_insert_equal_lower(_Arg&& __v)
1423 #else
1424 _M_insert_equal_lower(const _Val& __v)
1425 #endif
1426 {
1427 _Link_type __x = _M_begin();
1428 _Link_type __y = _M_end();
1429 while (__x != 0)
1430 {
1431 __y = __x;
1432 __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
1433 _S_left(__x) : _S_right(__x);
1434 }
1435 return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v));
1436 }
1437
1438 template<typename _Key, typename _Val, typename _KoV,
1439 typename _Compare, typename _Alloc>
1440 template<typename _NodeGen>
1441 typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
1442 _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
1443 _M_copy(_Const_Link_type __x, _Link_type __p, _NodeGen& __node_gen)
1444 {
1445 // Structural copy. __x and __p must be non-null.
1446 _Link_type __top = _M_clone_node(__x, __node_gen);
1447 __top->_M_parent = __p;
1448
1449 __try
1450 {
1451 if (__x->_M_right)
1452 __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen);
1453 __p = __top;
1454 __x = _S_left(__x);
1455
1456 while (__x != 0)
1457 {
1458 _Link_type __y = _M_clone_node(__x, __node_gen);
1459 __p->_M_left = __y;
1460 __y->_M_parent = __p;
1461 if (__x->_M_right)
1462 __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen);
1463 __p = __y;
1464 __x = _S_left(__x);
1465 }
1466 }
1467 __catch(...)
1468 {
1469 _M_erase(__top);
1470 __throw_exception_again;
1471 }
1472 return __top;
1473 }
1474
1475 template<typename _Key, typename _Val, typename _KeyOfValue,
1476 typename _Compare, typename _Alloc>
1477 void
1478 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1479 _M_erase(_Link_type __x)
1480 {
1481 // Erase without rebalancing.
1482 while (__x != 0)
1483 {
1484 _M_erase(_S_right(__x));
1485 _Link_type __y = _S_left(__x);
1486 _M_drop_node(__x);
1487 __x = __y;
1488 }
1489 }
1490
1491 template<typename _Key, typename _Val, typename _KeyOfValue,
1492 typename _Compare, typename _Alloc>
1493 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1494 _Compare, _Alloc>::iterator
1495 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1496 _M_lower_bound(_Link_type __x, _Link_type __y,
1497 const _Key& __k)
1498 {
1499 while (__x != 0)
1500 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1501 __y = __x, __x = _S_left(__x);
1502 else
1503 __x = _S_right(__x);
1504 return iterator(__y);
1505 }
1506
1507 template<typename _Key, typename _Val, typename _KeyOfValue,
1508 typename _Compare, typename _Alloc>
1509 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1510 _Compare, _Alloc>::const_iterator
1511 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1512 _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
1513 const _Key& __k) const
1514 {
1515 while (__x != 0)
1516 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1517 __y = __x, __x = _S_left(__x);
1518 else
1519 __x = _S_right(__x);
1520 return const_iterator(__y);
1521 }
1522
1523 template<typename _Key, typename _Val, typename _KeyOfValue,
1524 typename _Compare, typename _Alloc>
1525 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1526 _Compare, _Alloc>::iterator
1527 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1528 _M_upper_bound(_Link_type __x, _Link_type __y,
1529 const _Key& __k)
1530 {
1531 while (__x != 0)
1532 if (_M_impl._M_key_compare(__k, _S_key(__x)))
1533 __y = __x, __x = _S_left(__x);
1534 else
1535 __x = _S_right(__x);
1536 return iterator(__y);
1537 }
1538
1539 template<typename _Key, typename _Val, typename _KeyOfValue,
1540 typename _Compare, typename _Alloc>
1541 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1542 _Compare, _Alloc>::const_iterator
1543 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1544 _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
1545 const _Key& __k) const
1546 {
1547 while (__x != 0)
1548 if (_M_impl._M_key_compare(__k, _S_key(__x)))
1549 __y = __x, __x = _S_left(__x);
1550 else
1551 __x = _S_right(__x);
1552 return const_iterator(__y);
1553 }
1554
1555 template<typename _Key, typename _Val, typename _KeyOfValue,
1556 typename _Compare, typename _Alloc>
1557 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1558 _Compare, _Alloc>::iterator,
1559 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1560 _Compare, _Alloc>::iterator>
1561 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1562 equal_range(const _Key& __k)
1563 {
1564 _Link_type __x = _M_begin();
1565 _Link_type __y = _M_end();
1566 while (__x != 0)
1567 {
1568 if (_M_impl._M_key_compare(_S_key(__x), __k))
1569 __x = _S_right(__x);
1570 else if (_M_impl._M_key_compare(__k, _S_key(__x)))
1571 __y = __x, __x = _S_left(__x);
1572 else
1573 {
1574 _Link_type __xu(__x), __yu(__y);
1575 __y = __x, __x = _S_left(__x);
1576 __xu = _S_right(__xu);
1577 return pair<iterator,
1578 iterator>(_M_lower_bound(__x, __y, __k),
1579 _M_upper_bound(__xu, __yu, __k));
1580 }
1581 }
1582 return pair<iterator, iterator>(iterator(__y),
1583 iterator(__y));
1584 }
1585
1586 template<typename _Key, typename _Val, typename _KeyOfValue,
1587 typename _Compare, typename _Alloc>
1588 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1589 _Compare, _Alloc>::const_iterator,
1590 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1591 _Compare, _Alloc>::const_iterator>
1592 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1593 equal_range(const _Key& __k) const
1594 {
1595 _Const_Link_type __x = _M_begin();
1596 _Const_Link_type __y = _M_end();
1597 while (__x != 0)
1598 {
1599 if (_M_impl._M_key_compare(_S_key(__x), __k))
1600 __x = _S_right(__x);
1601 else if (_M_impl._M_key_compare(__k, _S_key(__x)))
1602 __y = __x, __x = _S_left(__x);
1603 else
1604 {
1605 _Const_Link_type __xu(__x), __yu(__y);
1606 __y = __x, __x = _S_left(__x);
1607 __xu = _S_right(__xu);
1608 return pair<const_iterator,
1609 const_iterator>(_M_lower_bound(__x, __y, __k),
1610 _M_upper_bound(__xu, __yu, __k));
1611 }
1612 }
1613 return pair<const_iterator, const_iterator>(const_iterator(__y),
1614 const_iterator(__y));
1615 }
1616
1617 template<typename _Key, typename _Val, typename _KeyOfValue,
1618 typename _Compare, typename _Alloc>
1619 void
1620 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1621 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
1622 #if __cplusplus >= 201103L
1623 noexcept(_Alloc_traits::_S_nothrow_swap())
1624 #endif
1625 {
1626 if (_M_root() == 0)
1627 {
1628 if (__t._M_root() != 0)
1629 {
1630 _M_root() = __t._M_root();
1631 _M_leftmost() = __t._M_leftmost();
1632 _M_rightmost() = __t._M_rightmost();
1633 _M_root()->_M_parent = _M_end();
1634 _M_impl._M_node_count = __t._M_impl._M_node_count;
1635
1636 __t._M_impl._M_reset();
1637 }
1638 }
1639 else if (__t._M_root() == 0)
1640 {
1641 __t._M_root() = _M_root();
1642 __t._M_leftmost() = _M_leftmost();
1643 __t._M_rightmost() = _M_rightmost();
1644 __t._M_root()->_M_parent = __t._M_end();
1645 __t._M_impl._M_node_count = _M_impl._M_node_count;
1646
1647 _M_impl._M_reset();
1648 }
1649 else
1650 {
1651 std::swap(_M_root(),__t._M_root());
1652 std::swap(_M_leftmost(),__t._M_leftmost());
1653 std::swap(_M_rightmost(),__t._M_rightmost());
1654
1655 _M_root()->_M_parent = _M_end();
1656 __t._M_root()->_M_parent = __t._M_end();
1657 std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
1658 }
1659 // No need to swap header's color as it does not change.
1660 std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
1661
1662 _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
1663 __t._M_get_Node_allocator());
1664 }
1665
1666 template<typename _Key, typename _Val, typename _KeyOfValue,
1667 typename _Compare, typename _Alloc>
1668 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1669 _Compare, _Alloc>::_Base_ptr,
1670 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1671 _Compare, _Alloc>::_Base_ptr>
1672 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1673 _M_get_insert_unique_pos(const key_type& __k)
1674 {
1675 typedef pair<_Base_ptr, _Base_ptr> _Res;
1676 _Link_type __x = _M_begin();
1677 _Link_type __y = _M_end();
1678 bool __comp = true;
1679 while (__x != 0)
1680 {
1681 __y = __x;
1682 __comp = _M_impl._M_key_compare(__k, _S_key(__x));
1683 __x = __comp ? _S_left(__x) : _S_right(__x);
1684 }
1685 iterator __j = iterator(__y);
1686 if (__comp)
1687 {
1688 if (__j == begin())
1689 return _Res(__x, __y);
1690 else
1691 --__j;
1692 }
1693 if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
1694 return _Res(__x, __y);
1695 return _Res(__j._M_node, 0);
1696 }
1697
1698 template<typename _Key, typename _Val, typename _KeyOfValue,
1699 typename _Compare, typename _Alloc>
1700 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1701 _Compare, _Alloc>::_Base_ptr,
1702 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1703 _Compare, _Alloc>::_Base_ptr>
1704 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1705 _M_get_insert_equal_pos(const key_type& __k)
1706 {
1707 typedef pair<_Base_ptr, _Base_ptr> _Res;
1708 _Link_type __x = _M_begin();
1709 _Link_type __y = _M_end();
1710 while (__x != 0)
1711 {
1712 __y = __x;
1713 __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
1714 _S_left(__x) : _S_right(__x);
1715 }
1716 return _Res(__x, __y);
1717 }
1718
1719 template<typename _Key, typename _Val, typename _KeyOfValue,
1720 typename _Compare, typename _Alloc>
1721 #if __cplusplus >= 201103L
1722 template<typename _Arg>
1723 #endif
1724 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1725 _Compare, _Alloc>::iterator, bool>
1726 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1727 #if __cplusplus >= 201103L
1728 _M_insert_unique(_Arg&& __v)
1729 #else
1730 _M_insert_unique(const _Val& __v)
1731 #endif
1732 {
1733 typedef pair<iterator, bool> _Res;
1734 pair<_Base_ptr, _Base_ptr> __res
1735 = _M_get_insert_unique_pos(_KeyOfValue()(__v));
1736
1737 if (__res.second)
1738 {
1739 _Alloc_node __an(*this);
1740 return _Res(_M_insert_(__res.first, __res.second,
1741 _GLIBCXX_FORWARD(_Arg, __v), __an),
1742 true);
1743 }
1744
1745 return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
1746 }
1747
1748 template<typename _Key, typename _Val, typename _KeyOfValue,
1749 typename _Compare, typename _Alloc>
1750 #if __cplusplus >= 201103L
1751 template<typename _Arg>
1752 #endif
1753 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1754 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1755 #if __cplusplus >= 201103L
1756 _M_insert_equal(_Arg&& __v)
1757 #else
1758 _M_insert_equal(const _Val& __v)
1759 #endif
1760 {
1761 pair<_Base_ptr, _Base_ptr> __res
1762 = _M_get_insert_equal_pos(_KeyOfValue()(__v));
1763 _Alloc_node __an(*this);
1764 return _M_insert_(__res.first, __res.second,
1765 _GLIBCXX_FORWARD(_Arg, __v), __an);
1766 }
1767
1768 template<typename _Key, typename _Val, typename _KeyOfValue,
1769 typename _Compare, typename _Alloc>
1770 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1771 _Compare, _Alloc>::_Base_ptr,
1772 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1773 _Compare, _Alloc>::_Base_ptr>
1774 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1775 _M_get_insert_hint_unique_pos(const_iterator __position,
1776 const key_type& __k)
1777 {
1778 iterator __pos = __position._M_const_cast();
1779 typedef pair<_Base_ptr, _Base_ptr> _Res;
1780
1781 // end()
1782 if (__pos._M_node == _M_end())
1783 {
1784 if (size() > 0
1785 && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k))
1786 return _Res(0, _M_rightmost());
1787 else
1788 return _M_get_insert_unique_pos(__k);
1789 }
1790 else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node)))
1791 {
1792 // First, try before...
1793 iterator __before = __pos;
1794 if (__pos._M_node == _M_leftmost()) // begin()
1795 return _Res(_M_leftmost(), _M_leftmost());
1796 else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k))
1797 {
1798 if (_S_right(__before._M_node) == 0)
1799 return _Res(0, __before._M_node);
1800 else
1801 return _Res(__pos._M_node, __pos._M_node);
1802 }
1803 else
1804 return _M_get_insert_unique_pos(__k);
1805 }
1806 else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
1807 {
1808 // ... then try after.
1809 iterator __after = __pos;
1810 if (__pos._M_node == _M_rightmost())
1811 return _Res(0, _M_rightmost());
1812 else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node)))
1813 {
1814 if (_S_right(__pos._M_node) == 0)
1815 return _Res(0, __pos._M_node);
1816 else
1817 return _Res(__after._M_node, __after._M_node);
1818 }
1819 else
1820 return _M_get_insert_unique_pos(__k);
1821 }
1822 else
1823 // Equivalent keys.
1824 return _Res(__pos._M_node, 0);
1825 }
1826
1827 template<typename _Key, typename _Val, typename _KeyOfValue,
1828 typename _Compare, typename _Alloc>
1829 #if __cplusplus >= 201103L
1830 template<typename _Arg, typename _NodeGen>
1831 #else
1832 template<typename _NodeGen>
1833 #endif
1834 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1835 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1836 _M_insert_unique_(const_iterator __position,
1837 #if __cplusplus >= 201103L
1838 _Arg&& __v,
1839 #else
1840 const _Val& __v,
1841 #endif
1842 _NodeGen& __node_gen)
1843 {
1844 pair<_Base_ptr, _Base_ptr> __res
1845 = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
1846
1847 if (__res.second)
1848 return _M_insert_(__res.first, __res.second,
1849 _GLIBCXX_FORWARD(_Arg, __v),
1850 __node_gen);
1851 return iterator(static_cast<_Link_type>(__res.first));
1852 }
1853
1854 template<typename _Key, typename _Val, typename _KeyOfValue,
1855 typename _Compare, typename _Alloc>
1856 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1857 _Compare, _Alloc>::_Base_ptr,
1858 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1859 _Compare, _Alloc>::_Base_ptr>
1860 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1861 _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k)
1862 {
1863 iterator __pos = __position._M_const_cast();
1864 typedef pair<_Base_ptr, _Base_ptr> _Res;
1865
1866 // end()
1867 if (__pos._M_node == _M_end())
1868 {
1869 if (size() > 0
1870 && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost())))
1871 return _Res(0, _M_rightmost());
1872 else
1873 return _M_get_insert_equal_pos(__k);
1874 }
1875 else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
1876 {
1877 // First, try before...
1878 iterator __before = __pos;
1879 if (__pos._M_node == _M_leftmost()) // begin()
1880 return _Res(_M_leftmost(), _M_leftmost());
1881 else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node)))
1882 {
1883 if (_S_right(__before._M_node) == 0)
1884 return _Res(0, __before._M_node);
1885 else
1886 return _Res(__pos._M_node, __pos._M_node);
1887 }
1888 else
1889 return _M_get_insert_equal_pos(__k);
1890 }
1891 else
1892 {
1893 // ... then try after.
1894 iterator __after = __pos;
1895 if (__pos._M_node == _M_rightmost())
1896 return _Res(0, _M_rightmost());
1897 else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k))
1898 {
1899 if (_S_right(__pos._M_node) == 0)
1900 return _Res(0, __pos._M_node);
1901 else
1902 return _Res(__after._M_node, __after._M_node);
1903 }
1904 else
1905 return _Res(0, 0);
1906 }
1907 }
1908
1909 template<typename _Key, typename _Val, typename _KeyOfValue,
1910 typename _Compare, typename _Alloc>
1911 #if __cplusplus >= 201103L
1912 template<typename _Arg, typename _NodeGen>
1913 #else
1914 template<typename _NodeGen>
1915 #endif
1916 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1917 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1918 _M_insert_equal_(const_iterator __position,
1919 #if __cplusplus >= 201103L
1920 _Arg&& __v,
1921 #else
1922 const _Val& __v,
1923 #endif
1924 _NodeGen& __node_gen)
1925 {
1926 pair<_Base_ptr, _Base_ptr> __res
1927 = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
1928
1929 if (__res.second)
1930 return _M_insert_(__res.first, __res.second,
1931 _GLIBCXX_FORWARD(_Arg, __v),
1932 __node_gen);
1933
1934 return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
1935 }
1936
1937 #if __cplusplus >= 201103L
1938 template<typename _Key, typename _Val, typename _KeyOfValue,
1939 typename _Compare, typename _Alloc>
1940 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1941 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1942 _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
1943 {
1944 bool __insert_left = (__x != 0 || __p == _M_end()
1945 || _M_impl._M_key_compare(_S_key(__z),
1946 _S_key(__p)));
1947
1948 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1949 this->_M_impl._M_header);
1950 ++_M_impl._M_node_count;
1951 return iterator(__z);
1952 }
1953
1954 template<typename _Key, typename _Val, typename _KeyOfValue,
1955 typename _Compare, typename _Alloc>
1956 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1957 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1958 _M_insert_lower_node(_Base_ptr __p, _Link_type __z)
1959 {
1960 bool __insert_left = (__p == _M_end()
1961 || !_M_impl._M_key_compare(_S_key(__p),
1962 _S_key(__z)));
1963
1964 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1965 this->_M_impl._M_header);
1966 ++_M_impl._M_node_count;
1967 return iterator(__z);
1968 }
1969
1970 template<typename _Key, typename _Val, typename _KeyOfValue,
1971 typename _Compare, typename _Alloc>
1972 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1973 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1974 _M_insert_equal_lower_node(_Link_type __z)
1975 {
1976 _Link_type __x = _M_begin();
1977 _Link_type __y = _M_end();
1978 while (__x != 0)
1979 {
1980 __y = __x;
1981 __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ?
1982 _S_left(__x) : _S_right(__x);
1983 }
1984 return _M_insert_lower_node(__y, __z);
1985 }
1986
1987 template<typename _Key, typename _Val, typename _KeyOfValue,
1988 typename _Compare, typename _Alloc>
1989 template<typename... _Args>
1990 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1991 _Compare, _Alloc>::iterator, bool>
1992 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1993 _M_emplace_unique(_Args&&... __args)
1994 {
1995 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1996
1997 __try
1998 {
1999 typedef pair<iterator, bool> _Res;
2000 auto __res = _M_get_insert_unique_pos(_S_key(__z));
2001 if (__res.second)
2002 return _Res(_M_insert_node(__res.first, __res.second, __z), true);
2003
2004 _M_drop_node(__z);
2005 return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
2006 }
2007 __catch(...)
2008 {
2009 _M_drop_node(__z);
2010 __throw_exception_again;
2011 }
2012 }
2013
2014 template<typename _Key, typename _Val, typename _KeyOfValue,
2015 typename _Compare, typename _Alloc>
2016 template<typename... _Args>
2017 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2018 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2019 _M_emplace_equal(_Args&&... __args)
2020 {
2021 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
2022
2023 __try
2024 {
2025 auto __res = _M_get_insert_equal_pos(_S_key(__z));
2026 return _M_insert_node(__res.first, __res.second, __z);
2027 }
2028 __catch(...)
2029 {
2030 _M_drop_node(__z);
2031 __throw_exception_again;
2032 }
2033 }
2034
2035 template<typename _Key, typename _Val, typename _KeyOfValue,
2036 typename _Compare, typename _Alloc>
2037 template<typename... _Args>
2038 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2039 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2040 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
2041 {
2042 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
2043
2044 __try
2045 {
2046 auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z));
2047
2048 if (__res.second)
2049 return _M_insert_node(__res.first, __res.second, __z);
2050
2051 _M_drop_node(__z);
2052 return iterator(static_cast<_Link_type>(__res.first));
2053 }
2054 __catch(...)
2055 {
2056 _M_drop_node(__z);
2057 __throw_exception_again;
2058 }
2059 }
2060
2061 template<typename _Key, typename _Val, typename _KeyOfValue,
2062 typename _Compare, typename _Alloc>
2063 template<typename... _Args>
2064 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2065 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2066 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
2067 {
2068 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
2069
2070 __try
2071 {
2072 auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z));
2073
2074 if (__res.second)
2075 return _M_insert_node(__res.first, __res.second, __z);
2076
2077 return _M_insert_equal_lower_node(__z);
2078 }
2079 __catch(...)
2080 {
2081 _M_drop_node(__z);
2082 __throw_exception_again;
2083 }
2084 }
2085 #endif
2086
2087 template<typename _Key, typename _Val, typename _KoV,
2088 typename _Cmp, typename _Alloc>
2089 template<class _II>
2090 void
2091 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
2092 _M_insert_unique(_II __first, _II __last)
2093 {
2094 _Alloc_node __an(*this);
2095 for (; __first != __last; ++__first)
2096 _M_insert_unique_(end(), *__first, __an);
2097 }
2098
2099 template<typename _Key, typename _Val, typename _KoV,
2100 typename _Cmp, typename _Alloc>
2101 template<class _II>
2102 void
2103 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
2104 _M_insert_equal(_II __first, _II __last)
2105 {
2106 _Alloc_node __an(*this);
2107 for (; __first != __last; ++__first)
2108 _M_insert_equal_(end(), *__first, __an);
2109 }
2110
2111 template<typename _Key, typename _Val, typename _KeyOfValue,
2112 typename _Compare, typename _Alloc>
2113 void
2114 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2115 _M_erase_aux(const_iterator __position)
2116 {
2117 _Link_type __y =
2118 static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
2119 (const_cast<_Base_ptr>(__position._M_node),
2120 this->_M_impl._M_header));
2121 _M_drop_node(__y);
2122 --_M_impl._M_node_count;
2123 }
2124
2125 template<typename _Key, typename _Val, typename _KeyOfValue,
2126 typename _Compare, typename _Alloc>
2127 void
2128 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2129 _M_erase_aux(const_iterator __first, const_iterator __last)
2130 {
2131 if (__first == begin() && __last == end())
2132 clear();
2133 else
2134 while (__first != __last)
2135 erase(__first++);
2136 }
2137
2138 template<typename _Key, typename _Val, typename _KeyOfValue,
2139 typename _Compare, typename _Alloc>
2140 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
2141 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2142 erase(const _Key& __x)
2143 {
2144 pair<iterator, iterator> __p = equal_range(__x);
2145 const size_type __old_size = size();
2146 erase(__p.first, __p.second);
2147 return __old_size - size();
2148 }
2149
2150 template<typename _Key, typename _Val, typename _KeyOfValue,
2151 typename _Compare, typename _Alloc>
2152 void
2153 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2154 erase(const _Key* __first, const _Key* __last)
2155 {
2156 while (__first != __last)
2157 erase(*__first++);
2158 }
2159
2160 template<typename _Key, typename _Val, typename _KeyOfValue,
2161 typename _Compare, typename _Alloc>
2162 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2163 _Compare, _Alloc>::iterator
2164 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2165 find(const _Key& __k)
2166 {
2167 iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
2168 return (__j == end()
2169 || _M_impl._M_key_compare(__k,
2170 _S_key(__j._M_node))) ? end() : __j;
2171 }
2172
2173 template<typename _Key, typename _Val, typename _KeyOfValue,
2174 typename _Compare, typename _Alloc>
2175 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2176 _Compare, _Alloc>::const_iterator
2177 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2178 find(const _Key& __k) const
2179 {
2180 const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
2181 return (__j == end()
2182 || _M_impl._M_key_compare(__k,
2183 _S_key(__j._M_node))) ? end() : __j;
2184 }
2185
2186 template<typename _Key, typename _Val, typename _KeyOfValue,
2187 typename _Compare, typename _Alloc>
2188 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
2189 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2190 count(const _Key& __k) const
2191 {
2192 pair<const_iterator, const_iterator> __p = equal_range(__k);
2193 const size_type __n = std::distance(__p.first, __p.second);
2194 return __n;
2195 }
2196
2197 _GLIBCXX_PURE unsigned int
2198 _Rb_tree_black_count(const _Rb_tree_node_base* __node,
2199 const _Rb_tree_node_base* __root) throw ();
2200
2201 template<typename _Key, typename _Val, typename _KeyOfValue,
2202 typename _Compare, typename _Alloc>
2203 bool
2204 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
2205 {
2206 if (_M_impl._M_node_count == 0 || begin() == end())
2207 return _M_impl._M_node_count == 0 && begin() == end()
2208 && this->_M_impl._M_header._M_left == _M_end()
2209 && this->_M_impl._M_header._M_right == _M_end();
2210
2211 unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
2212 for (const_iterator __it = begin(); __it != end(); ++__it)
2213 {
2214 _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
2215 _Const_Link_type __L = _S_left(__x);
2216 _Const_Link_type __R = _S_right(__x);
2217
2218 if (__x->_M_color == _S_red)
2219 if ((__L && __L->_M_color == _S_red)
2220 || (__R && __R->_M_color == _S_red))
2221 return false;
2222
2223 if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
2224 return false;
2225 if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
2226 return false;
2227
2228 if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
2229 return false;
2230 }
2231
2232 if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
2233 return false;
2234 if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
2235 return false;
2236 return true;
2237 }
2238
2239 _GLIBCXX_END_NAMESPACE_VERSION
2240 } // namespace
2241
2242 #endif