xref: /haiku/headers/cpp/stl_tree.h (revision f2ced752a08ff5d2618826bcd3ae3976c9f3e92e)
1 /*
2  *
3  * Copyright (c) 1996,1997
4  * Silicon Graphics Computer Systems, Inc.
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Silicon Graphics makes no
11  * representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  *
15  * Copyright (c) 1994
16  * Hewlett-Packard Company
17  *
18  * Permission to use, copy, modify, distribute and sell this software
19  * and its documentation for any purpose is hereby granted without fee,
20  * provided that the above copyright notice appear in all copies and
21  * that both that copyright notice and this permission notice appear
22  * in supporting documentation.  Hewlett-Packard Company makes no
23  * representations about the suitability of this software for any
24  * purpose.  It is provided "as is" without express or implied warranty.
25  *
26  *
27  */
28 
29 /* NOTE: This is an internal header file, included by other STL headers.
30  *   You should not attempt to use it directly.
31  */
32 
33 #ifndef __SGI_STL_INTERNAL_TREE_H
34 #define __SGI_STL_INTERNAL_TREE_H
35 
36 /*
37 
38 Red-black tree class, designed for use in implementing STL
39 associative containers (set, multiset, map, and multimap). The
40 insertion and deletion algorithms are based on those in Cormen,
41 Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
42 except that
43 
44 (1) the header cell is maintained with links not only to the root
45 but also to the leftmost node of the tree, to enable constant time
46 begin(), and to the rightmost node of the tree, to enable linear time
47 performance when used with the generic set algorithms (set_union,
48 etc.);
49 
50 (2) when a node being deleted has two children its successor node is
51 relinked into its place, rather than copied, so that the only
52 iterators invalidated are those referring to the deleted node.
53 
54 */
55 
56 #include <stl_algobase.h>
57 #include <stl_alloc.h>
58 #include <stl_construct.h>
59 #include <stl_function.h>
60 
61 __STL_BEGIN_NAMESPACE
62 
63 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
64 #pragma set woff 1375
65 #endif
66 
67 typedef bool _Rb_tree_Color_type;
68 const _Rb_tree_Color_type _S_rb_tree_red = false;
69 const _Rb_tree_Color_type _S_rb_tree_black = true;
70 
71 struct _Rb_tree_node_base
72 {
73   typedef _Rb_tree_Color_type _Color_type;
74   typedef _Rb_tree_node_base* _Base_ptr;
75 
76   _Color_type _M_color;
77   _Base_ptr _M_parent;
78   _Base_ptr _M_left;
79   _Base_ptr _M_right;
80 
_S_minimum_Rb_tree_node_base81   static _Base_ptr _S_minimum(_Base_ptr __x)
82   {
83     while (__x->_M_left != 0) __x = __x->_M_left;
84     return __x;
85   }
86 
_S_maximum_Rb_tree_node_base87   static _Base_ptr _S_maximum(_Base_ptr __x)
88   {
89     while (__x->_M_right != 0) __x = __x->_M_right;
90     return __x;
91   }
92 };
93 
94 template <class _Value>
95 struct _Rb_tree_node : public _Rb_tree_node_base
96 {
97   typedef _Rb_tree_node<_Value>* _Link_type;
98   _Value _M_value_field;
99 };
100 
101 
102 struct _Rb_tree_base_iterator
103 {
104   typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
105   typedef bidirectional_iterator_tag iterator_category;
106   typedef ptrdiff_t difference_type;
107   _Base_ptr _M_node;
108 
_M_increment_Rb_tree_base_iterator109   void _M_increment()
110   {
111     if (_M_node->_M_right != 0) {
112       _M_node = _M_node->_M_right;
113       while (_M_node->_M_left != 0)
114         _M_node = _M_node->_M_left;
115     }
116     else {
117       _Base_ptr __y = _M_node->_M_parent;
118       while (_M_node == __y->_M_right) {
119         _M_node = __y;
120         __y = __y->_M_parent;
121       }
122       if (_M_node->_M_right != __y)
123         _M_node = __y;
124     }
125   }
126 
_M_decrement_Rb_tree_base_iterator127   void _M_decrement()
128   {
129     if (_M_node->_M_color == _S_rb_tree_red &&
130         _M_node->_M_parent->_M_parent == _M_node)
131       _M_node = _M_node->_M_right;
132     else if (_M_node->_M_left != 0) {
133       _Base_ptr __y = _M_node->_M_left;
134       while (__y->_M_right != 0)
135         __y = __y->_M_right;
136       _M_node = __y;
137     }
138     else {
139       _Base_ptr __y = _M_node->_M_parent;
140       while (_M_node == __y->_M_left) {
141         _M_node = __y;
142         __y = __y->_M_parent;
143       }
144       _M_node = __y;
145     }
146   }
147 };
148 
149 template <class _Value, class _Ref, class _Ptr>
150 struct _Rb_tree_iterator : public _Rb_tree_base_iterator
151 {
152   typedef _Value value_type;
153   typedef _Ref reference;
154   typedef _Ptr pointer;
155   typedef _Rb_tree_iterator<_Value, _Value&, _Value*>
156     iterator;
157   typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*>
158     const_iterator;
159   typedef _Rb_tree_iterator<_Value, _Ref, _Ptr>
160     _Self;
161   typedef _Rb_tree_node<_Value>* _Link_type;
162 
_Rb_tree_iterator_Rb_tree_iterator163   _Rb_tree_iterator() {}
_Rb_tree_iterator_Rb_tree_iterator164   _Rb_tree_iterator(_Link_type __x) { _M_node = __x; }
_Rb_tree_iterator_Rb_tree_iterator165   _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; }
166 
167   reference operator*() const { return _Link_type(_M_node)->_M_value_field; }
168 #ifndef __SGI_STL_NO_ARROW_OPERATOR
169   pointer operator->() const { return &(operator*()); }
170 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
171 
172   _Self& operator++() { _M_increment(); return *this; }
173   _Self operator++(int) {
174     _Self __tmp = *this;
175     _M_increment();
176     return __tmp;
177   }
178 
179   _Self& operator--() { _M_decrement(); return *this; }
180   _Self operator--(int) {
181     _Self __tmp = *this;
182     _M_decrement();
183     return __tmp;
184   }
185 };
186 
187 inline bool operator==(const _Rb_tree_base_iterator& __x,
188                        const _Rb_tree_base_iterator& __y) {
189   return __x._M_node == __y._M_node;
190 }
191 
192 inline bool operator!=(const _Rb_tree_base_iterator& __x,
193                        const _Rb_tree_base_iterator& __y) {
194   return __x._M_node != __y._M_node;
195 }
196 
197 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
198 
199 inline bidirectional_iterator_tag
iterator_category(const _Rb_tree_base_iterator &)200 iterator_category(const _Rb_tree_base_iterator&) {
201   return bidirectional_iterator_tag();
202 }
203 
204 inline _Rb_tree_base_iterator::difference_type*
distance_type(const _Rb_tree_base_iterator &)205 distance_type(const _Rb_tree_base_iterator&) {
206   return (_Rb_tree_base_iterator::difference_type*) 0;
207 }
208 
209 template <class _Value, class _Ref, class _Ptr>
value_type(const _Rb_tree_iterator<_Value,_Ref,_Ptr> &)210 inline _Value* value_type(const _Rb_tree_iterator<_Value, _Ref, _Ptr>&) {
211   return (_Value*) 0;
212 }
213 
214 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
215 
216 inline void
_Rb_tree_rotate_left(_Rb_tree_node_base * __x,_Rb_tree_node_base * & __root)217 _Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
218 {
219   _Rb_tree_node_base* __y = __x->_M_right;
220   __x->_M_right = __y->_M_left;
221   if (__y->_M_left !=0)
222     __y->_M_left->_M_parent = __x;
223   __y->_M_parent = __x->_M_parent;
224 
225   if (__x == __root)
226     __root = __y;
227   else if (__x == __x->_M_parent->_M_left)
228     __x->_M_parent->_M_left = __y;
229   else
230     __x->_M_parent->_M_right = __y;
231   __y->_M_left = __x;
232   __x->_M_parent = __y;
233 }
234 
235 inline void
_Rb_tree_rotate_right(_Rb_tree_node_base * __x,_Rb_tree_node_base * & __root)236 _Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
237 {
238   _Rb_tree_node_base* __y = __x->_M_left;
239   __x->_M_left = __y->_M_right;
240   if (__y->_M_right != 0)
241     __y->_M_right->_M_parent = __x;
242   __y->_M_parent = __x->_M_parent;
243 
244   if (__x == __root)
245     __root = __y;
246   else if (__x == __x->_M_parent->_M_right)
247     __x->_M_parent->_M_right = __y;
248   else
249     __x->_M_parent->_M_left = __y;
250   __y->_M_right = __x;
251   __x->_M_parent = __y;
252 }
253 
254 inline void
_Rb_tree_rebalance(_Rb_tree_node_base * __x,_Rb_tree_node_base * & __root)255 _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
256 {
257   __x->_M_color = _S_rb_tree_red;
258   while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) {
259     if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) {
260       _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right;
261       if (__y && __y->_M_color == _S_rb_tree_red) {
262         __x->_M_parent->_M_color = _S_rb_tree_black;
263         __y->_M_color = _S_rb_tree_black;
264         __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
265         __x = __x->_M_parent->_M_parent;
266       }
267       else {
268         if (__x == __x->_M_parent->_M_right) {
269           __x = __x->_M_parent;
270           _Rb_tree_rotate_left(__x, __root);
271         }
272         __x->_M_parent->_M_color = _S_rb_tree_black;
273         __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
274         _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root);
275       }
276     }
277     else {
278       _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left;
279       if (__y && __y->_M_color == _S_rb_tree_red) {
280         __x->_M_parent->_M_color = _S_rb_tree_black;
281         __y->_M_color = _S_rb_tree_black;
282         __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
283         __x = __x->_M_parent->_M_parent;
284       }
285       else {
286         if (__x == __x->_M_parent->_M_left) {
287           __x = __x->_M_parent;
288           _Rb_tree_rotate_right(__x, __root);
289         }
290         __x->_M_parent->_M_color = _S_rb_tree_black;
291         __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
292         _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root);
293       }
294     }
295   }
296   __root->_M_color = _S_rb_tree_black;
297 }
298 
299 inline _Rb_tree_node_base*
_Rb_tree_rebalance_for_erase(_Rb_tree_node_base * __z,_Rb_tree_node_base * & __root,_Rb_tree_node_base * & __leftmost,_Rb_tree_node_base * & __rightmost)300 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z,
301                              _Rb_tree_node_base*& __root,
302                              _Rb_tree_node_base*& __leftmost,
303                              _Rb_tree_node_base*& __rightmost)
304 {
305   _Rb_tree_node_base* __y = __z;
306   _Rb_tree_node_base* __x = 0;
307   _Rb_tree_node_base* __x_parent = 0;
308   if (__y->_M_left == 0)     // __z has at most one non-null child. y == z.
309     __x = __y->_M_right;     // __x might be null.
310   else
311     if (__y->_M_right == 0)  // __z has exactly one non-null child. y == z.
312       __x = __y->_M_left;    // __x is not null.
313     else {                   // __z has two non-null children.  Set __y to
314       __y = __y->_M_right;   //   __z's successor.  __x might be null.
315       while (__y->_M_left != 0)
316         __y = __y->_M_left;
317       __x = __y->_M_right;
318     }
319   if (__y != __z) {          // relink y in place of z.  y is z's successor
320     __z->_M_left->_M_parent = __y;
321     __y->_M_left = __z->_M_left;
322     if (__y != __z->_M_right) {
323       __x_parent = __y->_M_parent;
324       if (__x) __x->_M_parent = __y->_M_parent;
325       __y->_M_parent->_M_left = __x;      // __y must be a child of _M_left
326       __y->_M_right = __z->_M_right;
327       __z->_M_right->_M_parent = __y;
328     }
329     else
330       __x_parent = __y;
331     if (__root == __z)
332       __root = __y;
333     else if (__z->_M_parent->_M_left == __z)
334       __z->_M_parent->_M_left = __y;
335     else
336       __z->_M_parent->_M_right = __y;
337     __y->_M_parent = __z->_M_parent;
338     __STD::swap(__y->_M_color, __z->_M_color);
339     __y = __z;
340     // __y now points to node to be actually deleted
341   }
342   else {                        // __y == __z
343     __x_parent = __y->_M_parent;
344     if (__x) __x->_M_parent = __y->_M_parent;
345     if (__root == __z)
346       __root = __x;
347     else
348       if (__z->_M_parent->_M_left == __z)
349         __z->_M_parent->_M_left = __x;
350       else
351         __z->_M_parent->_M_right = __x;
352     if (__leftmost == __z)
353       if (__z->_M_right == 0)        // __z->_M_left must be null also
354         __leftmost = __z->_M_parent;
355     // makes __leftmost == _M_header if __z == __root
356       else
357         __leftmost = _Rb_tree_node_base::_S_minimum(__x);
358     if (__rightmost == __z)
359       if (__z->_M_left == 0)         // __z->_M_right must be null also
360         __rightmost = __z->_M_parent;
361     // makes __rightmost == _M_header if __z == __root
362       else                      // __x == __z->_M_left
363         __rightmost = _Rb_tree_node_base::_S_maximum(__x);
364   }
365   if (__y->_M_color != _S_rb_tree_red) {
366     while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black))
367       if (__x == __x_parent->_M_left) {
368         _Rb_tree_node_base* __w = __x_parent->_M_right;
369         if (__w->_M_color == _S_rb_tree_red) {
370           __w->_M_color = _S_rb_tree_black;
371           __x_parent->_M_color = _S_rb_tree_red;
372           _Rb_tree_rotate_left(__x_parent, __root);
373           __w = __x_parent->_M_right;
374         }
375         if ((__w->_M_left == 0 ||
376              __w->_M_left->_M_color == _S_rb_tree_black) &&
377             (__w->_M_right == 0 ||
378              __w->_M_right->_M_color == _S_rb_tree_black)) {
379           __w->_M_color = _S_rb_tree_red;
380           __x = __x_parent;
381           __x_parent = __x_parent->_M_parent;
382         } else {
383           if (__w->_M_right == 0 ||
384               __w->_M_right->_M_color == _S_rb_tree_black) {
385             if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;
386             __w->_M_color = _S_rb_tree_red;
387             _Rb_tree_rotate_right(__w, __root);
388             __w = __x_parent->_M_right;
389           }
390           __w->_M_color = __x_parent->_M_color;
391           __x_parent->_M_color = _S_rb_tree_black;
392           if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;
393           _Rb_tree_rotate_left(__x_parent, __root);
394           break;
395         }
396       } else {                  // same as above, with _M_right <-> _M_left.
397         _Rb_tree_node_base* __w = __x_parent->_M_left;
398         if (__w->_M_color == _S_rb_tree_red) {
399           __w->_M_color = _S_rb_tree_black;
400           __x_parent->_M_color = _S_rb_tree_red;
401           _Rb_tree_rotate_right(__x_parent, __root);
402           __w = __x_parent->_M_left;
403         }
404         if ((__w->_M_right == 0 ||
405              __w->_M_right->_M_color == _S_rb_tree_black) &&
406             (__w->_M_left == 0 ||
407              __w->_M_left->_M_color == _S_rb_tree_black)) {
408           __w->_M_color = _S_rb_tree_red;
409           __x = __x_parent;
410           __x_parent = __x_parent->_M_parent;
411         } else {
412           if (__w->_M_left == 0 ||
413               __w->_M_left->_M_color == _S_rb_tree_black) {
414             if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;
415             __w->_M_color = _S_rb_tree_red;
416             _Rb_tree_rotate_left(__w, __root);
417             __w = __x_parent->_M_left;
418           }
419           __w->_M_color = __x_parent->_M_color;
420           __x_parent->_M_color = _S_rb_tree_black;
421           if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;
422           _Rb_tree_rotate_right(__x_parent, __root);
423           break;
424         }
425       }
426     if (__x) __x->_M_color = _S_rb_tree_black;
427   }
428   return __y;
429 }
430 
431 // Base class to encapsulate the differences between old SGI-style
432 // allocators and standard-conforming allocators.  In order to avoid
433 // having an empty base class, we arbitrarily move one of rb_tree's
434 // data members into the base class.
435 
436 #ifdef __STL_USE_STD_ALLOCATORS
437 
438 // _Base for general standard-conforming allocators.
439 template <class _Tp, class _Alloc, bool _S_instanceless>
440 class _Rb_tree_alloc_base {
441 public:
442   typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
get_allocator()443   allocator_type get_allocator() const { return _M_node_allocator; }
444 
_Rb_tree_alloc_base(const allocator_type & __a)445   _Rb_tree_alloc_base(const allocator_type& __a)
446     : _M_node_allocator(__a), _M_header(0) {}
447 
448 protected:
449   typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type
450            _M_node_allocator;
451   _Rb_tree_node<_Tp>* _M_header;
452 
_M_get_node()453   _Rb_tree_node<_Tp>* _M_get_node()
454     { return _M_node_allocator.allocate(1); }
_M_put_node(_Rb_tree_node<_Tp> * __p)455   void _M_put_node(_Rb_tree_node<_Tp>* __p)
456     { _M_node_allocator.deallocate(__p, 1); }
457 };
458 
459 // Specialization for instanceless allocators.
460 template <class _Tp, class _Alloc>
461 class _Rb_tree_alloc_base<_Tp, _Alloc, true> {
462 public:
463   typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
get_allocator()464   allocator_type get_allocator() const { return allocator_type(); }
465 
_Rb_tree_alloc_base(const allocator_type &)466   _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {}
467 
468 protected:
469   _Rb_tree_node<_Tp>* _M_header;
470 
471   typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type
472           _Alloc_type;
473 
_M_get_node()474   _Rb_tree_node<_Tp>* _M_get_node()
475     { return _Alloc_type::allocate(1); }
_M_put_node(_Rb_tree_node<_Tp> * __p)476   void _M_put_node(_Rb_tree_node<_Tp>* __p)
477     { _Alloc_type::deallocate(__p, 1); }
478 };
479 
480 template <class _Tp, class _Alloc>
481 struct _Rb_tree_base
482   : public _Rb_tree_alloc_base<_Tp, _Alloc,
483                                _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
484 {
485   typedef _Rb_tree_alloc_base<_Tp, _Alloc,
486                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
487           _Base;
488   typedef typename _Base::allocator_type allocator_type;
489 
_Rb_tree_base_Rb_tree_base490   _Rb_tree_base(const allocator_type& __a)
491     : _Base(__a) { _M_header = _M_get_node(); }
~_Rb_tree_base_Rb_tree_base492   ~_Rb_tree_base() { _M_put_node(_M_header); }
493 
494 };
495 
496 #else /* __STL_USE_STD_ALLOCATORS */
497 
498 template <class _Tp, class _Alloc>
499 struct _Rb_tree_base
500 {
501   typedef _Alloc allocator_type;
get_allocator_Rb_tree_base502   allocator_type get_allocator() const { return allocator_type(); }
503 
_Rb_tree_base_Rb_tree_base504   _Rb_tree_base(const allocator_type&)
505     : _M_header(0) { _M_header = _M_get_node(); }
~_Rb_tree_base_Rb_tree_base506   ~_Rb_tree_base() { _M_put_node(_M_header); }
507 
508 protected:
509   _Rb_tree_node<_Tp>* _M_header;
510 
511   typedef simple_alloc<_Rb_tree_node<_Tp>, _Alloc> _Alloc_type;
512 
_M_get_node_Rb_tree_base513   _Rb_tree_node<_Tp>* _M_get_node()
514     { return _Alloc_type::allocate(1); }
_M_put_node_Rb_tree_base515   void _M_put_node(_Rb_tree_node<_Tp>* __p)
516     { _Alloc_type::deallocate(__p, 1); }
517 };
518 
519 #endif /* __STL_USE_STD_ALLOCATORS */
520 
521 template <class _Key, class _Value, class _KeyOfValue, class _Compare,
522           class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) >
523 class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> {
524   typedef _Rb_tree_base<_Value, _Alloc> _Base;
525 protected:
526   typedef _Rb_tree_node_base* _Base_ptr;
527   typedef _Rb_tree_node<_Value> _Rb_tree_node;
528   typedef _Rb_tree_Color_type _Color_type;
529 public:
530   typedef _Key key_type;
531   typedef _Value value_type;
532   typedef value_type* pointer;
533   typedef const value_type* const_pointer;
534   typedef value_type& reference;
535   typedef const value_type& const_reference;
536   typedef _Rb_tree_node* _Link_type;
537   typedef size_t size_type;
538   typedef ptrdiff_t difference_type;
539 
540   typedef typename _Base::allocator_type allocator_type;
get_allocator()541   allocator_type get_allocator() const { return _Base::get_allocator(); }
542 
543 protected:
544 #ifdef __STL_USE_NAMESPACES
545   using _Base::_M_get_node;
546   using _Base::_M_put_node;
547   using _Base::_M_header;
548 #endif /* __STL_USE_NAMESPACES */
549 
550 protected:
551 
_M_create_node(const value_type & __x)552   _Link_type _M_create_node(const value_type& __x)
553   {
554     _Link_type __tmp = _M_get_node();
555     __STL_TRY {
556       construct(&__tmp->_M_value_field, __x);
557     }
558     __STL_UNWIND(_M_put_node(__tmp));
559     return __tmp;
560   }
561 
_M_clone_node(_Link_type __x)562   _Link_type _M_clone_node(_Link_type __x)
563   {
564     _Link_type __tmp = _M_create_node(__x->_M_value_field);
565     __tmp->_M_color = __x->_M_color;
566     __tmp->_M_left = 0;
567     __tmp->_M_right = 0;
568     return __tmp;
569   }
570 
destroy_node(_Link_type __p)571   void destroy_node(_Link_type __p)
572   {
573     destroy(&__p->_M_value_field);
574     _M_put_node(__p);
575   }
576 
577 protected:
578   size_type _M_node_count; // keeps track of size of tree
579   _Compare _M_key_compare;
580 
_M_root()581   _Link_type& _M_root() const
582     { return (_Link_type&) _M_header->_M_parent; }
_M_leftmost()583   _Link_type& _M_leftmost() const
584     { return (_Link_type&) _M_header->_M_left; }
_M_rightmost()585   _Link_type& _M_rightmost() const
586     { return (_Link_type&) _M_header->_M_right; }
587 
_S_left(_Link_type __x)588   static _Link_type& _S_left(_Link_type __x)
589     { return (_Link_type&)(__x->_M_left); }
_S_right(_Link_type __x)590   static _Link_type& _S_right(_Link_type __x)
591     { return (_Link_type&)(__x->_M_right); }
_S_parent(_Link_type __x)592   static _Link_type& _S_parent(_Link_type __x)
593     { return (_Link_type&)(__x->_M_parent); }
_S_value(_Link_type __x)594   static reference _S_value(_Link_type __x)
595     { return __x->_M_value_field; }
_S_key(_Link_type __x)596   static const _Key& _S_key(_Link_type __x)
597     { return _KeyOfValue()(_S_value(__x)); }
_S_color(_Link_type __x)598   static _Color_type& _S_color(_Link_type __x)
599     { return (_Color_type&)(__x->_M_color); }
600 
_S_left(_Base_ptr __x)601   static _Link_type& _S_left(_Base_ptr __x)
602     { return (_Link_type&)(__x->_M_left); }
_S_right(_Base_ptr __x)603   static _Link_type& _S_right(_Base_ptr __x)
604     { return (_Link_type&)(__x->_M_right); }
_S_parent(_Base_ptr __x)605   static _Link_type& _S_parent(_Base_ptr __x)
606     { return (_Link_type&)(__x->_M_parent); }
_S_value(_Base_ptr __x)607   static reference _S_value(_Base_ptr __x)
608     { return ((_Link_type)__x)->_M_value_field; }
_S_key(_Base_ptr __x)609   static const _Key& _S_key(_Base_ptr __x)
610     { return _KeyOfValue()(_S_value(_Link_type(__x)));}
_S_color(_Base_ptr __x)611   static _Color_type& _S_color(_Base_ptr __x)
612     { return (_Color_type&)(_Link_type(__x)->_M_color); }
613 
_S_minimum(_Link_type __x)614   static _Link_type _S_minimum(_Link_type __x)
615     { return (_Link_type)  _Rb_tree_node_base::_S_minimum(__x); }
616 
_S_maximum(_Link_type __x)617   static _Link_type _S_maximum(_Link_type __x)
618     { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); }
619 
620 public:
621   typedef _Rb_tree_iterator<value_type, reference, pointer> iterator;
622   typedef _Rb_tree_iterator<value_type, const_reference, const_pointer>
623           const_iterator;
624 
625 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
626   typedef reverse_iterator<const_iterator> const_reverse_iterator;
627   typedef reverse_iterator<iterator> reverse_iterator;
628 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
629   typedef reverse_bidirectional_iterator<iterator, value_type, reference,
630                                          difference_type>
631           reverse_iterator;
632   typedef reverse_bidirectional_iterator<const_iterator, value_type,
633                                          const_reference, difference_type>
634           const_reverse_iterator;
635 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
636 
637 private:
638   iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
639   _Link_type _M_copy(_Link_type __x, _Link_type __p);
640   void _M_erase(_Link_type __x);
641 
642 public:
643                                 // allocation/deallocation
_Rb_tree()644   _Rb_tree()
645     : _Base(allocator_type()), _M_node_count(0), _M_key_compare()
646     { _M_empty_initialize(); }
647 
_Rb_tree(const _Compare & __comp)648   _Rb_tree(const _Compare& __comp)
649     : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp)
650     { _M_empty_initialize(); }
651 
_Rb_tree(const _Compare & __comp,const allocator_type & __a)652   _Rb_tree(const _Compare& __comp, const allocator_type& __a)
653     : _Base(__a), _M_node_count(0), _M_key_compare(__comp)
654     { _M_empty_initialize(); }
655 
_Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> & __x)656   _Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x)
657     : _Base(__x.get_allocator()),
658       _M_node_count(0), _M_key_compare(__x._M_key_compare)
659   {
660     if (__x._M_root() == 0)
661       _M_empty_initialize();
662     else {
663       _S_color(_M_header) = _S_rb_tree_red;
664       _M_root() = _M_copy(__x._M_root(), _M_header);
665       _M_leftmost() = _S_minimum(_M_root());
666       _M_rightmost() = _S_maximum(_M_root());
667     }
668     _M_node_count = __x._M_node_count;
669   }
~_Rb_tree()670   ~_Rb_tree() { clear(); }
671   _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>&
672   operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x);
673 
674 private:
_M_empty_initialize()675   void _M_empty_initialize() {
676     _S_color(_M_header) = _S_rb_tree_red; // used to distinguish header from
677                                           // __root, in iterator.operator++
678     _M_root() = 0;
679     _M_leftmost() = _M_header;
680     _M_rightmost() = _M_header;
681   }
682 
683 public:
684                                 // accessors:
key_comp()685   _Compare key_comp() const { return _M_key_compare; }
begin()686   iterator begin() { return _M_leftmost(); }
begin()687   const_iterator begin() const { return _M_leftmost(); }
end()688   iterator end() { return _M_header; }
end()689   const_iterator end() const { return _M_header; }
rbegin()690   reverse_iterator rbegin() { return reverse_iterator(end()); }
rbegin()691   const_reverse_iterator rbegin() const {
692     return const_reverse_iterator(end());
693   }
rend()694   reverse_iterator rend() { return reverse_iterator(begin()); }
rend()695   const_reverse_iterator rend() const {
696     return const_reverse_iterator(begin());
697   }
empty()698   bool empty() const { return _M_node_count == 0; }
size()699   size_type size() const { return _M_node_count; }
max_size()700   size_type max_size() const { return size_type(-1); }
701 
swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> & __t)702   void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __t) {
703     __STD::swap(_M_header, __t._M_header);
704     __STD::swap(_M_node_count, __t._M_node_count);
705     __STD::swap(_M_key_compare, __t._M_key_compare);
706   }
707 
708 public:
709                                 // insert/erase
710   pair<iterator,bool> insert_unique(const value_type& __x);
711   iterator insert_equal(const value_type& __x);
712 
713   iterator insert_unique(iterator __position, const value_type& __x);
714   iterator insert_equal(iterator __position, const value_type& __x);
715 
716 #ifdef __STL_MEMBER_TEMPLATES
717   template <class _InputIterator>
718   void insert_unique(_InputIterator __first, _InputIterator __last);
719   template <class _InputIterator>
720   void insert_equal(_InputIterator __first, _InputIterator __last);
721 #else /* __STL_MEMBER_TEMPLATES */
722   void insert_unique(const_iterator __first, const_iterator __last);
723   void insert_unique(const value_type* __first, const value_type* __last);
724   void insert_equal(const_iterator __first, const_iterator __last);
725   void insert_equal(const value_type* __first, const value_type* __last);
726 #endif /* __STL_MEMBER_TEMPLATES */
727 
728   void erase(iterator __position);
729   size_type erase(const key_type& __x);
730   void erase(iterator __first, iterator __last);
731   void erase(const key_type* __first, const key_type* __last);
clear()732   void clear() {
733     if (_M_node_count != 0) {
734       _M_erase(_M_root());
735       _M_leftmost() = _M_header;
736       _M_root() = 0;
737       _M_rightmost() = _M_header;
738       _M_node_count = 0;
739     }
740   }
741 
742 public:
743                                 // set operations:
744   iterator find(const key_type& __x);
745   const_iterator find(const key_type& __x) const;
746   size_type count(const key_type& __x) const;
747   iterator lower_bound(const key_type& __x);
748   const_iterator lower_bound(const key_type& __x) const;
749   iterator upper_bound(const key_type& __x);
750   const_iterator upper_bound(const key_type& __x) const;
751   pair<iterator,iterator> equal_range(const key_type& __x);
752   pair<const_iterator, const_iterator> equal_range(const key_type& __x) const;
753 
754 public:
755                                 // Debugging.
756   bool __rb_verify() const;
757 };
758 
759 template <class _Key, class _Value, class _KeyOfValue,
760           class _Compare, class _Alloc>
761 inline bool
762 operator==(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
763            const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y)
764 {
765   return __x.size() == __y.size() &&
766          equal(__x.begin(), __x.end(), __y.begin());
767 }
768 
769 template <class _Key, class _Value, class _KeyOfValue,
770           class _Compare, class _Alloc>
771 inline bool
772 operator<(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
773           const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y)
774 {
775   return lexicographical_compare(__x.begin(), __x.end(),
776                                  __y.begin(), __y.end());
777 }
778 
779 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
780 
781 template <class _Key, class _Value, class _KeyOfValue,
782           class _Compare, class _Alloc>
783 inline void
swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> & __x,_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> & __y)784 swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x,
785      _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y)
786 {
787   __x.swap(__y);
788 }
789 
790 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
791 
792 
793 template <class _Key, class _Value, class _KeyOfValue,
794           class _Compare, class _Alloc>
795 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>&
796 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
797   ::operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x)
798 {
799   if (this != &__x) {
800                                 // Note that _Key may be a constant type.
801     clear();
802     _M_node_count = 0;
803     _M_key_compare = __x._M_key_compare;
804     if (__x._M_root() == 0) {
805       _M_root() = 0;
806       _M_leftmost() = _M_header;
807       _M_rightmost() = _M_header;
808     }
809     else {
810       _M_root() = _M_copy(__x._M_root(), _M_header);
811       _M_leftmost() = _S_minimum(_M_root());
812       _M_rightmost() = _S_maximum(_M_root());
813       _M_node_count = __x._M_node_count;
814     }
815   }
816   return *this;
817 }
818 
819 template <class _Key, class _Value, class _KeyOfValue,
820           class _Compare, class _Alloc>
821 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
822 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
_M_insert(_Base_ptr __x_,_Base_ptr __y_,const _Value & __v)823   ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v)
824 {
825   _Link_type __x = (_Link_type) __x_;
826   _Link_type __y = (_Link_type) __y_;
827   _Link_type __z;
828 
829   if (__y == _M_header || __x != 0 ||
830       _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) {
831     __z = _M_create_node(__v);
832     _S_left(__y) = __z;               // also makes _M_leftmost() = __z
833                                       //    when __y == _M_header
834     if (__y == _M_header) {
835       _M_root() = __z;
836       _M_rightmost() = __z;
837     }
838     else if (__y == _M_leftmost())
839       _M_leftmost() = __z;   // maintain _M_leftmost() pointing to min node
840   }
841   else {
842     __z = _M_create_node(__v);
843     _S_right(__y) = __z;
844     if (__y == _M_rightmost())
845       _M_rightmost() = __z;  // maintain _M_rightmost() pointing to max node
846   }
847   _S_parent(__z) = __y;
848   _S_left(__z) = 0;
849   _S_right(__z) = 0;
850   _Rb_tree_rebalance(__z, _M_header->_M_parent);
851   ++_M_node_count;
852   return iterator(__z);
853 }
854 
855 template <class _Key, class _Value, class _KeyOfValue,
856           class _Compare, class _Alloc>
857 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
858 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
insert_equal(const _Value & __v)859   ::insert_equal(const _Value& __v)
860 {
861   _Link_type __y = _M_header;
862   _Link_type __x = _M_root();
863   while (__x != 0) {
864     __y = __x;
865     __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
866             _S_left(__x) : _S_right(__x);
867   }
868   return _M_insert(__x, __y, __v);
869 }
870 
871 
872 template <class _Key, class _Value, class _KeyOfValue,
873           class _Compare, class _Alloc>
874 pair<typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator,
875      bool>
876 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
insert_unique(const _Value & __v)877   ::insert_unique(const _Value& __v)
878 {
879   _Link_type __y = _M_header;
880   _Link_type __x = _M_root();
881   bool __comp = true;
882   while (__x != 0) {
883     __y = __x;
884     __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x));
885     __x = __comp ? _S_left(__x) : _S_right(__x);
886   }
887   iterator __j = iterator(__y);
888   if (__comp)
889     if (__j == begin())
890       return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
891     else
892       --__j;
893   if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
894     return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
895   return pair<iterator,bool>(__j, false);
896 }
897 
898 
899 template <class _Key, class _Val, class _KeyOfValue,
900           class _Compare, class _Alloc>
901 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
902 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>
insert_unique(iterator __position,const _Val & __v)903   ::insert_unique(iterator __position, const _Val& __v)
904 {
905   if (__position._M_node == _M_header->_M_left) { // begin()
906     if (size() > 0 &&
907         _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node)))
908       return _M_insert(__position._M_node, __position._M_node, __v);
909     // first argument just needs to be non-null
910     else
911       return insert_unique(__v).first;
912   } else if (__position._M_node == _M_header) { // end()
913     if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v)))
914       return _M_insert(0, _M_rightmost(), __v);
915     else
916       return insert_unique(__v).first;
917   } else {
918     iterator __before = __position;
919     --__before;
920     if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v))
921         && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) {
922       if (_S_right(__before._M_node) == 0)
923         return _M_insert(0, __before._M_node, __v);
924       else
925         return _M_insert(__position._M_node, __position._M_node, __v);
926     // first argument just needs to be non-null
927     } else
928       return insert_unique(__v).first;
929   }
930 }
931 
932 template <class _Key, class _Val, class _KeyOfValue,
933           class _Compare, class _Alloc>
934 typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
935 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>
insert_equal(iterator __position,const _Val & __v)936   ::insert_equal(iterator __position, const _Val& __v)
937 {
938   if (__position._M_node == _M_header->_M_left) { // begin()
939     if (size() > 0 &&
940         _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node)))
941       return _M_insert(__position._M_node, __position._M_node, __v);
942     // first argument just needs to be non-null
943     else
944       return insert_equal(__v);
945   } else if (__position._M_node == _M_header) {// end()
946     if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost())))
947       return _M_insert(0, _M_rightmost(), __v);
948     else
949       return insert_equal(__v);
950   } else {
951     iterator __before = __position;
952     --__before;
953     if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node))
954         && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) {
955       if (_S_right(__before._M_node) == 0)
956         return _M_insert(0, __before._M_node, __v);
957       else
958         return _M_insert(__position._M_node, __position._M_node, __v);
959     // first argument just needs to be non-null
960     } else
961       return insert_equal(__v);
962   }
963 }
964 
965 #ifdef __STL_MEMBER_TEMPLATES
966 
967 template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
968   template<class _II>
969 void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
insert_equal(_II __first,_II __last)970   ::insert_equal(_II __first, _II __last)
971 {
972   for ( ; __first != __last; ++__first)
973     insert_equal(*__first);
974 }
975 
976 template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
977   template<class _II>
978 void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
insert_unique(_II __first,_II __last)979   ::insert_unique(_II __first, _II __last) {
980   for ( ; __first != __last; ++__first)
981     insert_unique(*__first);
982 }
983 
984 #else /* __STL_MEMBER_TEMPLATES */
985 
986 template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
987 void
988 _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
insert_equal(const _Val * __first,const _Val * __last)989   ::insert_equal(const _Val* __first, const _Val* __last)
990 {
991   for ( ; __first != __last; ++__first)
992     insert_equal(*__first);
993 }
994 
995 template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
996 void
997 _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
insert_equal(const_iterator __first,const_iterator __last)998   ::insert_equal(const_iterator __first, const_iterator __last)
999 {
1000   for ( ; __first != __last; ++__first)
1001     insert_equal(*__first);
1002 }
1003 
1004 template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
1005 void
1006 _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
insert_unique(const _Val * __first,const _Val * __last)1007   ::insert_unique(const _Val* __first, const _Val* __last)
1008 {
1009   for ( ; __first != __last; ++__first)
1010     insert_unique(*__first);
1011 }
1012 
1013 template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
1014 void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
insert_unique(const_iterator __first,const_iterator __last)1015   ::insert_unique(const_iterator __first, const_iterator __last)
1016 {
1017   for ( ; __first != __last; ++__first)
1018     insert_unique(*__first);
1019 }
1020 
1021 #endif /* __STL_MEMBER_TEMPLATES */
1022 
1023 template <class _Key, class _Value, class _KeyOfValue,
1024           class _Compare, class _Alloc>
1025 inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
erase(iterator __position)1026   ::erase(iterator __position)
1027 {
1028   _Link_type __y =
1029     (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node,
1030                                               _M_header->_M_parent,
1031                                               _M_header->_M_left,
1032                                               _M_header->_M_right);
1033   destroy_node(__y);
1034   --_M_node_count;
1035 }
1036 
1037 template <class _Key, class _Value, class _KeyOfValue,
1038           class _Compare, class _Alloc>
1039 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type
erase(const _Key & __x)1040 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x)
1041 {
1042   pair<iterator,iterator> __p = equal_range(__x);
1043   size_type __n = 0;
1044   distance(__p.first, __p.second, __n);
1045   erase(__p.first, __p.second);
1046   return __n;
1047 }
1048 
1049 template <class _Key, class _Val, class _KoV, class _Compare, class _Alloc>
1050 typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
1051 _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>
_M_copy(_Link_type __x,_Link_type __p)1052   ::_M_copy(_Link_type __x, _Link_type __p)
1053 {
1054                         // structural copy.  __x and __p must be non-null.
1055   _Link_type __top = _M_clone_node(__x);
1056   __top->_M_parent = __p;
1057 
1058   __STL_TRY {
1059     if (__x->_M_right)
1060       __top->_M_right = _M_copy(_S_right(__x), __top);
1061     __p = __top;
1062     __x = _S_left(__x);
1063 
1064     while (__x != 0) {
1065       _Link_type __y = _M_clone_node(__x);
1066       __p->_M_left = __y;
1067       __y->_M_parent = __p;
1068       if (__x->_M_right)
1069         __y->_M_right = _M_copy(_S_right(__x), __y);
1070       __p = __y;
1071       __x = _S_left(__x);
1072     }
1073   }
1074   __STL_UNWIND(_M_erase(__top));
1075 
1076   return __top;
1077 }
1078 
1079 template <class _Key, class _Value, class _KeyOfValue,
1080           class _Compare, class _Alloc>
1081 void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
_M_erase(_Link_type __x)1082   ::_M_erase(_Link_type __x)
1083 {
1084                                 // erase without rebalancing
1085   while (__x != 0) {
1086     _M_erase(_S_right(__x));
1087     _Link_type __y = _S_left(__x);
1088     destroy_node(__x);
1089     __x = __y;
1090   }
1091 }
1092 
1093 template <class _Key, class _Value, class _KeyOfValue,
1094           class _Compare, class _Alloc>
1095 void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
erase(iterator __first,iterator __last)1096   ::erase(iterator __first, iterator __last)
1097 {
1098   if (__first == begin() && __last == end())
1099     clear();
1100   else
1101     while (__first != __last) erase(__first++);
1102 }
1103 
1104 template <class _Key, class _Value, class _KeyOfValue,
1105           class _Compare, class _Alloc>
1106 void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
erase(const _Key * __first,const _Key * __last)1107   ::erase(const _Key* __first, const _Key* __last)
1108 {
1109   while (__first != __last) erase(*__first++);
1110 }
1111 
1112 template <class _Key, class _Value, class _KeyOfValue,
1113           class _Compare, class _Alloc>
1114 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
find(const _Key & __k)1115 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k)
1116 {
1117   _Link_type __y = _M_header;      // Last node which is not less than __k.
1118   _Link_type __x = _M_root();      // Current node.
1119 
1120   while (__x != 0)
1121     if (!_M_key_compare(_S_key(__x), __k))
1122       __y = __x, __x = _S_left(__x);
1123     else
1124       __x = _S_right(__x);
1125 
1126   iterator __j = iterator(__y);
1127   return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ?
1128      end() : __j;
1129 }
1130 
1131 template <class _Key, class _Value, class _KeyOfValue,
1132           class _Compare, class _Alloc>
1133 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator
find(const _Key & __k)1134 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) const
1135 {
1136   _Link_type __y = _M_header; /* Last node which is not less than __k. */
1137   _Link_type __x = _M_root(); /* Current node. */
1138 
1139   while (__x != 0) {
1140     if (!_M_key_compare(_S_key(__x), __k))
1141       __y = __x, __x = _S_left(__x);
1142     else
1143       __x = _S_right(__x);
1144   }
1145   const_iterator __j = const_iterator(__y);
1146   return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ?
1147     end() : __j;
1148 }
1149 
1150 template <class _Key, class _Value, class _KeyOfValue,
1151           class _Compare, class _Alloc>
1152 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type
1153 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
count(const _Key & __k)1154   ::count(const _Key& __k) const
1155 {
1156   pair<const_iterator, const_iterator> __p = equal_range(__k);
1157   size_type __n = 0;
1158   distance(__p.first, __p.second, __n);
1159   return __n;
1160 }
1161 
1162 template <class _Key, class _Value, class _KeyOfValue,
1163           class _Compare, class _Alloc>
1164 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
1165 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
lower_bound(const _Key & __k)1166   ::lower_bound(const _Key& __k)
1167 {
1168   _Link_type __y = _M_header; /* Last node which is not less than __k. */
1169   _Link_type __x = _M_root(); /* Current node. */
1170 
1171   while (__x != 0)
1172     if (!_M_key_compare(_S_key(__x), __k))
1173       __y = __x, __x = _S_left(__x);
1174     else
1175       __x = _S_right(__x);
1176 
1177   return iterator(__y);
1178 }
1179 
1180 template <class _Key, class _Value, class _KeyOfValue,
1181           class _Compare, class _Alloc>
1182 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator
1183 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
lower_bound(const _Key & __k)1184   ::lower_bound(const _Key& __k) const
1185 {
1186   _Link_type __y = _M_header; /* Last node which is not less than __k. */
1187   _Link_type __x = _M_root(); /* Current node. */
1188 
1189   while (__x != 0)
1190     if (!_M_key_compare(_S_key(__x), __k))
1191       __y = __x, __x = _S_left(__x);
1192     else
1193       __x = _S_right(__x);
1194 
1195   return const_iterator(__y);
1196 }
1197 
1198 template <class _Key, class _Value, class _KeyOfValue,
1199           class _Compare, class _Alloc>
1200 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator
1201 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
upper_bound(const _Key & __k)1202   ::upper_bound(const _Key& __k)
1203 {
1204   _Link_type __y = _M_header; /* Last node which is greater than __k. */
1205   _Link_type __x = _M_root(); /* Current node. */
1206 
1207    while (__x != 0)
1208      if (_M_key_compare(__k, _S_key(__x)))
1209        __y = __x, __x = _S_left(__x);
1210      else
1211        __x = _S_right(__x);
1212 
1213    return iterator(__y);
1214 }
1215 
1216 template <class _Key, class _Value, class _KeyOfValue,
1217           class _Compare, class _Alloc>
1218 typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator
1219 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
upper_bound(const _Key & __k)1220   ::upper_bound(const _Key& __k) const
1221 {
1222   _Link_type __y = _M_header; /* Last node which is greater than __k. */
1223   _Link_type __x = _M_root(); /* Current node. */
1224 
1225    while (__x != 0)
1226      if (_M_key_compare(__k, _S_key(__x)))
1227        __y = __x, __x = _S_left(__x);
1228      else
1229        __x = _S_right(__x);
1230 
1231    return const_iterator(__y);
1232 }
1233 
1234 template <class _Key, class _Value, class _KeyOfValue,
1235           class _Compare, class _Alloc>
1236 inline
1237 pair<typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator,
1238      typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator>
1239 _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>
equal_range(const _Key & __k)1240   ::equal_range(const _Key& __k)
1241 {
1242   return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k));
1243 }
1244 
1245 template <class _Key, class _Value, class _KoV, class _Compare, class _Alloc>
1246 inline
1247 pair<typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator,
1248      typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator>
1249 _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>
equal_range(const _Key & __k)1250   ::equal_range(const _Key& __k) const
1251 {
1252   return pair<const_iterator,const_iterator>(lower_bound(__k),
1253                                              upper_bound(__k));
1254 }
1255 
1256 inline int
__black_count(_Rb_tree_node_base * __node,_Rb_tree_node_base * __root)1257 __black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root)
1258 {
1259   if (__node == 0)
1260     return 0;
1261   else {
1262     int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0;
1263     if (__node == __root)
1264       return __bc;
1265     else
1266       return __bc + __black_count(__node->_M_parent, __root);
1267   }
1268 }
1269 
1270 template <class _Key, class _Value, class _KeyOfValue,
1271           class _Compare, class _Alloc>
__rb_verify()1272 bool _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
1273 {
1274   if (_M_node_count == 0 || begin() == end())
1275     return _M_node_count == 0 && begin() == end() &&
1276       _M_header->_M_left == _M_header && _M_header->_M_right == _M_header;
1277 
1278   int __len = __black_count(_M_leftmost(), _M_root());
1279   for (const_iterator __it = begin(); __it != end(); ++__it) {
1280     _Link_type __x = (_Link_type) __it._M_node;
1281     _Link_type __L = _S_left(__x);
1282     _Link_type __R = _S_right(__x);
1283 
1284     if (__x->_M_color == _S_rb_tree_red)
1285       if ((__L && __L->_M_color == _S_rb_tree_red) ||
1286           (__R && __R->_M_color == _S_rb_tree_red))
1287         return false;
1288 
1289     if (__L && _M_key_compare(_S_key(__x), _S_key(__L)))
1290       return false;
1291     if (__R && _M_key_compare(_S_key(__R), _S_key(__x)))
1292       return false;
1293 
1294     if (!__L && !__R && __black_count(__x, _M_root()) != __len)
1295       return false;
1296   }
1297 
1298   if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
1299     return false;
1300   if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
1301     return false;
1302 
1303   return true;
1304 }
1305 
1306 // Class rb_tree is not part of the C++ standard.  It is provided for
1307 // compatibility with the HP STL.
1308 
1309 template <class _Key, class _Value, class _KeyOfValue, class _Compare,
1310           class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) >
1311 struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc>
1312 {
1313   typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base;
1314   typedef typename _Base::allocator_type allocator_type;
1315 
1316   rb_tree(const _Compare& __comp = _Compare(),
1317           const allocator_type& __a = allocator_type())
_Baserb_tree1318     : _Base(__comp, __a) {}
1319 
~rb_treerb_tree1320   ~rb_tree() {}
1321 };
1322 
1323 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
1324 #pragma reset woff 1375
1325 #endif
1326 
1327 __STL_END_NAMESPACE
1328 
1329 #endif /* __SGI_STL_INTERNAL_TREE_H */
1330 
1331 // Local Variables:
1332 // mode:C++
1333 // End:
1334