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