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