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