]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/stl_tree.h
re PR rtl-optimization/55489 (insane PRE memory usage with PIE (translate.i))
[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 134
734f5023 135#if __cplusplus >= 201103L
25bbe9bc
PC
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
734f5023 375#if __cplusplus < 201103L
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
734f5023 453#if __cplusplus >= 201103L
6f59ea25
PC
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:
55826ab6
FD
573 pair<_Base_ptr, _Base_ptr>
574 _M_get_insert_unique_pos(const key_type& __k);
575
576 pair<_Base_ptr, _Base_ptr>
577 _M_get_insert_equal_pos(const key_type& __k);
578
579 pair<_Base_ptr, _Base_ptr>
580 _M_get_insert_hint_unique_pos(const_iterator __pos,
581 const key_type& __k);
582
583 pair<_Base_ptr, _Base_ptr>
584 _M_get_insert_hint_equal_pos(const_iterator __pos,
585 const key_type& __k);
586
734f5023 587#if __cplusplus >= 201103L
e6a05448
PC
588 template<typename _Arg>
589 iterator
55826ab6
FD
590 _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v);
591
592 iterator
593 _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
e6a05448
PC
594
595 template<typename _Arg>
596 iterator
55826ab6 597 _M_insert_lower(_Base_ptr __y, _Arg&& __v);
e6a05448
PC
598
599 template<typename _Arg>
600 iterator
601 _M_insert_equal_lower(_Arg&& __x);
55826ab6
FD
602
603 iterator
604 _M_insert_lower_node(_Base_ptr __p, _Link_type __z);
605
606 iterator
607 _M_insert_equal_lower_node(_Link_type __z);
e6a05448 608#else
ed6814f7 609 iterator
55826ab6 610 _M_insert_(_Base_ptr __x, _Base_ptr __y,
dc4871cb 611 const value_type& __v);
d3d526ac 612
cf1e0371
PC
613 // _GLIBCXX_RESOLVE_LIB_DEFECTS
614 // 233. Insertion hints in associative containers.
615 iterator
55826ab6 616 _M_insert_lower(_Base_ptr __y, const value_type& __v);
cf1e0371 617
dc4871cb
PC
618 iterator
619 _M_insert_equal_lower(const value_type& __x);
e6a05448 620#endif
d5e07b79 621
ed6814f7 622 _Link_type
b4c70e89 623 _M_copy(_Const_Link_type __x, _Link_type __p);
d3d526ac 624
ed6814f7 625 void
d3d526ac
BK
626 _M_erase(_Link_type __x);
627
dc4871cb 628 iterator
f7e52577
PC
629 _M_lower_bound(_Link_type __x, _Link_type __y,
630 const _Key& __k);
631
632 const_iterator
dc4871cb
PC
633 _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
634 const _Key& __k) const;
635
636 iterator
f7e52577
PC
637 _M_upper_bound(_Link_type __x, _Link_type __y,
638 const _Key& __k);
639
640 const_iterator
dc4871cb
PC
641 _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
642 const _Key& __k) const;
643
d3d526ac
BK
644 public:
645 // allocation/deallocation
78b36b70 646 _Rb_tree() { }
d3d526ac 647
78b36b70
PC
648 _Rb_tree(const _Compare& __comp,
649 const allocator_type& __a = allocator_type())
ff15f019 650 : _M_impl(__comp, _Node_allocator(__a)) { }
d3d526ac 651
78b36b70
PC
652 _Rb_tree(const _Rb_tree& __x)
653 : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
ed6814f7 654 {
8bd22a3c 655 if (__x._M_root() != 0)
d3d526ac 656 {
b4c70e89 657 _M_root() = _M_copy(__x._M_begin(), _M_end());
d3d526ac
BK
658 _M_leftmost() = _S_minimum(_M_root());
659 _M_rightmost() = _S_maximum(_M_root());
8bd22a3c 660 _M_impl._M_node_count = __x._M_impl._M_node_count;
d3d526ac 661 }
725dc051 662 }
d3d526ac 663
734f5023 664#if __cplusplus >= 201103L
053cc380
PC
665 _Rb_tree(_Rb_tree&& __x);
666#endif
667
6f59ea25 668 ~_Rb_tree() _GLIBCXX_NOEXCEPT
737ab798 669 { _M_erase(_M_begin()); }
d3d526ac 670
78b36b70
PC
671 _Rb_tree&
672 operator=(const _Rb_tree& __x);
d3d526ac 673
d3d526ac 674 // Accessors.
ed6814f7 675 _Compare
62e67651 676 key_comp() const
8bd22a3c 677 { return _M_impl._M_key_compare; }
d3d526ac 678
ed6814f7 679 iterator
d3677132 680 begin() _GLIBCXX_NOEXCEPT
e182017e
PC
681 {
682 return iterator(static_cast<_Link_type>
683 (this->_M_impl._M_header._M_left));
684 }
d3d526ac 685
ed6814f7 686 const_iterator
d3677132 687 begin() const _GLIBCXX_NOEXCEPT
e182017e
PC
688 {
689 return const_iterator(static_cast<_Const_Link_type>
690 (this->_M_impl._M_header._M_left));
11aaf40c 691 }
d3d526ac 692
ed6814f7 693 iterator
d3677132 694 end() _GLIBCXX_NOEXCEPT
e182017e 695 { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }
d3d526ac 696
7f6dd1ca 697 const_iterator
d3677132 698 end() const _GLIBCXX_NOEXCEPT
e182017e
PC
699 {
700 return const_iterator(static_cast<_Const_Link_type>
701 (&this->_M_impl._M_header));
702 }
d3d526ac 703
ed6814f7 704 reverse_iterator
d3677132 705 rbegin() _GLIBCXX_NOEXCEPT
62e67651 706 { return reverse_iterator(end()); }
d3d526ac 707
ed6814f7 708 const_reverse_iterator
d3677132 709 rbegin() const _GLIBCXX_NOEXCEPT
62e67651 710 { return const_reverse_iterator(end()); }
d3d526ac 711
ed6814f7 712 reverse_iterator
d3677132 713 rend() _GLIBCXX_NOEXCEPT
62e67651 714 { return reverse_iterator(begin()); }
d3d526ac 715
ed6814f7 716 const_reverse_iterator
d3677132 717 rend() const _GLIBCXX_NOEXCEPT
62e67651 718 { return const_reverse_iterator(begin()); }
ed6814f7
BI
719
720 bool
d3677132 721 empty() const _GLIBCXX_NOEXCEPT
8bd22a3c 722 { return _M_impl._M_node_count == 0; }
d3d526ac 723
ed6814f7 724 size_type
d3677132 725 size() const _GLIBCXX_NOEXCEPT
8bd22a3c 726 { return _M_impl._M_node_count; }
d3d526ac 727
ed6814f7 728 size_type
d3677132 729 max_size() const _GLIBCXX_NOEXCEPT
1fea874e 730 { return _M_get_Node_allocator().max_size(); }
d3d526ac 731
ed6814f7 732 void
78b36b70 733 swap(_Rb_tree& __t);
ed6814f7 734
d3d526ac 735 // Insert/erase.
734f5023 736#if __cplusplus >= 201103L
e6a05448
PC
737 template<typename _Arg>
738 pair<iterator, bool>
739 _M_insert_unique(_Arg&& __x);
740
741 template<typename _Arg>
742 iterator
743 _M_insert_equal(_Arg&& __x);
744
745 template<typename _Arg>
746 iterator
747 _M_insert_unique_(const_iterator __position, _Arg&& __x);
748
749 template<typename _Arg>
750 iterator
751 _M_insert_equal_(const_iterator __position, _Arg&& __x);
55826ab6
FD
752
753 template<typename... _Args>
754 pair<iterator, bool>
755 _M_emplace_unique(_Args&&... __args);
756
757 template<typename... _Args>
758 iterator
759 _M_emplace_equal(_Args&&... __args);
760
761 template<typename... _Args>
762 iterator
763 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args);
764
765 template<typename... _Args>
766 iterator
767 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args);
e6a05448 768#else
42a27024
PC
769 pair<iterator, bool>
770 _M_insert_unique(const value_type& __x);
d3d526ac 771
ed6814f7 772 iterator
42a27024 773 _M_insert_equal(const value_type& __x);
d3d526ac 774
ed6814f7 775 iterator
dc4871cb 776 _M_insert_unique_(const_iterator __position, const value_type& __x);
d5e07b79 777
ed6814f7 778 iterator
dc4871cb 779 _M_insert_equal_(const_iterator __position, const value_type& __x);
e6a05448 780#endif
d5e07b79 781
d3d526ac 782 template<typename _InputIterator>
e182017e 783 void
42a27024 784 _M_insert_unique(_InputIterator __first, _InputIterator __last);
d3d526ac
BK
785
786 template<typename _InputIterator>
e182017e 787 void
42a27024 788 _M_insert_equal(_InputIterator __first, _InputIterator __last);
d3d526ac 789
7606bd11
PC
790 private:
791 void
792 _M_erase_aux(const_iterator __position);
793
794 void
795 _M_erase_aux(const_iterator __first, const_iterator __last);
796
797 public:
734f5023 798#if __cplusplus >= 201103L
c105751c
ESR
799 // _GLIBCXX_RESOLVE_LIB_DEFECTS
800 // DR 130. Associative erase should return an iterator.
801 iterator
7606bd11
PC
802 erase(const_iterator __position)
803 {
804 const_iterator __result = __position;
805 ++__result;
806 _M_erase_aux(__position);
6b6d5d09 807 return __result._M_const_cast();
7606bd11 808 }
6dc88283
PC
809
810 // LWG 2059.
811 iterator
812 erase(iterator __position)
813 {
814 iterator __result = __position;
815 ++__result;
816 _M_erase_aux(__position);
817 return __result;
818 }
c105751c 819#else
03e38c1a
PC
820 void
821 erase(iterator __position)
822 { _M_erase_aux(__position); }
823
ed6814f7 824 void
7606bd11
PC
825 erase(const_iterator __position)
826 { _M_erase_aux(__position); }
c105751c 827#endif
ed6814f7 828 size_type
d3d526ac
BK
829 erase(const key_type& __x);
830
734f5023 831#if __cplusplus >= 201103L
c105751c
ESR
832 // _GLIBCXX_RESOLVE_LIB_DEFECTS
833 // DR 130. Associative erase should return an iterator.
834 iterator
7606bd11
PC
835 erase(const_iterator __first, const_iterator __last)
836 {
837 _M_erase_aux(__first, __last);
6b6d5d09 838 return __last._M_const_cast();
7606bd11 839 }
c105751c 840#else
03e38c1a
PC
841 void
842 erase(iterator __first, iterator __last)
843 { _M_erase_aux(__first, __last); }
844
ed6814f7 845 void
7606bd11
PC
846 erase(const_iterator __first, const_iterator __last)
847 { _M_erase_aux(__first, __last); }
c105751c 848#endif
ed6814f7 849 void
d3d526ac
BK
850 erase(const key_type* __first, const key_type* __last);
851
e135a038 852 void
d3677132 853 clear() _GLIBCXX_NOEXCEPT
d3d526ac 854 {
e135a038
BK
855 _M_erase(_M_begin());
856 _M_leftmost() = _M_end();
857 _M_root() = 0;
858 _M_rightmost() = _M_end();
8bd22a3c 859 _M_impl._M_node_count = 0;
e135a038 860 }
d3d526ac
BK
861
862 // Set operations.
ed6814f7 863 iterator
dc4871cb 864 find(const key_type& __k);
d3d526ac 865
ed6814f7 866 const_iterator
dc4871cb 867 find(const key_type& __k) const;
d3d526ac 868
ed6814f7 869 size_type
dc4871cb 870 count(const key_type& __k) const;
d3d526ac 871
ed6814f7 872 iterator
dc4871cb 873 lower_bound(const key_type& __k)
f7e52577 874 { return _M_lower_bound(_M_begin(), _M_end(), __k); }
d3d526ac 875
ed6814f7 876 const_iterator
dc4871cb 877 lower_bound(const key_type& __k) const
f7e52577 878 { return _M_lower_bound(_M_begin(), _M_end(), __k); }
d3d526ac 879
ed6814f7 880 iterator
dc4871cb 881 upper_bound(const key_type& __k)
f7e52577 882 { return _M_upper_bound(_M_begin(), _M_end(), __k); }
d3d526ac 883
ed6814f7 884 const_iterator
dc4871cb 885 upper_bound(const key_type& __k) const
f7e52577 886 { return _M_upper_bound(_M_begin(), _M_end(), __k); }
d3d526ac 887
dc4871cb 888 pair<iterator, iterator>
f7e52577 889 equal_range(const key_type& __k);
d3d526ac 890
ed6814f7 891 pair<const_iterator, const_iterator>
f7e52577 892 equal_range(const key_type& __k) const;
d3d526ac
BK
893
894 // Debugging.
ed6814f7 895 bool
d3d526ac
BK
896 __rb_verify() const;
897 };
898
ed6814f7 899 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 900 typename _Compare, typename _Alloc>
ed6814f7 901 inline bool
11aaf40c
PC
902 operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
903 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
d3d526ac 904 {
62e67651 905 return __x.size() == __y.size()
ac317859 906 && std::equal(__x.begin(), __x.end(), __y.begin());
725dc051 907 }
d3d526ac 908
ed6814f7 909 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 910 typename _Compare, typename _Alloc>
ed6814f7 911 inline bool
11aaf40c
PC
912 operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
913 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
d3d526ac 914 {
ac317859
PC
915 return std::lexicographical_compare(__x.begin(), __x.end(),
916 __y.begin(), __y.end());
725dc051 917 }
d3d526ac 918
ed6814f7 919 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 920 typename _Compare, typename _Alloc>
ed6814f7 921 inline bool
11aaf40c
PC
922 operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
923 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
d3d526ac
BK
924 { return !(__x == __y); }
925
ed6814f7 926 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 927 typename _Compare, typename _Alloc>
ed6814f7 928 inline bool
11aaf40c
PC
929 operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
930 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
d3d526ac
BK
931 { return __y < __x; }
932
ed6814f7 933 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 934 typename _Compare, typename _Alloc>
ed6814f7 935 inline bool
11aaf40c
PC
936 operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
937 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
737ab798 938 { return !(__y < __x); }
d3d526ac 939
ed6814f7 940 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 941 typename _Compare, typename _Alloc>
ed6814f7 942 inline bool
11aaf40c
PC
943 operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
944 const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
737ab798 945 { return !(__x < __y); }
d3d526ac 946
ed6814f7 947 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 948 typename _Compare, typename _Alloc>
ed6814f7 949 inline void
11aaf40c
PC
950 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
951 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
d3d526ac
BK
952 { __x.swap(__y); }
953
734f5023 954#if __cplusplus >= 201103L
053cc380
PC
955 template<typename _Key, typename _Val, typename _KeyOfValue,
956 typename _Compare, typename _Alloc>
957 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
958 _Rb_tree(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __x)
6f59ea25
PC
959 : _M_impl(__x._M_impl._M_key_compare,
960 std::move(__x._M_get_Node_allocator()))
053cc380
PC
961 {
962 if (__x._M_root() != 0)
963 {
964 _M_root() = __x._M_root();
965 _M_leftmost() = __x._M_leftmost();
966 _M_rightmost() = __x._M_rightmost();
967 _M_root()->_M_parent = _M_end();
968
969 __x._M_root() = 0;
970 __x._M_leftmost() = __x._M_end();
971 __x._M_rightmost() = __x._M_end();
972
973 this->_M_impl._M_node_count = __x._M_impl._M_node_count;
974 __x._M_impl._M_node_count = 0;
975 }
976 }
977#endif
978
ed6814f7 979 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 980 typename _Compare, typename _Alloc>
11aaf40c
PC
981 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
982 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
983 operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
d3d526ac 984 {
ed6814f7 985 if (this != &__x)
d3d526ac
BK
986 {
987 // Note that _Key may be a constant type.
988 clear();
8bd22a3c 989 _M_impl._M_key_compare = __x._M_impl._M_key_compare;
ed6814f7 990 if (__x._M_root() != 0)
d3d526ac 991 {
b4c70e89 992 _M_root() = _M_copy(__x._M_begin(), _M_end());
d3d526ac
BK
993 _M_leftmost() = _S_minimum(_M_root());
994 _M_rightmost() = _S_maximum(_M_root());
8bd22a3c 995 _M_impl._M_node_count = __x._M_impl._M_node_count;
d3d526ac
BK
996 }
997 }
998 return *this;
725dc051 999 }
d3d526ac 1000
ed6814f7 1001 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1002 typename _Compare, typename _Alloc>
734f5023 1003#if __cplusplus >= 201103L
e6a05448
PC
1004 template<typename _Arg>
1005#endif
11aaf40c
PC
1006 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1007 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
734f5023 1008#if __cplusplus >= 201103L
55826ab6 1009 _M_insert_(_Base_ptr __x, _Base_ptr __p, _Arg&& __v)
e6a05448 1010#else
55826ab6 1011 _M_insert_(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
e6a05448 1012#endif
d3d526ac 1013 {
7320b491 1014 bool __insert_left = (__x != 0 || __p == _M_end()
55826ab6 1015 || _M_impl._M_key_compare(_KeyOfValue()(__v),
7320b491 1016 _S_key(__p)));
e135a038 1017
e6a05448 1018 _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
e135a038 1019
55826ab6 1020 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
8bd22a3c
BK
1021 this->_M_impl._M_header);
1022 ++_M_impl._M_node_count;
d3d526ac
BK
1023 return iterator(__z);
1024 }
1025
cf1e0371
PC
1026 template<typename _Key, typename _Val, typename _KeyOfValue,
1027 typename _Compare, typename _Alloc>
734f5023 1028#if __cplusplus >= 201103L
e6a05448
PC
1029 template<typename _Arg>
1030#endif
cf1e0371
PC
1031 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1032 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
734f5023 1033#if __cplusplus >= 201103L
55826ab6 1034 _M_insert_lower(_Base_ptr __p, _Arg&& __v)
e6a05448 1035#else
55826ab6 1036 _M_insert_lower(_Base_ptr __p, const _Val& __v)
e6a05448 1037#endif
cf1e0371 1038 {
55826ab6 1039 bool __insert_left = (__p == _M_end()
cf1e0371
PC
1040 || !_M_impl._M_key_compare(_S_key(__p),
1041 _KeyOfValue()(__v)));
1042
e6a05448 1043 _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
cf1e0371 1044
55826ab6 1045 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
cf1e0371
PC
1046 this->_M_impl._M_header);
1047 ++_M_impl._M_node_count;
1048 return iterator(__z);
1049 }
1050
d5e07b79
PC
1051 template<typename _Key, typename _Val, typename _KeyOfValue,
1052 typename _Compare, typename _Alloc>
734f5023 1053#if __cplusplus >= 201103L
e6a05448
PC
1054 template<typename _Arg>
1055#endif
dc4871cb 1056 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
d5e07b79 1057 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
734f5023 1058#if __cplusplus >= 201103L
e6a05448
PC
1059 _M_insert_equal_lower(_Arg&& __v)
1060#else
dc4871cb 1061 _M_insert_equal_lower(const _Val& __v)
e6a05448 1062#endif
d5e07b79 1063 {
dc4871cb
PC
1064 _Link_type __x = _M_begin();
1065 _Link_type __y = _M_end();
1066 while (__x != 0)
1067 {
1068 __y = __x;
1069 __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
1070 _S_left(__x) : _S_right(__x);
1071 }
55826ab6 1072 return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v));
dc4871cb 1073 }
d5e07b79 1074
dc4871cb
PC
1075 template<typename _Key, typename _Val, typename _KoV,
1076 typename _Compare, typename _Alloc>
1077 typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
1078 _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
1079 _M_copy(_Const_Link_type __x, _Link_type __p)
1080 {
1081 // Structural copy. __x and __p must be non-null.
1082 _Link_type __top = _M_clone_node(__x);
1083 __top->_M_parent = __p;
d5e07b79 1084
bc2631e0 1085 __try
dc4871cb
PC
1086 {
1087 if (__x->_M_right)
1088 __top->_M_right = _M_copy(_S_right(__x), __top);
1089 __p = __top;
1090 __x = _S_left(__x);
1091
1092 while (__x != 0)
1093 {
1094 _Link_type __y = _M_clone_node(__x);
1095 __p->_M_left = __y;
1096 __y->_M_parent = __p;
1097 if (__x->_M_right)
1098 __y->_M_right = _M_copy(_S_right(__x), __y);
1099 __p = __y;
1100 __x = _S_left(__x);
1101 }
1102 }
bc2631e0 1103 __catch(...)
dc4871cb
PC
1104 {
1105 _M_erase(__top);
1106 __throw_exception_again;
1107 }
1108 return __top;
d5e07b79
PC
1109 }
1110
ed6814f7 1111 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1112 typename _Compare, typename _Alloc>
dc4871cb 1113 void
11aaf40c 1114 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
dc4871cb 1115 _M_erase(_Link_type __x)
d3d526ac 1116 {
dc4871cb 1117 // Erase without rebalancing.
ed6814f7 1118 while (__x != 0)
d3d526ac 1119 {
dc4871cb
PC
1120 _M_erase(_S_right(__x));
1121 _Link_type __y = _S_left(__x);
1122 _M_destroy_node(__x);
1123 __x = __y;
d3d526ac 1124 }
d3d526ac
BK
1125 }
1126
cf1e0371
PC
1127 template<typename _Key, typename _Val, typename _KeyOfValue,
1128 typename _Compare, typename _Alloc>
f7e52577
PC
1129 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1130 _Compare, _Alloc>::iterator
1131 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1132 _M_lower_bound(_Link_type __x, _Link_type __y,
1133 const _Key& __k)
1134 {
1135 while (__x != 0)
1136 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1137 __y = __x, __x = _S_left(__x);
1138 else
1139 __x = _S_right(__x);
1140 return iterator(__y);
1141 }
1142
1143 template<typename _Key, typename _Val, typename _KeyOfValue,
1144 typename _Compare, typename _Alloc>
1145 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1146 _Compare, _Alloc>::const_iterator
cf1e0371 1147 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
dc4871cb
PC
1148 _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
1149 const _Key& __k) const
cf1e0371 1150 {
cf1e0371 1151 while (__x != 0)
dc4871cb
PC
1152 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1153 __y = __x, __x = _S_left(__x);
1154 else
1155 __x = _S_right(__x);
f7e52577 1156 return const_iterator(__y);
dc4871cb
PC
1157 }
1158
1159 template<typename _Key, typename _Val, typename _KeyOfValue,
1160 typename _Compare, typename _Alloc>
f7e52577
PC
1161 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1162 _Compare, _Alloc>::iterator
1163 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1164 _M_upper_bound(_Link_type __x, _Link_type __y,
1165 const _Key& __k)
1166 {
1167 while (__x != 0)
1168 if (_M_impl._M_key_compare(__k, _S_key(__x)))
1169 __y = __x, __x = _S_left(__x);
1170 else
1171 __x = _S_right(__x);
1172 return iterator(__y);
1173 }
1174
1175 template<typename _Key, typename _Val, typename _KeyOfValue,
1176 typename _Compare, typename _Alloc>
1177 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1178 _Compare, _Alloc>::const_iterator
dc4871cb
PC
1179 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1180 _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
1181 const _Key& __k) const
1182 {
1183 while (__x != 0)
1184 if (_M_impl._M_key_compare(__k, _S_key(__x)))
1185 __y = __x, __x = _S_left(__x);
1186 else
1187 __x = _S_right(__x);
f7e52577 1188 return const_iterator(__y);
cf1e0371
PC
1189 }
1190
639b490b
PC
1191 template<typename _Key, typename _Val, typename _KeyOfValue,
1192 typename _Compare, typename _Alloc>
1193 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1194 _Compare, _Alloc>::iterator,
f7e52577
PC
1195 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1196 _Compare, _Alloc>::iterator>
1197 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1198 equal_range(const _Key& __k)
1199 {
1200 _Link_type __x = _M_begin();
1201 _Link_type __y = _M_end();
1202 while (__x != 0)
1203 {
1204 if (_M_impl._M_key_compare(_S_key(__x), __k))
1205 __x = _S_right(__x);
1206 else if (_M_impl._M_key_compare(__k, _S_key(__x)))
1207 __y = __x, __x = _S_left(__x);
1208 else
1209 {
1210 _Link_type __xu(__x), __yu(__y);
1211 __y = __x, __x = _S_left(__x);
1212 __xu = _S_right(__xu);
1213 return pair<iterator,
1214 iterator>(_M_lower_bound(__x, __y, __k),
1215 _M_upper_bound(__xu, __yu, __k));
1216 }
1217 }
1218 return pair<iterator, iterator>(iterator(__y),
1219 iterator(__y));
1220 }
1221
1222 template<typename _Key, typename _Val, typename _KeyOfValue,
1223 typename _Compare, typename _Alloc>
1224 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1225 _Compare, _Alloc>::const_iterator,
1226 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1227 _Compare, _Alloc>::const_iterator>
639b490b 1228 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
f7e52577 1229 equal_range(const _Key& __k) const
639b490b
PC
1230 {
1231 _Const_Link_type __x = _M_begin();
1232 _Const_Link_type __y = _M_end();
1233 while (__x != 0)
1234 {
1235 if (_M_impl._M_key_compare(_S_key(__x), __k))
1236 __x = _S_right(__x);
1237 else if (_M_impl._M_key_compare(__k, _S_key(__x)))
1238 __y = __x, __x = _S_left(__x);
1239 else
1240 {
1241 _Const_Link_type __xu(__x), __yu(__y);
1242 __y = __x, __x = _S_left(__x);
1243 __xu = _S_right(__xu);
f7e52577
PC
1244 return pair<const_iterator,
1245 const_iterator>(_M_lower_bound(__x, __y, __k),
1246 _M_upper_bound(__xu, __yu, __k));
639b490b
PC
1247 }
1248 }
f7e52577
PC
1249 return pair<const_iterator, const_iterator>(const_iterator(__y),
1250 const_iterator(__y));
639b490b
PC
1251 }
1252
ed6814f7 1253 template<typename _Key, typename _Val, typename _KeyOfValue,
7f6dd1ca
GB
1254 typename _Compare, typename _Alloc>
1255 void
11aaf40c
PC
1256 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1257 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
7f6dd1ca
GB
1258 {
1259 if (_M_root() == 0)
7f6dd1ca 1260 {
42a27024
PC
1261 if (__t._M_root() != 0)
1262 {
1263 _M_root() = __t._M_root();
1264 _M_leftmost() = __t._M_leftmost();
1265 _M_rightmost() = __t._M_rightmost();
1266 _M_root()->_M_parent = _M_end();
1267
1268 __t._M_root() = 0;
1269 __t._M_leftmost() = __t._M_end();
1270 __t._M_rightmost() = __t._M_end();
1271 }
7f6dd1ca 1272 }
7f6dd1ca 1273 else if (__t._M_root() == 0)
42a27024
PC
1274 {
1275 __t._M_root() = _M_root();
1276 __t._M_leftmost() = _M_leftmost();
1277 __t._M_rightmost() = _M_rightmost();
1278 __t._M_root()->_M_parent = __t._M_end();
1279
1280 _M_root() = 0;
1281 _M_leftmost() = _M_end();
1282 _M_rightmost() = _M_end();
1283 }
7f6dd1ca 1284 else
42a27024
PC
1285 {
1286 std::swap(_M_root(),__t._M_root());
1287 std::swap(_M_leftmost(),__t._M_leftmost());
1288 std::swap(_M_rightmost(),__t._M_rightmost());
1289
1290 _M_root()->_M_parent = _M_end();
1291 __t._M_root()->_M_parent = __t._M_end();
1292 }
7f6dd1ca 1293 // No need to swap header's color as it does not change.
8bd22a3c
BK
1294 std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
1295 std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
42a27024 1296
f7ace77f
PC
1297 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1298 // 431. Swapping containers with unequal allocators.
1299 std::__alloc_swap<_Node_allocator>::
1300 _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
7f6dd1ca
GB
1301 }
1302
ed6814f7 1303 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1304 typename _Compare, typename _Alloc>
11aaf40c 1305 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
55826ab6
FD
1306 _Compare, _Alloc>::_Base_ptr,
1307 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1308 _Compare, _Alloc>::_Base_ptr>
11aaf40c 1309 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
55826ab6 1310 _M_get_insert_unique_pos(const key_type& __k)
d3d526ac 1311 {
55826ab6 1312 typedef pair<_Base_ptr, _Base_ptr> _Res;
b4c70e89 1313 _Link_type __x = _M_begin();
7f6dd1ca 1314 _Link_type __y = _M_end();
d3d526ac 1315 bool __comp = true;
62e67651 1316 while (__x != 0)
d3d526ac
BK
1317 {
1318 __y = __x;
55826ab6 1319 __comp = _M_impl._M_key_compare(__k, _S_key(__x));
d3d526ac
BK
1320 __x = __comp ? _S_left(__x) : _S_right(__x);
1321 }
62e67651 1322 iterator __j = iterator(__y);
d3d526ac 1323 if (__comp)
2a67bec2
ILT
1324 {
1325 if (__j == begin())
55826ab6 1326 return _Res(__x, __y);
2a67bec2
ILT
1327 else
1328 --__j;
1329 }
55826ab6
FD
1330 if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
1331 return _Res(__x, __y);
1332 return _Res(__j._M_node, 0);
d3d526ac 1333 }
ed6814f7
BI
1334
1335 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1336 typename _Compare, typename _Alloc>
55826ab6
FD
1337 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1338 _Compare, _Alloc>::_Base_ptr,
1339 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1340 _Compare, _Alloc>::_Base_ptr>
d3d526ac 1341 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
55826ab6 1342 _M_get_insert_equal_pos(const key_type& __k)
d3d526ac 1343 {
55826ab6 1344 typedef pair<_Base_ptr, _Base_ptr> _Res;
dc4871cb
PC
1345 _Link_type __x = _M_begin();
1346 _Link_type __y = _M_end();
1347 while (__x != 0)
ec5537cc 1348 {
dc4871cb 1349 __y = __x;
55826ab6 1350 __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
dc4871cb 1351 _S_left(__x) : _S_right(__x);
d3d526ac 1352 }
55826ab6
FD
1353 return _Res(__x, __y);
1354 }
1355
1356 template<typename _Key, typename _Val, typename _KeyOfValue,
1357 typename _Compare, typename _Alloc>
734f5023 1358#if __cplusplus >= 201103L
55826ab6
FD
1359 template<typename _Arg>
1360#endif
1361 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1362 _Compare, _Alloc>::iterator, bool>
1363 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
734f5023 1364#if __cplusplus >= 201103L
55826ab6
FD
1365 _M_insert_unique(_Arg&& __v)
1366#else
1367 _M_insert_unique(const _Val& __v)
1368#endif
1369 {
1370 typedef pair<iterator, bool> _Res;
1371 pair<_Base_ptr, _Base_ptr> __res
1372 = _M_get_insert_unique_pos(_KeyOfValue()(__v));
1373
1374 if (__res.second)
1375 return _Res(_M_insert_(__res.first, __res.second,
1376 _GLIBCXX_FORWARD(_Arg, __v)),
1377 true);
1378
1379 return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
725dc051 1380 }
d3d526ac 1381
d5e07b79
PC
1382 template<typename _Key, typename _Val, typename _KeyOfValue,
1383 typename _Compare, typename _Alloc>
734f5023 1384#if __cplusplus >= 201103L
e6a05448
PC
1385 template<typename _Arg>
1386#endif
dc4871cb 1387 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
d5e07b79 1388 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
734f5023 1389#if __cplusplus >= 201103L
55826ab6 1390 _M_insert_equal(_Arg&& __v)
e6a05448 1391#else
55826ab6 1392 _M_insert_equal(const _Val& __v)
e6a05448 1393#endif
d5e07b79 1394 {
55826ab6
FD
1395 pair<_Base_ptr, _Base_ptr> __res
1396 = _M_get_insert_equal_pos(_KeyOfValue()(__v));
1397 return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v));
1398 }
1399
1400 template<typename _Key, typename _Val, typename _KeyOfValue,
1401 typename _Compare, typename _Alloc>
1402 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1403 _Compare, _Alloc>::_Base_ptr,
1404 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1405 _Compare, _Alloc>::_Base_ptr>
1406 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1407 _M_get_insert_hint_unique_pos(const_iterator __position,
1408 const key_type& __k)
1409 {
1410 iterator __pos = __position._M_const_cast();
1411 typedef pair<_Base_ptr, _Base_ptr> _Res;
1412
d5e07b79 1413 // end()
55826ab6 1414 if (__pos._M_node == _M_end())
d5e07b79
PC
1415 {
1416 if (size() > 0
55826ab6
FD
1417 && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k))
1418 return _Res(0, _M_rightmost());
d5e07b79 1419 else
55826ab6 1420 return _M_get_insert_unique_pos(__k);
d5e07b79 1421 }
55826ab6 1422 else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node)))
d5e07b79
PC
1423 {
1424 // First, try before...
55826ab6
FD
1425 iterator __before = __pos;
1426 if (__pos._M_node == _M_leftmost()) // begin()
1427 return _Res(_M_leftmost(), _M_leftmost());
1428 else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k))
d5e07b79
PC
1429 {
1430 if (_S_right(__before._M_node) == 0)
55826ab6 1431 return _Res(0, __before._M_node);
d5e07b79 1432 else
55826ab6 1433 return _Res(__pos._M_node, __pos._M_node);
d5e07b79
PC
1434 }
1435 else
55826ab6 1436 return _M_get_insert_unique_pos(__k);
d5e07b79 1437 }
55826ab6 1438 else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
d5e07b79
PC
1439 {
1440 // ... then try after.
55826ab6
FD
1441 iterator __after = __pos;
1442 if (__pos._M_node == _M_rightmost())
1443 return _Res(0, _M_rightmost());
1444 else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node)))
d5e07b79 1445 {
55826ab6
FD
1446 if (_S_right(__pos._M_node) == 0)
1447 return _Res(0, __pos._M_node);
d5e07b79 1448 else
55826ab6 1449 return _Res(__after._M_node, __after._M_node);
d5e07b79
PC
1450 }
1451 else
55826ab6 1452 return _M_get_insert_unique_pos(__k);
d5e07b79
PC
1453 }
1454 else
dc4871cb 1455 // Equivalent keys.
55826ab6 1456 return _Res(__pos._M_node, 0);
d5e07b79
PC
1457 }
1458
ed6814f7 1459 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1460 typename _Compare, typename _Alloc>
734f5023 1461#if __cplusplus >= 201103L
e6a05448
PC
1462 template<typename _Arg>
1463#endif
11aaf40c
PC
1464 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1465 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
734f5023 1466#if __cplusplus >= 201103L
55826ab6 1467 _M_insert_unique_(const_iterator __position, _Arg&& __v)
e6a05448 1468#else
55826ab6 1469 _M_insert_unique_(const_iterator __position, const _Val& __v)
e6a05448 1470#endif
d3d526ac 1471 {
55826ab6
FD
1472 pair<_Base_ptr, _Base_ptr> __res
1473 = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
1474
1475 if (__res.second)
1476 return _M_insert_(__res.first, __res.second,
1477 _GLIBCXX_FORWARD(_Arg, __v));
1478 return iterator(static_cast<_Link_type>(__res.first));
1479 }
1480
1481 template<typename _Key, typename _Val, typename _KeyOfValue,
1482 typename _Compare, typename _Alloc>
1483 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1484 _Compare, _Alloc>::_Base_ptr,
1485 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1486 _Compare, _Alloc>::_Base_ptr>
1487 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1488 _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k)
1489 {
1490 iterator __pos = __position._M_const_cast();
1491 typedef pair<_Base_ptr, _Base_ptr> _Res;
1492
ec5537cc 1493 // end()
55826ab6 1494 if (__pos._M_node == _M_end())
ed6814f7 1495 {
62e67651 1496 if (size() > 0
55826ab6
FD
1497 && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost())))
1498 return _Res(0, _M_rightmost());
d3d526ac 1499 else
55826ab6 1500 return _M_get_insert_equal_pos(__k);
ed6814f7 1501 }
55826ab6 1502 else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
d5e07b79
PC
1503 {
1504 // First, try before...
55826ab6
FD
1505 iterator __before = __pos;
1506 if (__pos._M_node == _M_leftmost()) // begin()
1507 return _Res(_M_leftmost(), _M_leftmost());
1508 else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node)))
d5e07b79
PC
1509 {
1510 if (_S_right(__before._M_node) == 0)
55826ab6 1511 return _Res(0, __before._M_node);
d5e07b79 1512 else
55826ab6 1513 return _Res(__pos._M_node, __pos._M_node);
d5e07b79
PC
1514 }
1515 else
55826ab6 1516 return _M_get_insert_equal_pos(__k);
d5e07b79
PC
1517 }
1518 else
1519 {
1520 // ... then try after.
55826ab6
FD
1521 iterator __after = __pos;
1522 if (__pos._M_node == _M_rightmost())
1523 return _Res(0, _M_rightmost());
1524 else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k))
d5e07b79 1525 {
55826ab6
FD
1526 if (_S_right(__pos._M_node) == 0)
1527 return _Res(0, __pos._M_node);
d5e07b79 1528 else
55826ab6 1529 return _Res(__after._M_node, __after._M_node);
d5e07b79
PC
1530 }
1531 else
55826ab6 1532 return _Res(0, 0);
d5e07b79
PC
1533 }
1534 }
1535
55826ab6
FD
1536 template<typename _Key, typename _Val, typename _KeyOfValue,
1537 typename _Compare, typename _Alloc>
734f5023 1538#if __cplusplus >= 201103L
55826ab6
FD
1539 template<typename _Arg>
1540#endif
1541 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1542 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
734f5023 1543#if __cplusplus >= 201103L
55826ab6
FD
1544 _M_insert_equal_(const_iterator __position, _Arg&& __v)
1545#else
1546 _M_insert_equal_(const_iterator __position, const _Val& __v)
1547#endif
1548 {
1549 pair<_Base_ptr, _Base_ptr> __res
1550 = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
1551
1552 if (__res.second)
1553 return _M_insert_(__res.first, __res.second,
1554 _GLIBCXX_FORWARD(_Arg, __v));
1555
1556 return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
1557 }
1558
734f5023 1559#if __cplusplus >= 201103L
55826ab6
FD
1560 template<typename _Key, typename _Val, typename _KeyOfValue,
1561 typename _Compare, typename _Alloc>
1562 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1563 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1564 _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
1565 {
1566 bool __insert_left = (__x != 0 || __p == _M_end()
1567 || _M_impl._M_key_compare(_S_key(__z),
1568 _S_key(__p)));
1569
1570 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1571 this->_M_impl._M_header);
1572 ++_M_impl._M_node_count;
1573 return iterator(__z);
1574 }
1575
1576 template<typename _Key, typename _Val, typename _KeyOfValue,
1577 typename _Compare, typename _Alloc>
1578 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1579 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1580 _M_insert_lower_node(_Base_ptr __p, _Link_type __z)
1581 {
1582 bool __insert_left = (__p == _M_end()
1583 || !_M_impl._M_key_compare(_S_key(__p),
1584 _S_key(__z)));
1585
1586 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1587 this->_M_impl._M_header);
1588 ++_M_impl._M_node_count;
1589 return iterator(__z);
1590 }
1591
1592 template<typename _Key, typename _Val, typename _KeyOfValue,
1593 typename _Compare, typename _Alloc>
1594 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1595 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1596 _M_insert_equal_lower_node(_Link_type __z)
1597 {
1598 _Link_type __x = _M_begin();
1599 _Link_type __y = _M_end();
1600 while (__x != 0)
1601 {
1602 __y = __x;
1603 __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ?
1604 _S_left(__x) : _S_right(__x);
1605 }
1606 return _M_insert_lower_node(__y, __z);
1607 }
1608
1609 template<typename _Key, typename _Val, typename _KeyOfValue,
1610 typename _Compare, typename _Alloc>
1611 template<typename... _Args>
1612 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1613 _Compare, _Alloc>::iterator, bool>
1614 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1615 _M_emplace_unique(_Args&&... __args)
1616 {
1617 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1618
1619 __try
1620 {
1621 typedef pair<iterator, bool> _Res;
1622 auto __res = _M_get_insert_unique_pos(_S_key(__z));
1623 if (__res.second)
1624 return _Res(_M_insert_node(__res.first, __res.second, __z), true);
1625
1626 _M_destroy_node(__z);
1627 return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
1628 }
1629 __catch(...)
1630 {
1631 _M_destroy_node(__z);
1632 __throw_exception_again;
1633 }
1634 }
1635
1636 template<typename _Key, typename _Val, typename _KeyOfValue,
1637 typename _Compare, typename _Alloc>
1638 template<typename... _Args>
1639 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1640 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1641 _M_emplace_equal(_Args&&... __args)
1642 {
1643 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1644
1645 __try
1646 {
1647 auto __res = _M_get_insert_equal_pos(_S_key(__z));
1648 return _M_insert_node(__res.first, __res.second, __z);
1649 }
1650 __catch(...)
1651 {
1652 _M_destroy_node(__z);
1653 __throw_exception_again;
1654 }
1655 }
1656
1657 template<typename _Key, typename _Val, typename _KeyOfValue,
1658 typename _Compare, typename _Alloc>
1659 template<typename... _Args>
1660 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1661 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1662 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
1663 {
1664 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1665
1666 __try
1667 {
1668 auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z));
1669
1670 if (__res.second)
1671 return _M_insert_node(__res.first, __res.second, __z);
1672
1673 _M_destroy_node(__z);
1674 return iterator(static_cast<_Link_type>(__res.first));
1675 }
1676 __catch(...)
1677 {
1678 _M_destroy_node(__z);
1679 __throw_exception_again;
1680 }
1681 }
1682
1683 template<typename _Key, typename _Val, typename _KeyOfValue,
1684 typename _Compare, typename _Alloc>
1685 template<typename... _Args>
1686 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1687 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1688 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
1689 {
1690 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
1691
1692 __try
1693 {
1694 auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z));
1695
1696 if (__res.second)
1697 return _M_insert_node(__res.first, __res.second, __z);
1698
1699 return _M_insert_equal_lower_node(__z);
1700 }
1701 __catch(...)
1702 {
1703 _M_destroy_node(__z);
1704 __throw_exception_again;
1705 }
1706 }
1707#endif
1708
ed6814f7 1709 template<typename _Key, typename _Val, typename _KoV,
d3d526ac
BK
1710 typename _Cmp, typename _Alloc>
1711 template<class _II>
ed6814f7 1712 void
11aaf40c 1713 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
dc4871cb 1714 _M_insert_unique(_II __first, _II __last)
322821b9 1715 {
11aaf40c 1716 for (; __first != __last; ++__first)
dc4871cb 1717 _M_insert_unique_(end(), *__first);
322821b9 1718 }
725dc051 1719
ed6814f7
BI
1720 template<typename _Key, typename _Val, typename _KoV,
1721 typename _Cmp, typename _Alloc>
d3d526ac 1722 template<class _II>
d5e07b79
PC
1723 void
1724 _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
dc4871cb 1725 _M_insert_equal(_II __first, _II __last)
d5e07b79
PC
1726 {
1727 for (; __first != __last; ++__first)
dc4871cb 1728 _M_insert_equal_(end(), *__first);
d5e07b79 1729 }
725dc051 1730
c105751c
ESR
1731 template<typename _Key, typename _Val, typename _KeyOfValue,
1732 typename _Compare, typename _Alloc>
7606bd11 1733 void
d5e07b79 1734 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
7606bd11 1735 _M_erase_aux(const_iterator __position)
d5e07b79
PC
1736 {
1737 _Link_type __y =
1738 static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
1739 (const_cast<_Base_ptr>(__position._M_node),
1740 this->_M_impl._M_header));
dc4871cb 1741 _M_destroy_node(__y);
d5e07b79
PC
1742 --_M_impl._M_node_count;
1743 }
c105751c 1744
ed6814f7 1745 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1746 typename _Compare, typename _Alloc>
ed6814f7 1747 void
11aaf40c 1748 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
7606bd11 1749 _M_erase_aux(const_iterator __first, const_iterator __last)
d3d526ac
BK
1750 {
1751 if (__first == begin() && __last == end())
1752 clear();
1753 else
a3186d4e
PC
1754 while (__first != __last)
1755 erase(__first++);
725dc051 1756 }
d3d526ac 1757
d5e07b79
PC
1758 template<typename _Key, typename _Val, typename _KeyOfValue,
1759 typename _Compare, typename _Alloc>
7606bd11 1760 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
d5e07b79 1761 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
7606bd11 1762 erase(const _Key& __x)
d5e07b79 1763 {
7606bd11
PC
1764 pair<iterator, iterator> __p = equal_range(__x);
1765 const size_type __old_size = size();
1766 erase(__p.first, __p.second);
1767 return __old_size - size();
d5e07b79
PC
1768 }
1769
ed6814f7 1770 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1771 typename _Compare, typename _Alloc>
ed6814f7 1772 void
11aaf40c 1773 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
ed6814f7
BI
1774 erase(const _Key* __first, const _Key* __last)
1775 {
1776 while (__first != __last)
1777 erase(*__first++);
725dc051 1778 }
d3d526ac 1779
ed6814f7 1780 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1781 typename _Compare, typename _Alloc>
f7e52577
PC
1782 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1783 _Compare, _Alloc>::iterator
11aaf40c
PC
1784 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1785 find(const _Key& __k)
d3d526ac 1786 {
f7e52577 1787 iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
11aaf40c
PC
1788 return (__j == end()
1789 || _M_impl._M_key_compare(__k,
1790 _S_key(__j._M_node))) ? end() : __j;
d3d526ac 1791 }
ed6814f7
BI
1792
1793 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1794 typename _Compare, typename _Alloc>
f7e52577
PC
1795 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1796 _Compare, _Alloc>::const_iterator
11aaf40c 1797 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
d3d526ac
BK
1798 find(const _Key& __k) const
1799 {
f7e52577 1800 const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
dc4871cb
PC
1801 return (__j == end()
1802 || _M_impl._M_key_compare(__k,
1803 _S_key(__j._M_node))) ? end() : __j;
725dc051 1804 }
d3d526ac 1805
ed6814f7 1806 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1807 typename _Compare, typename _Alloc>
11aaf40c
PC
1808 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
1809 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
d3d526ac 1810 count(const _Key& __k) const
322821b9 1811 {
d3d526ac 1812 pair<const_iterator, const_iterator> __p = equal_range(__k);
62e67651 1813 const size_type __n = std::distance(__p.first, __p.second);
d3d526ac 1814 return __n;
322821b9 1815 }
d3d526ac 1816
b8add594 1817 _GLIBCXX_PURE unsigned int
b4c70e89 1818 _Rb_tree_black_count(const _Rb_tree_node_base* __node,
1cf1c842 1819 const _Rb_tree_node_base* __root) throw ();
d3d526ac 1820
ed6814f7 1821 template<typename _Key, typename _Val, typename _KeyOfValue,
d3d526ac 1822 typename _Compare, typename _Alloc>
ed6814f7 1823 bool
d3d526ac
BK
1824 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
1825 {
8bd22a3c
BK
1826 if (_M_impl._M_node_count == 0 || begin() == end())
1827 return _M_impl._M_node_count == 0 && begin() == end()
1828 && this->_M_impl._M_header._M_left == _M_end()
1829 && this->_M_impl._M_header._M_right == _M_end();
ed6814f7 1830
737ab798 1831 unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
ed6814f7 1832 for (const_iterator __it = begin(); __it != end(); ++__it)
737ab798
PC
1833 {
1834 _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
1835 _Const_Link_type __L = _S_left(__x);
1836 _Const_Link_type __R = _S_right(__x);
ed6814f7 1837
737ab798 1838 if (__x->_M_color == _S_red)
ed6814f7 1839 if ((__L && __L->_M_color == _S_red)
737ab798
PC
1840 || (__R && __R->_M_color == _S_red))
1841 return false;
ed6814f7 1842
8bd22a3c 1843 if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
737ab798 1844 return false;
8bd22a3c 1845 if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
737ab798 1846 return false;
ed6814f7 1847
737ab798
PC
1848 if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
1849 return false;
1850 }
ed6814f7 1851
737ab798
PC
1852 if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
1853 return false;
1854 if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
1855 return false;
1856 return true;
d3d526ac 1857 }
3cbc7af0 1858
12ffa228
BK
1859_GLIBCXX_END_NAMESPACE_VERSION
1860} // namespace
725dc051 1861
ed6814f7 1862#endif