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