Home | History | Annotate | Download | only in stl
      1 /*
      2  *
      3  * Copyright (c) 1994
      4  * Hewlett-Packard Company
      5  *
      6  * Copyright (c) 1996,1997
      7  * Silicon Graphics Computer Systems, Inc.
      8  *
      9  * Copyright (c) 1997
     10  * Moscow Center for SPARC Technology
     11  *
     12  * Copyright (c) 1999
     13  * Boris Fomitchev
     14  *
     15  * This material is provided "as is", with absolutely no warranty expressed
     16  * or implied. Any use is at your own risk.
     17  *
     18  * Permission to use or copy this software for any purpose is hereby granted
     19  * without fee, provided the above notices are retained on all copies.
     20  * Permission to modify the code and to distribute modified code is granted,
     21  * provided the above notices are retained, and a notice that the code was
     22  * modified is included with the above copyright notice.
     23  *
     24  */
     25 
     26 /* NOTE: This is an internal header file, included by other STL headers.
     27  *   You should not attempt to use it directly.
     28  */
     29 
     30 #ifndef _STLP_INTERNAL_TREE_H
     31 #define _STLP_INTERNAL_TREE_H
     32 
     33 /*
     34 
     35 Red-black tree class, designed for use in implementing STL
     36 associative containers (set, multiset, map, and multimap). The
     37 insertion and deletion algorithms are based on those in Cormen,
     38 Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
     39 except that
     40 
     41 (1) the header cell is maintained with links not only to the root
     42 but also to the leftmost node of the tree, to enable constant time
     43 begin(), and to the rightmost node of the tree, to enable linear time
     44 performance when used with the generic set algorithms (set_union,
     45 etc.);
     46 
     47 (2) when a node being deleted has two children its successor node is
     48 relinked into its place, rather than copied, so that the only
     49 iterators invalidated are those referring to the deleted node.
     50 
     51 */
     52 
     53 #ifndef _STLP_INTERNAL_ALGOBASE_H
     54 #  include <stl/_algobase.h>
     55 #endif
     56 
     57 #ifndef _STLP_INTERNAL_ALLOC_H
     58 #  include <stl/_alloc.h>
     59 #endif
     60 
     61 #ifndef _STLP_INTERNAL_ITERATOR_H
     62 #  include <stl/_iterator.h>
     63 #endif
     64 
     65 #ifndef _STLP_INTERNAL_CONSTRUCT_H
     66 #  include <stl/_construct.h>
     67 #endif
     68 
     69 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H
     70 #  include <stl/_function_base.h>
     71 #endif
     72 
     73 _STLP_BEGIN_NAMESPACE
     74 
     75 _STLP_MOVE_TO_PRIV_NAMESPACE
     76 
     77 typedef bool _Rb_tree_Color_type;
     78 //const _Rb_tree_Color_type _S_rb_tree_red = false;
     79 //const _Rb_tree_Color_type _S_rb_tree_black = true;
     80 
     81 #define _S_rb_tree_red false
     82 #define _S_rb_tree_black true
     83 
     84 struct _Rb_tree_node_base {
     85   typedef _Rb_tree_Color_type _Color_type;
     86   typedef _Rb_tree_node_base* _Base_ptr;
     87 
     88   _Color_type _M_color;
     89   _Base_ptr _M_parent;
     90   _Base_ptr _M_left;
     91   _Base_ptr _M_right;
     92 
     93   static _Base_ptr _STLP_CALL _S_minimum(_Base_ptr __x) {
     94     while (__x->_M_left != 0) __x = __x->_M_left;
     95     return __x;
     96   }
     97 
     98   static _Base_ptr _STLP_CALL _S_maximum(_Base_ptr __x) {
     99     while (__x->_M_right != 0) __x = __x->_M_right;
    100     return __x;
    101   }
    102 };
    103 
    104 template <class _Value>
    105 struct _Rb_tree_node : public _Rb_tree_node_base {
    106   _Value _M_value_field;
    107   __TRIVIAL_STUFF(_Rb_tree_node)
    108 };
    109 
    110 struct _Rb_tree_base_iterator;
    111 
    112 template <class _Dummy>
    113 class _Rb_global {
    114 public:
    115   typedef _Rb_tree_node_base* _Base_ptr;
    116   // those used to be global functions
    117   static void _STLP_CALL _Rebalance(_Base_ptr __x, _Base_ptr& __root);
    118   static _Base_ptr _STLP_CALL _Rebalance_for_erase(_Base_ptr __z,
    119                                                    _Base_ptr& __root,
    120                                                    _Base_ptr& __leftmost,
    121                                                    _Base_ptr& __rightmost);
    122   // those are from _Rb_tree_base_iterator - moved here to reduce code bloat
    123   // moved here to reduce code bloat without templatizing _Rb_tree_base_iterator
    124   static _Base_ptr  _STLP_CALL _M_increment (_Base_ptr);
    125   static _Base_ptr  _STLP_CALL _M_decrement (_Base_ptr);
    126   static void       _STLP_CALL _Rotate_left (_Base_ptr __x, _Base_ptr& __root);
    127   static void       _STLP_CALL _Rotate_right(_Base_ptr __x, _Base_ptr& __root);
    128 };
    129 
    130 # if defined (_STLP_USE_TEMPLATE_EXPORT)
    131 _STLP_EXPORT_TEMPLATE_CLASS _Rb_global<bool>;
    132 # endif
    133 
    134 typedef _Rb_global<bool> _Rb_global_inst;
    135 
    136 struct _Rb_tree_base_iterator {
    137   typedef _Rb_tree_node_base*        _Base_ptr;
    138   typedef bidirectional_iterator_tag iterator_category;
    139   typedef ptrdiff_t                  difference_type;
    140   _Base_ptr _M_node;
    141   _Rb_tree_base_iterator() : _M_node(0) {}
    142   _Rb_tree_base_iterator(_Base_ptr __x) : _M_node(__x) {}
    143 };
    144 
    145 template <class _Value, class _Traits>
    146 struct _Rb_tree_iterator : public _Rb_tree_base_iterator {
    147   typedef _Value value_type;
    148   typedef typename _Traits::reference  reference;
    149   typedef typename _Traits::pointer    pointer;
    150   typedef _Rb_tree_iterator<_Value, _Traits> _Self;
    151   typedef _Rb_tree_node_base*    _Base_ptr;
    152   typedef _Rb_tree_node<_Value>* _Link_type;
    153 
    154   typedef typename _Traits::_NonConstTraits _NonConstTraits;
    155   typedef _Rb_tree_iterator<_Value, _NonConstTraits> iterator;
    156   typedef typename _Traits::_ConstTraits _ConstTraits;
    157   typedef _Rb_tree_iterator<_Value, _ConstTraits> const_iterator;
    158 
    159   _Rb_tree_iterator() {}
    160 #if !defined (_STLP_DEBUG)
    161   /* In STL debug mode we need this constructor implicit for the pointer
    162    * specialization implementation.
    163    */
    164   explicit
    165 #endif
    166   _Rb_tree_iterator(_Base_ptr __x) : _Rb_tree_base_iterator(__x) {}
    167   //copy constructor for iterator and constructor from iterator for const_iterator
    168   _Rb_tree_iterator(const iterator& __it) : _Rb_tree_base_iterator(__it._M_node) {}
    169 
    170   reference operator*() const {
    171     return __STATIC_CAST(_Link_type, _M_node)->_M_value_field;
    172   }
    173 
    174   _STLP_DEFINE_ARROW_OPERATOR
    175 
    176   _Self& operator++() {
    177     _M_node = _Rb_global_inst::_M_increment(_M_node);
    178     return *this;
    179   }
    180   _Self operator++(int) {
    181     _Self __tmp = *this;
    182     ++(*this);
    183     return __tmp;
    184   }
    185 
    186   _Self& operator--() {
    187     _M_node = _Rb_global_inst::_M_decrement(_M_node);
    188     return *this;
    189   }
    190   _Self operator--(int) {
    191     _Self __tmp = *this;
    192     --(*this);
    193     return __tmp;
    194   }
    195 
    196   bool operator == (const_iterator __rhs) const {
    197     return _M_node == __rhs._M_node;
    198   }
    199   bool operator != (const_iterator __rhs) const {
    200     return _M_node != __rhs._M_node;
    201   }
    202 };
    203 
    204 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    205 _STLP_MOVE_TO_STD_NAMESPACE
    206 template <class _Value, class _Traits>
    207 struct __type_traits<_STLP_PRIV _Rb_tree_iterator<_Value, _Traits> > {
    208   typedef __false_type   has_trivial_default_constructor;
    209   typedef __true_type    has_trivial_copy_constructor;
    210   typedef __true_type    has_trivial_assignment_operator;
    211   typedef __true_type    has_trivial_destructor;
    212   typedef __false_type   is_POD_type;
    213 };
    214 _STLP_MOVE_TO_PRIV_NAMESPACE
    215 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
    216 
    217 #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
    218 _STLP_MOVE_TO_STD_NAMESPACE
    219 template <class _Value, class _Traits>
    220 inline _Value* value_type(const _STLP_PRIV _Rb_tree_iterator<_Value, _Traits>&)
    221 { return (_Value*)0; }
    222 inline bidirectional_iterator_tag iterator_category(const _STLP_PRIV _Rb_tree_base_iterator&)
    223 { return bidirectional_iterator_tag(); }
    224 inline ptrdiff_t* distance_type(const _STLP_PRIV _Rb_tree_base_iterator&)
    225 { return (ptrdiff_t*) 0; }
    226 _STLP_MOVE_TO_PRIV_NAMESPACE
    227 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
    228 
    229 // Base class to help EH
    230 
    231 template <class _Tp, class _Alloc>
    232 class _Rb_tree_base {
    233 public:
    234   typedef _Rb_tree_node_base _Node_base;
    235   typedef _Rb_tree_node<_Tp> _Node;
    236   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
    237   typedef _Alloc allocator_type;
    238 private:
    239   typedef _Rb_tree_base<_Tp, _Alloc> _Self;
    240   typedef typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator_type;
    241   typedef _STLP_alloc_proxy<_Node_base, _Node, _M_node_allocator_type> _AllocProxy;
    242 
    243 public:
    244   allocator_type get_allocator() const {
    245     return _STLP_CONVERT_ALLOCATOR(_M_header, _Tp);
    246   }
    247 
    248 protected:
    249   _Rb_tree_base(const allocator_type& __a) :
    250     _M_header(_STLP_CONVERT_ALLOCATOR(__a, _Node), _Node_base() ) {
    251     _M_empty_initialize();
    252   }
    253 
    254 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    255   _Rb_tree_base(__move_source<_Self> src) :
    256     _M_header(__move_source<_AllocProxy>(src.get()._M_header)) {
    257     _M_rebind(&src.get()._M_header._M_data);
    258     src.get()._M_empty_initialize();
    259   }
    260 #endif
    261 
    262   void _M_empty_initialize() {
    263     _M_header._M_data._M_color = _S_rb_tree_red; // used to distinguish header from
    264                                                  // __root, in iterator.operator++
    265     _M_header._M_data._M_parent = 0;
    266     _M_header._M_data._M_left = &_M_header._M_data;
    267     _M_header._M_data._M_right = &_M_header._M_data;
    268   }
    269 
    270   void _M_rebind(_Node_base *__static_node) {
    271     if (_M_header._M_data._M_parent != 0) {
    272       _M_header._M_data._M_parent->_M_parent = &_M_header._M_data;
    273     }
    274     if (_M_header._M_data._M_right == __static_node) {
    275       _M_header._M_data._M_right = &_M_header._M_data;
    276     }
    277     if (_M_header._M_data._M_left == __static_node) {
    278       _M_header._M_data._M_left = &_M_header._M_data;
    279     }
    280   }
    281 
    282   _AllocProxy _M_header;
    283 };
    284 
    285 #if defined (_STLP_DEBUG)
    286 #  define _Rb_tree _STLP_NON_DBG_NAME(Rb_tree)
    287 #endif
    288 
    289 template <class _Key, class _Compare,
    290           class _Value, class _KeyOfValue, class _Traits,
    291           _STLP_DFL_TMPL_PARAM(_Alloc, allocator<_Value>) >
    292 class _Rb_tree : public _Rb_tree_base<_Value, _Alloc> {
    293   typedef _Rb_tree_base<_Value, _Alloc> _Base;
    294   typedef _Rb_tree<_Key, _Compare, _Value, _KeyOfValue, _Traits, _Alloc> _Self;
    295 protected:
    296   typedef _Rb_tree_node_base * _Base_ptr;
    297   typedef _Rb_tree_node<_Value> _Node;
    298   typedef _Node* _Link_type;
    299   typedef _Rb_tree_Color_type _Color_type;
    300 public:
    301   typedef _Key key_type;
    302   typedef _Value value_type;
    303   typedef typename _Traits::pointer pointer;
    304   typedef const value_type* const_pointer;
    305   typedef typename _Traits::reference reference;
    306   typedef const value_type& const_reference;
    307   typedef size_t size_type;
    308   typedef ptrdiff_t difference_type;
    309   typedef bidirectional_iterator_tag _Iterator_category;
    310   typedef typename _Base::allocator_type allocator_type;
    311 
    312 protected:
    313 
    314   _STLP_KEY_TYPE_FOR_CONT_EXT(key_type)
    315   _Base_ptr _M_create_node(const value_type& __x) {
    316     _Link_type __tmp = this->_M_header.allocate(1);
    317     _STLP_TRY {
    318       _Copy_Construct(&__tmp->_M_value_field, __x);
    319     }
    320     _STLP_UNWIND(this->_M_header.deallocate(__tmp,1))
    321     _S_left(__tmp) = 0;
    322     _S_right(__tmp) = 0;
    323     return __tmp;
    324   }
    325 
    326   _Base_ptr _M_clone_node(_Base_ptr __x) {
    327     _Base_ptr __tmp = _M_create_node(_S_value(__x));
    328     _S_color(__tmp) = _S_color(__x);
    329     return __tmp;
    330   }
    331 
    332   size_type _M_node_count; // keeps track of size of tree
    333   _Compare _M_key_compare;
    334 
    335   _Base_ptr _M_root() const
    336   { return this->_M_header._M_data._M_parent; }
    337   _Base_ptr _M_leftmost() const
    338   { return this->_M_header._M_data._M_left; }
    339   _Base_ptr _M_rightmost() const
    340   { return this->_M_header._M_data._M_right; }
    341 
    342   _Base_ptr& _M_root()
    343   { return this->_M_header._M_data._M_parent; }
    344   _Base_ptr& _M_leftmost()
    345   { return this->_M_header._M_data._M_left; }
    346   _Base_ptr& _M_rightmost()
    347   { return this->_M_header._M_data._M_right; }
    348 
    349   static _Base_ptr& _STLP_CALL _S_left(_Base_ptr __x)
    350   { return __x->_M_left; }
    351   static _Base_ptr& _STLP_CALL _S_right(_Base_ptr __x)
    352   { return __x->_M_right; }
    353   static _Base_ptr& _STLP_CALL _S_parent(_Base_ptr __x)
    354   { return __x->_M_parent; }
    355   static value_type& _STLP_CALL _S_value(_Base_ptr __x)
    356   { return __STATIC_CAST(_Link_type, __x)->_M_value_field; }
    357   static const _Key& _STLP_CALL _S_key(_Base_ptr __x)
    358   { return _KeyOfValue()(_S_value(__x));}
    359   static _Color_type& _STLP_CALL _S_color(_Base_ptr __x)
    360   { return (_Color_type&)(__x->_M_color); }
    361 
    362   static _Base_ptr _STLP_CALL _S_minimum(_Base_ptr __x)
    363   { return _Rb_tree_node_base::_S_minimum(__x); }
    364 
    365   static _Base_ptr _STLP_CALL _S_maximum(_Base_ptr __x)
    366   { return _Rb_tree_node_base::_S_maximum(__x); }
    367 
    368 public:
    369   typedef typename _Traits::_NonConstTraits _NonConstTraits;
    370   typedef typename _Traits::_ConstTraits _ConstTraits;
    371   typedef _Rb_tree_iterator<value_type, _NonConstTraits> iterator;
    372   typedef _Rb_tree_iterator<value_type, _ConstTraits> const_iterator;
    373   _STLP_DECLARE_BIDIRECTIONAL_REVERSE_ITERATORS;
    374 
    375 private:
    376   iterator _M_insert(_Base_ptr __parent, const value_type& __val, _Base_ptr __on_left = 0, _Base_ptr __on_right = 0);
    377   _Base_ptr _M_copy(_Base_ptr __x, _Base_ptr __p);
    378   void _M_erase(_Base_ptr __x);
    379 
    380 public:
    381                                 // allocation/deallocation
    382   _Rb_tree()
    383     : _Rb_tree_base<_Value, _Alloc>(allocator_type()), _M_node_count(0), _M_key_compare(_Compare())
    384     {}
    385 
    386   _Rb_tree(const _Compare& __comp)
    387     : _Rb_tree_base<_Value, _Alloc>(allocator_type()), _M_node_count(0), _M_key_compare(__comp)
    388     {}
    389 
    390   _Rb_tree(const _Compare& __comp, const allocator_type& __a)
    391     : _Rb_tree_base<_Value, _Alloc>(__a), _M_node_count(0), _M_key_compare(__comp)
    392     {}
    393 
    394   _Rb_tree(const _Self& __x)
    395     : _Rb_tree_base<_Value, _Alloc>(__x.get_allocator()),
    396       _M_node_count(0), _M_key_compare(__x._M_key_compare) {
    397     if (__x._M_root() != 0) {
    398       _S_color(&this->_M_header._M_data) = _S_rb_tree_red;
    399       _M_root() = _M_copy(__x._M_root(), &this->_M_header._M_data);
    400       _M_leftmost() = _S_minimum(_M_root());
    401       _M_rightmost() = _S_maximum(_M_root());
    402     }
    403     _M_node_count = __x._M_node_count;
    404   }
    405 
    406 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    407   _Rb_tree(__move_source<_Self> src)
    408     : _Rb_tree_base<_Value, _Alloc>(__move_source<_Base>(src.get())),
    409       _M_node_count(src.get()._M_node_count),
    410       _M_key_compare(_AsMoveSource(src.get()._M_key_compare))
    411   { src.get()._M_node_count = 0; }
    412 #endif
    413 
    414   ~_Rb_tree() { clear(); }
    415   _Self& operator=(const _Self& __x);
    416 
    417 public:
    418                                 // accessors:
    419   _Compare key_comp() const { return _M_key_compare; }
    420 
    421   iterator begin() { return iterator(_M_leftmost()); }
    422   const_iterator begin() const { return const_iterator(_M_leftmost()); }
    423   iterator end() { return iterator(&this->_M_header._M_data); }
    424   const_iterator end() const { return const_iterator(__CONST_CAST(_Base_ptr, &this->_M_header._M_data)); }
    425 
    426   reverse_iterator rbegin() { return reverse_iterator(end()); }
    427   const_reverse_iterator rbegin() const
    428   { return const_reverse_iterator(end()); }
    429   reverse_iterator rend() { return reverse_iterator(begin()); }
    430   const_reverse_iterator rend() const
    431   { return const_reverse_iterator(begin()); }
    432   bool empty() const { return _M_node_count == 0; }
    433   size_type size() const { return _M_node_count; }
    434   size_type max_size() const { return size_type(-1); }
    435 
    436   void swap(_Self& __t) {
    437     if (__t.empty()) {
    438       if (this->empty()) return;
    439       __t._M_header.swap(this->_M_header);
    440       __t._M_rebind(&this->_M_header._M_data);
    441       this->_M_empty_initialize();
    442     }
    443     else if (this->empty()) {
    444       __t.swap(*this);
    445       return;
    446     }
    447     else {
    448       this->_M_header.swap(__t._M_header);
    449       this->_M_rebind(&__t._M_header._M_data);
    450       __t._M_rebind(&this->_M_header._M_data);
    451     }
    452     _STLP_STD::swap(_M_node_count, __t._M_node_count);
    453     _STLP_STD::swap(_M_key_compare, __t._M_key_compare);
    454   }
    455 
    456 public:
    457                                 // insert/erase
    458   pair<iterator,bool> insert_unique(const value_type& __x);
    459   iterator insert_equal(const value_type& __x);
    460 
    461   iterator insert_unique(iterator __pos, const value_type& __x);
    462   iterator insert_equal(iterator __pos, const value_type& __x);
    463 
    464 #if defined (_STLP_MEMBER_TEMPLATES)
    465   template<class _II> void insert_equal(_II __first, _II __last) {
    466     for ( ; __first != __last; ++__first)
    467       insert_equal(*__first);
    468   }
    469   template<class _II> void insert_unique(_II __first, _II __last) {
    470     for ( ; __first != __last; ++__first)
    471       insert_unique(*__first);
    472   }
    473 #else
    474   void insert_unique(const_iterator __first, const_iterator __last) {
    475     for ( ; __first != __last; ++__first)
    476       insert_unique(*__first);
    477   }
    478   void insert_unique(const value_type* __first, const value_type* __last) {
    479     for ( ; __first != __last; ++__first)
    480       insert_unique(*__first);
    481   }
    482   void insert_equal(const_iterator __first, const_iterator __last) {
    483     for ( ; __first != __last; ++__first)
    484       insert_equal(*__first);
    485   }
    486   void insert_equal(const value_type* __first, const value_type* __last) {
    487     for ( ; __first != __last; ++__first)
    488       insert_equal(*__first);
    489   }
    490 #endif
    491 
    492   void erase(iterator __pos) {
    493     _Base_ptr __x = _Rb_global_inst::_Rebalance_for_erase(__pos._M_node,
    494                                                           this->_M_header._M_data._M_parent,
    495                                                           this->_M_header._M_data._M_left,
    496                                                           this->_M_header._M_data._M_right);
    497     _STLP_STD::_Destroy(&_S_value(__x));
    498     this->_M_header.deallocate(__STATIC_CAST(_Link_type, __x), 1);
    499     --_M_node_count;
    500   }
    501 
    502   size_type erase(const key_type& __x) {
    503     pair<iterator,iterator> __p = equal_range(__x);
    504     size_type __n = _STLP_STD::distance(__p.first, __p.second);
    505     erase(__p.first, __p.second);
    506     return __n;
    507   }
    508 
    509   size_type erase_unique(const key_type& __x) {
    510     iterator __i = find(__x);
    511     if (__i._M_node != &this->_M_header._M_data) {
    512       erase(__i);
    513       return 1;
    514     }
    515     return 0;
    516   }
    517 
    518   void erase(iterator __first, iterator __last) {
    519     if (__first._M_node == this->_M_header._M_data._M_left && // begin()
    520         __last._M_node == &this->_M_header._M_data)           // end()
    521       clear();
    522     else
    523       while (__first != __last) erase(__first++);
    524   }
    525 
    526   void erase(const key_type* __first, const key_type* __last) {
    527     while (__first != __last) erase(*__first++);
    528   }
    529 
    530   void clear() {
    531     if (_M_node_count != 0) {
    532       _M_erase(_M_root());
    533       _M_leftmost() = &this->_M_header._M_data;
    534       _M_root() = 0;
    535       _M_rightmost() = &this->_M_header._M_data;
    536       _M_node_count = 0;
    537     }
    538   }
    539 
    540 public:
    541                                 // set operations:
    542   _STLP_TEMPLATE_FOR_CONT_EXT
    543   iterator find(const _KT& __k) { return iterator(_M_find(__k)); }
    544   _STLP_TEMPLATE_FOR_CONT_EXT
    545   const_iterator find(const _KT& __k) const { return const_iterator(_M_find(__k)); }
    546 private:
    547   _STLP_TEMPLATE_FOR_CONT_EXT
    548   _Base_ptr _M_find(const _KT& __k) const {
    549     _Base_ptr __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data);      // Last node which is not less than __k.
    550     _Base_ptr __x = _M_root();      // Current node.
    551 
    552     while (__x != 0)
    553       if (!_M_key_compare(_S_key(__x), __k))
    554         __y = __x, __x = _S_left(__x);
    555       else
    556         __x = _S_right(__x);
    557 
    558     if (__y != &this->_M_header._M_data) {
    559       if (_M_key_compare(__k, _S_key(__y))) {
    560         __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data);
    561       }
    562     }
    563     return __y;
    564   }
    565 
    566   _STLP_TEMPLATE_FOR_CONT_EXT
    567   _Base_ptr _M_lower_bound(const _KT& __k) const {
    568     _Base_ptr __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data); /* Last node which is not less than __k. */
    569     _Base_ptr __x = _M_root(); /* Current node. */
    570 
    571     while (__x != 0)
    572       if (!_M_key_compare(_S_key(__x), __k))
    573         __y = __x, __x = _S_left(__x);
    574       else
    575         __x = _S_right(__x);
    576 
    577     return __y;
    578   }
    579 
    580   _STLP_TEMPLATE_FOR_CONT_EXT
    581   _Base_ptr _M_upper_bound(const _KT& __k) const {
    582     _Base_ptr __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data); /* Last node which is greater than __k. */
    583     _Base_ptr __x = _M_root(); /* Current node. */
    584 
    585     while (__x != 0)
    586       if (_M_key_compare(__k, _S_key(__x)))
    587         __y = __x, __x = _S_left(__x);
    588       else
    589         __x = _S_right(__x);
    590 
    591     return __y;
    592   }
    593 
    594 public:
    595   _STLP_TEMPLATE_FOR_CONT_EXT
    596   size_type count(const _KT& __x) const {
    597     pair<const_iterator, const_iterator> __p = equal_range(__x);
    598     return _STLP_STD::distance(__p.first, __p.second);
    599   }
    600   _STLP_TEMPLATE_FOR_CONT_EXT
    601   iterator lower_bound(const _KT& __x) { return iterator(_M_lower_bound(__x)); }
    602   _STLP_TEMPLATE_FOR_CONT_EXT
    603   const_iterator lower_bound(const _KT& __x) const { return const_iterator(_M_lower_bound(__x)); }
    604   _STLP_TEMPLATE_FOR_CONT_EXT
    605   iterator upper_bound(const _KT& __x) { return iterator(_M_upper_bound(__x)); }
    606   _STLP_TEMPLATE_FOR_CONT_EXT
    607   const_iterator upper_bound(const _KT& __x) const { return const_iterator(_M_upper_bound(__x)); }
    608   _STLP_TEMPLATE_FOR_CONT_EXT
    609   pair<iterator,iterator> equal_range(const _KT& __x)
    610   { return pair<iterator, iterator>(lower_bound(__x), upper_bound(__x)); }
    611   _STLP_TEMPLATE_FOR_CONT_EXT
    612   pair<const_iterator, const_iterator> equal_range(const _KT& __x) const
    613   { return pair<const_iterator, const_iterator>(lower_bound(__x), upper_bound(__x)); }
    614   _STLP_TEMPLATE_FOR_CONT_EXT
    615   pair<iterator,iterator> equal_range_unique(const _KT& __x) {
    616     pair<iterator, iterator> __p;
    617     __p.second = lower_bound(__x);
    618     if (__p.second._M_node != &this->_M_header._M_data &&
    619         !_M_key_compare(__x, _S_key(__p.second._M_node))) {
    620       __p.first = __p.second++;
    621     }
    622     else {
    623       __p.first = __p.second;
    624     }
    625     return __p;
    626   }
    627   _STLP_TEMPLATE_FOR_CONT_EXT
    628   pair<const_iterator, const_iterator> equal_range_unique(const _KT& __x) const {
    629     pair<const_iterator, const_iterator> __p;
    630     __p.second = lower_bound(__x);
    631     if (__p.second._M_node != &this->_M_header._M_data &&
    632         !_M_key_compare(__x, _S_key(__p.second._M_node))) {
    633       __p.first = __p.second++;
    634     }
    635     else {
    636       __p.first = __p.second;
    637     }
    638     return __p;
    639   }
    640 
    641 #if defined (_STLP_DEBUG)
    642 public:
    643   // Debugging.
    644   bool __rb_verify() const;
    645 #endif //_STLP_DEBUG
    646 };
    647 
    648 #if defined (_STLP_DEBUG)
    649 #  undef _Rb_tree
    650 #endif
    651 
    652 _STLP_MOVE_TO_STD_NAMESPACE
    653 
    654 _STLP_END_NAMESPACE
    655 
    656 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
    657 #  include <stl/_tree.c>
    658 #endif
    659 
    660 #if defined (_STLP_DEBUG)
    661 #  include <stl/debug/_tree.h>
    662 #endif
    663 
    664 _STLP_BEGIN_NAMESPACE
    665 
    666 #define _STLP_TEMPLATE_HEADER template <class _Key, class _Compare, class _Value, class _KeyOfValue, class _Traits, class _Alloc>
    667 #define _STLP_TEMPLATE_CONTAINER _STLP_PRIV _Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc>
    668 #include <stl/_relops_cont.h>
    669 #undef _STLP_TEMPLATE_CONTAINER
    670 #undef _STLP_TEMPLATE_HEADER
    671 
    672 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_NO_MOVE_SEMANTIC)
    673 template <class _Key, class _Compare, class _Value, class _KeyOfValue, class _Traits, class _Alloc>
    674 struct __move_traits<_STLP_PRIV _Rb_tree<_Key, _Compare, _Value, _KeyOfValue, _Traits, _Alloc> >
    675   : _STLP_PRIV __move_traits_help2<_Compare, _Alloc> {};
    676 #endif
    677 
    678 _STLP_END_NAMESPACE
    679 
    680 #endif /* _STLP_INTERNAL_TREE_H */
    681 
    682 // Local Variables:
    683 // mode:C++
    684 // End:
    685