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