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