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