File Coverage

/usr/include/c++/5/bits/stl_tree.h
Criterion Covered Total %
statement 114 120 95.0
branch 28 42 66.6
condition n/a
subroutine n/a
pod n/a
total 142 162 87.6


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