stl_tree.h

Go to the documentation of this file.
00001 // RB tree implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /*
00031  *
00032  * Copyright (c) 1996,1997
00033  * Silicon Graphics Computer Systems, Inc.
00034  *
00035  * Permission to use, copy, modify, distribute and sell this software
00036  * and its documentation for any purpose is hereby granted without fee,
00037  * provided that the above copyright notice appear in all copies and
00038  * that both that copyright notice and this permission notice appear
00039  * in supporting documentation.  Silicon Graphics makes no
00040  * representations about the suitability of this software for any
00041  * purpose.  It is provided "as is" without express or implied warranty.
00042  *
00043  *
00044  * Copyright (c) 1994
00045  * Hewlett-Packard Company
00046  *
00047  * Permission to use, copy, modify, distribute and sell this software
00048  * and its documentation for any purpose is hereby granted without fee,
00049  * provided that the above copyright notice appear in all copies and
00050  * that both that copyright notice and this permission notice appear
00051  * in supporting documentation.  Hewlett-Packard Company makes no
00052  * representations about the suitability of this software for any
00053  * purpose.  It is provided "as is" without express or implied warranty.
00054  *
00055  *
00056  */
00057 
00063 #ifndef _TREE_H
00064 #define _TREE_H 1
00065 
00066 #include <bits/stl_algobase.h>
00067 #include <bits/allocator.h>
00068 #include <bits/stl_construct.h>
00069 #include <bits/stl_function.h>
00070 #include <bits/cpp_type_traits.h>
00071 
00072 namespace std
00073 {
00074   // Red-black tree class, designed for use in implementing STL
00075   // associative containers (set, multiset, map, and multimap). The
00076   // insertion and deletion algorithms are based on those in Cormen,
00077   // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
00078   // 1990), except that
00079   //
00080   // (1) the header cell is maintained with links not only to the root
00081   // but also to the leftmost node of the tree, to enable constant
00082   // time begin(), and to the rightmost node of the tree, to enable
00083   // linear time performance when used with the generic set algorithms
00084   // (set_union, etc.)
00085   // 
00086   // (2) when a node being deleted has two children its successor node
00087   // is relinked into its place, rather than copied, so that the only
00088   // iterators invalidated are those referring to the deleted node.
00089 
00090   enum _Rb_tree_color { _S_red = false, _S_black = true };
00091 
00092   struct _Rb_tree_node_base
00093   {
00094     typedef _Rb_tree_node_base* _Base_ptr;
00095     typedef const _Rb_tree_node_base* _Const_Base_ptr;
00096 
00097     _Rb_tree_color  _M_color;
00098     _Base_ptr       _M_parent;
00099     _Base_ptr       _M_left;
00100     _Base_ptr       _M_right;
00101 
00102     static _Base_ptr
00103     _S_minimum(_Base_ptr __x)
00104     {
00105       while (__x->_M_left != 0) __x = __x->_M_left;
00106       return __x;
00107     }
00108 
00109     static _Const_Base_ptr
00110     _S_minimum(_Const_Base_ptr __x)
00111     {
00112       while (__x->_M_left != 0) __x = __x->_M_left;
00113       return __x;
00114     }
00115 
00116     static _Base_ptr
00117     _S_maximum(_Base_ptr __x)
00118     {
00119       while (__x->_M_right != 0) __x = __x->_M_right;
00120       return __x;
00121     }
00122 
00123     static _Const_Base_ptr
00124     _S_maximum(_Const_Base_ptr __x)
00125     {
00126       while (__x->_M_right != 0) __x = __x->_M_right;
00127       return __x;
00128     }
00129   };
00130 
00131   template<typename _Val>
00132     struct _Rb_tree_node : public _Rb_tree_node_base
00133     {
00134       typedef _Rb_tree_node<_Val>* _Link_type;
00135       _Val _M_value_field;
00136     };
00137 
00138   _Rb_tree_node_base*
00139   _Rb_tree_increment(_Rb_tree_node_base* __x);
00140 
00141   const _Rb_tree_node_base*
00142   _Rb_tree_increment(const _Rb_tree_node_base* __x);
00143 
00144   _Rb_tree_node_base*
00145   _Rb_tree_decrement(_Rb_tree_node_base* __x);
00146 
00147   const _Rb_tree_node_base*
00148   _Rb_tree_decrement(const _Rb_tree_node_base* __x);
00149 
00150   template<typename _Tp>
00151     struct _Rb_tree_iterator
00152     {
00153       typedef _Tp  value_type;
00154       typedef _Tp& reference;
00155       typedef _Tp* pointer;
00156 
00157       typedef bidirectional_iterator_tag iterator_category;
00158       typedef ptrdiff_t                  difference_type;
00159 
00160       typedef _Rb_tree_iterator<_Tp>        _Self;
00161       typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
00162       typedef _Rb_tree_node<_Tp>*           _Link_type;
00163 
00164       _Rb_tree_iterator()
00165       : _M_node() { }
00166 
00167       _Rb_tree_iterator(_Link_type __x)
00168       : _M_node(__x) { }
00169 
00170       reference
00171       operator*() const
00172       { return static_cast<_Link_type>(_M_node)->_M_value_field; }
00173 
00174       pointer
00175       operator->() const
00176       { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
00177 
00178       _Self&
00179       operator++()
00180       {
00181     _M_node = _Rb_tree_increment(_M_node);
00182     return *this;
00183       }
00184 
00185       _Self
00186       operator++(int)
00187       {
00188     _Self __tmp = *this;
00189     _M_node = _Rb_tree_increment(_M_node);
00190     return __tmp;
00191       }
00192 
00193       _Self&
00194       operator--()
00195       {
00196     _M_node = _Rb_tree_decrement(_M_node);
00197     return *this;
00198       }
00199 
00200       _Self
00201       operator--(int)
00202       {
00203     _Self __tmp = *this;
00204     _M_node = _Rb_tree_decrement(_M_node);
00205     return __tmp;
00206       }
00207 
00208       bool
00209       operator==(const _Self& __x) const
00210       { return _M_node == __x._M_node; }
00211 
00212       bool
00213       operator!=(const _Self& __x) const
00214       { return _M_node != __x._M_node; }
00215 
00216       _Base_ptr _M_node;
00217   };
00218 
00219   template<typename _Tp>
00220     struct _Rb_tree_const_iterator
00221     {
00222       typedef _Tp        value_type;
00223       typedef const _Tp& reference;
00224       typedef const _Tp* pointer;
00225 
00226       typedef _Rb_tree_iterator<_Tp> iterator;
00227 
00228       typedef bidirectional_iterator_tag iterator_category;
00229       typedef ptrdiff_t                  difference_type;
00230 
00231       typedef _Rb_tree_const_iterator<_Tp>        _Self;
00232       typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
00233       typedef const _Rb_tree_node<_Tp>*           _Link_type;
00234 
00235       _Rb_tree_const_iterator()
00236       : _M_node() { }
00237 
00238       _Rb_tree_const_iterator(_Link_type __x)
00239       : _M_node(__x) { }
00240 
00241       _Rb_tree_const_iterator(const iterator& __it)
00242       : _M_node(__it._M_node) { }
00243 
00244       reference
00245       operator*() const
00246       { return static_cast<_Link_type>(_M_node)->_M_value_field; }
00247 
00248       pointer
00249       operator->() const
00250       { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
00251 
00252       _Self&
00253       operator++()
00254       {
00255     _M_node = _Rb_tree_increment(_M_node);
00256     return *this;
00257       }
00258 
00259       _Self
00260       operator++(int)
00261       {
00262     _Self __tmp = *this;
00263     _M_node = _Rb_tree_increment(_M_node);
00264     return __tmp;
00265       }
00266 
00267       _Self&
00268       operator--()
00269       {
00270     _M_node = _Rb_tree_decrement(_M_node);
00271     return *this;
00272       }
00273 
00274       _Self
00275       operator--(int)
00276       {
00277     _Self __tmp = *this;
00278     _M_node = _Rb_tree_decrement(_M_node);
00279     return __tmp;
00280       }
00281 
00282       bool
00283       operator==(const _Self& __x) const
00284       { return _M_node == __x._M_node; }
00285 
00286       bool
00287       operator!=(const _Self& __x) const
00288       { return _M_node != __x._M_node; }
00289 
00290       _Base_ptr _M_node;
00291     };
00292 
00293   template<typename _Val>
00294     inline bool
00295     operator==(const _Rb_tree_iterator<_Val>& __x,
00296                const _Rb_tree_const_iterator<_Val>& __y)
00297     { return __x._M_node == __y._M_node; }
00298 
00299   template<typename _Val>
00300     inline bool
00301     operator!=(const _Rb_tree_iterator<_Val>& __x,
00302                const _Rb_tree_const_iterator<_Val>& __y)
00303     { return __x._M_node != __y._M_node; }
00304 
00305   void
00306   _Rb_tree_rotate_left(_Rb_tree_node_base* const __x,
00307                        _Rb_tree_node_base*& __root);
00308 
00309   void
00310   _Rb_tree_rotate_right(_Rb_tree_node_base* const __x,
00311                         _Rb_tree_node_base*& __root);
00312 
00313   void
00314   _Rb_tree_insert_and_rebalance(const bool __insert_left,
00315                                 _Rb_tree_node_base* __x,
00316                                 _Rb_tree_node_base* __p,
00317                                 _Rb_tree_node_base& __header);
00318 
00319   _Rb_tree_node_base*
00320   _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
00321                    _Rb_tree_node_base& __header);
00322 
00323 
00324   template<typename _Key, typename _Val, typename _KeyOfValue,
00325            typename _Compare, typename _Alloc = allocator<_Val> >
00326     class _Rb_tree
00327     {
00328       typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
00329               _Node_allocator;
00330 
00331     protected:
00332       typedef _Rb_tree_node_base* _Base_ptr;
00333       typedef const _Rb_tree_node_base* _Const_Base_ptr;
00334       typedef _Rb_tree_node<_Val> _Rb_tree_node;
00335 
00336     public:
00337       typedef _Key key_type;
00338       typedef _Val value_type;
00339       typedef value_type* pointer;
00340       typedef const value_type* const_pointer;
00341       typedef value_type& reference;
00342       typedef const value_type& const_reference;
00343       typedef _Rb_tree_node* _Link_type;
00344       typedef const _Rb_tree_node* _Const_Link_type;
00345       typedef size_t size_type;
00346       typedef ptrdiff_t difference_type;
00347       typedef _Alloc allocator_type;
00348 
00349       allocator_type 
00350       get_allocator() const
00351       { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
00352 
00353     protected:
00354       _Rb_tree_node*
00355       _M_get_node()
00356       { return _M_impl._Node_allocator::allocate(1); }
00357 
00358       void
00359       _M_put_node(_Rb_tree_node* __p)
00360       { _M_impl._Node_allocator::deallocate(__p, 1); }
00361 
00362       _Link_type
00363       _M_create_node(const value_type& __x)
00364       {
00365     _Link_type __tmp = _M_get_node();
00366     try
00367       { std::_Construct(&__tmp->_M_value_field, __x); }
00368     catch(...)
00369       {
00370         _M_put_node(__tmp);
00371         __throw_exception_again;
00372       }
00373     return __tmp;
00374       }
00375 
00376       _Link_type
00377       _M_clone_node(_Const_Link_type __x)
00378       {
00379     _Link_type __tmp = _M_create_node(__x->_M_value_field);
00380     __tmp->_M_color = __x->_M_color;
00381     __tmp->_M_left = 0;
00382     __tmp->_M_right = 0;
00383     return __tmp;
00384       }
00385 
00386       void
00387       destroy_node(_Link_type __p)
00388       {
00389     std::_Destroy(&__p->_M_value_field);
00390     _M_put_node(__p);
00391       }
00392 
00393     protected:
00394       template<typename _Key_compare, 
00395            bool _Is_pod_comparator = std::__is_pod<_Key_compare>::_M_type>
00396         struct _Rb_tree_impl : public _Node_allocator
00397         {
00398       _Key_compare      _M_key_compare;
00399       _Rb_tree_node_base    _M_header;
00400       size_type         _M_node_count; // Keeps track of size of tree.
00401 
00402       _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
00403             const _Key_compare& __comp = _Key_compare())
00404       : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0)
00405       {
00406         this->_M_header._M_color = _S_red;
00407         this->_M_header._M_parent = 0;
00408         this->_M_header._M_left = &this->_M_header;
00409         this->_M_header._M_right = &this->_M_header;
00410       }
00411     };
00412 
00413       // Specialization for _Comparison types that are not capable of
00414       // being base classes / super classes.
00415       template<typename _Key_compare>
00416         struct _Rb_tree_impl<_Key_compare, true> : public _Node_allocator 
00417     {
00418       _Key_compare      _M_key_compare;
00419       _Rb_tree_node_base    _M_header;
00420       size_type         _M_node_count; // Keeps track of size of tree.
00421 
00422       _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
00423             const _Key_compare& __comp = _Key_compare())
00424       : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0)
00425       { 
00426         this->_M_header._M_color = _S_red;
00427         this->_M_header._M_parent = 0;
00428         this->_M_header._M_left = &this->_M_header;
00429         this->_M_header._M_right = &this->_M_header;
00430       }
00431     };
00432 
00433       _Rb_tree_impl<_Compare> _M_impl;
00434 
00435     protected:
00436       _Base_ptr&
00437       _M_root()
00438       { return this->_M_impl._M_header._M_parent; }
00439 
00440       _Const_Base_ptr
00441       _M_root() const
00442       { return this->_M_impl._M_header._M_parent; }
00443 
00444       _Base_ptr&
00445       _M_leftmost()
00446       { return this->_M_impl._M_header._M_left; }
00447 
00448       _Const_Base_ptr
00449       _M_leftmost() const
00450       { return this->_M_impl._M_header._M_left; }
00451 
00452       _Base_ptr&
00453       _M_rightmost()
00454       { return this->_M_impl._M_header._M_right; }
00455 
00456       _Const_Base_ptr
00457       _M_rightmost() const
00458       { return this->_M_impl._M_header._M_right; }
00459 
00460       _Link_type
00461       _M_begin()
00462       { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
00463 
00464       _Const_Link_type
00465       _M_begin() const
00466       { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_parent); }
00467 
00468       _Link_type
00469       _M_end()
00470       { return static_cast<_Link_type>(&this->_M_impl._M_header); }
00471 
00472       _Const_Link_type
00473       _M_end() const
00474       { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); }
00475 
00476       static const_reference
00477       _S_value(_Const_Link_type __x)
00478       { return __x->_M_value_field; }
00479 
00480       static const _Key&
00481       _S_key(_Const_Link_type __x)
00482       { return _KeyOfValue()(_S_value(__x)); }
00483 
00484       static _Link_type
00485       _S_left(_Base_ptr __x)
00486       { return static_cast<_Link_type>(__x->_M_left); }
00487 
00488       static _Const_Link_type
00489       _S_left(_Const_Base_ptr __x)
00490       { return static_cast<_Const_Link_type>(__x->_M_left); }
00491 
00492       static _Link_type
00493       _S_right(_Base_ptr __x)
00494       { return static_cast<_Link_type>(__x->_M_right); }
00495 
00496       static _Const_Link_type
00497       _S_right(_Const_Base_ptr __x)
00498       { return static_cast<_Const_Link_type>(__x->_M_right); }
00499 
00500       static const_reference
00501       _S_value(_Const_Base_ptr __x)
00502       { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
00503 
00504       static const _Key&
00505       _S_key(_Const_Base_ptr __x)
00506       { return _KeyOfValue()(_S_value(__x)); }
00507 
00508       static _Base_ptr
00509       _S_minimum(_Base_ptr __x)
00510       { return _Rb_tree_node_base::_S_minimum(__x); }
00511 
00512       static _Const_Base_ptr
00513       _S_minimum(_Const_Base_ptr __x)
00514       { return _Rb_tree_node_base::_S_minimum(__x); }
00515 
00516       static _Base_ptr
00517       _S_maximum(_Base_ptr __x)
00518       { return _Rb_tree_node_base::_S_maximum(__x); }
00519 
00520       static _Const_Base_ptr
00521       _S_maximum(_Const_Base_ptr __x)
00522       { return _Rb_tree_node_base::_S_maximum(__x); }
00523 
00524     public:
00525       typedef _Rb_tree_iterator<value_type>       iterator;
00526       typedef _Rb_tree_const_iterator<value_type> const_iterator;
00527 
00528       typedef std::reverse_iterator<iterator>       reverse_iterator;
00529       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00530 
00531     private:
00532       iterator
00533       _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
00534 
00535       _Link_type
00536       _M_copy(_Const_Link_type __x, _Link_type __p);
00537 
00538       void
00539       _M_erase(_Link_type __x);
00540 
00541     public:
00542       // allocation/deallocation
00543       _Rb_tree()
00544       { }
00545 
00546       _Rb_tree(const _Compare& __comp)
00547       : _M_impl(allocator_type(), __comp)
00548       { }
00549 
00550       _Rb_tree(const _Compare& __comp, const allocator_type& __a)
00551       : _M_impl(__a, __comp)
00552       { }
00553 
00554       _Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x)
00555       : _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare)
00556       {
00557     if (__x._M_root() != 0)
00558       {
00559         _M_root() = _M_copy(__x._M_begin(), _M_end());
00560         _M_leftmost() = _S_minimum(_M_root());
00561         _M_rightmost() = _S_maximum(_M_root());
00562         _M_impl._M_node_count = __x._M_impl._M_node_count;
00563       }
00564       }
00565 
00566       ~_Rb_tree()
00567       { _M_erase(_M_begin()); }
00568 
00569       _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>&
00570       operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x);
00571 
00572       // Accessors.
00573       _Compare
00574       key_comp() const
00575       { return _M_impl._M_key_compare; }
00576 
00577       iterator
00578       begin()
00579       { return static_cast<_Link_type>(this->_M_impl._M_header._M_left); }
00580 
00581       const_iterator
00582       begin() const
00583       { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_left); }
00584 
00585       iterator
00586       end()
00587       { return static_cast<_Link_type>(&this->_M_impl._M_header); }
00588 
00589       const_iterator
00590       end() const
00591       { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); }
00592 
00593       reverse_iterator
00594       rbegin()
00595       { return reverse_iterator(end()); }
00596 
00597       const_reverse_iterator
00598       rbegin() const
00599       { return const_reverse_iterator(end()); }
00600 
00601       reverse_iterator
00602       rend()
00603       { return reverse_iterator(begin()); }
00604 
00605       const_reverse_iterator
00606       rend() const
00607       { return const_reverse_iterator(begin()); }
00608 
00609       bool
00610       empty() const
00611       { return _M_impl._M_node_count == 0; }
00612 
00613       size_type
00614       size() const
00615       { return _M_impl._M_node_count; }
00616 
00617       size_type
00618       max_size() const
00619       { return size_type(-1); }
00620 
00621       void
00622       swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t);
00623 
00624       // Insert/erase.
00625       pair<iterator,bool>
00626       insert_unique(const value_type& __x);
00627 
00628       iterator
00629       insert_equal(const value_type& __x);
00630 
00631       iterator
00632       insert_unique(iterator __position, const value_type& __x);
00633 
00634       iterator
00635       insert_equal(iterator __position, const value_type& __x);
00636 
00637       template<typename _InputIterator>
00638       void
00639       insert_unique(_InputIterator __first, _InputIterator __last);
00640 
00641       template<typename _InputIterator>
00642       void
00643       insert_equal(_InputIterator __first, _InputIterator __last);
00644 
00645       void
00646       erase(iterator __position);
00647 
00648       size_type
00649       erase(const key_type& __x);
00650 
00651       void
00652       erase(iterator __first, iterator __last);
00653 
00654       void
00655       erase(const key_type* __first, const key_type* __last);
00656 
00657       void
00658       clear()
00659       {
00660         _M_erase(_M_begin());
00661         _M_leftmost() = _M_end();
00662         _M_root() = 0;
00663         _M_rightmost() = _M_end();
00664         _M_impl._M_node_count = 0;
00665       }
00666 
00667       // Set operations.
00668       iterator
00669       find(const key_type& __x);
00670 
00671       const_iterator
00672       find(const key_type& __x) const;
00673 
00674       size_type
00675       count(const key_type& __x) const;
00676 
00677       iterator
00678       lower_bound(const key_type& __x);
00679 
00680       const_iterator
00681       lower_bound(const key_type& __x) const;
00682 
00683       iterator
00684       upper_bound(const key_type& __x);
00685 
00686       const_iterator
00687       upper_bound(const key_type& __x) const;
00688 
00689       pair<iterator,iterator>
00690       equal_range(const key_type& __x);
00691 
00692       pair<const_iterator, const_iterator>
00693       equal_range(const key_type& __x) const;
00694 
00695       // Debugging.
00696       bool
00697       __rb_verify() const;
00698     };
00699 
00700   template<typename _Key, typename _Val, typename _KeyOfValue,
00701            typename _Compare, typename _Alloc>
00702     inline bool
00703     operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
00704            const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
00705     {
00706       return __x.size() == __y.size()
00707          && std::equal(__x.begin(), __x.end(), __y.begin());
00708     }
00709 
00710   template<typename _Key, typename _Val, typename _KeyOfValue,
00711            typename _Compare, typename _Alloc>
00712     inline bool
00713     operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
00714           const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
00715     {
00716       return std::lexicographical_compare(__x.begin(), __x.end(), 
00717                       __y.begin(), __y.end());
00718     }
00719 
00720   template<typename _Key, typename _Val, typename _KeyOfValue,
00721            typename _Compare, typename _Alloc>
00722     inline bool
00723     operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
00724            const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
00725     { return !(__x == __y); }
00726 
00727   template<typename _Key, typename _Val, typename _KeyOfValue,
00728            typename _Compare, typename _Alloc>
00729     inline bool
00730     operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
00731           const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
00732     { return __y < __x; }
00733 
00734   template<typename _Key, typename _Val, typename _KeyOfValue,
00735            typename _Compare, typename _Alloc>
00736     inline bool
00737     operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
00738            const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
00739     { return !(__y < __x); }
00740 
00741   template<typename _Key, typename _Val, typename _KeyOfValue,
00742            typename _Compare, typename _Alloc>
00743     inline bool
00744     operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
00745            const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
00746     { return !(__x < __y); }
00747 
00748   template<typename _Key, typename _Val, typename _KeyOfValue,
00749            typename _Compare, typename _Alloc>
00750     inline void
00751     swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x,
00752      _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y)
00753     { __x.swap(__y); }
00754 
00755   template<typename _Key, typename _Val, typename _KeyOfValue,
00756            typename _Compare, typename _Alloc>
00757     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>&
00758     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
00759     operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x)
00760     {
00761       if (this != &__x)
00762     {
00763       // Note that _Key may be a constant type.
00764       clear();
00765       _M_impl._M_key_compare = __x._M_impl._M_key_compare;
00766       if (__x._M_root() != 0)
00767         {
00768           _M_root() = _M_copy(__x._M_begin(), _M_end());
00769           _M_leftmost() = _S_minimum(_M_root());
00770           _M_rightmost() = _S_maximum(_M_root());
00771           _M_impl._M_node_count = __x._M_impl._M_node_count;
00772         }
00773     }
00774       return *this;
00775     }
00776 
00777   template<typename _Key, typename _Val, typename _KeyOfValue,
00778            typename _Compare, typename _Alloc>
00779     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
00780     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
00781     _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
00782     {
00783       _Link_type __z = _M_create_node(__v);
00784       bool __insert_left;
00785 
00786       __insert_left = __x != 0 || __p == _M_end()
00787                   || _M_impl._M_key_compare(_KeyOfValue()(__v), 
00788                         _S_key(__p));
00789 
00790       _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,  
00791                     this->_M_impl._M_header);
00792       ++_M_impl._M_node_count;
00793       return iterator(__z);
00794     }
00795 
00796   template<typename _Key, typename _Val, typename _KeyOfValue,
00797            typename _Compare, typename _Alloc>
00798     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
00799     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
00800     insert_equal(const _Val& __v)
00801     {
00802       _Link_type __x = _M_begin();
00803       _Link_type __y = _M_end();
00804       while (__x != 0)
00805     {
00806       __y = __x;
00807       __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
00808             _S_left(__x) : _S_right(__x);
00809     }
00810       return _M_insert(__x, __y, __v);
00811     }
00812 
00813   template<typename _Key, typename _Val, typename _KeyOfValue,
00814            typename _Compare, typename _Alloc>
00815     void
00816     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
00817     swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t)
00818     {
00819       if (_M_root() == 0)
00820       {
00821     if (__t._M_root() != 0)
00822     {
00823       _M_root() = __t._M_root();
00824       _M_leftmost() = __t._M_leftmost();
00825       _M_rightmost() = __t._M_rightmost();
00826           _M_root()->_M_parent = _M_end();
00827 
00828       __t._M_root() = 0;
00829       __t._M_leftmost() = __t._M_end();
00830       __t._M_rightmost() = __t._M_end();
00831     }
00832       }
00833       else if (__t._M_root() == 0)
00834       {
00835     __t._M_root() = _M_root();
00836     __t._M_leftmost() = _M_leftmost();
00837     __t._M_rightmost() = _M_rightmost();
00838         __t._M_root()->_M_parent = __t._M_end();
00839 
00840     _M_root() = 0;
00841     _M_leftmost() = _M_end();
00842     _M_rightmost() = _M_end();
00843       }
00844       else
00845       {
00846     std::swap(_M_root(),__t._M_root());
00847     std::swap(_M_leftmost(),__t._M_leftmost());
00848     std::swap(_M_rightmost(),__t._M_rightmost());
00849 
00850     _M_root()->_M_parent = _M_end();
00851     __t._M_root()->_M_parent = __t._M_end();
00852       }
00853       // No need to swap header's color as it does not change.
00854       std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
00855       std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
00856     }
00857 
00858   template<typename _Key, typename _Val, typename _KeyOfValue,
00859            typename _Compare, typename _Alloc>
00860     pair<typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator,
00861     bool>
00862     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
00863     insert_unique(const _Val& __v)
00864     {
00865       _Link_type __x = _M_begin();
00866       _Link_type __y = _M_end();
00867       bool __comp = true;
00868       while (__x != 0)
00869     {
00870       __y = __x;
00871       __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x));
00872       __x = __comp ? _S_left(__x) : _S_right(__x);
00873     }
00874       iterator __j = iterator(__y);
00875       if (__comp)
00876     if (__j == begin())
00877       return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
00878     else
00879       --__j;
00880       if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
00881     return pair<iterator,bool>(_M_insert(__x, __y, __v), true);
00882       return pair<iterator,bool>(__j, false);
00883     }
00884 
00885   template<typename _Key, typename _Val, typename _KeyOfValue,
00886            typename _Compare, typename _Alloc>
00887     typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
00888     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
00889     insert_unique(iterator __position, const _Val& __v)
00890     {
00891       if (__position._M_node == _M_leftmost())
00892     {
00893       // begin()
00894       if (size() > 0
00895           && _M_impl._M_key_compare(_KeyOfValue()(__v), 
00896                     _S_key(__position._M_node)))
00897         return _M_insert(__position._M_node, __position._M_node, __v);
00898       // First argument just needs to be non-null.
00899       else
00900         return insert_unique(__v).first;
00901     }
00902       else if (__position._M_node == _M_end())
00903     {
00904       // end()
00905       if (_M_impl._M_key_compare(_S_key(_M_rightmost()), 
00906                      _KeyOfValue()(__v)))
00907         return _M_insert(0, _M_rightmost(), __v);
00908       else
00909         return insert_unique(__v).first;
00910     }
00911       else
00912     {
00913       iterator __before = __position;
00914       --__before;
00915       if (_M_impl._M_key_compare(_S_key(__before._M_node), 
00916                      _KeyOfValue()(__v))
00917           && _M_impl._M_key_compare(_KeyOfValue()(__v),
00918                     _S_key(__position._M_node)))
00919         {
00920           if (_S_right(__before._M_node) == 0)
00921         return _M_insert(0, __before._M_node, __v);
00922           else
00923         return _M_insert(__position._M_node, __position._M_node, __v);
00924           // First argument just needs to be non-null.
00925         }
00926       else
00927         return insert_unique(__v).first;
00928     }
00929     }
00930 
00931   template<typename _Key, typename _Val, typename _KeyOfValue,
00932            typename _Compare, typename _Alloc>
00933     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
00934     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
00935     insert_equal(iterator __position, const _Val& __v)
00936     {
00937       if (__position._M_node == _M_leftmost())
00938     {
00939       // begin()
00940       if (size() > 0
00941           && !_M_impl._M_key_compare(_S_key(__position._M_node),
00942                      _KeyOfValue()(__v)))
00943         return _M_insert(__position._M_node, __position._M_node, __v);
00944       // first argument just needs to be non-null
00945       else
00946         return insert_equal(__v);
00947     }
00948       else if (__position._M_node == _M_end())
00949     {
00950       // end()
00951       if (!_M_impl._M_key_compare(_KeyOfValue()(__v), 
00952                       _S_key(_M_rightmost())))
00953         return _M_insert(0, _M_rightmost(), __v);
00954       else
00955         return insert_equal(__v);
00956     }
00957       else
00958     {
00959       iterator __before = __position;
00960       --__before;
00961       if (!_M_impl._M_key_compare(_KeyOfValue()(__v), 
00962                       _S_key(__before._M_node))
00963           && !_M_impl._M_key_compare(_S_key(__position._M_node),
00964                      _KeyOfValue()(__v)))
00965         {
00966           if (_S_right(__before._M_node) == 0)
00967         return _M_insert(0, __before._M_node, __v);
00968           else
00969         return _M_insert(__position._M_node, __position._M_node, __v);
00970           // First argument just needs to be non-null.
00971         }
00972       else
00973         return insert_equal(__v);
00974     }
00975     }
00976 
00977   template<typename _Key, typename _Val, typename _KoV,
00978            typename _Cmp, typename _Alloc>
00979     template<class _II>
00980       void
00981       _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>::
00982       insert_equal(_II __first, _II __last)
00983       {
00984     for ( ; __first != __last; ++__first)
00985       insert_equal(*__first);
00986       }
00987 
00988   template<typename _Key, typename _Val, typename _KoV,
00989            typename _Cmp, typename _Alloc>
00990     template<class _II>
00991     void
00992     _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>::
00993     insert_unique(_II __first, _II __last)
00994     {
00995       for ( ; __first != __last; ++__first)
00996     insert_unique(*__first);
00997     }
00998 
00999   template<typename _Key, typename _Val, typename _KeyOfValue,
01000            typename _Compare, typename _Alloc>
01001     inline void
01002     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position)
01003     {
01004       _Link_type __y =
01005     static_cast<_Link_type>(_Rb_tree_rebalance_for_erase(__position._M_node,
01006                                  this->_M_impl._M_header));
01007       destroy_node(__y);
01008       --_M_impl._M_node_count;
01009     }
01010 
01011   template<typename _Key, typename _Val, typename _KeyOfValue,
01012            typename _Compare, typename _Alloc>
01013     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type
01014     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x)
01015     {
01016       pair<iterator,iterator> __p = equal_range(__x);
01017       size_type __n = std::distance(__p.first, __p.second);
01018       erase(__p.first, __p.second);
01019       return __n;
01020     }
01021 
01022   template<typename _Key, typename _Val, typename _KoV,
01023            typename _Compare, typename _Alloc>
01024     typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
01025     _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>::
01026     _M_copy(_Const_Link_type __x, _Link_type __p)
01027     {
01028       // Structural copy.  __x and __p must be non-null.
01029       _Link_type __top = _M_clone_node(__x);
01030       __top->_M_parent = __p;
01031 
01032       try
01033     {
01034       if (__x->_M_right)
01035         __top->_M_right = _M_copy(_S_right(__x), __top);
01036       __p = __top;
01037       __x = _S_left(__x);
01038 
01039       while (__x != 0)
01040         {
01041           _Link_type __y = _M_clone_node(__x);
01042           __p->_M_left = __y;
01043           __y->_M_parent = __p;
01044           if (__x->_M_right)
01045         __y->_M_right = _M_copy(_S_right(__x), __y);
01046           __p = __y;
01047           __x = _S_left(__x);
01048         }
01049     }
01050       catch(...)
01051     {
01052       _M_erase(__top);
01053       __throw_exception_again;
01054     }
01055       return __top;
01056     }
01057 
01058   template<typename _Key, typename _Val, typename _KeyOfValue,
01059            typename _Compare, typename _Alloc>
01060     void
01061     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_erase(_Link_type __x)
01062     {
01063       // Erase without rebalancing.
01064       while (__x != 0)
01065     {
01066       _M_erase(_S_right(__x));
01067       _Link_type __y = _S_left(__x);
01068       destroy_node(__x);
01069       __x = __y;
01070     }
01071     }
01072 
01073   template<typename _Key, typename _Val, typename _KeyOfValue,
01074            typename _Compare, typename _Alloc>
01075     void
01076     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01077     erase(iterator __first, iterator __last)
01078     {
01079       if (__first == begin() && __last == end())
01080     clear();
01081       else
01082     while (__first != __last) erase(__first++);
01083     }
01084 
01085   template<typename _Key, typename _Val, typename _KeyOfValue,
01086            typename _Compare, typename _Alloc>
01087     void
01088     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01089     erase(const _Key* __first, const _Key* __last)
01090     {
01091       while (__first != __last)
01092     erase(*__first++);
01093     }
01094 
01095   template<typename _Key, typename _Val, typename _KeyOfValue,
01096            typename _Compare, typename _Alloc>
01097     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
01098     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k)
01099     {
01100       _Link_type __x = _M_begin(); // Current node.
01101       _Link_type __y = _M_end(); // Last node which is not less than __k.
01102 
01103       while (__x != 0)
01104     if (!_M_impl._M_key_compare(_S_key(__x), __k))
01105       __y = __x, __x = _S_left(__x);
01106     else
01107       __x = _S_right(__x);
01108 
01109       iterator __j = iterator(__y);
01110       return (__j == end() 
01111       || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j;
01112     }
01113 
01114   template<typename _Key, typename _Val, typename _KeyOfValue,
01115            typename _Compare, typename _Alloc>
01116     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator
01117     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01118     find(const _Key& __k) const
01119     {
01120       _Const_Link_type __x = _M_begin(); // Current node.
01121       _Const_Link_type __y = _M_end(); // Last node which is not less than __k.
01122 
01123      while (__x != 0)
01124        {
01125      if (!_M_impl._M_key_compare(_S_key(__x), __k))
01126        __y = __x, __x = _S_left(__x);
01127      else
01128        __x = _S_right(__x);
01129        }
01130      const_iterator __j = const_iterator(__y);
01131      return (__j == end() 
01132       || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j;
01133     }
01134 
01135   template<typename _Key, typename _Val, typename _KeyOfValue,
01136            typename _Compare, typename _Alloc>
01137     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type
01138     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01139     count(const _Key& __k) const
01140     {
01141       pair<const_iterator, const_iterator> __p = equal_range(__k);
01142       const size_type __n = std::distance(__p.first, __p.second);
01143       return __n;
01144     }
01145 
01146   template<typename _Key, typename _Val, typename _KeyOfValue,
01147            typename _Compare, typename _Alloc>
01148     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
01149     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01150     lower_bound(const _Key& __k)
01151     {
01152       _Link_type __x = _M_begin(); // Current node.
01153       _Link_type __y = _M_end(); // Last node which is not less than __k.
01154 
01155       while (__x != 0)
01156     if (!_M_impl._M_key_compare(_S_key(__x), __k))
01157       __y = __x, __x = _S_left(__x);
01158     else
01159       __x = _S_right(__x);
01160 
01161       return iterator(__y);
01162     }
01163 
01164   template<typename _Key, typename _Val, typename _KeyOfValue,
01165            typename _Compare, typename _Alloc>
01166     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator
01167     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01168     lower_bound(const _Key& __k) const
01169     {
01170       _Const_Link_type __x = _M_begin(); // Current node.
01171       _Const_Link_type __y = _M_end(); // Last node which is not less than __k.
01172 
01173       while (__x != 0)
01174     if (!_M_impl._M_key_compare(_S_key(__x), __k))
01175       __y = __x, __x = _S_left(__x);
01176     else
01177       __x = _S_right(__x);
01178 
01179       return const_iterator(__y);
01180     }
01181 
01182   template<typename _Key, typename _Val, typename _KeyOfValue,
01183            typename _Compare, typename _Alloc>
01184     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
01185     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01186     upper_bound(const _Key& __k)
01187     {
01188       _Link_type __x = _M_begin(); // Current node.
01189       _Link_type __y = _M_end(); // Last node which is greater than __k.
01190 
01191       while (__x != 0)
01192     if (_M_impl._M_key_compare(__k, _S_key(__x)))
01193       __y = __x, __x = _S_left(__x);
01194     else
01195       __x = _S_right(__x);
01196 
01197       return iterator(__y);
01198     }
01199 
01200   template<typename _Key, typename _Val, typename _KeyOfValue,
01201            typename _Compare, typename _Alloc>
01202     typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator
01203     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01204     upper_bound(const _Key& __k) const
01205     {
01206       _Const_Link_type __x = _M_begin(); // Current node.
01207       _Const_Link_type __y = _M_end(); // Last node which is greater than __k.
01208 
01209       while (__x != 0)
01210     if (_M_impl._M_key_compare(__k, _S_key(__x)))
01211       __y = __x, __x = _S_left(__x);
01212     else
01213       __x = _S_right(__x);
01214 
01215       return const_iterator(__y);
01216     }
01217 
01218   template<typename _Key, typename _Val, typename _KeyOfValue,
01219            typename _Compare, typename _Alloc>
01220     inline
01221     pair<typename _Rb_tree<_Key,_Val,_KeyOfValue,
01222                _Compare,_Alloc>::iterator,
01223      typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator>
01224     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::
01225     equal_range(const _Key& __k)
01226     { return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k)); }
01227 
01228   template<typename _Key, typename _Val, typename _KoV,
01229            typename _Compare, typename _Alloc>
01230     inline
01231     pair<typename _Rb_tree<_Key, _Val, _KoV,
01232                _Compare, _Alloc>::const_iterator,
01233      typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator>
01234     _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
01235     equal_range(const _Key& __k) const
01236     { return pair<const_iterator, const_iterator>(lower_bound(__k),
01237                           upper_bound(__k)); }
01238 
01239   unsigned int
01240   _Rb_tree_black_count(const _Rb_tree_node_base* __node,
01241                        const _Rb_tree_node_base* __root);
01242 
01243   template<typename _Key, typename _Val, typename _KeyOfValue,
01244            typename _Compare, typename _Alloc>
01245     bool
01246     _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
01247     {
01248       if (_M_impl._M_node_count == 0 || begin() == end())
01249     return _M_impl._M_node_count == 0 && begin() == end()
01250            && this->_M_impl._M_header._M_left == _M_end()
01251            && this->_M_impl._M_header._M_right == _M_end();
01252 
01253       unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
01254       for (const_iterator __it = begin(); __it != end(); ++__it)
01255     {
01256       _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
01257       _Const_Link_type __L = _S_left(__x);
01258       _Const_Link_type __R = _S_right(__x);
01259 
01260       if (__x->_M_color == _S_red)
01261         if ((__L && __L->_M_color == _S_red)
01262         || (__R && __R->_M_color == _S_red))
01263           return false;
01264 
01265       if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
01266         return false;
01267       if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
01268         return false;
01269 
01270       if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
01271         return false;
01272     }
01273 
01274       if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
01275     return false;
01276       if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
01277     return false;
01278       return true;
01279     }
01280 } // namespace std
01281 
01282 #endif
01283 

Generated on Tue Jan 30 17:31:55 2007 for GNU C++ STL by doxygen 1.3.6