xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/bits/stl_tree.h (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert // RB tree implementation -*- C++ -*-
2*404b540aSrobert 
3*404b540aSrobert // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
4*404b540aSrobert // Free Software Foundation, Inc.
5*404b540aSrobert //
6*404b540aSrobert // This file is part of the GNU ISO C++ Library.  This library is free
7*404b540aSrobert // software; you can redistribute it and/or modify it under the
8*404b540aSrobert // terms of the GNU General Public License as published by the
9*404b540aSrobert // Free Software Foundation; either version 2, or (at your option)
10*404b540aSrobert // any later version.
11*404b540aSrobert 
12*404b540aSrobert // This library is distributed in the hope that it will be useful,
13*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*404b540aSrobert // GNU General Public License for more details.
16*404b540aSrobert 
17*404b540aSrobert // You should have received a copy of the GNU General Public License along
18*404b540aSrobert // with this library; see the file COPYING.  If not, write to the Free
19*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20*404b540aSrobert // USA.
21*404b540aSrobert 
22*404b540aSrobert // As a special exception, you may use this file as part of a free software
23*404b540aSrobert // library without restriction.  Specifically, if other files instantiate
24*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
25*404b540aSrobert // this file and link it with other files to produce an executable, this
26*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
27*404b540aSrobert // the GNU General Public License.  This exception does not however
28*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
29*404b540aSrobert // the GNU General Public License.
30*404b540aSrobert 
31*404b540aSrobert /*
32*404b540aSrobert  *
33*404b540aSrobert  * Copyright (c) 1996,1997
34*404b540aSrobert  * Silicon Graphics Computer Systems, Inc.
35*404b540aSrobert  *
36*404b540aSrobert  * Permission to use, copy, modify, distribute and sell this software
37*404b540aSrobert  * and its documentation for any purpose is hereby granted without fee,
38*404b540aSrobert  * provided that the above copyright notice appear in all copies and
39*404b540aSrobert  * that both that copyright notice and this permission notice appear
40*404b540aSrobert  * in supporting documentation.  Silicon Graphics makes no
41*404b540aSrobert  * representations about the suitability of this software for any
42*404b540aSrobert  * purpose.  It is provided "as is" without express or implied warranty.
43*404b540aSrobert  *
44*404b540aSrobert  *
45*404b540aSrobert  * Copyright (c) 1994
46*404b540aSrobert  * Hewlett-Packard Company
47*404b540aSrobert  *
48*404b540aSrobert  * Permission to use, copy, modify, distribute and sell this software
49*404b540aSrobert  * and its documentation for any purpose is hereby granted without fee,
50*404b540aSrobert  * provided that the above copyright notice appear in all copies and
51*404b540aSrobert  * that both that copyright notice and this permission notice appear
52*404b540aSrobert  * in supporting documentation.  Hewlett-Packard Company makes no
53*404b540aSrobert  * representations about the suitability of this software for any
54*404b540aSrobert  * purpose.  It is provided "as is" without express or implied warranty.
55*404b540aSrobert  *
56*404b540aSrobert  *
57*404b540aSrobert  */
58*404b540aSrobert 
59*404b540aSrobert /** @file stl_tree.h
60*404b540aSrobert  *  This is an internal header file, included by other library headers.
61*404b540aSrobert  *  You should not attempt to use it directly.
62*404b540aSrobert  */
63*404b540aSrobert 
64*404b540aSrobert #ifndef _TREE_H
65*404b540aSrobert #define _TREE_H 1
66*404b540aSrobert 
67*404b540aSrobert #include <bits/stl_algobase.h>
68*404b540aSrobert #include <bits/allocator.h>
69*404b540aSrobert #include <bits/stl_construct.h>
70*404b540aSrobert #include <bits/stl_function.h>
71*404b540aSrobert #include <bits/cpp_type_traits.h>
72*404b540aSrobert 
73*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(std)
74*404b540aSrobert 
75*404b540aSrobert   // Red-black tree class, designed for use in implementing STL
76*404b540aSrobert   // associative containers (set, multiset, map, and multimap). The
77*404b540aSrobert   // insertion and deletion algorithms are based on those in Cormen,
78*404b540aSrobert   // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
79*404b540aSrobert   // 1990), except that
80*404b540aSrobert   //
81*404b540aSrobert   // (1) the header cell is maintained with links not only to the root
82*404b540aSrobert   // but also to the leftmost node of the tree, to enable constant
83*404b540aSrobert   // time begin(), and to the rightmost node of the tree, to enable
84*404b540aSrobert   // linear time performance when used with the generic set algorithms
85*404b540aSrobert   // (set_union, etc.)
86*404b540aSrobert   //
87*404b540aSrobert   // (2) when a node being deleted has two children its successor node
88*404b540aSrobert   // is relinked into its place, rather than copied, so that the only
89*404b540aSrobert   // iterators invalidated are those referring to the deleted node.
90*404b540aSrobert 
91*404b540aSrobert   enum _Rb_tree_color { _S_red = false, _S_black = true };
92*404b540aSrobert 
93*404b540aSrobert   struct _Rb_tree_node_base
94*404b540aSrobert   {
95*404b540aSrobert     typedef _Rb_tree_node_base* _Base_ptr;
96*404b540aSrobert     typedef const _Rb_tree_node_base* _Const_Base_ptr;
97*404b540aSrobert 
98*404b540aSrobert     _Rb_tree_color	_M_color;
99*404b540aSrobert     _Base_ptr		_M_parent;
100*404b540aSrobert     _Base_ptr		_M_left;
101*404b540aSrobert     _Base_ptr		_M_right;
102*404b540aSrobert 
103*404b540aSrobert     static _Base_ptr
_S_minimum_Rb_tree_node_base104*404b540aSrobert     _S_minimum(_Base_ptr __x)
105*404b540aSrobert     {
106*404b540aSrobert       while (__x->_M_left != 0) __x = __x->_M_left;
107*404b540aSrobert       return __x;
108*404b540aSrobert     }
109*404b540aSrobert 
110*404b540aSrobert     static _Const_Base_ptr
_S_minimum_Rb_tree_node_base111*404b540aSrobert     _S_minimum(_Const_Base_ptr __x)
112*404b540aSrobert     {
113*404b540aSrobert       while (__x->_M_left != 0) __x = __x->_M_left;
114*404b540aSrobert       return __x;
115*404b540aSrobert     }
116*404b540aSrobert 
117*404b540aSrobert     static _Base_ptr
_S_maximum_Rb_tree_node_base118*404b540aSrobert     _S_maximum(_Base_ptr __x)
119*404b540aSrobert     {
120*404b540aSrobert       while (__x->_M_right != 0) __x = __x->_M_right;
121*404b540aSrobert       return __x;
122*404b540aSrobert     }
123*404b540aSrobert 
124*404b540aSrobert     static _Const_Base_ptr
_S_maximum_Rb_tree_node_base125*404b540aSrobert     _S_maximum(_Const_Base_ptr __x)
126*404b540aSrobert     {
127*404b540aSrobert       while (__x->_M_right != 0) __x = __x->_M_right;
128*404b540aSrobert       return __x;
129*404b540aSrobert     }
130*404b540aSrobert   };
131*404b540aSrobert 
132*404b540aSrobert   template<typename _Val>
133*404b540aSrobert     struct _Rb_tree_node : public _Rb_tree_node_base
134*404b540aSrobert     {
135*404b540aSrobert       typedef _Rb_tree_node<_Val>* _Link_type;
136*404b540aSrobert       _Val _M_value_field;
137*404b540aSrobert     };
138*404b540aSrobert 
139*404b540aSrobert   _Rb_tree_node_base*
140*404b540aSrobert   _Rb_tree_increment(_Rb_tree_node_base* __x);
141*404b540aSrobert 
142*404b540aSrobert   const _Rb_tree_node_base*
143*404b540aSrobert   _Rb_tree_increment(const _Rb_tree_node_base* __x);
144*404b540aSrobert 
145*404b540aSrobert   _Rb_tree_node_base*
146*404b540aSrobert   _Rb_tree_decrement(_Rb_tree_node_base* __x);
147*404b540aSrobert 
148*404b540aSrobert   const _Rb_tree_node_base*
149*404b540aSrobert   _Rb_tree_decrement(const _Rb_tree_node_base* __x);
150*404b540aSrobert 
151*404b540aSrobert   template<typename _Tp>
152*404b540aSrobert     struct _Rb_tree_iterator
153*404b540aSrobert     {
154*404b540aSrobert       typedef _Tp  value_type;
155*404b540aSrobert       typedef _Tp& reference;
156*404b540aSrobert       typedef _Tp* pointer;
157*404b540aSrobert 
158*404b540aSrobert       typedef bidirectional_iterator_tag iterator_category;
159*404b540aSrobert       typedef ptrdiff_t                  difference_type;
160*404b540aSrobert 
161*404b540aSrobert       typedef _Rb_tree_iterator<_Tp>        _Self;
162*404b540aSrobert       typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
163*404b540aSrobert       typedef _Rb_tree_node<_Tp>*           _Link_type;
164*404b540aSrobert 
_Rb_tree_iterator_Rb_tree_iterator165*404b540aSrobert       _Rb_tree_iterator()
166*404b540aSrobert       : _M_node() { }
167*404b540aSrobert 
168*404b540aSrobert       explicit
_Rb_tree_iterator_Rb_tree_iterator169*404b540aSrobert       _Rb_tree_iterator(_Link_type __x)
170*404b540aSrobert       : _M_node(__x) { }
171*404b540aSrobert 
172*404b540aSrobert       reference
173*404b540aSrobert       operator*() const
174*404b540aSrobert       { return static_cast<_Link_type>(_M_node)->_M_value_field; }
175*404b540aSrobert 
176*404b540aSrobert       pointer
177*404b540aSrobert       operator->() const
178*404b540aSrobert       { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
179*404b540aSrobert 
180*404b540aSrobert       _Self&
181*404b540aSrobert       operator++()
182*404b540aSrobert       {
183*404b540aSrobert 	_M_node = _Rb_tree_increment(_M_node);
184*404b540aSrobert 	return *this;
185*404b540aSrobert       }
186*404b540aSrobert 
187*404b540aSrobert       _Self
188*404b540aSrobert       operator++(int)
189*404b540aSrobert       {
190*404b540aSrobert 	_Self __tmp = *this;
191*404b540aSrobert 	_M_node = _Rb_tree_increment(_M_node);
192*404b540aSrobert 	return __tmp;
193*404b540aSrobert       }
194*404b540aSrobert 
195*404b540aSrobert       _Self&
196*404b540aSrobert       operator--()
197*404b540aSrobert       {
198*404b540aSrobert 	_M_node = _Rb_tree_decrement(_M_node);
199*404b540aSrobert 	return *this;
200*404b540aSrobert       }
201*404b540aSrobert 
202*404b540aSrobert       _Self
203*404b540aSrobert       operator--(int)
204*404b540aSrobert       {
205*404b540aSrobert 	_Self __tmp = *this;
206*404b540aSrobert 	_M_node = _Rb_tree_decrement(_M_node);
207*404b540aSrobert 	return __tmp;
208*404b540aSrobert       }
209*404b540aSrobert 
210*404b540aSrobert       bool
211*404b540aSrobert       operator==(const _Self& __x) const
212*404b540aSrobert       { return _M_node == __x._M_node; }
213*404b540aSrobert 
214*404b540aSrobert       bool
215*404b540aSrobert       operator!=(const _Self& __x) const
216*404b540aSrobert       { return _M_node != __x._M_node; }
217*404b540aSrobert 
218*404b540aSrobert       _Base_ptr _M_node;
219*404b540aSrobert   };
220*404b540aSrobert 
221*404b540aSrobert   template<typename _Tp>
222*404b540aSrobert     struct _Rb_tree_const_iterator
223*404b540aSrobert     {
224*404b540aSrobert       typedef _Tp        value_type;
225*404b540aSrobert       typedef const _Tp& reference;
226*404b540aSrobert       typedef const _Tp* pointer;
227*404b540aSrobert 
228*404b540aSrobert       typedef _Rb_tree_iterator<_Tp> iterator;
229*404b540aSrobert 
230*404b540aSrobert       typedef bidirectional_iterator_tag iterator_category;
231*404b540aSrobert       typedef ptrdiff_t                  difference_type;
232*404b540aSrobert 
233*404b540aSrobert       typedef _Rb_tree_const_iterator<_Tp>        _Self;
234*404b540aSrobert       typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
235*404b540aSrobert       typedef const _Rb_tree_node<_Tp>*           _Link_type;
236*404b540aSrobert 
_Rb_tree_const_iterator_Rb_tree_const_iterator237*404b540aSrobert       _Rb_tree_const_iterator()
238*404b540aSrobert       : _M_node() { }
239*404b540aSrobert 
240*404b540aSrobert       explicit
_Rb_tree_const_iterator_Rb_tree_const_iterator241*404b540aSrobert       _Rb_tree_const_iterator(_Link_type __x)
242*404b540aSrobert       : _M_node(__x) { }
243*404b540aSrobert 
_Rb_tree_const_iterator_Rb_tree_const_iterator244*404b540aSrobert       _Rb_tree_const_iterator(const iterator& __it)
245*404b540aSrobert       : _M_node(__it._M_node) { }
246*404b540aSrobert 
247*404b540aSrobert       reference
248*404b540aSrobert       operator*() const
249*404b540aSrobert       { return static_cast<_Link_type>(_M_node)->_M_value_field; }
250*404b540aSrobert 
251*404b540aSrobert       pointer
252*404b540aSrobert       operator->() const
253*404b540aSrobert       { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
254*404b540aSrobert 
255*404b540aSrobert       _Self&
256*404b540aSrobert       operator++()
257*404b540aSrobert       {
258*404b540aSrobert 	_M_node = _Rb_tree_increment(_M_node);
259*404b540aSrobert 	return *this;
260*404b540aSrobert       }
261*404b540aSrobert 
262*404b540aSrobert       _Self
263*404b540aSrobert       operator++(int)
264*404b540aSrobert       {
265*404b540aSrobert 	_Self __tmp = *this;
266*404b540aSrobert 	_M_node = _Rb_tree_increment(_M_node);
267*404b540aSrobert 	return __tmp;
268*404b540aSrobert       }
269*404b540aSrobert 
270*404b540aSrobert       _Self&
271*404b540aSrobert       operator--()
272*404b540aSrobert       {
273*404b540aSrobert 	_M_node = _Rb_tree_decrement(_M_node);
274*404b540aSrobert 	return *this;
275*404b540aSrobert       }
276*404b540aSrobert 
277*404b540aSrobert       _Self
278*404b540aSrobert       operator--(int)
279*404b540aSrobert       {
280*404b540aSrobert 	_Self __tmp = *this;
281*404b540aSrobert 	_M_node = _Rb_tree_decrement(_M_node);
282*404b540aSrobert 	return __tmp;
283*404b540aSrobert       }
284*404b540aSrobert 
285*404b540aSrobert       bool
286*404b540aSrobert       operator==(const _Self& __x) const
287*404b540aSrobert       { return _M_node == __x._M_node; }
288*404b540aSrobert 
289*404b540aSrobert       bool
290*404b540aSrobert       operator!=(const _Self& __x) const
291*404b540aSrobert       { return _M_node != __x._M_node; }
292*404b540aSrobert 
293*404b540aSrobert       _Base_ptr _M_node;
294*404b540aSrobert     };
295*404b540aSrobert 
296*404b540aSrobert   template<typename _Val>
297*404b540aSrobert     inline bool
298*404b540aSrobert     operator==(const _Rb_tree_iterator<_Val>& __x,
299*404b540aSrobert                const _Rb_tree_const_iterator<_Val>& __y)
300*404b540aSrobert     { return __x._M_node == __y._M_node; }
301*404b540aSrobert 
302*404b540aSrobert   template<typename _Val>
303*404b540aSrobert     inline bool
304*404b540aSrobert     operator!=(const _Rb_tree_iterator<_Val>& __x,
305*404b540aSrobert                const _Rb_tree_const_iterator<_Val>& __y)
306*404b540aSrobert     { return __x._M_node != __y._M_node; }
307*404b540aSrobert 
308*404b540aSrobert   void
309*404b540aSrobert   _Rb_tree_rotate_left(_Rb_tree_node_base* const __x,
310*404b540aSrobert                        _Rb_tree_node_base*& __root);
311*404b540aSrobert 
312*404b540aSrobert   void
313*404b540aSrobert   _Rb_tree_rotate_right(_Rb_tree_node_base* const __x,
314*404b540aSrobert                         _Rb_tree_node_base*& __root);
315*404b540aSrobert 
316*404b540aSrobert   void
317*404b540aSrobert   _Rb_tree_insert_and_rebalance(const bool __insert_left,
318*404b540aSrobert                                 _Rb_tree_node_base* __x,
319*404b540aSrobert                                 _Rb_tree_node_base* __p,
320*404b540aSrobert                                 _Rb_tree_node_base& __header);
321*404b540aSrobert 
322*404b540aSrobert   _Rb_tree_node_base*
323*404b540aSrobert   _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
324*404b540aSrobert 			       _Rb_tree_node_base& __header);
325*404b540aSrobert 
326*404b540aSrobert 
327*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
328*404b540aSrobert            typename _Compare, typename _Alloc = allocator<_Val> >
329*404b540aSrobert     class _Rb_tree
330*404b540aSrobert     {
331*404b540aSrobert       typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
332*404b540aSrobert               _Node_allocator;
333*404b540aSrobert 
334*404b540aSrobert     protected:
335*404b540aSrobert       typedef _Rb_tree_node_base* _Base_ptr;
336*404b540aSrobert       typedef const _Rb_tree_node_base* _Const_Base_ptr;
337*404b540aSrobert       typedef _Rb_tree_node<_Val> _Rb_tree_node;
338*404b540aSrobert 
339*404b540aSrobert     public:
340*404b540aSrobert       typedef _Key key_type;
341*404b540aSrobert       typedef _Val value_type;
342*404b540aSrobert       typedef value_type* pointer;
343*404b540aSrobert       typedef const value_type* const_pointer;
344*404b540aSrobert       typedef value_type& reference;
345*404b540aSrobert       typedef const value_type& const_reference;
346*404b540aSrobert       typedef _Rb_tree_node* _Link_type;
347*404b540aSrobert       typedef const _Rb_tree_node* _Const_Link_type;
348*404b540aSrobert       typedef size_t size_type;
349*404b540aSrobert       typedef ptrdiff_t difference_type;
350*404b540aSrobert       typedef _Alloc allocator_type;
351*404b540aSrobert 
352*404b540aSrobert       _Node_allocator&
_M_get_Node_allocator()353*404b540aSrobert       _M_get_Node_allocator()
354*404b540aSrobert       { return *static_cast<_Node_allocator*>(&this->_M_impl); }
355*404b540aSrobert 
356*404b540aSrobert       const _Node_allocator&
_M_get_Node_allocator()357*404b540aSrobert       _M_get_Node_allocator() const
358*404b540aSrobert       { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
359*404b540aSrobert 
360*404b540aSrobert       allocator_type
get_allocator()361*404b540aSrobert       get_allocator() const
362*404b540aSrobert       { return allocator_type(_M_get_Node_allocator()); }
363*404b540aSrobert 
364*404b540aSrobert     protected:
365*404b540aSrobert       _Rb_tree_node*
_M_get_node()366*404b540aSrobert       _M_get_node()
367*404b540aSrobert       { return _M_impl._Node_allocator::allocate(1); }
368*404b540aSrobert 
369*404b540aSrobert       void
_M_put_node(_Rb_tree_node * __p)370*404b540aSrobert       _M_put_node(_Rb_tree_node* __p)
371*404b540aSrobert       { _M_impl._Node_allocator::deallocate(__p, 1); }
372*404b540aSrobert 
373*404b540aSrobert       _Link_type
_M_create_node(const value_type & __x)374*404b540aSrobert       _M_create_node(const value_type& __x)
375*404b540aSrobert       {
376*404b540aSrobert 	_Link_type __tmp = _M_get_node();
377*404b540aSrobert 	try
378*404b540aSrobert 	  { get_allocator().construct(&__tmp->_M_value_field, __x); }
379*404b540aSrobert 	catch(...)
380*404b540aSrobert 	  {
381*404b540aSrobert 	    _M_put_node(__tmp);
382*404b540aSrobert 	    __throw_exception_again;
383*404b540aSrobert 	  }
384*404b540aSrobert 	return __tmp;
385*404b540aSrobert       }
386*404b540aSrobert 
387*404b540aSrobert       _Link_type
_M_clone_node(_Const_Link_type __x)388*404b540aSrobert       _M_clone_node(_Const_Link_type __x)
389*404b540aSrobert       {
390*404b540aSrobert 	_Link_type __tmp = _M_create_node(__x->_M_value_field);
391*404b540aSrobert 	__tmp->_M_color = __x->_M_color;
392*404b540aSrobert 	__tmp->_M_left = 0;
393*404b540aSrobert 	__tmp->_M_right = 0;
394*404b540aSrobert 	return __tmp;
395*404b540aSrobert       }
396*404b540aSrobert 
397*404b540aSrobert       void
_M_destroy_node(_Link_type __p)398*404b540aSrobert       _M_destroy_node(_Link_type __p)
399*404b540aSrobert       {
400*404b540aSrobert 	get_allocator().destroy(&__p->_M_value_field);
401*404b540aSrobert 	_M_put_node(__p);
402*404b540aSrobert       }
403*404b540aSrobert 
404*404b540aSrobert     protected:
405*404b540aSrobert       template<typename _Key_compare,
406*404b540aSrobert 	       bool _Is_pod_comparator = std::__is_pod<_Key_compare>::__value>
407*404b540aSrobert         struct _Rb_tree_impl : public _Node_allocator
408*404b540aSrobert         {
409*404b540aSrobert 	  _Key_compare		_M_key_compare;
410*404b540aSrobert 	  _Rb_tree_node_base 	_M_header;
411*404b540aSrobert 	  size_type 		_M_node_count; // Keeps track of size of tree.
412*404b540aSrobert 
413*404b540aSrobert 	  _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
414*404b540aSrobert 			const _Key_compare& __comp = _Key_compare())
_Node_allocator_Rb_tree_impl415*404b540aSrobert 	  : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
416*404b540aSrobert 	    _M_node_count(0)
417*404b540aSrobert 	  {
418*404b540aSrobert 	    this->_M_header._M_color = _S_red;
419*404b540aSrobert 	    this->_M_header._M_parent = 0;
420*404b540aSrobert 	    this->_M_header._M_left = &this->_M_header;
421*404b540aSrobert 	    this->_M_header._M_right = &this->_M_header;
422*404b540aSrobert 	  }
423*404b540aSrobert 	};
424*404b540aSrobert 
425*404b540aSrobert       // Specialization for _Comparison types that are not capable of
426*404b540aSrobert       // being base classes / super classes.
427*404b540aSrobert       template<typename _Key_compare>
428*404b540aSrobert         struct _Rb_tree_impl<_Key_compare, true> : public _Node_allocator
429*404b540aSrobert 	{
430*404b540aSrobert 	  _Key_compare 		_M_key_compare;
431*404b540aSrobert 	  _Rb_tree_node_base 	_M_header;
432*404b540aSrobert 	  size_type 		_M_node_count; // Keeps track of size of tree.
433*404b540aSrobert 
434*404b540aSrobert 	  _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
435*404b540aSrobert 			const _Key_compare& __comp = _Key_compare())
436*404b540aSrobert 	  : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
437*404b540aSrobert 	    _M_node_count(0)
438*404b540aSrobert 	  {
439*404b540aSrobert 	    this->_M_header._M_color = _S_red;
440*404b540aSrobert 	    this->_M_header._M_parent = 0;
441*404b540aSrobert 	    this->_M_header._M_left = &this->_M_header;
442*404b540aSrobert 	    this->_M_header._M_right = &this->_M_header;
443*404b540aSrobert 	  }
444*404b540aSrobert 	};
445*404b540aSrobert 
446*404b540aSrobert       _Rb_tree_impl<_Compare> _M_impl;
447*404b540aSrobert 
448*404b540aSrobert     protected:
449*404b540aSrobert       _Base_ptr&
450*404b540aSrobert       _M_root()
451*404b540aSrobert       { return this->_M_impl._M_header._M_parent; }
452*404b540aSrobert 
453*404b540aSrobert       _Const_Base_ptr
454*404b540aSrobert       _M_root() const
455*404b540aSrobert       { return this->_M_impl._M_header._M_parent; }
456*404b540aSrobert 
457*404b540aSrobert       _Base_ptr&
458*404b540aSrobert       _M_leftmost()
459*404b540aSrobert       { return this->_M_impl._M_header._M_left; }
460*404b540aSrobert 
461*404b540aSrobert       _Const_Base_ptr
462*404b540aSrobert       _M_leftmost() const
463*404b540aSrobert       { return this->_M_impl._M_header._M_left; }
464*404b540aSrobert 
465*404b540aSrobert       _Base_ptr&
466*404b540aSrobert       _M_rightmost()
467*404b540aSrobert       { return this->_M_impl._M_header._M_right; }
468*404b540aSrobert 
469*404b540aSrobert       _Const_Base_ptr
470*404b540aSrobert       _M_rightmost() const
471*404b540aSrobert       { return this->_M_impl._M_header._M_right; }
472*404b540aSrobert 
473*404b540aSrobert       _Link_type
474*404b540aSrobert       _M_begin()
475*404b540aSrobert       { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
476*404b540aSrobert 
477*404b540aSrobert       _Const_Link_type
478*404b540aSrobert       _M_begin() const
479*404b540aSrobert       {
480*404b540aSrobert 	return static_cast<_Const_Link_type>
481*404b540aSrobert 	  (this->_M_impl._M_header._M_parent);
482*404b540aSrobert       }
483*404b540aSrobert 
484*404b540aSrobert       _Link_type
485*404b540aSrobert       _M_end()
486*404b540aSrobert       { return static_cast<_Link_type>(&this->_M_impl._M_header); }
487*404b540aSrobert 
488*404b540aSrobert       _Const_Link_type
489*404b540aSrobert       _M_end() const
490*404b540aSrobert       { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); }
491*404b540aSrobert 
492*404b540aSrobert       static const_reference
493*404b540aSrobert       _S_value(_Const_Link_type __x)
494*404b540aSrobert       { return __x->_M_value_field; }
495*404b540aSrobert 
496*404b540aSrobert       static const _Key&
497*404b540aSrobert       _S_key(_Const_Link_type __x)
498*404b540aSrobert       { return _KeyOfValue()(_S_value(__x)); }
499*404b540aSrobert 
500*404b540aSrobert       static _Link_type
501*404b540aSrobert       _S_left(_Base_ptr __x)
502*404b540aSrobert       { return static_cast<_Link_type>(__x->_M_left); }
503*404b540aSrobert 
504*404b540aSrobert       static _Const_Link_type
505*404b540aSrobert       _S_left(_Const_Base_ptr __x)
506*404b540aSrobert       { return static_cast<_Const_Link_type>(__x->_M_left); }
507*404b540aSrobert 
508*404b540aSrobert       static _Link_type
509*404b540aSrobert       _S_right(_Base_ptr __x)
510*404b540aSrobert       { return static_cast<_Link_type>(__x->_M_right); }
511*404b540aSrobert 
512*404b540aSrobert       static _Const_Link_type
513*404b540aSrobert       _S_right(_Const_Base_ptr __x)
514*404b540aSrobert       { return static_cast<_Const_Link_type>(__x->_M_right); }
515*404b540aSrobert 
516*404b540aSrobert       static const_reference
517*404b540aSrobert       _S_value(_Const_Base_ptr __x)
518*404b540aSrobert       { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
519*404b540aSrobert 
520*404b540aSrobert       static const _Key&
521*404b540aSrobert       _S_key(_Const_Base_ptr __x)
522*404b540aSrobert       { return _KeyOfValue()(_S_value(__x)); }
523*404b540aSrobert 
524*404b540aSrobert       static _Base_ptr
525*404b540aSrobert       _S_minimum(_Base_ptr __x)
526*404b540aSrobert       { return _Rb_tree_node_base::_S_minimum(__x); }
527*404b540aSrobert 
528*404b540aSrobert       static _Const_Base_ptr
529*404b540aSrobert       _S_minimum(_Const_Base_ptr __x)
530*404b540aSrobert       { return _Rb_tree_node_base::_S_minimum(__x); }
531*404b540aSrobert 
532*404b540aSrobert       static _Base_ptr
533*404b540aSrobert       _S_maximum(_Base_ptr __x)
534*404b540aSrobert       { return _Rb_tree_node_base::_S_maximum(__x); }
535*404b540aSrobert 
536*404b540aSrobert       static _Const_Base_ptr
537*404b540aSrobert       _S_maximum(_Const_Base_ptr __x)
538*404b540aSrobert       { return _Rb_tree_node_base::_S_maximum(__x); }
539*404b540aSrobert 
540*404b540aSrobert     public:
541*404b540aSrobert       typedef _Rb_tree_iterator<value_type>       iterator;
542*404b540aSrobert       typedef _Rb_tree_const_iterator<value_type> const_iterator;
543*404b540aSrobert 
544*404b540aSrobert       typedef std::reverse_iterator<iterator>       reverse_iterator;
545*404b540aSrobert       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
546*404b540aSrobert 
547*404b540aSrobert     private:
548*404b540aSrobert       iterator
549*404b540aSrobert       _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
550*404b540aSrobert 
551*404b540aSrobert       // _GLIBCXX_RESOLVE_LIB_DEFECTS
552*404b540aSrobert       // 233. Insertion hints in associative containers.
553*404b540aSrobert       iterator
554*404b540aSrobert       _M_insert_lower(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
555*404b540aSrobert 
556*404b540aSrobert       const_iterator
557*404b540aSrobert       _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __y,
558*404b540aSrobert 		const value_type& __v);
559*404b540aSrobert 
560*404b540aSrobert       _Link_type
561*404b540aSrobert       _M_copy(_Const_Link_type __x, _Link_type __p);
562*404b540aSrobert 
563*404b540aSrobert       void
564*404b540aSrobert       _M_erase(_Link_type __x);
565*404b540aSrobert 
566*404b540aSrobert     public:
567*404b540aSrobert       // allocation/deallocation
568*404b540aSrobert       _Rb_tree()
569*404b540aSrobert       { }
570*404b540aSrobert 
571*404b540aSrobert       _Rb_tree(const _Compare& __comp)
572*404b540aSrobert       : _M_impl(allocator_type(), __comp)
573*404b540aSrobert       { }
574*404b540aSrobert 
575*404b540aSrobert       _Rb_tree(const _Compare& __comp, const allocator_type& __a)
576*404b540aSrobert       : _M_impl(__a, __comp)
577*404b540aSrobert       { }
578*404b540aSrobert 
579*404b540aSrobert       _Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
580*404b540aSrobert       : _M_impl(__x._M_get_Node_allocator(), __x._M_impl._M_key_compare)
581*404b540aSrobert       {
582*404b540aSrobert 	if (__x._M_root() != 0)
583*404b540aSrobert 	  {
584*404b540aSrobert 	    _M_root() = _M_copy(__x._M_begin(), _M_end());
585*404b540aSrobert 	    _M_leftmost() = _S_minimum(_M_root());
586*404b540aSrobert 	    _M_rightmost() = _S_maximum(_M_root());
587*404b540aSrobert 	    _M_impl._M_node_count = __x._M_impl._M_node_count;
588*404b540aSrobert 	  }
589*404b540aSrobert       }
590*404b540aSrobert 
591*404b540aSrobert       ~_Rb_tree()
592*404b540aSrobert       { _M_erase(_M_begin()); }
593*404b540aSrobert 
594*404b540aSrobert       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
595*404b540aSrobert       operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x);
596*404b540aSrobert 
597*404b540aSrobert       // Accessors.
598*404b540aSrobert       _Compare
599*404b540aSrobert       key_comp() const
600*404b540aSrobert       { return _M_impl._M_key_compare; }
601*404b540aSrobert 
602*404b540aSrobert       iterator
603*404b540aSrobert       begin()
604*404b540aSrobert       {
605*404b540aSrobert 	return iterator(static_cast<_Link_type>
606*404b540aSrobert 			(this->_M_impl._M_header._M_left));
607*404b540aSrobert       }
608*404b540aSrobert 
609*404b540aSrobert       const_iterator
610*404b540aSrobert       begin() const
611*404b540aSrobert       {
612*404b540aSrobert 	return const_iterator(static_cast<_Const_Link_type>
613*404b540aSrobert 			      (this->_M_impl._M_header._M_left));
614*404b540aSrobert       }
615*404b540aSrobert 
616*404b540aSrobert       iterator
617*404b540aSrobert       end()
618*404b540aSrobert       { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }
619*404b540aSrobert 
620*404b540aSrobert       const_iterator
621*404b540aSrobert       end() const
622*404b540aSrobert       {
623*404b540aSrobert 	return const_iterator(static_cast<_Const_Link_type>
624*404b540aSrobert 			      (&this->_M_impl._M_header));
625*404b540aSrobert       }
626*404b540aSrobert 
627*404b540aSrobert       reverse_iterator
628*404b540aSrobert       rbegin()
629*404b540aSrobert       { return reverse_iterator(end()); }
630*404b540aSrobert 
631*404b540aSrobert       const_reverse_iterator
632*404b540aSrobert       rbegin() const
633*404b540aSrobert       { return const_reverse_iterator(end()); }
634*404b540aSrobert 
635*404b540aSrobert       reverse_iterator
636*404b540aSrobert       rend()
637*404b540aSrobert       { return reverse_iterator(begin()); }
638*404b540aSrobert 
639*404b540aSrobert       const_reverse_iterator
640*404b540aSrobert       rend() const
641*404b540aSrobert       { return const_reverse_iterator(begin()); }
642*404b540aSrobert 
643*404b540aSrobert       bool
644*404b540aSrobert       empty() const
645*404b540aSrobert       { return _M_impl._M_node_count == 0; }
646*404b540aSrobert 
647*404b540aSrobert       size_type
648*404b540aSrobert       size() const
649*404b540aSrobert       { return _M_impl._M_node_count; }
650*404b540aSrobert 
651*404b540aSrobert       size_type
652*404b540aSrobert       max_size() const
653*404b540aSrobert       { return get_allocator().max_size(); }
654*404b540aSrobert 
655*404b540aSrobert       void
656*404b540aSrobert       swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t);
657*404b540aSrobert 
658*404b540aSrobert       // Insert/erase.
659*404b540aSrobert       pair<iterator, bool>
660*404b540aSrobert       _M_insert_unique(const value_type& __x);
661*404b540aSrobert 
662*404b540aSrobert       iterator
663*404b540aSrobert       _M_insert_equal(const value_type& __x);
664*404b540aSrobert 
665*404b540aSrobert       // _GLIBCXX_RESOLVE_LIB_DEFECTS
666*404b540aSrobert       // 233. Insertion hints in associative containers.
667*404b540aSrobert       iterator
668*404b540aSrobert       _M_insert_equal_lower(const value_type& __x);
669*404b540aSrobert 
670*404b540aSrobert       iterator
671*404b540aSrobert       _M_insert_unique(iterator __position, const value_type& __x);
672*404b540aSrobert 
673*404b540aSrobert       const_iterator
674*404b540aSrobert       _M_insert_unique(const_iterator __position, const value_type& __x);
675*404b540aSrobert 
676*404b540aSrobert       iterator
677*404b540aSrobert       _M_insert_equal(iterator __position, const value_type& __x);
678*404b540aSrobert 
679*404b540aSrobert       const_iterator
680*404b540aSrobert       _M_insert_equal(const_iterator __position, const value_type& __x);
681*404b540aSrobert 
682*404b540aSrobert       template<typename _InputIterator>
683*404b540aSrobert         void
684*404b540aSrobert         _M_insert_unique(_InputIterator __first, _InputIterator __last);
685*404b540aSrobert 
686*404b540aSrobert       template<typename _InputIterator>
687*404b540aSrobert         void
688*404b540aSrobert         _M_insert_equal(_InputIterator __first, _InputIterator __last);
689*404b540aSrobert 
690*404b540aSrobert       void
691*404b540aSrobert       erase(iterator __position);
692*404b540aSrobert 
693*404b540aSrobert       void
694*404b540aSrobert       erase(const_iterator __position);
695*404b540aSrobert 
696*404b540aSrobert       size_type
697*404b540aSrobert       erase(const key_type& __x);
698*404b540aSrobert 
699*404b540aSrobert       void
700*404b540aSrobert       erase(iterator __first, iterator __last);
701*404b540aSrobert 
702*404b540aSrobert       void
703*404b540aSrobert       erase(const_iterator __first, const_iterator __last);
704*404b540aSrobert 
705*404b540aSrobert       void
706*404b540aSrobert       erase(const key_type* __first, const key_type* __last);
707*404b540aSrobert 
708*404b540aSrobert       void
709*404b540aSrobert       clear()
710*404b540aSrobert       {
711*404b540aSrobert         _M_erase(_M_begin());
712*404b540aSrobert         _M_leftmost() = _M_end();
713*404b540aSrobert         _M_root() = 0;
714*404b540aSrobert         _M_rightmost() = _M_end();
715*404b540aSrobert         _M_impl._M_node_count = 0;
716*404b540aSrobert       }
717*404b540aSrobert 
718*404b540aSrobert       // Set operations.
719*404b540aSrobert       iterator
720*404b540aSrobert       find(const key_type& __x);
721*404b540aSrobert 
722*404b540aSrobert       const_iterator
723*404b540aSrobert       find(const key_type& __x) const;
724*404b540aSrobert 
725*404b540aSrobert       size_type
726*404b540aSrobert       count(const key_type& __x) const;
727*404b540aSrobert 
728*404b540aSrobert       iterator
729*404b540aSrobert       lower_bound(const key_type& __x);
730*404b540aSrobert 
731*404b540aSrobert       const_iterator
732*404b540aSrobert       lower_bound(const key_type& __x) const;
733*404b540aSrobert 
734*404b540aSrobert       iterator
735*404b540aSrobert       upper_bound(const key_type& __x);
736*404b540aSrobert 
737*404b540aSrobert       const_iterator
738*404b540aSrobert       upper_bound(const key_type& __x) const;
739*404b540aSrobert 
740*404b540aSrobert       pair<iterator,iterator>
741*404b540aSrobert       equal_range(const key_type& __x);
742*404b540aSrobert 
743*404b540aSrobert       pair<const_iterator, const_iterator>
744*404b540aSrobert       equal_range(const key_type& __x) const;
745*404b540aSrobert 
746*404b540aSrobert       // Debugging.
747*404b540aSrobert       bool
748*404b540aSrobert       __rb_verify() const;
749*404b540aSrobert     };
750*404b540aSrobert 
751*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
752*404b540aSrobert            typename _Compare, typename _Alloc>
753*404b540aSrobert     inline bool
754*404b540aSrobert     operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
755*404b540aSrobert 	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
756*404b540aSrobert     {
757*404b540aSrobert       return __x.size() == __y.size()
758*404b540aSrobert 	     && std::equal(__x.begin(), __x.end(), __y.begin());
759*404b540aSrobert     }
760*404b540aSrobert 
761*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
762*404b540aSrobert            typename _Compare, typename _Alloc>
763*404b540aSrobert     inline bool
764*404b540aSrobert     operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
765*404b540aSrobert 	      const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
766*404b540aSrobert     {
767*404b540aSrobert       return std::lexicographical_compare(__x.begin(), __x.end(),
768*404b540aSrobert 					  __y.begin(), __y.end());
769*404b540aSrobert     }
770*404b540aSrobert 
771*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
772*404b540aSrobert            typename _Compare, typename _Alloc>
773*404b540aSrobert     inline bool
774*404b540aSrobert     operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
775*404b540aSrobert 	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
776*404b540aSrobert     { return !(__x == __y); }
777*404b540aSrobert 
778*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
779*404b540aSrobert            typename _Compare, typename _Alloc>
780*404b540aSrobert     inline bool
781*404b540aSrobert     operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
782*404b540aSrobert 	      const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
783*404b540aSrobert     { return __y < __x; }
784*404b540aSrobert 
785*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
786*404b540aSrobert            typename _Compare, typename _Alloc>
787*404b540aSrobert     inline bool
788*404b540aSrobert     operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
789*404b540aSrobert 	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
790*404b540aSrobert     { return !(__y < __x); }
791*404b540aSrobert 
792*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
793*404b540aSrobert            typename _Compare, typename _Alloc>
794*404b540aSrobert     inline bool
795*404b540aSrobert     operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
796*404b540aSrobert 	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
797*404b540aSrobert     { return !(__x < __y); }
798*404b540aSrobert 
799*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
800*404b540aSrobert            typename _Compare, typename _Alloc>
801*404b540aSrobert     inline void
802*404b540aSrobert     swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
803*404b540aSrobert 	 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
804*404b540aSrobert     { __x.swap(__y); }
805*404b540aSrobert 
806*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
807*404b540aSrobert            typename _Compare, typename _Alloc>
808*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
809*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
810*404b540aSrobert     operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
811*404b540aSrobert     {
812*404b540aSrobert       if (this != &__x)
813*404b540aSrobert 	{
814*404b540aSrobert 	  // Note that _Key may be a constant type.
815*404b540aSrobert 	  clear();
816*404b540aSrobert 	  _M_impl._M_key_compare = __x._M_impl._M_key_compare;
817*404b540aSrobert 	  if (__x._M_root() != 0)
818*404b540aSrobert 	    {
819*404b540aSrobert 	      _M_root() = _M_copy(__x._M_begin(), _M_end());
820*404b540aSrobert 	      _M_leftmost() = _S_minimum(_M_root());
821*404b540aSrobert 	      _M_rightmost() = _S_maximum(_M_root());
822*404b540aSrobert 	      _M_impl._M_node_count = __x._M_impl._M_node_count;
823*404b540aSrobert 	    }
824*404b540aSrobert 	}
825*404b540aSrobert       return *this;
826*404b540aSrobert     }
827*404b540aSrobert 
828*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
829*404b540aSrobert            typename _Compare, typename _Alloc>
830*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
831*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
832*404b540aSrobert     _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
833*404b540aSrobert     {
834*404b540aSrobert       bool __insert_left = (__x != 0 || __p == _M_end()
835*404b540aSrobert 			    || _M_impl._M_key_compare(_KeyOfValue()(__v),
836*404b540aSrobert 						      _S_key(__p)));
837*404b540aSrobert 
838*404b540aSrobert       _Link_type __z = _M_create_node(__v);
839*404b540aSrobert 
840*404b540aSrobert       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
841*404b540aSrobert 				    this->_M_impl._M_header);
842*404b540aSrobert       ++_M_impl._M_node_count;
843*404b540aSrobert       return iterator(__z);
844*404b540aSrobert     }
845*404b540aSrobert 
846*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
847*404b540aSrobert            typename _Compare, typename _Alloc>
848*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
849*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
850*404b540aSrobert     _M_insert_lower(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
851*404b540aSrobert     {
852*404b540aSrobert       bool __insert_left = (__x != 0 || __p == _M_end()
853*404b540aSrobert 			    || !_M_impl._M_key_compare(_S_key(__p),
854*404b540aSrobert 						       _KeyOfValue()(__v)));
855*404b540aSrobert 
856*404b540aSrobert       _Link_type __z = _M_create_node(__v);
857*404b540aSrobert 
858*404b540aSrobert       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
859*404b540aSrobert 				    this->_M_impl._M_header);
860*404b540aSrobert       ++_M_impl._M_node_count;
861*404b540aSrobert       return iterator(__z);
862*404b540aSrobert     }
863*404b540aSrobert 
864*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
865*404b540aSrobert            typename _Compare, typename _Alloc>
866*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
867*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
868*404b540aSrobert     _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v)
869*404b540aSrobert     {
870*404b540aSrobert       bool __insert_left = (__x != 0 || __p == _M_end()
871*404b540aSrobert 			    || _M_impl._M_key_compare(_KeyOfValue()(__v),
872*404b540aSrobert 						      _S_key(__p)));
873*404b540aSrobert 
874*404b540aSrobert       _Link_type __z = _M_create_node(__v);
875*404b540aSrobert 
876*404b540aSrobert       _Rb_tree_insert_and_rebalance(__insert_left, __z,
877*404b540aSrobert 				    const_cast<_Base_ptr>(__p),
878*404b540aSrobert 				    this->_M_impl._M_header);
879*404b540aSrobert       ++_M_impl._M_node_count;
880*404b540aSrobert       return const_iterator(__z);
881*404b540aSrobert     }
882*404b540aSrobert 
883*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
884*404b540aSrobert            typename _Compare, typename _Alloc>
885*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
886*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
887*404b540aSrobert     _M_insert_equal(const _Val& __v)
888*404b540aSrobert     {
889*404b540aSrobert       _Link_type __x = _M_begin();
890*404b540aSrobert       _Link_type __y = _M_end();
891*404b540aSrobert       while (__x != 0)
892*404b540aSrobert 	{
893*404b540aSrobert 	  __y = __x;
894*404b540aSrobert 	  __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
895*404b540aSrobert 	        _S_left(__x) : _S_right(__x);
896*404b540aSrobert 	}
897*404b540aSrobert       return _M_insert(__x, __y, __v);
898*404b540aSrobert     }
899*404b540aSrobert 
900*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
901*404b540aSrobert            typename _Compare, typename _Alloc>
902*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
903*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
904*404b540aSrobert     _M_insert_equal_lower(const _Val& __v)
905*404b540aSrobert     {
906*404b540aSrobert       _Link_type __x = _M_begin();
907*404b540aSrobert       _Link_type __y = _M_end();
908*404b540aSrobert       while (__x != 0)
909*404b540aSrobert 	{
910*404b540aSrobert 	  __y = __x;
911*404b540aSrobert 	  __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
912*404b540aSrobert 	        _S_left(__x) : _S_right(__x);
913*404b540aSrobert 	}
914*404b540aSrobert       return _M_insert_lower(__x, __y, __v);
915*404b540aSrobert     }
916*404b540aSrobert 
917*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
918*404b540aSrobert            typename _Compare, typename _Alloc>
919*404b540aSrobert     void
920*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
921*404b540aSrobert     swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
922*404b540aSrobert     {
923*404b540aSrobert       if (_M_root() == 0)
924*404b540aSrobert 	{
925*404b540aSrobert 	  if (__t._M_root() != 0)
926*404b540aSrobert 	    {
927*404b540aSrobert 	      _M_root() = __t._M_root();
928*404b540aSrobert 	      _M_leftmost() = __t._M_leftmost();
929*404b540aSrobert 	      _M_rightmost() = __t._M_rightmost();
930*404b540aSrobert 	      _M_root()->_M_parent = _M_end();
931*404b540aSrobert 
932*404b540aSrobert 	      __t._M_root() = 0;
933*404b540aSrobert 	      __t._M_leftmost() = __t._M_end();
934*404b540aSrobert 	      __t._M_rightmost() = __t._M_end();
935*404b540aSrobert 	    }
936*404b540aSrobert 	}
937*404b540aSrobert       else if (__t._M_root() == 0)
938*404b540aSrobert 	{
939*404b540aSrobert 	  __t._M_root() = _M_root();
940*404b540aSrobert 	  __t._M_leftmost() = _M_leftmost();
941*404b540aSrobert 	  __t._M_rightmost() = _M_rightmost();
942*404b540aSrobert 	  __t._M_root()->_M_parent = __t._M_end();
943*404b540aSrobert 
944*404b540aSrobert 	  _M_root() = 0;
945*404b540aSrobert 	  _M_leftmost() = _M_end();
946*404b540aSrobert 	  _M_rightmost() = _M_end();
947*404b540aSrobert 	}
948*404b540aSrobert       else
949*404b540aSrobert 	{
950*404b540aSrobert 	  std::swap(_M_root(),__t._M_root());
951*404b540aSrobert 	  std::swap(_M_leftmost(),__t._M_leftmost());
952*404b540aSrobert 	  std::swap(_M_rightmost(),__t._M_rightmost());
953*404b540aSrobert 
954*404b540aSrobert 	  _M_root()->_M_parent = _M_end();
955*404b540aSrobert 	  __t._M_root()->_M_parent = __t._M_end();
956*404b540aSrobert 	}
957*404b540aSrobert       // No need to swap header's color as it does not change.
958*404b540aSrobert       std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
959*404b540aSrobert       std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
960*404b540aSrobert 
961*404b540aSrobert       // _GLIBCXX_RESOLVE_LIB_DEFECTS
962*404b540aSrobert       // 431. Swapping containers with unequal allocators.
963*404b540aSrobert       std::__alloc_swap<_Node_allocator>::
964*404b540aSrobert 	_S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
965*404b540aSrobert     }
966*404b540aSrobert 
967*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
968*404b540aSrobert            typename _Compare, typename _Alloc>
969*404b540aSrobert     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
970*404b540aSrobert 			   _Compare, _Alloc>::iterator, bool>
971*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
972*404b540aSrobert     _M_insert_unique(const _Val& __v)
973*404b540aSrobert     {
974*404b540aSrobert       _Link_type __x = _M_begin();
975*404b540aSrobert       _Link_type __y = _M_end();
976*404b540aSrobert       bool __comp = true;
977*404b540aSrobert       while (__x != 0)
978*404b540aSrobert 	{
979*404b540aSrobert 	  __y = __x;
980*404b540aSrobert 	  __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x));
981*404b540aSrobert 	  __x = __comp ? _S_left(__x) : _S_right(__x);
982*404b540aSrobert 	}
983*404b540aSrobert       iterator __j = iterator(__y);
984*404b540aSrobert       if (__comp)
985*404b540aSrobert 	if (__j == begin())
986*404b540aSrobert 	  return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
987*404b540aSrobert 	else
988*404b540aSrobert 	  --__j;
989*404b540aSrobert       if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
990*404b540aSrobert 	return pair<iterator, bool>(_M_insert(__x, __y, __v), true);
991*404b540aSrobert       return pair<iterator, bool>(__j, false);
992*404b540aSrobert     }
993*404b540aSrobert 
994*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
995*404b540aSrobert            typename _Compare, typename _Alloc>
996*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
997*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
998*404b540aSrobert     _M_insert_unique(iterator __position, const _Val& __v)
999*404b540aSrobert     {
1000*404b540aSrobert       // end()
1001*404b540aSrobert       if (__position._M_node == _M_end())
1002*404b540aSrobert 	{
1003*404b540aSrobert 	  if (size() > 0
1004*404b540aSrobert 	      && _M_impl._M_key_compare(_S_key(_M_rightmost()),
1005*404b540aSrobert 					_KeyOfValue()(__v)))
1006*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1007*404b540aSrobert 	  else
1008*404b540aSrobert 	    return _M_insert_unique(__v).first;
1009*404b540aSrobert 	}
1010*404b540aSrobert       else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
1011*404b540aSrobert 				      _S_key(__position._M_node)))
1012*404b540aSrobert 	{
1013*404b540aSrobert 	  // First, try before...
1014*404b540aSrobert 	  iterator __before = __position;
1015*404b540aSrobert 	  if (__position._M_node == _M_leftmost()) // begin()
1016*404b540aSrobert 	    return _M_insert(_M_leftmost(), _M_leftmost(), __v);
1017*404b540aSrobert 	  else if (_M_impl._M_key_compare(_S_key((--__before)._M_node),
1018*404b540aSrobert 					  _KeyOfValue()(__v)))
1019*404b540aSrobert 	    {
1020*404b540aSrobert 	      if (_S_right(__before._M_node) == 0)
1021*404b540aSrobert 		return _M_insert(0, __before._M_node, __v);
1022*404b540aSrobert 	      else
1023*404b540aSrobert 		return _M_insert(__position._M_node,
1024*404b540aSrobert 				 __position._M_node, __v);
1025*404b540aSrobert 	    }
1026*404b540aSrobert 	  else
1027*404b540aSrobert 	    return _M_insert_unique(__v).first;
1028*404b540aSrobert 	}
1029*404b540aSrobert       else if (_M_impl._M_key_compare(_S_key(__position._M_node),
1030*404b540aSrobert 				      _KeyOfValue()(__v)))
1031*404b540aSrobert 	{
1032*404b540aSrobert 	  // ... then try after.
1033*404b540aSrobert 	  iterator __after = __position;
1034*404b540aSrobert 	  if (__position._M_node == _M_rightmost())
1035*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1036*404b540aSrobert 	  else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
1037*404b540aSrobert 					  _S_key((++__after)._M_node)))
1038*404b540aSrobert 	    {
1039*404b540aSrobert 	      if (_S_right(__position._M_node) == 0)
1040*404b540aSrobert 		return _M_insert(0, __position._M_node, __v);
1041*404b540aSrobert 	      else
1042*404b540aSrobert 		return _M_insert(__after._M_node, __after._M_node, __v);
1043*404b540aSrobert 	    }
1044*404b540aSrobert 	  else
1045*404b540aSrobert 	    return _M_insert_unique(__v).first;
1046*404b540aSrobert 	}
1047*404b540aSrobert       else
1048*404b540aSrobert 	return __position; // Equivalent keys.
1049*404b540aSrobert     }
1050*404b540aSrobert 
1051*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1052*404b540aSrobert            typename _Compare, typename _Alloc>
1053*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
1054*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1055*404b540aSrobert     _M_insert_unique(const_iterator __position, const _Val& __v)
1056*404b540aSrobert     {
1057*404b540aSrobert       // end()
1058*404b540aSrobert       if (__position._M_node == _M_end())
1059*404b540aSrobert 	{
1060*404b540aSrobert 	  if (size() > 0
1061*404b540aSrobert 	      && _M_impl._M_key_compare(_S_key(_M_rightmost()),
1062*404b540aSrobert 					_KeyOfValue()(__v)))
1063*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1064*404b540aSrobert 	  else
1065*404b540aSrobert 	    return const_iterator(_M_insert_unique(__v).first);
1066*404b540aSrobert 	}
1067*404b540aSrobert       else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
1068*404b540aSrobert 				      _S_key(__position._M_node)))
1069*404b540aSrobert 	{
1070*404b540aSrobert 	  // First, try before...
1071*404b540aSrobert 	  const_iterator __before = __position;
1072*404b540aSrobert 	  if (__position._M_node == _M_leftmost()) // begin()
1073*404b540aSrobert 	    return _M_insert(_M_leftmost(), _M_leftmost(), __v);
1074*404b540aSrobert 	  else if (_M_impl._M_key_compare(_S_key((--__before)._M_node),
1075*404b540aSrobert 					  _KeyOfValue()(__v)))
1076*404b540aSrobert 	    {
1077*404b540aSrobert 	      if (_S_right(__before._M_node) == 0)
1078*404b540aSrobert 		return _M_insert(0, __before._M_node, __v);
1079*404b540aSrobert 	      else
1080*404b540aSrobert 		return _M_insert(__position._M_node,
1081*404b540aSrobert 				 __position._M_node, __v);
1082*404b540aSrobert 	    }
1083*404b540aSrobert 	  else
1084*404b540aSrobert 	    return const_iterator(_M_insert_unique(__v).first);
1085*404b540aSrobert 	}
1086*404b540aSrobert       else if (_M_impl._M_key_compare(_S_key(__position._M_node),
1087*404b540aSrobert 				      _KeyOfValue()(__v)))
1088*404b540aSrobert 	{
1089*404b540aSrobert 	  // ... then try after.
1090*404b540aSrobert 	  const_iterator __after = __position;
1091*404b540aSrobert 	  if (__position._M_node == _M_rightmost())
1092*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1093*404b540aSrobert 	  else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
1094*404b540aSrobert 					  _S_key((++__after)._M_node)))
1095*404b540aSrobert 	    {
1096*404b540aSrobert 	      if (_S_right(__position._M_node) == 0)
1097*404b540aSrobert 		return _M_insert(0, __position._M_node, __v);
1098*404b540aSrobert 	      else
1099*404b540aSrobert 		return _M_insert(__after._M_node, __after._M_node, __v);
1100*404b540aSrobert 	    }
1101*404b540aSrobert 	  else
1102*404b540aSrobert 	    return const_iterator(_M_insert_unique(__v).first);
1103*404b540aSrobert 	}
1104*404b540aSrobert       else
1105*404b540aSrobert 	return __position; // Equivalent keys.
1106*404b540aSrobert     }
1107*404b540aSrobert 
1108*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1109*404b540aSrobert            typename _Compare, typename _Alloc>
1110*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1111*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1112*404b540aSrobert     _M_insert_equal(iterator __position, const _Val& __v)
1113*404b540aSrobert     {
1114*404b540aSrobert       // end()
1115*404b540aSrobert       if (__position._M_node == _M_end())
1116*404b540aSrobert 	{
1117*404b540aSrobert 	  if (size() > 0
1118*404b540aSrobert 	      && !_M_impl._M_key_compare(_KeyOfValue()(__v),
1119*404b540aSrobert 					 _S_key(_M_rightmost())))
1120*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1121*404b540aSrobert 	  else
1122*404b540aSrobert 	    return _M_insert_equal(__v);
1123*404b540aSrobert 	}
1124*404b540aSrobert       else if (!_M_impl._M_key_compare(_S_key(__position._M_node),
1125*404b540aSrobert 				       _KeyOfValue()(__v)))
1126*404b540aSrobert 	{
1127*404b540aSrobert 	  // First, try before...
1128*404b540aSrobert 	  iterator __before = __position;
1129*404b540aSrobert 	  if (__position._M_node == _M_leftmost()) // begin()
1130*404b540aSrobert 	    return _M_insert(_M_leftmost(), _M_leftmost(), __v);
1131*404b540aSrobert 	  else if (!_M_impl._M_key_compare(_KeyOfValue()(__v),
1132*404b540aSrobert 					   _S_key((--__before)._M_node)))
1133*404b540aSrobert 	    {
1134*404b540aSrobert 	      if (_S_right(__before._M_node) == 0)
1135*404b540aSrobert 		return _M_insert(0, __before._M_node, __v);
1136*404b540aSrobert 	      else
1137*404b540aSrobert 		return _M_insert(__position._M_node,
1138*404b540aSrobert 				 __position._M_node, __v);
1139*404b540aSrobert 	    }
1140*404b540aSrobert 	  else
1141*404b540aSrobert 	    return _M_insert_equal(__v);
1142*404b540aSrobert 	}
1143*404b540aSrobert       else
1144*404b540aSrobert 	{
1145*404b540aSrobert 	  // ... then try after.
1146*404b540aSrobert 	  iterator __after = __position;
1147*404b540aSrobert 	  if (__position._M_node == _M_rightmost())
1148*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1149*404b540aSrobert 	  else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node),
1150*404b540aSrobert 					   _KeyOfValue()(__v)))
1151*404b540aSrobert 	    {
1152*404b540aSrobert 	      if (_S_right(__position._M_node) == 0)
1153*404b540aSrobert 		return _M_insert(0, __position._M_node, __v);
1154*404b540aSrobert 	      else
1155*404b540aSrobert 		return _M_insert(__after._M_node, __after._M_node, __v);
1156*404b540aSrobert 	    }
1157*404b540aSrobert 	  else
1158*404b540aSrobert 	    return _M_insert_equal_lower(__v);
1159*404b540aSrobert 	}
1160*404b540aSrobert     }
1161*404b540aSrobert 
1162*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1163*404b540aSrobert            typename _Compare, typename _Alloc>
1164*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
1165*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1166*404b540aSrobert     _M_insert_equal(const_iterator __position, const _Val& __v)
1167*404b540aSrobert     {
1168*404b540aSrobert       // end()
1169*404b540aSrobert       if (__position._M_node == _M_end())
1170*404b540aSrobert 	{
1171*404b540aSrobert 	  if (size() > 0
1172*404b540aSrobert 	      && !_M_impl._M_key_compare(_KeyOfValue()(__v),
1173*404b540aSrobert 					 _S_key(_M_rightmost())))
1174*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1175*404b540aSrobert 	  else
1176*404b540aSrobert 	    return const_iterator(_M_insert_equal(__v));
1177*404b540aSrobert 	}
1178*404b540aSrobert       else if (!_M_impl._M_key_compare(_S_key(__position._M_node),
1179*404b540aSrobert 				       _KeyOfValue()(__v)))
1180*404b540aSrobert 	{
1181*404b540aSrobert 	  // First, try before...
1182*404b540aSrobert 	  const_iterator __before = __position;
1183*404b540aSrobert 	  if (__position._M_node == _M_leftmost()) // begin()
1184*404b540aSrobert 	    return _M_insert(_M_leftmost(), _M_leftmost(), __v);
1185*404b540aSrobert 	  else if (!_M_impl._M_key_compare(_KeyOfValue()(__v),
1186*404b540aSrobert 					   _S_key((--__before)._M_node)))
1187*404b540aSrobert 	    {
1188*404b540aSrobert 	      if (_S_right(__before._M_node) == 0)
1189*404b540aSrobert 		return _M_insert(0, __before._M_node, __v);
1190*404b540aSrobert 	      else
1191*404b540aSrobert 		return _M_insert(__position._M_node,
1192*404b540aSrobert 				 __position._M_node, __v);
1193*404b540aSrobert 	    }
1194*404b540aSrobert 	  else
1195*404b540aSrobert 	    return const_iterator(_M_insert_equal(__v));
1196*404b540aSrobert 	}
1197*404b540aSrobert       else
1198*404b540aSrobert 	{
1199*404b540aSrobert 	  // ... then try after.
1200*404b540aSrobert 	  const_iterator __after = __position;
1201*404b540aSrobert 	  if (__position._M_node == _M_rightmost())
1202*404b540aSrobert 	    return _M_insert(0, _M_rightmost(), __v);
1203*404b540aSrobert 	  else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node),
1204*404b540aSrobert 					   _KeyOfValue()(__v)))
1205*404b540aSrobert 	    {
1206*404b540aSrobert 	      if (_S_right(__position._M_node) == 0)
1207*404b540aSrobert 		return _M_insert(0, __position._M_node, __v);
1208*404b540aSrobert 	      else
1209*404b540aSrobert 		return _M_insert(__after._M_node, __after._M_node, __v);
1210*404b540aSrobert 	    }
1211*404b540aSrobert 	  else
1212*404b540aSrobert 	    return const_iterator(_M_insert_equal_lower(__v));
1213*404b540aSrobert 	}
1214*404b540aSrobert     }
1215*404b540aSrobert 
1216*404b540aSrobert   template<typename _Key, typename _Val, typename _KoV,
1217*404b540aSrobert            typename _Cmp, typename _Alloc>
1218*404b540aSrobert     template<class _II>
1219*404b540aSrobert       void
1220*404b540aSrobert       _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
1221*404b540aSrobert       _M_insert_equal(_II __first, _II __last)
1222*404b540aSrobert       {
1223*404b540aSrobert 	for (; __first != __last; ++__first)
1224*404b540aSrobert 	  _M_insert_equal(end(), *__first);
1225*404b540aSrobert       }
1226*404b540aSrobert 
1227*404b540aSrobert   template<typename _Key, typename _Val, typename _KoV,
1228*404b540aSrobert            typename _Cmp, typename _Alloc>
1229*404b540aSrobert     template<class _II>
1230*404b540aSrobert       void
1231*404b540aSrobert       _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
1232*404b540aSrobert       _M_insert_unique(_II __first, _II __last)
1233*404b540aSrobert       {
1234*404b540aSrobert 	for (; __first != __last; ++__first)
1235*404b540aSrobert 	  _M_insert_unique(end(), *__first);
1236*404b540aSrobert       }
1237*404b540aSrobert 
1238*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1239*404b540aSrobert            typename _Compare, typename _Alloc>
1240*404b540aSrobert     inline void
1241*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1242*404b540aSrobert     erase(iterator __position)
1243*404b540aSrobert     {
1244*404b540aSrobert       _Link_type __y =
1245*404b540aSrobert 	static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
1246*404b540aSrobert 				(__position._M_node,
1247*404b540aSrobert 				 this->_M_impl._M_header));
1248*404b540aSrobert       _M_destroy_node(__y);
1249*404b540aSrobert       --_M_impl._M_node_count;
1250*404b540aSrobert     }
1251*404b540aSrobert 
1252*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1253*404b540aSrobert            typename _Compare, typename _Alloc>
1254*404b540aSrobert     inline void
1255*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1256*404b540aSrobert     erase(const_iterator __position)
1257*404b540aSrobert     {
1258*404b540aSrobert       _Link_type __y =
1259*404b540aSrobert 	static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
1260*404b540aSrobert 				(const_cast<_Base_ptr>(__position._M_node),
1261*404b540aSrobert 				 this->_M_impl._M_header));
1262*404b540aSrobert       _M_destroy_node(__y);
1263*404b540aSrobert       --_M_impl._M_node_count;
1264*404b540aSrobert     }
1265*404b540aSrobert 
1266*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1267*404b540aSrobert            typename _Compare, typename _Alloc>
1268*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
1269*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1270*404b540aSrobert     erase(const _Key& __x)
1271*404b540aSrobert     {
1272*404b540aSrobert       pair<iterator, iterator> __p = equal_range(__x);
1273*404b540aSrobert       const size_type __old_size = size();
1274*404b540aSrobert       erase(__p.first, __p.second);
1275*404b540aSrobert       return __old_size - size();
1276*404b540aSrobert     }
1277*404b540aSrobert 
1278*404b540aSrobert   template<typename _Key, typename _Val, typename _KoV,
1279*404b540aSrobert            typename _Compare, typename _Alloc>
1280*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
1281*404b540aSrobert     _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
1282*404b540aSrobert     _M_copy(_Const_Link_type __x, _Link_type __p)
1283*404b540aSrobert     {
1284*404b540aSrobert       // Structural copy.  __x and __p must be non-null.
1285*404b540aSrobert       _Link_type __top = _M_clone_node(__x);
1286*404b540aSrobert       __top->_M_parent = __p;
1287*404b540aSrobert 
1288*404b540aSrobert       try
1289*404b540aSrobert 	{
1290*404b540aSrobert 	  if (__x->_M_right)
1291*404b540aSrobert 	    __top->_M_right = _M_copy(_S_right(__x), __top);
1292*404b540aSrobert 	  __p = __top;
1293*404b540aSrobert 	  __x = _S_left(__x);
1294*404b540aSrobert 
1295*404b540aSrobert 	  while (__x != 0)
1296*404b540aSrobert 	    {
1297*404b540aSrobert 	      _Link_type __y = _M_clone_node(__x);
1298*404b540aSrobert 	      __p->_M_left = __y;
1299*404b540aSrobert 	      __y->_M_parent = __p;
1300*404b540aSrobert 	      if (__x->_M_right)
1301*404b540aSrobert 		__y->_M_right = _M_copy(_S_right(__x), __y);
1302*404b540aSrobert 	      __p = __y;
1303*404b540aSrobert 	      __x = _S_left(__x);
1304*404b540aSrobert 	    }
1305*404b540aSrobert 	}
1306*404b540aSrobert       catch(...)
1307*404b540aSrobert 	{
1308*404b540aSrobert 	  _M_erase(__top);
1309*404b540aSrobert 	  __throw_exception_again;
1310*404b540aSrobert 	}
1311*404b540aSrobert       return __top;
1312*404b540aSrobert     }
1313*404b540aSrobert 
1314*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1315*404b540aSrobert            typename _Compare, typename _Alloc>
1316*404b540aSrobert     void
1317*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1318*404b540aSrobert     _M_erase(_Link_type __x)
1319*404b540aSrobert     {
1320*404b540aSrobert       // Erase without rebalancing.
1321*404b540aSrobert       while (__x != 0)
1322*404b540aSrobert 	{
1323*404b540aSrobert 	  _M_erase(_S_right(__x));
1324*404b540aSrobert 	  _Link_type __y = _S_left(__x);
1325*404b540aSrobert 	  _M_destroy_node(__x);
1326*404b540aSrobert 	  __x = __y;
1327*404b540aSrobert 	}
1328*404b540aSrobert     }
1329*404b540aSrobert 
1330*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1331*404b540aSrobert            typename _Compare, typename _Alloc>
1332*404b540aSrobert     void
1333*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1334*404b540aSrobert     erase(iterator __first, iterator __last)
1335*404b540aSrobert     {
1336*404b540aSrobert       if (__first == begin() && __last == end())
1337*404b540aSrobert 	clear();
1338*404b540aSrobert       else
1339*404b540aSrobert 	while (__first != __last)
1340*404b540aSrobert 	  erase(__first++);
1341*404b540aSrobert     }
1342*404b540aSrobert 
1343*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1344*404b540aSrobert            typename _Compare, typename _Alloc>
1345*404b540aSrobert     void
1346*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1347*404b540aSrobert     erase(const_iterator __first, const_iterator __last)
1348*404b540aSrobert     {
1349*404b540aSrobert       if (__first == begin() && __last == end())
1350*404b540aSrobert 	clear();
1351*404b540aSrobert       else
1352*404b540aSrobert 	while (__first != __last)
1353*404b540aSrobert 	  erase(__first++);
1354*404b540aSrobert     }
1355*404b540aSrobert 
1356*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1357*404b540aSrobert            typename _Compare, typename _Alloc>
1358*404b540aSrobert     void
1359*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1360*404b540aSrobert     erase(const _Key* __first, const _Key* __last)
1361*404b540aSrobert     {
1362*404b540aSrobert       while (__first != __last)
1363*404b540aSrobert 	erase(*__first++);
1364*404b540aSrobert     }
1365*404b540aSrobert 
1366*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1367*404b540aSrobert            typename _Compare, typename _Alloc>
1368*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1369*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1370*404b540aSrobert     find(const _Key& __k)
1371*404b540aSrobert     {
1372*404b540aSrobert       _Link_type __x = _M_begin(); // Current node.
1373*404b540aSrobert       _Link_type __y = _M_end(); // Last node which is not less than __k.
1374*404b540aSrobert 
1375*404b540aSrobert       while (__x != 0)
1376*404b540aSrobert 	if (!_M_impl._M_key_compare(_S_key(__x), __k))
1377*404b540aSrobert 	  __y = __x, __x = _S_left(__x);
1378*404b540aSrobert 	else
1379*404b540aSrobert 	  __x = _S_right(__x);
1380*404b540aSrobert 
1381*404b540aSrobert       iterator __j = iterator(__y);
1382*404b540aSrobert       return (__j == end()
1383*404b540aSrobert 	      || _M_impl._M_key_compare(__k,
1384*404b540aSrobert 					_S_key(__j._M_node))) ? end() : __j;
1385*404b540aSrobert     }
1386*404b540aSrobert 
1387*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1388*404b540aSrobert            typename _Compare, typename _Alloc>
1389*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
1390*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1391*404b540aSrobert     find(const _Key& __k) const
1392*404b540aSrobert     {
1393*404b540aSrobert       _Const_Link_type __x = _M_begin(); // Current node.
1394*404b540aSrobert       _Const_Link_type __y = _M_end(); // Last node which is not less than __k.
1395*404b540aSrobert 
1396*404b540aSrobert      while (__x != 0)
1397*404b540aSrobert        {
1398*404b540aSrobert 	 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1399*404b540aSrobert 	   __y = __x, __x = _S_left(__x);
1400*404b540aSrobert 	 else
1401*404b540aSrobert 	   __x = _S_right(__x);
1402*404b540aSrobert        }
1403*404b540aSrobert      const_iterator __j = const_iterator(__y);
1404*404b540aSrobert      return (__j == end()
1405*404b540aSrobert 	     || _M_impl._M_key_compare(__k,
1406*404b540aSrobert 				       _S_key(__j._M_node))) ? end() : __j;
1407*404b540aSrobert     }
1408*404b540aSrobert 
1409*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1410*404b540aSrobert            typename _Compare, typename _Alloc>
1411*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
1412*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1413*404b540aSrobert     count(const _Key& __k) const
1414*404b540aSrobert     {
1415*404b540aSrobert       pair<const_iterator, const_iterator> __p = equal_range(__k);
1416*404b540aSrobert       const size_type __n = std::distance(__p.first, __p.second);
1417*404b540aSrobert       return __n;
1418*404b540aSrobert     }
1419*404b540aSrobert 
1420*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1421*404b540aSrobert            typename _Compare, typename _Alloc>
1422*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1423*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1424*404b540aSrobert     lower_bound(const _Key& __k)
1425*404b540aSrobert     {
1426*404b540aSrobert       _Link_type __x = _M_begin(); // Current node.
1427*404b540aSrobert       _Link_type __y = _M_end(); // Last node which is not less than __k.
1428*404b540aSrobert 
1429*404b540aSrobert       while (__x != 0)
1430*404b540aSrobert 	if (!_M_impl._M_key_compare(_S_key(__x), __k))
1431*404b540aSrobert 	  __y = __x, __x = _S_left(__x);
1432*404b540aSrobert 	else
1433*404b540aSrobert 	  __x = _S_right(__x);
1434*404b540aSrobert 
1435*404b540aSrobert       return iterator(__y);
1436*404b540aSrobert     }
1437*404b540aSrobert 
1438*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1439*404b540aSrobert            typename _Compare, typename _Alloc>
1440*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
1441*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1442*404b540aSrobert     lower_bound(const _Key& __k) const
1443*404b540aSrobert     {
1444*404b540aSrobert       _Const_Link_type __x = _M_begin(); // Current node.
1445*404b540aSrobert       _Const_Link_type __y = _M_end(); // Last node which is not less than __k.
1446*404b540aSrobert 
1447*404b540aSrobert       while (__x != 0)
1448*404b540aSrobert 	if (!_M_impl._M_key_compare(_S_key(__x), __k))
1449*404b540aSrobert 	  __y = __x, __x = _S_left(__x);
1450*404b540aSrobert 	else
1451*404b540aSrobert 	  __x = _S_right(__x);
1452*404b540aSrobert 
1453*404b540aSrobert       return const_iterator(__y);
1454*404b540aSrobert     }
1455*404b540aSrobert 
1456*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1457*404b540aSrobert            typename _Compare, typename _Alloc>
1458*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1459*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1460*404b540aSrobert     upper_bound(const _Key& __k)
1461*404b540aSrobert     {
1462*404b540aSrobert       _Link_type __x = _M_begin(); // Current node.
1463*404b540aSrobert       _Link_type __y = _M_end(); // Last node which is greater than __k.
1464*404b540aSrobert 
1465*404b540aSrobert       while (__x != 0)
1466*404b540aSrobert 	if (_M_impl._M_key_compare(__k, _S_key(__x)))
1467*404b540aSrobert 	  __y = __x, __x = _S_left(__x);
1468*404b540aSrobert 	else
1469*404b540aSrobert 	  __x = _S_right(__x);
1470*404b540aSrobert 
1471*404b540aSrobert       return iterator(__y);
1472*404b540aSrobert     }
1473*404b540aSrobert 
1474*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1475*404b540aSrobert            typename _Compare, typename _Alloc>
1476*404b540aSrobert     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
1477*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1478*404b540aSrobert     upper_bound(const _Key& __k) const
1479*404b540aSrobert     {
1480*404b540aSrobert       _Const_Link_type __x = _M_begin(); // Current node.
1481*404b540aSrobert       _Const_Link_type __y = _M_end(); // Last node which is greater than __k.
1482*404b540aSrobert 
1483*404b540aSrobert       while (__x != 0)
1484*404b540aSrobert 	if (_M_impl._M_key_compare(__k, _S_key(__x)))
1485*404b540aSrobert 	  __y = __x, __x = _S_left(__x);
1486*404b540aSrobert 	else
1487*404b540aSrobert 	  __x = _S_right(__x);
1488*404b540aSrobert 
1489*404b540aSrobert       return const_iterator(__y);
1490*404b540aSrobert     }
1491*404b540aSrobert 
1492*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1493*404b540aSrobert            typename _Compare, typename _Alloc>
1494*404b540aSrobert     inline
1495*404b540aSrobert     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1496*404b540aSrobert 			   _Compare, _Alloc>::iterator,
1497*404b540aSrobert 	 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator>
1498*404b540aSrobert     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1499*404b540aSrobert     equal_range(const _Key& __k)
1500*404b540aSrobert     { return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k)); }
1501*404b540aSrobert 
1502*404b540aSrobert   template<typename _Key, typename _Val, typename _KoV,
1503*404b540aSrobert            typename _Compare, typename _Alloc>
1504*404b540aSrobert     inline
1505*404b540aSrobert     pair<typename _Rb_tree<_Key, _Val, _KoV,
1506*404b540aSrobert 			   _Compare, _Alloc>::const_iterator,
1507*404b540aSrobert 	 typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator>
1508*404b540aSrobert     _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
1509*404b540aSrobert     equal_range(const _Key& __k) const
1510*404b540aSrobert     { return pair<const_iterator, const_iterator>(lower_bound(__k),
1511*404b540aSrobert 						  upper_bound(__k)); }
1512*404b540aSrobert 
1513*404b540aSrobert   unsigned int
1514*404b540aSrobert   _Rb_tree_black_count(const _Rb_tree_node_base* __node,
1515*404b540aSrobert                        const _Rb_tree_node_base* __root);
1516*404b540aSrobert 
1517*404b540aSrobert   template<typename _Key, typename _Val, typename _KeyOfValue,
1518*404b540aSrobert            typename _Compare, typename _Alloc>
1519*404b540aSrobert     bool
1520*404b540aSrobert     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
1521*404b540aSrobert     {
1522*404b540aSrobert       if (_M_impl._M_node_count == 0 || begin() == end())
1523*404b540aSrobert 	return _M_impl._M_node_count == 0 && begin() == end()
1524*404b540aSrobert 	       && this->_M_impl._M_header._M_left == _M_end()
1525*404b540aSrobert 	       && this->_M_impl._M_header._M_right == _M_end();
1526*404b540aSrobert 
1527*404b540aSrobert       unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
1528*404b540aSrobert       for (const_iterator __it = begin(); __it != end(); ++__it)
1529*404b540aSrobert 	{
1530*404b540aSrobert 	  _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
1531*404b540aSrobert 	  _Const_Link_type __L = _S_left(__x);
1532*404b540aSrobert 	  _Const_Link_type __R = _S_right(__x);
1533*404b540aSrobert 
1534*404b540aSrobert 	  if (__x->_M_color == _S_red)
1535*404b540aSrobert 	    if ((__L && __L->_M_color == _S_red)
1536*404b540aSrobert 		|| (__R && __R->_M_color == _S_red))
1537*404b540aSrobert 	      return false;
1538*404b540aSrobert 
1539*404b540aSrobert 	  if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
1540*404b540aSrobert 	    return false;
1541*404b540aSrobert 	  if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
1542*404b540aSrobert 	    return false;
1543*404b540aSrobert 
1544*404b540aSrobert 	  if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
1545*404b540aSrobert 	    return false;
1546*404b540aSrobert 	}
1547*404b540aSrobert 
1548*404b540aSrobert       if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
1549*404b540aSrobert 	return false;
1550*404b540aSrobert       if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
1551*404b540aSrobert 	return false;
1552*404b540aSrobert       return true;
1553*404b540aSrobert     }
1554*404b540aSrobert 
1555*404b540aSrobert _GLIBCXX_END_NAMESPACE
1556*404b540aSrobert 
1557*404b540aSrobert #endif
1558