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