]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/bits/stl_tree.h
re PR c++/26099 (support for type traits is not available)
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / stl_tree.h
1 // RB tree implementation -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 /*
32 *
33 * Copyright (c) 1996,1997
34 * Silicon Graphics Computer Systems, Inc.
35 *
36 * Permission to use, copy, modify, distribute and sell this software
37 * and its documentation for any purpose is hereby granted without fee,
38 * provided that the above copyright notice appear in all copies and
39 * that both that copyright notice and this permission notice appear
40 * in supporting documentation. Silicon Graphics makes no
41 * representations about the suitability of this software for any
42 * purpose. It is provided "as is" without express or implied warranty.
43 *
44 *
45 * Copyright (c) 1994
46 * Hewlett-Packard Company
47 *
48 * Permission to use, copy, modify, distribute and sell this software
49 * and its documentation for any purpose is hereby granted without fee,
50 * provided that the above copyright notice appear in all copies and
51 * that both that copyright notice and this permission notice appear
52 * in supporting documentation. Hewlett-Packard Company makes no
53 * representations about the suitability of this software for any
54 * purpose. It is provided "as is" without express or implied warranty.
55 *
56 *
57 */
58
59 /** @file stl_tree.h
60 * This is an internal header file, included by other library headers.
61 * You should not attempt to use it directly.
62 */
63
64 #ifndef _TREE_H
65 #define _TREE_H 1
66
67 #include <bits/stl_algobase.h>
68 #include <bits/allocator.h>
69 #include <bits/stl_function.h>
70 #include <bits/cpp_type_traits.h>
71
72 _GLIBCXX_BEGIN_NAMESPACE(std)
73
74 // Red-black tree class, designed for use in implementing STL
75 // associative containers (set, multiset, map, and multimap). The
76 // insertion and deletion algorithms are based on those in Cormen,
77 // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
78 // 1990), except that
79 //
80 // (1) the header cell is maintained with links not only to the root
81 // but also to the leftmost node of the tree, to enable constant
82 // time begin(), and to the rightmost node of the tree, to enable
83 // linear time performance when used with the generic set algorithms
84 // (set_union, etc.)
85 //
86 // (2) when a node being deleted has two children its successor node
87 // is relinked into its place, rather than copied, so that the only
88 // iterators invalidated are those referring to the deleted node.
89
90 enum _Rb_tree_color { _S_red = false, _S_black = true };
91
92 struct _Rb_tree_node_base
93 {
94 typedef _Rb_tree_node_base* _Base_ptr;
95 typedef const _Rb_tree_node_base* _Const_Base_ptr;
96
97 _Rb_tree_color _M_color;
98 _Base_ptr _M_parent;
99 _Base_ptr _M_left;
100 _Base_ptr _M_right;
101
102 static _Base_ptr
103 _S_minimum(_Base_ptr __x)
104 {
105 while (__x->_M_left != 0) __x = __x->_M_left;
106 return __x;
107 }
108
109 static _Const_Base_ptr
110 _S_minimum(_Const_Base_ptr __x)
111 {
112 while (__x->_M_left != 0) __x = __x->_M_left;
113 return __x;
114 }
115
116 static _Base_ptr
117 _S_maximum(_Base_ptr __x)
118 {
119 while (__x->_M_right != 0) __x = __x->_M_right;
120 return __x;
121 }
122
123 static _Const_Base_ptr
124 _S_maximum(_Const_Base_ptr __x)
125 {
126 while (__x->_M_right != 0) __x = __x->_M_right;
127 return __x;
128 }
129 };
130
131 template<typename _Val>
132 struct _Rb_tree_node : public _Rb_tree_node_base
133 {
134 typedef _Rb_tree_node<_Val>* _Link_type;
135 _Val _M_value_field;
136 };
137
138 _Rb_tree_node_base*
139 _Rb_tree_increment(_Rb_tree_node_base* __x);
140
141 const _Rb_tree_node_base*
142 _Rb_tree_increment(const _Rb_tree_node_base* __x);
143
144 _Rb_tree_node_base*
145 _Rb_tree_decrement(_Rb_tree_node_base* __x);
146
147 const _Rb_tree_node_base*
148 _Rb_tree_decrement(const _Rb_tree_node_base* __x);
149
150 template<typename _Tp>
151 struct _Rb_tree_iterator
152 {
153 typedef _Tp value_type;
154 typedef _Tp& reference;
155 typedef _Tp* pointer;
156
157 typedef bidirectional_iterator_tag iterator_category;
158 typedef ptrdiff_t difference_type;
159
160 typedef _Rb_tree_iterator<_Tp> _Self;
161 typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
162 typedef _Rb_tree_node<_Tp>* _Link_type;
163
164 _Rb_tree_iterator()
165 : _M_node() { }
166
167 explicit
168 _Rb_tree_iterator(_Link_type __x)
169 : _M_node(__x) { }
170
171 reference
172 operator*() const
173 { return static_cast<_Link_type>(_M_node)->_M_value_field; }
174
175 pointer
176 operator->() const
177 { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
178
179 _Self&
180 operator++()
181 {
182 _M_node = _Rb_tree_increment(_M_node);
183 return *this;
184 }
185
186 _Self
187 operator++(int)
188 {
189 _Self __tmp = *this;
190 _M_node = _Rb_tree_increment(_M_node);
191 return __tmp;
192 }
193
194 _Self&
195 operator--()
196 {
197 _M_node = _Rb_tree_decrement(_M_node);
198 return *this;
199 }
200
201 _Self
202 operator--(int)
203 {
204 _Self __tmp = *this;
205 _M_node = _Rb_tree_decrement(_M_node);
206 return __tmp;
207 }
208
209 bool
210 operator==(const _Self& __x) const
211 { return _M_node == __x._M_node; }
212
213 bool
214 operator!=(const _Self& __x) const
215 { return _M_node != __x._M_node; }
216
217 _Base_ptr _M_node;
218 };
219
220 template<typename _Tp>
221 struct _Rb_tree_const_iterator
222 {
223 typedef _Tp value_type;
224 typedef const _Tp& reference;
225 typedef const _Tp* pointer;
226
227 typedef _Rb_tree_iterator<_Tp> iterator;
228
229 typedef bidirectional_iterator_tag iterator_category;
230 typedef ptrdiff_t difference_type;
231
232 typedef _Rb_tree_const_iterator<_Tp> _Self;
233 typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
234 typedef const _Rb_tree_node<_Tp>* _Link_type;
235
236 _Rb_tree_const_iterator()
237 : _M_node() { }
238
239 explicit
240 _Rb_tree_const_iterator(_Link_type __x)
241 : _M_node(__x) { }
242
243 _Rb_tree_const_iterator(const iterator& __it)
244 : _M_node(__it._M_node) { }
245
246 reference
247 operator*() const
248 { return static_cast<_Link_type>(_M_node)->_M_value_field; }
249
250 pointer
251 operator->() const
252 { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
253
254 _Self&
255 operator++()
256 {
257 _M_node = _Rb_tree_increment(_M_node);
258 return *this;
259 }
260
261 _Self
262 operator++(int)
263 {
264 _Self __tmp = *this;
265 _M_node = _Rb_tree_increment(_M_node);
266 return __tmp;
267 }
268
269 _Self&
270 operator--()
271 {
272 _M_node = _Rb_tree_decrement(_M_node);
273 return *this;
274 }
275
276 _Self
277 operator--(int)
278 {
279 _Self __tmp = *this;
280 _M_node = _Rb_tree_decrement(_M_node);
281 return __tmp;
282 }
283
284 bool
285 operator==(const _Self& __x) const
286 { return _M_node == __x._M_node; }
287
288 bool
289 operator!=(const _Self& __x) const
290 { return _M_node != __x._M_node; }
291
292 _Base_ptr _M_node;
293 };
294
295 template<typename _Val>
296 inline bool
297 operator==(const _Rb_tree_iterator<_Val>& __x,
298 const _Rb_tree_const_iterator<_Val>& __y)
299 { return __x._M_node == __y._M_node; }
300
301 template<typename _Val>
302 inline bool
303 operator!=(const _Rb_tree_iterator<_Val>& __x,
304 const _Rb_tree_const_iterator<_Val>& __y)
305 { return __x._M_node != __y._M_node; }
306
307 void
308 _Rb_tree_insert_and_rebalance(const bool __insert_left,
309 _Rb_tree_node_base* __x,
310 _Rb_tree_node_base* __p,
311 _Rb_tree_node_base& __header);
312
313 _Rb_tree_node_base*
314 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
315 _Rb_tree_node_base& __header);
316
317
318 template<typename _Key, typename _Val, typename _KeyOfValue,
319 typename _Compare, typename _Alloc = allocator<_Val> >
320 class _Rb_tree
321 {
322 typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
323 _Node_allocator;
324
325 protected:
326 typedef _Rb_tree_node_base* _Base_ptr;
327 typedef const _Rb_tree_node_base* _Const_Base_ptr;
328
329 public:
330 typedef _Key key_type;
331 typedef _Val value_type;
332 typedef value_type* pointer;
333 typedef const value_type* const_pointer;
334 typedef value_type& reference;
335 typedef const value_type& const_reference;
336 typedef _Rb_tree_node<_Val>* _Link_type;
337 typedef const _Rb_tree_node<_Val>* _Const_Link_type;
338 typedef size_t size_type;
339 typedef ptrdiff_t difference_type;
340 typedef _Alloc allocator_type;
341
342 _Node_allocator&
343 _M_get_Node_allocator()
344 { return *static_cast<_Node_allocator*>(&this->_M_impl); }
345
346 const _Node_allocator&
347 _M_get_Node_allocator() const
348 { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
349
350 allocator_type
351 get_allocator() const
352 { return allocator_type(_M_get_Node_allocator()); }
353
354 protected:
355 _Link_type
356 _M_get_node()
357 { return _M_impl._Node_allocator::allocate(1); }
358
359 void
360 _M_put_node(_Link_type __p)
361 { _M_impl._Node_allocator::deallocate(__p, 1); }
362
363 _Link_type
364 _M_create_node(const value_type& __x)
365 {
366 _Link_type __tmp = _M_get_node();
367 try
368 { get_allocator().construct(&__tmp->_M_value_field, __x); }
369 catch(...)
370 {
371 _M_put_node(__tmp);
372 __throw_exception_again;
373 }
374 return __tmp;
375 }
376
377 _Link_type
378 _M_clone_node(_Const_Link_type __x)
379 {
380 _Link_type __tmp = _M_create_node(__x->_M_value_field);
381 __tmp->_M_color = __x->_M_color;
382 __tmp->_M_left = 0;
383 __tmp->_M_right = 0;
384 return __tmp;
385 }
386
387 void
388 _M_destroy_node(_Link_type __p)
389 {
390 get_allocator().destroy(&__p->_M_value_field);
391 _M_put_node(__p);
392 }
393
394 protected:
395 template<typename _Key_compare,
396 bool _Is_pod_comparator = __is_pod(_Key_compare)>
397 struct _Rb_tree_impl : public _Node_allocator
398 {
399 _Key_compare _M_key_compare;
400 _Rb_tree_node_base _M_header;
401 size_type _M_node_count; // Keeps track of size of tree.
402
403 _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
404 const _Key_compare& __comp = _Key_compare())
405 : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
406 _M_node_count(0)
407 {
408 this->_M_header._M_color = _S_red;
409 this->_M_header._M_parent = 0;
410 this->_M_header._M_left = &this->_M_header;
411 this->_M_header._M_right = &this->_M_header;
412 }
413 };
414
415 // Specialization for _Comparison types that are not capable of
416 // being base classes / super classes.
417 template<typename _Key_compare>
418 struct _Rb_tree_impl<_Key_compare, true> : public _Node_allocator
419 {
420 _Key_compare _M_key_compare;
421 _Rb_tree_node_base _M_header;
422 size_type _M_node_count; // Keeps track of size of tree.
423
424 _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
425 const _Key_compare& __comp = _Key_compare())
426 : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
427 _M_node_count(0)
428 {
429 this->_M_header._M_color = _S_red;
430 this->_M_header._M_parent = 0;
431 this->_M_header._M_left = &this->_M_header;
432 this->_M_header._M_right = &this->_M_header;
433 }
434 };
435
436 _Rb_tree_impl<_Compare> _M_impl;
437
438 protected:
439 _Base_ptr&
440 _M_root()
441 { return this->_M_impl._M_header._M_parent; }
442
443 _Const_Base_ptr
444 _M_root() const
445 { return this->_M_impl._M_header._M_parent; }
446
447 _Base_ptr&
448 _M_leftmost()
449 { return this->_M_impl._M_header._M_left; }
450
451 _Const_Base_ptr
452 _M_leftmost() const
453 { return this->_M_impl._M_header._M_left; }
454
455 _Base_ptr&
456 _M_rightmost()
457 { return this->_M_impl._M_header._M_right; }
458
459 _Const_Base_ptr
460 _M_rightmost() const
461 { return this->_M_impl._M_header._M_right; }
462
463 _Link_type
464 _M_begin()
465 { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
466
467 _Const_Link_type
468 _M_begin() const
469 {
470 return static_cast<_Const_Link_type>
471 (this->_M_impl._M_header._M_parent);
472 }
473
474 _Link_type
475 _M_end()
476 { return static_cast<_Link_type>(&this->_M_impl._M_header); }
477
478 _Const_Link_type
479 _M_end() const
480 { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); }
481
482 static const_reference
483 _S_value(_Const_Link_type __x)
484 { return __x->_M_value_field; }
485
486 static const _Key&
487 _S_key(_Const_Link_type __x)
488 { return _KeyOfValue()(_S_value(__x)); }
489
490 static _Link_type
491 _S_left(_Base_ptr __x)
492 { return static_cast<_Link_type>(__x->_M_left); }
493
494 static _Const_Link_type
495 _S_left(_Const_Base_ptr __x)
496 { return static_cast<_Const_Link_type>(__x->_M_left); }
497
498 static _Link_type
499 _S_right(_Base_ptr __x)
500 { return static_cast<_Link_type>(__x->_M_right); }
501
502 static _Const_Link_type
503 _S_right(_Const_Base_ptr __x)
504 { return static_cast<_Const_Link_type>(__x->_M_right); }
505
506 static const_reference
507 _S_value(_Const_Base_ptr __x)
508 { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
509
510 static const _Key&
511 _S_key(_Const_Base_ptr __x)
512 { return _KeyOfValue()(_S_value(__x)); }
513
514 static _Base_ptr
515 _S_minimum(_Base_ptr __x)
516 { return _Rb_tree_node_base::_S_minimum(__x); }
517
518 static _Const_Base_ptr
519 _S_minimum(_Const_Base_ptr __x)
520 { return _Rb_tree_node_base::_S_minimum(__x); }
521
522 static _Base_ptr
523 _S_maximum(_Base_ptr __x)
524 { return _Rb_tree_node_base::_S_maximum(__x); }
525
526 static _Const_Base_ptr
527 _S_maximum(_Const_Base_ptr __x)
528 { return _Rb_tree_node_base::_S_maximum(__x); }
529
530 public:
531 typedef _Rb_tree_iterator<value_type> iterator;
532 typedef _Rb_tree_const_iterator<value_type> const_iterator;
533
534 typedef std::reverse_iterator<iterator> reverse_iterator;
535 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
536
537 private:
538 iterator
539 _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __y,
540 const value_type& __v);
541
542 // _GLIBCXX_RESOLVE_LIB_DEFECTS
543 // 233. Insertion hints in associative containers.
544 iterator
545 _M_insert_lower(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
546
547 iterator
548 _M_insert_equal_lower(const value_type& __x);
549
550 _Link_type
551 _M_copy(_Const_Link_type __x, _Link_type __p);
552
553 void
554 _M_erase(_Link_type __x);
555
556 iterator
557 _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
558 const _Key& __k) const;
559
560 iterator
561 _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
562 const _Key& __k) const;
563
564 pair<iterator, iterator>
565 _M_equal_range(const _Key& __k) const;
566
567 public:
568 // allocation/deallocation
569 _Rb_tree()
570 { }
571
572 _Rb_tree(const _Compare& __comp)
573 : _M_impl(allocator_type(), __comp)
574 { }
575
576 _Rb_tree(const _Compare& __comp, const allocator_type& __a)
577 : _M_impl(__a, __comp)
578 { }
579
580 _Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
581 : _M_impl(__x._M_get_Node_allocator(), __x._M_impl._M_key_compare)
582 {
583 if (__x._M_root() != 0)
584 {
585 _M_root() = _M_copy(__x._M_begin(), _M_end());
586 _M_leftmost() = _S_minimum(_M_root());
587 _M_rightmost() = _S_maximum(_M_root());
588 _M_impl._M_node_count = __x._M_impl._M_node_count;
589 }
590 }
591
592 ~_Rb_tree()
593 { _M_erase(_M_begin()); }
594
595 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
596 operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x);
597
598 // Accessors.
599 _Compare
600 key_comp() const
601 { return _M_impl._M_key_compare; }
602
603 iterator
604 begin()
605 {
606 return iterator(static_cast<_Link_type>
607 (this->_M_impl._M_header._M_left));
608 }
609
610 const_iterator
611 begin() const
612 {
613 return const_iterator(static_cast<_Const_Link_type>
614 (this->_M_impl._M_header._M_left));
615 }
616
617 iterator
618 end()
619 { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }
620
621 const_iterator
622 end() const
623 {
624 return const_iterator(static_cast<_Const_Link_type>
625 (&this->_M_impl._M_header));
626 }
627
628 reverse_iterator
629 rbegin()
630 { return reverse_iterator(end()); }
631
632 const_reverse_iterator
633 rbegin() const
634 { return const_reverse_iterator(end()); }
635
636 reverse_iterator
637 rend()
638 { return reverse_iterator(begin()); }
639
640 const_reverse_iterator
641 rend() const
642 { return const_reverse_iterator(begin()); }
643
644 bool
645 empty() const
646 { return _M_impl._M_node_count == 0; }
647
648 size_type
649 size() const
650 { return _M_impl._M_node_count; }
651
652 size_type
653 max_size() const
654 { return get_allocator().max_size(); }
655
656 void
657 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t);
658
659 // Insert/erase.
660 pair<iterator, bool>
661 _M_insert_unique(const value_type& __x);
662
663 iterator
664 _M_insert_equal(const value_type& __x);
665
666 iterator
667 _M_insert_unique_(const_iterator __position, const value_type& __x);
668
669 iterator
670 _M_insert_equal_(const_iterator __position, const value_type& __x);
671
672 template<typename _InputIterator>
673 void
674 _M_insert_unique(_InputIterator __first, _InputIterator __last);
675
676 template<typename _InputIterator>
677 void
678 _M_insert_equal(_InputIterator __first, _InputIterator __last);
679
680 void
681 erase(iterator __position);
682
683 void
684 erase(const_iterator __position);
685
686 size_type
687 erase(const key_type& __x);
688
689 void
690 erase(iterator __first, iterator __last);
691
692 void
693 erase(const_iterator __first, const_iterator __last);
694
695 void
696 erase(const key_type* __first, const key_type* __last);
697
698 void
699 clear()
700 {
701 _M_erase(_M_begin());
702 _M_leftmost() = _M_end();
703 _M_root() = 0;
704 _M_rightmost() = _M_end();
705 _M_impl._M_node_count = 0;
706 }
707
708 // Set operations.
709 iterator
710 find(const key_type& __k);
711
712 const_iterator
713 find(const key_type& __k) const;
714
715 size_type
716 count(const key_type& __k) const;
717
718 iterator
719 lower_bound(const key_type& __k)
720 { return iterator(_M_lower_bound(_M_begin(), _M_end(), __k)); }
721
722 const_iterator
723 lower_bound(const key_type& __k) const
724 { return const_iterator(_M_lower_bound(_M_begin(), _M_end(), __k)); }
725
726 iterator
727 upper_bound(const key_type& __k)
728 { return iterator(_M_upper_bound(_M_begin(), _M_end(), __k)); }
729
730 const_iterator
731 upper_bound(const key_type& __k) const
732 { return const_iterator(_M_upper_bound(_M_begin(), _M_end(), __k)); }
733
734 pair<iterator, iterator>
735 equal_range(const key_type& __k)
736 { return pair<iterator, iterator>(_M_equal_range(__k)); }
737
738 pair<const_iterator, const_iterator>
739 equal_range(const key_type& __k) const
740 { return pair<const_iterator, const_iterator>(_M_equal_range(__k)); }
741
742 // Debugging.
743 bool
744 __rb_verify() const;
745 };
746
747 template<typename _Key, typename _Val, typename _KeyOfValue,
748 typename _Compare, typename _Alloc>
749 inline bool
750 operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
751 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
752 {
753 return __x.size() == __y.size()
754 && std::equal(__x.begin(), __x.end(), __y.begin());
755 }
756
757 template<typename _Key, typename _Val, typename _KeyOfValue,
758 typename _Compare, typename _Alloc>
759 inline bool
760 operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
761 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
762 {
763 return std::lexicographical_compare(__x.begin(), __x.end(),
764 __y.begin(), __y.end());
765 }
766
767 template<typename _Key, typename _Val, typename _KeyOfValue,
768 typename _Compare, typename _Alloc>
769 inline bool
770 operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
771 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
772 { return !(__x == __y); }
773
774 template<typename _Key, typename _Val, typename _KeyOfValue,
775 typename _Compare, typename _Alloc>
776 inline bool
777 operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
778 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
779 { return __y < __x; }
780
781 template<typename _Key, typename _Val, typename _KeyOfValue,
782 typename _Compare, typename _Alloc>
783 inline bool
784 operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
785 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
786 { return !(__y < __x); }
787
788 template<typename _Key, typename _Val, typename _KeyOfValue,
789 typename _Compare, typename _Alloc>
790 inline bool
791 operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
792 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
793 { return !(__x < __y); }
794
795 template<typename _Key, typename _Val, typename _KeyOfValue,
796 typename _Compare, typename _Alloc>
797 inline void
798 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
799 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
800 { __x.swap(__y); }
801
802 template<typename _Key, typename _Val, typename _KeyOfValue,
803 typename _Compare, typename _Alloc>
804 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
805 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
806 operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
807 {
808 if (this != &__x)
809 {
810 // Note that _Key may be a constant type.
811 clear();
812 _M_impl._M_key_compare = __x._M_impl._M_key_compare;
813 if (__x._M_root() != 0)
814 {
815 _M_root() = _M_copy(__x._M_begin(), _M_end());
816 _M_leftmost() = _S_minimum(_M_root());
817 _M_rightmost() = _S_maximum(_M_root());
818 _M_impl._M_node_count = __x._M_impl._M_node_count;
819 }
820 }
821 return *this;
822 }
823
824 template<typename _Key, typename _Val, typename _KeyOfValue,
825 typename _Compare, typename _Alloc>
826 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
827 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
828 _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v)
829 {
830 bool __insert_left = (__x != 0 || __p == _M_end()
831 || _M_impl._M_key_compare(_KeyOfValue()(__v),
832 _S_key(__p)));
833
834 _Link_type __z = _M_create_node(__v);
835
836 _Rb_tree_insert_and_rebalance(__insert_left, __z,
837 const_cast<_Base_ptr>(__p),
838 this->_M_impl._M_header);
839 ++_M_impl._M_node_count;
840 return iterator(__z);
841 }
842
843 template<typename _Key, typename _Val, typename _KeyOfValue,
844 typename _Compare, typename _Alloc>
845 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
846 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
847 _M_insert_lower(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
848 {
849 bool __insert_left = (__x != 0 || __p == _M_end()
850 || !_M_impl._M_key_compare(_S_key(__p),
851 _KeyOfValue()(__v)));
852
853 _Link_type __z = _M_create_node(__v);
854
855 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
856 this->_M_impl._M_header);
857 ++_M_impl._M_node_count;
858 return iterator(__z);
859 }
860
861 template<typename _Key, typename _Val, typename _KeyOfValue,
862 typename _Compare, typename _Alloc>
863 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
864 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
865 _M_insert_equal_lower(const _Val& __v)
866 {
867 _Link_type __x = _M_begin();
868 _Link_type __y = _M_end();
869 while (__x != 0)
870 {
871 __y = __x;
872 __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
873 _S_left(__x) : _S_right(__x);
874 }
875 return _M_insert_lower(__x, __y, __v);
876 }
877
878 template<typename _Key, typename _Val, typename _KoV,
879 typename _Compare, typename _Alloc>
880 typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
881 _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
882 _M_copy(_Const_Link_type __x, _Link_type __p)
883 {
884 // Structural copy. __x and __p must be non-null.
885 _Link_type __top = _M_clone_node(__x);
886 __top->_M_parent = __p;
887
888 try
889 {
890 if (__x->_M_right)
891 __top->_M_right = _M_copy(_S_right(__x), __top);
892 __p = __top;
893 __x = _S_left(__x);
894
895 while (__x != 0)
896 {
897 _Link_type __y = _M_clone_node(__x);
898 __p->_M_left = __y;
899 __y->_M_parent = __p;
900 if (__x->_M_right)
901 __y->_M_right = _M_copy(_S_right(__x), __y);
902 __p = __y;
903 __x = _S_left(__x);
904 }
905 }
906 catch(...)
907 {
908 _M_erase(__top);
909 __throw_exception_again;
910 }
911 return __top;
912 }
913
914 template<typename _Key, typename _Val, typename _KeyOfValue,
915 typename _Compare, typename _Alloc>
916 void
917 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
918 _M_erase(_Link_type __x)
919 {
920 // Erase without rebalancing.
921 while (__x != 0)
922 {
923 _M_erase(_S_right(__x));
924 _Link_type __y = _S_left(__x);
925 _M_destroy_node(__x);
926 __x = __y;
927 }
928 }
929
930 template<typename _Key, typename _Val, typename _KeyOfValue,
931 typename _Compare, typename _Alloc>
932 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
933 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
934 _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
935 const _Key& __k) const
936 {
937 while (__x != 0)
938 if (!_M_impl._M_key_compare(_S_key(__x), __k))
939 __y = __x, __x = _S_left(__x);
940 else
941 __x = _S_right(__x);
942 return iterator(const_cast<_Link_type>(__y));
943 }
944
945 template<typename _Key, typename _Val, typename _KeyOfValue,
946 typename _Compare, typename _Alloc>
947 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
948 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
949 _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
950 const _Key& __k) const
951 {
952 while (__x != 0)
953 if (_M_impl._M_key_compare(__k, _S_key(__x)))
954 __y = __x, __x = _S_left(__x);
955 else
956 __x = _S_right(__x);
957 return iterator(const_cast<_Link_type>(__y));
958 }
959
960 template<typename _Key, typename _Val, typename _KeyOfValue,
961 typename _Compare, typename _Alloc>
962 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
963 _Compare, _Alloc>::iterator,
964 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator>
965 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
966 _M_equal_range(const _Key& __k) const
967 {
968 _Const_Link_type __x = _M_begin();
969 _Const_Link_type __y = _M_end();
970 while (__x != 0)
971 {
972 if (_M_impl._M_key_compare(_S_key(__x), __k))
973 __x = _S_right(__x);
974 else if (_M_impl._M_key_compare(__k, _S_key(__x)))
975 __y = __x, __x = _S_left(__x);
976 else
977 {
978 _Const_Link_type __xu(__x), __yu(__y);
979 __y = __x, __x = _S_left(__x);
980 __xu = _S_right(__xu);
981 return pair<iterator, iterator>(_M_lower_bound(__x, __y, __k),
982 _M_upper_bound(__xu, __yu, __k));
983 }
984 }
985 return pair<iterator, iterator>(iterator(const_cast<_Link_type>(__y)),
986 iterator(const_cast<_Link_type>(__y)));
987 }
988
989 template<typename _Key, typename _Val, typename _KeyOfValue,
990 typename _Compare, typename _Alloc>
991 void
992 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
993 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
994 {
995 if (_M_root() == 0)
996 {
997 if (__t._M_root() != 0)
998 {
999 _M_root() = __t._M_root();
1000 _M_leftmost() = __t._M_leftmost();
1001 _M_rightmost() = __t._M_rightmost();
1002 _M_root()->_M_parent = _M_end();
1003
1004 __t._M_root() = 0;
1005 __t._M_leftmost() = __t._M_end();
1006 __t._M_rightmost() = __t._M_end();
1007 }
1008 }
1009 else if (__t._M_root() == 0)
1010 {
1011 __t._M_root() = _M_root();
1012 __t._M_leftmost() = _M_leftmost();
1013 __t._M_rightmost() = _M_rightmost();
1014 __t._M_root()->_M_parent = __t._M_end();
1015
1016 _M_root() = 0;
1017 _M_leftmost() = _M_end();
1018 _M_rightmost() = _M_end();
1019 }
1020 else
1021 {
1022 std::swap(_M_root(),__t._M_root());
1023 std::swap(_M_leftmost(),__t._M_leftmost());
1024 std::swap(_M_rightmost(),__t._M_rightmost());
1025
1026 _M_root()->_M_parent = _M_end();
1027 __t._M_root()->_M_parent = __t._M_end();
1028 }
1029 // No need to swap header's color as it does not change.
1030 std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
1031 std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
1032
1033 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1034 // 431. Swapping containers with unequal allocators.
1035 std::__alloc_swap<_Node_allocator>::
1036 _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
1037 }
1038
1039 template<typename _Key, typename _Val, typename _KeyOfValue,
1040 typename _Compare, typename _Alloc>
1041 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1042 _Compare, _Alloc>::iterator, bool>
1043 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1044 _M_insert_unique(const _Val& __v)
1045 {
1046 _Link_type __x = _M_begin();
1047 _Link_type __y = _M_end();
1048 bool __comp = true;
1049 while (__x != 0)
1050 {
1051 __y = __x;
1052 __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x));
1053 __x = __comp ? _S_left(__x) : _S_right(__x);
1054 }
1055 iterator __j = iterator(__y);
1056 if (__comp)
1057 {
1058 if (__j == begin())
1059 return pair<iterator, bool>(_M_insert_(__x, __y, __v), true);
1060 else
1061 --__j;
1062 }
1063 if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
1064 return pair<iterator, bool>(_M_insert_(__x, __y, __v), true);
1065 return pair<iterator, bool>(__j, false);
1066 }
1067
1068 template<typename _Key, typename _Val, typename _KeyOfValue,
1069 typename _Compare, typename _Alloc>
1070 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1071 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1072 _M_insert_equal(const _Val& __v)
1073 {
1074 _Link_type __x = _M_begin();
1075 _Link_type __y = _M_end();
1076 while (__x != 0)
1077 {
1078 __y = __x;
1079 __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
1080 _S_left(__x) : _S_right(__x);
1081 }
1082 return _M_insert_(__x, __y, __v);
1083 }
1084
1085 template<typename _Key, typename _Val, typename _KeyOfValue,
1086 typename _Compare, typename _Alloc>
1087 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1088 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1089 _M_insert_unique_(const_iterator __position, const _Val& __v)
1090 {
1091 // end()
1092 if (__position._M_node == _M_end())
1093 {
1094 if (size() > 0
1095 && _M_impl._M_key_compare(_S_key(_M_rightmost()),
1096 _KeyOfValue()(__v)))
1097 return _M_insert_(0, _M_rightmost(), __v);
1098 else
1099 return _M_insert_unique(__v).first;
1100 }
1101 else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
1102 _S_key(__position._M_node)))
1103 {
1104 // First, try before...
1105 const_iterator __before = __position;
1106 if (__position._M_node == _M_leftmost()) // begin()
1107 return _M_insert_(_M_leftmost(), _M_leftmost(), __v);
1108 else if (_M_impl._M_key_compare(_S_key((--__before)._M_node),
1109 _KeyOfValue()(__v)))
1110 {
1111 if (_S_right(__before._M_node) == 0)
1112 return _M_insert_(0, __before._M_node, __v);
1113 else
1114 return _M_insert_(__position._M_node,
1115 __position._M_node, __v);
1116 }
1117 else
1118 return _M_insert_unique(__v).first;
1119 }
1120 else if (_M_impl._M_key_compare(_S_key(__position._M_node),
1121 _KeyOfValue()(__v)))
1122 {
1123 // ... then try after.
1124 const_iterator __after = __position;
1125 if (__position._M_node == _M_rightmost())
1126 return _M_insert_(0, _M_rightmost(), __v);
1127 else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
1128 _S_key((++__after)._M_node)))
1129 {
1130 if (_S_right(__position._M_node) == 0)
1131 return _M_insert_(0, __position._M_node, __v);
1132 else
1133 return _M_insert_(__after._M_node, __after._M_node, __v);
1134 }
1135 else
1136 return _M_insert_unique(__v).first;
1137 }
1138 else
1139 // Equivalent keys.
1140 return iterator(static_cast<_Link_type>
1141 (const_cast<_Base_ptr>(__position._M_node)));
1142 }
1143
1144 template<typename _Key, typename _Val, typename _KeyOfValue,
1145 typename _Compare, typename _Alloc>
1146 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1147 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1148 _M_insert_equal_(const_iterator __position, const _Val& __v)
1149 {
1150 // end()
1151 if (__position._M_node == _M_end())
1152 {
1153 if (size() > 0
1154 && !_M_impl._M_key_compare(_KeyOfValue()(__v),
1155 _S_key(_M_rightmost())))
1156 return _M_insert_(0, _M_rightmost(), __v);
1157 else
1158 return _M_insert_equal(__v);
1159 }
1160 else if (!_M_impl._M_key_compare(_S_key(__position._M_node),
1161 _KeyOfValue()(__v)))
1162 {
1163 // First, try before...
1164 const_iterator __before = __position;
1165 if (__position._M_node == _M_leftmost()) // begin()
1166 return _M_insert_(_M_leftmost(), _M_leftmost(), __v);
1167 else if (!_M_impl._M_key_compare(_KeyOfValue()(__v),
1168 _S_key((--__before)._M_node)))
1169 {
1170 if (_S_right(__before._M_node) == 0)
1171 return _M_insert_(0, __before._M_node, __v);
1172 else
1173 return _M_insert_(__position._M_node,
1174 __position._M_node, __v);
1175 }
1176 else
1177 return _M_insert_equal(__v);
1178 }
1179 else
1180 {
1181 // ... then try after.
1182 const_iterator __after = __position;
1183 if (__position._M_node == _M_rightmost())
1184 return _M_insert_(0, _M_rightmost(), __v);
1185 else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node),
1186 _KeyOfValue()(__v)))
1187 {
1188 if (_S_right(__position._M_node) == 0)
1189 return _M_insert_(0, __position._M_node, __v);
1190 else
1191 return _M_insert_(__after._M_node, __after._M_node, __v);
1192 }
1193 else
1194 return _M_insert_equal_lower(__v);
1195 }
1196 }
1197
1198 template<typename _Key, typename _Val, typename _KoV,
1199 typename _Cmp, typename _Alloc>
1200 template<class _II>
1201 void
1202 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
1203 _M_insert_unique(_II __first, _II __last)
1204 {
1205 for (; __first != __last; ++__first)
1206 _M_insert_unique_(end(), *__first);
1207 }
1208
1209 template<typename _Key, typename _Val, typename _KoV,
1210 typename _Cmp, typename _Alloc>
1211 template<class _II>
1212 void
1213 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
1214 _M_insert_equal(_II __first, _II __last)
1215 {
1216 for (; __first != __last; ++__first)
1217 _M_insert_equal_(end(), *__first);
1218 }
1219
1220 template<typename _Key, typename _Val, typename _KeyOfValue,
1221 typename _Compare, typename _Alloc>
1222 inline void
1223 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1224 erase(iterator __position)
1225 {
1226 _Link_type __y =
1227 static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
1228 (__position._M_node,
1229 this->_M_impl._M_header));
1230 _M_destroy_node(__y);
1231 --_M_impl._M_node_count;
1232 }
1233
1234 template<typename _Key, typename _Val, typename _KeyOfValue,
1235 typename _Compare, typename _Alloc>
1236 inline void
1237 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1238 erase(const_iterator __position)
1239 {
1240 _Link_type __y =
1241 static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
1242 (const_cast<_Base_ptr>(__position._M_node),
1243 this->_M_impl._M_header));
1244 _M_destroy_node(__y);
1245 --_M_impl._M_node_count;
1246 }
1247
1248 template<typename _Key, typename _Val, typename _KeyOfValue,
1249 typename _Compare, typename _Alloc>
1250 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
1251 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1252 erase(const _Key& __x)
1253 {
1254 pair<iterator, iterator> __p = equal_range(__x);
1255 const size_type __old_size = size();
1256 erase(__p.first, __p.second);
1257 return __old_size - size();
1258 }
1259
1260 template<typename _Key, typename _Val, typename _KeyOfValue,
1261 typename _Compare, typename _Alloc>
1262 void
1263 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1264 erase(iterator __first, iterator __last)
1265 {
1266 if (__first == begin() && __last == end())
1267 clear();
1268 else
1269 while (__first != __last)
1270 erase(__first++);
1271 }
1272
1273 template<typename _Key, typename _Val, typename _KeyOfValue,
1274 typename _Compare, typename _Alloc>
1275 void
1276 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1277 erase(const_iterator __first, const_iterator __last)
1278 {
1279 if (__first == begin() && __last == end())
1280 clear();
1281 else
1282 while (__first != __last)
1283 erase(__first++);
1284 }
1285
1286 template<typename _Key, typename _Val, typename _KeyOfValue,
1287 typename _Compare, typename _Alloc>
1288 void
1289 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1290 erase(const _Key* __first, const _Key* __last)
1291 {
1292 while (__first != __last)
1293 erase(*__first++);
1294 }
1295
1296 template<typename _Key, typename _Val, typename _KeyOfValue,
1297 typename _Compare, typename _Alloc>
1298 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1299 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1300 find(const _Key& __k)
1301 {
1302 iterator __j = iterator(_M_lower_bound(_M_begin(), _M_end(), __k));
1303 return (__j == end()
1304 || _M_impl._M_key_compare(__k,
1305 _S_key(__j._M_node))) ? end() : __j;
1306 }
1307
1308 template<typename _Key, typename _Val, typename _KeyOfValue,
1309 typename _Compare, typename _Alloc>
1310 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
1311 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1312 find(const _Key& __k) const
1313 {
1314 const_iterator __j = const_iterator(_M_lower_bound(_M_begin(),
1315 _M_end(), __k));
1316 return (__j == end()
1317 || _M_impl._M_key_compare(__k,
1318 _S_key(__j._M_node))) ? end() : __j;
1319 }
1320
1321 template<typename _Key, typename _Val, typename _KeyOfValue,
1322 typename _Compare, typename _Alloc>
1323 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
1324 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1325 count(const _Key& __k) const
1326 {
1327 pair<const_iterator, const_iterator> __p = equal_range(__k);
1328 const size_type __n = std::distance(__p.first, __p.second);
1329 return __n;
1330 }
1331
1332 unsigned int
1333 _Rb_tree_black_count(const _Rb_tree_node_base* __node,
1334 const _Rb_tree_node_base* __root);
1335
1336 template<typename _Key, typename _Val, typename _KeyOfValue,
1337 typename _Compare, typename _Alloc>
1338 bool
1339 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
1340 {
1341 if (_M_impl._M_node_count == 0 || begin() == end())
1342 return _M_impl._M_node_count == 0 && begin() == end()
1343 && this->_M_impl._M_header._M_left == _M_end()
1344 && this->_M_impl._M_header._M_right == _M_end();
1345
1346 unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
1347 for (const_iterator __it = begin(); __it != end(); ++__it)
1348 {
1349 _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
1350 _Const_Link_type __L = _S_left(__x);
1351 _Const_Link_type __R = _S_right(__x);
1352
1353 if (__x->_M_color == _S_red)
1354 if ((__L && __L->_M_color == _S_red)
1355 || (__R && __R->_M_color == _S_red))
1356 return false;
1357
1358 if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
1359 return false;
1360 if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
1361 return false;
1362
1363 if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
1364 return false;
1365 }
1366
1367 if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
1368 return false;
1369 if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
1370 return false;
1371 return true;
1372 }
1373
1374 _GLIBCXX_END_NAMESPACE
1375
1376 #endif