epoc32/include/tools/stlport/stl/_tree.c
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
williamr@4
     1
/*
williamr@4
     2
 *
williamr@4
     3
 *
williamr@4
     4
 * Copyright (c) 1994
williamr@4
     5
 * Hewlett-Packard Company
williamr@4
     6
 *
williamr@4
     7
 * Copyright (c) 1996,1997
williamr@4
     8
 * Silicon Graphics Computer Systems, Inc.
williamr@4
     9
 *
williamr@4
    10
 * Copyright (c) 1997
williamr@4
    11
 * Moscow Center for SPARC Technology
williamr@4
    12
 *
williamr@4
    13
 * Copyright (c) 1999
williamr@4
    14
 * Boris Fomitchev
williamr@4
    15
 *
williamr@4
    16
 * This material is provided "as is", with absolutely no warranty expressed
williamr@4
    17
 * or implied. Any use is at your own risk.
williamr@4
    18
 *
williamr@4
    19
 * Permission to use or copy this software for any purpose is hereby granted
williamr@4
    20
 * without fee, provided the above notices are retained on all copies.
williamr@4
    21
 * Permission to modify the code and to distribute modified code is granted,
williamr@4
    22
 * provided the above notices are retained, and a notice that the code was
williamr@4
    23
 * modified is included with the above copyright notice.
williamr@4
    24
 *
williamr@4
    25
 * Modified CRP 7/10/00 for improved conformance / efficiency on insert_unique /
williamr@4
    26
 * insert_equal with valid hint -- efficiency is improved all around, and it is
williamr@4
    27
 * should now be standard conforming for complexity on insert point immediately
williamr@4
    28
 * after hint (amortized constant time).
williamr@4
    29
 *
williamr@4
    30
 */
williamr@4
    31
#ifndef _STLP_TREE_C
williamr@4
    32
#define _STLP_TREE_C
williamr@4
    33
williamr@4
    34
#ifndef _STLP_INTERNAL_TREE_H
williamr@4
    35
#  include <stl/_tree.h>
williamr@4
    36
#endif
williamr@4
    37
williamr@4
    38
#if defined (_STLP_DEBUG)
williamr@4
    39
#  define _Rb_tree _STLP_NON_DBG_NAME(Rb_tree)
williamr@4
    40
#endif
williamr@4
    41
williamr@4
    42
// fbp: these defines are for outline methods definitions.
williamr@4
    43
// needed for definitions to be portable. Should not be used in method bodies.
williamr@4
    44
#if defined (_STLP_NESTED_TYPE_PARAM_BUG)
williamr@4
    45
#  define __iterator__  _Rb_tree_iterator<_Value, _STLP_HEADER_TYPENAME _Traits::_NonConstTraits>
williamr@4
    46
#  define __size_type__ size_t
williamr@4
    47
#  define iterator __iterator__
williamr@4
    48
#else
williamr@4
    49
#  define __iterator__  _STLP_TYPENAME_ON_RETURN_TYPE _Rb_tree<_Key, _Compare, _Value, _KeyOfValue, _Traits, _Alloc>::iterator
williamr@4
    50
#  define __size_type__  _STLP_TYPENAME_ON_RETURN_TYPE _Rb_tree<_Key, _Compare, _Value, _KeyOfValue, _Traits, _Alloc>::size_type
williamr@4
    51
#endif
williamr@4
    52
williamr@4
    53
_STLP_BEGIN_NAMESPACE
williamr@4
    54
williamr@4
    55
_STLP_MOVE_TO_PRIV_NAMESPACE
williamr@4
    56
williamr@4
    57
#if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
williamr@4
    58
williamr@4
    59
template <class _Dummy> void _STLP_CALL
williamr@4
    60
_Rb_global<_Dummy>::_Rotate_left(_Rb_tree_node_base* __x,
williamr@4
    61
                                 _Rb_tree_node_base*& __root) {
williamr@4
    62
  _Rb_tree_node_base* __y = __x->_M_right;
williamr@4
    63
  __x->_M_right = __y->_M_left;
williamr@4
    64
  if (__y->_M_left != 0)
williamr@4
    65
    __y->_M_left->_M_parent = __x;
williamr@4
    66
  __y->_M_parent = __x->_M_parent;
williamr@4
    67
williamr@4
    68
  if (__x == __root)
williamr@4
    69
    __root = __y;
williamr@4
    70
  else if (__x == __x->_M_parent->_M_left)
williamr@4
    71
    __x->_M_parent->_M_left = __y;
williamr@4
    72
  else
williamr@4
    73
    __x->_M_parent->_M_right = __y;
williamr@4
    74
  __y->_M_left = __x;
williamr@4
    75
  __x->_M_parent = __y;
williamr@4
    76
}
williamr@4
    77
williamr@4
    78
template <class _Dummy> void _STLP_CALL
williamr@4
    79
_Rb_global<_Dummy>::_Rotate_right(_Rb_tree_node_base* __x,
williamr@4
    80
                                  _Rb_tree_node_base*& __root) {
williamr@4
    81
  _Rb_tree_node_base* __y = __x->_M_left;
williamr@4
    82
  __x->_M_left = __y->_M_right;
williamr@4
    83
  if (__y->_M_right != 0)
williamr@4
    84
    __y->_M_right->_M_parent = __x;
williamr@4
    85
  __y->_M_parent = __x->_M_parent;
williamr@4
    86
williamr@4
    87
  if (__x == __root)
williamr@4
    88
    __root = __y;
williamr@4
    89
  else if (__x == __x->_M_parent->_M_right)
williamr@4
    90
    __x->_M_parent->_M_right = __y;
williamr@4
    91
  else
williamr@4
    92
    __x->_M_parent->_M_left = __y;
williamr@4
    93
  __y->_M_right = __x;
williamr@4
    94
  __x->_M_parent = __y;
williamr@4
    95
}
williamr@4
    96
williamr@4
    97
template <class _Dummy> void _STLP_CALL
williamr@4
    98
_Rb_global<_Dummy>::_Rebalance(_Rb_tree_node_base* __x,
williamr@4
    99
                               _Rb_tree_node_base*& __root) {
williamr@4
   100
  __x->_M_color = _S_rb_tree_red;
williamr@4
   101
  while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) {
williamr@4
   102
    if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) {
williamr@4
   103
      _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right;
williamr@4
   104
      if (__y && __y->_M_color == _S_rb_tree_red) {
williamr@4
   105
        __x->_M_parent->_M_color = _S_rb_tree_black;
williamr@4
   106
        __y->_M_color = _S_rb_tree_black;
williamr@4
   107
        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
williamr@4
   108
        __x = __x->_M_parent->_M_parent;
williamr@4
   109
      }
williamr@4
   110
      else {
williamr@4
   111
        if (__x == __x->_M_parent->_M_right) {
williamr@4
   112
          __x = __x->_M_parent;
williamr@4
   113
          _Rotate_left(__x, __root);
williamr@4
   114
        }
williamr@4
   115
        __x->_M_parent->_M_color = _S_rb_tree_black;
williamr@4
   116
        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
williamr@4
   117
        _Rotate_right(__x->_M_parent->_M_parent, __root);
williamr@4
   118
      }
williamr@4
   119
    }
williamr@4
   120
    else {
williamr@4
   121
      _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left;
williamr@4
   122
      if (__y && __y->_M_color == _S_rb_tree_red) {
williamr@4
   123
        __x->_M_parent->_M_color = _S_rb_tree_black;
williamr@4
   124
        __y->_M_color = _S_rb_tree_black;
williamr@4
   125
        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
williamr@4
   126
        __x = __x->_M_parent->_M_parent;
williamr@4
   127
      }
williamr@4
   128
      else {
williamr@4
   129
        if (__x == __x->_M_parent->_M_left) {
williamr@4
   130
          __x = __x->_M_parent;
williamr@4
   131
          _Rotate_right(__x, __root);
williamr@4
   132
        }
williamr@4
   133
        __x->_M_parent->_M_color = _S_rb_tree_black;
williamr@4
   134
        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
williamr@4
   135
        _Rotate_left(__x->_M_parent->_M_parent, __root);
williamr@4
   136
      }
williamr@4
   137
    }
williamr@4
   138
  }
williamr@4
   139
  __root->_M_color = _S_rb_tree_black;
williamr@4
   140
}
williamr@4
   141
williamr@4
   142
template <class _Dummy> _Rb_tree_node_base* _STLP_CALL
williamr@4
   143
_Rb_global<_Dummy>::_Rebalance_for_erase(_Rb_tree_node_base* __z,
williamr@4
   144
                                         _Rb_tree_node_base*& __root,
williamr@4
   145
                                         _Rb_tree_node_base*& __leftmost,
williamr@4
   146
                                         _Rb_tree_node_base*& __rightmost) {
williamr@4
   147
  _Rb_tree_node_base* __y = __z;
williamr@4
   148
  _Rb_tree_node_base* __x;
williamr@4
   149
  _Rb_tree_node_base* __x_parent;
williamr@4
   150
williamr@4
   151
  if (__y->_M_left == 0)     // __z has at most one non-null child. y == z.
williamr@4
   152
    __x = __y->_M_right;     // __x might be null.
williamr@4
   153
  else {
williamr@4
   154
    if (__y->_M_right == 0)  // __z has exactly one non-null child. y == z.
williamr@4
   155
      __x = __y->_M_left;    // __x is not null.
williamr@4
   156
    else {                   // __z has two non-null children.  Set __y to
williamr@4
   157
      __y = _Rb_tree_node_base::_S_minimum(__y->_M_right);   //   __z's successor.  __x might be null.
williamr@4
   158
      __x = __y->_M_right;
williamr@4
   159
    }
williamr@4
   160
  }
williamr@4
   161
williamr@4
   162
  if (__y != __z) {          // relink y in place of z.  y is z's successor
williamr@4
   163
    __z->_M_left->_M_parent = __y;
williamr@4
   164
    __y->_M_left = __z->_M_left;
williamr@4
   165
    if (__y != __z->_M_right) {
williamr@4
   166
      __x_parent = __y->_M_parent;
williamr@4
   167
      if (__x) __x->_M_parent = __y->_M_parent;
williamr@4
   168
      __y->_M_parent->_M_left = __x;      // __y must be a child of _M_left
williamr@4
   169
      __y->_M_right = __z->_M_right;
williamr@4
   170
      __z->_M_right->_M_parent = __y;
williamr@4
   171
    }
williamr@4
   172
    else
williamr@4
   173
      __x_parent = __y;
williamr@4
   174
    if (__root == __z)
williamr@4
   175
      __root = __y;
williamr@4
   176
    else if (__z->_M_parent->_M_left == __z)
williamr@4
   177
      __z->_M_parent->_M_left = __y;
williamr@4
   178
    else
williamr@4
   179
      __z->_M_parent->_M_right = __y;
williamr@4
   180
    __y->_M_parent = __z->_M_parent;
williamr@4
   181
    _STLP_STD::swap(__y->_M_color, __z->_M_color);
williamr@4
   182
    __y = __z;
williamr@4
   183
    // __y now points to node to be actually deleted
williamr@4
   184
  }
williamr@4
   185
  else {                        // __y == __z
williamr@4
   186
    __x_parent = __y->_M_parent;
williamr@4
   187
    if (__x) __x->_M_parent = __y->_M_parent;
williamr@4
   188
    if (__root == __z)
williamr@4
   189
      __root = __x;
williamr@4
   190
    else {
williamr@4
   191
      if (__z->_M_parent->_M_left == __z)
williamr@4
   192
        __z->_M_parent->_M_left = __x;
williamr@4
   193
      else
williamr@4
   194
        __z->_M_parent->_M_right = __x;
williamr@4
   195
    }
williamr@4
   196
williamr@4
   197
    if (__leftmost == __z) {
williamr@4
   198
      if (__z->_M_right == 0)        // __z->_M_left must be null also
williamr@4
   199
        __leftmost = __z->_M_parent;
williamr@4
   200
    // makes __leftmost == _M_header if __z == __root
williamr@4
   201
      else
williamr@4
   202
        __leftmost = _Rb_tree_node_base::_S_minimum(__x);
williamr@4
   203
    }
williamr@4
   204
    if (__rightmost == __z) {
williamr@4
   205
      if (__z->_M_left == 0)         // __z->_M_right must be null also
williamr@4
   206
        __rightmost = __z->_M_parent;
williamr@4
   207
    // makes __rightmost == _M_header if __z == __root
williamr@4
   208
      else                      // __x == __z->_M_left
williamr@4
   209
        __rightmost = _Rb_tree_node_base::_S_maximum(__x);
williamr@4
   210
    }
williamr@4
   211
  }
williamr@4
   212
williamr@4
   213
  if (__y->_M_color != _S_rb_tree_red) {
williamr@4
   214
    while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black))
williamr@4
   215
      if (__x == __x_parent->_M_left) {
williamr@4
   216
        _Rb_tree_node_base* __w = __x_parent->_M_right;
williamr@4
   217
        if (__w->_M_color == _S_rb_tree_red) {
williamr@4
   218
          __w->_M_color = _S_rb_tree_black;
williamr@4
   219
          __x_parent->_M_color = _S_rb_tree_red;
williamr@4
   220
          _Rotate_left(__x_parent, __root);
williamr@4
   221
          __w = __x_parent->_M_right;
williamr@4
   222
        }
williamr@4
   223
        if ((__w->_M_left == 0 ||
williamr@4
   224
             __w->_M_left->_M_color == _S_rb_tree_black) && (__w->_M_right == 0 ||
williamr@4
   225
             __w->_M_right->_M_color == _S_rb_tree_black)) {
williamr@4
   226
          __w->_M_color = _S_rb_tree_red;
williamr@4
   227
          __x = __x_parent;
williamr@4
   228
          __x_parent = __x_parent->_M_parent;
williamr@4
   229
        } else {
williamr@4
   230
          if (__w->_M_right == 0 ||
williamr@4
   231
              __w->_M_right->_M_color == _S_rb_tree_black) {
williamr@4
   232
            if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;
williamr@4
   233
            __w->_M_color = _S_rb_tree_red;
williamr@4
   234
            _Rotate_right(__w, __root);
williamr@4
   235
            __w = __x_parent->_M_right;
williamr@4
   236
          }
williamr@4
   237
          __w->_M_color = __x_parent->_M_color;
williamr@4
   238
          __x_parent->_M_color = _S_rb_tree_black;
williamr@4
   239
          if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;
williamr@4
   240
          _Rotate_left(__x_parent, __root);
williamr@4
   241
          break;
williamr@4
   242
        }
williamr@4
   243
      } else {                  // same as above, with _M_right <-> _M_left.
williamr@4
   244
        _Rb_tree_node_base* __w = __x_parent->_M_left;
williamr@4
   245
        if (__w->_M_color == _S_rb_tree_red) {
williamr@4
   246
          __w->_M_color = _S_rb_tree_black;
williamr@4
   247
          __x_parent->_M_color = _S_rb_tree_red;
williamr@4
   248
          _Rotate_right(__x_parent, __root);
williamr@4
   249
          __w = __x_parent->_M_left;
williamr@4
   250
        }
williamr@4
   251
        if ((__w->_M_right == 0 ||
williamr@4
   252
             __w->_M_right->_M_color == _S_rb_tree_black) && (__w->_M_left == 0 ||
williamr@4
   253
             __w->_M_left->_M_color == _S_rb_tree_black)) {
williamr@4
   254
          __w->_M_color = _S_rb_tree_red;
williamr@4
   255
          __x = __x_parent;
williamr@4
   256
          __x_parent = __x_parent->_M_parent;
williamr@4
   257
        } else {
williamr@4
   258
          if (__w->_M_left == 0 ||
williamr@4
   259
              __w->_M_left->_M_color == _S_rb_tree_black) {
williamr@4
   260
            if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;
williamr@4
   261
            __w->_M_color = _S_rb_tree_red;
williamr@4
   262
            _Rotate_left(__w, __root);
williamr@4
   263
            __w = __x_parent->_M_left;
williamr@4
   264
          }
williamr@4
   265
          __w->_M_color = __x_parent->_M_color;
williamr@4
   266
          __x_parent->_M_color = _S_rb_tree_black;
williamr@4
   267
          if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;
williamr@4
   268
          _Rotate_right(__x_parent, __root);
williamr@4
   269
          break;
williamr@4
   270
        }
williamr@4
   271
      }
williamr@4
   272
    if (__x) __x->_M_color = _S_rb_tree_black;
williamr@4
   273
  }
williamr@4
   274
  return __y;
williamr@4
   275
}
williamr@4
   276
williamr@4
   277
template <class _Dummy> _Rb_tree_node_base* _STLP_CALL
williamr@4
   278
_Rb_global<_Dummy>::_M_decrement(_Rb_tree_node_base* _M_node) {
williamr@4
   279
  if (_M_node->_M_color == _S_rb_tree_red && _M_node->_M_parent->_M_parent == _M_node)
williamr@4
   280
    _M_node = _M_node->_M_right;
williamr@4
   281
  else if (_M_node->_M_left != 0) {
williamr@4
   282
    _M_node = _Rb_tree_node_base::_S_maximum(_M_node->_M_left);
williamr@4
   283
  }
williamr@4
   284
  else {
williamr@4
   285
    _Base_ptr __y = _M_node->_M_parent;
williamr@4
   286
    while (_M_node == __y->_M_left) {
williamr@4
   287
      _M_node = __y;
williamr@4
   288
      __y = __y->_M_parent;
williamr@4
   289
    }
williamr@4
   290
    _M_node = __y;
williamr@4
   291
  }
williamr@4
   292
  return _M_node;
williamr@4
   293
}
williamr@4
   294
williamr@4
   295
template <class _Dummy> _Rb_tree_node_base* _STLP_CALL
williamr@4
   296
_Rb_global<_Dummy>::_M_increment(_Rb_tree_node_base* _M_node) {
williamr@4
   297
  if (_M_node->_M_right != 0) {
williamr@4
   298
    _M_node = _Rb_tree_node_base::_S_minimum(_M_node->_M_right);
williamr@4
   299
  }
williamr@4
   300
  else {
williamr@4
   301
    _Base_ptr __y = _M_node->_M_parent;
williamr@4
   302
    while (_M_node == __y->_M_right) {
williamr@4
   303
      _M_node = __y;
williamr@4
   304
      __y = __y->_M_parent;
williamr@4
   305
    }
williamr@4
   306
    // check special case: This is necessary if _M_node is the
williamr@4
   307
    // _M_head and the tree contains only a single node __y. In
williamr@4
   308
    // that case parent, left and right all point to __y!
williamr@4
   309
    if (_M_node->_M_right != __y)
williamr@4
   310
      _M_node = __y;
williamr@4
   311
  }
williamr@4
   312
  return _M_node;
williamr@4
   313
}
williamr@4
   314
williamr@4
   315
#endif /* _STLP_EXPOSE_GLOBALS_IMPLEMENTATION */
williamr@4
   316
williamr@4
   317
williamr@4
   318
template <class _Key, class _Compare,
williamr@4
   319
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   320
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc>&
williamr@4
   321
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::operator=(
williamr@4
   322
  const _Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc>& __x) {
williamr@4
   323
  if (this != &__x) {
williamr@4
   324
    // Note that _Key may be a constant type.
williamr@4
   325
    clear();
williamr@4
   326
    _M_node_count = 0;
williamr@4
   327
    _M_key_compare = __x._M_key_compare;
williamr@4
   328
    if (__x._M_root() == 0) {
williamr@4
   329
      _M_root() = 0;
williamr@4
   330
      _M_leftmost() = &this->_M_header._M_data;
williamr@4
   331
      _M_rightmost() = &this->_M_header._M_data;
williamr@4
   332
    }
williamr@4
   333
    else {
williamr@4
   334
      _M_root() = _M_copy(__x._M_root(), &this->_M_header._M_data);
williamr@4
   335
      _M_leftmost() = _S_minimum(_M_root());
williamr@4
   336
      _M_rightmost() = _S_maximum(_M_root());
williamr@4
   337
      _M_node_count = __x._M_node_count;
williamr@4
   338
    }
williamr@4
   339
  }
williamr@4
   340
  return *this;
williamr@4
   341
}
williamr@4
   342
williamr@4
   343
// CRP 7/10/00 inserted argument __on_right, which is another hint (meant to
williamr@4
   344
// act like __on_left and ignore a portion of the if conditions -- specify
williamr@4
   345
// __on_right != 0 to bypass comparison as false or __on_left != 0 to bypass
williamr@4
   346
// comparison as true)
williamr@4
   347
template <class _Key, class _Compare,
williamr@4
   348
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   349
__iterator__
williamr@4
   350
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::_M_insert(_Rb_tree_node_base * __parent,
williamr@4
   351
                                                                      const _Value& __val,
williamr@4
   352
                                                                      _Rb_tree_node_base * __on_left,
williamr@4
   353
                                                                      _Rb_tree_node_base * __on_right) {
williamr@4
   354
  // We do not create the node here as, depending on tests, we might call
williamr@4
   355
  // _M_key_compare that can throw an exception.
williamr@4
   356
  _Base_ptr __new_node;
williamr@4
   357
williamr@4
   358
  if ( __parent == &this->_M_header._M_data ) {
williamr@4
   359
    __new_node = _M_create_node(__val);
williamr@4
   360
    _S_left(__parent) = __new_node;   // also makes _M_leftmost() = __new_node
williamr@4
   361
    _M_root() = __new_node;
williamr@4
   362
    _M_rightmost() = __new_node;
williamr@4
   363
  }
williamr@4
   364
  else if ( __on_right == 0 &&     // If __on_right != 0, the remainder fails to false
williamr@4
   365
           ( __on_left != 0 ||     // If __on_left != 0, the remainder succeeds to true
williamr@4
   366
             _M_key_compare( _KeyOfValue()(__val), _S_key(__parent) ) ) ) {
williamr@4
   367
    __new_node = _M_create_node(__val);
williamr@4
   368
    _S_left(__parent) = __new_node;
williamr@4
   369
    if (__parent == _M_leftmost())
williamr@4
   370
      _M_leftmost() = __new_node;   // maintain _M_leftmost() pointing to min node
williamr@4
   371
  }
williamr@4
   372
  else {
williamr@4
   373
    __new_node = _M_create_node(__val);
williamr@4
   374
    _S_right(__parent) = __new_node;
williamr@4
   375
    if (__parent == _M_rightmost())
williamr@4
   376
      _M_rightmost() = __new_node;  // maintain _M_rightmost() pointing to max node
williamr@4
   377
  }
williamr@4
   378
  _S_parent(__new_node) = __parent;
williamr@4
   379
  _Rb_global_inst::_Rebalance(__new_node, this->_M_header._M_data._M_parent);
williamr@4
   380
  ++_M_node_count;
williamr@4
   381
  return iterator(__new_node);
williamr@4
   382
}
williamr@4
   383
williamr@4
   384
template <class _Key, class _Compare,
williamr@4
   385
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   386
__iterator__
williamr@4
   387
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_equal(const _Value& __val) {
williamr@4
   388
  _Base_ptr __y = &this->_M_header._M_data;
williamr@4
   389
  _Base_ptr __x = _M_root();
williamr@4
   390
  while (__x != 0) {
williamr@4
   391
    __y = __x;
williamr@4
   392
    if (_M_key_compare(_KeyOfValue()(__val), _S_key(__x))) {
williamr@4
   393
      __x = _S_left(__x);
williamr@4
   394
    }
williamr@4
   395
    else
williamr@4
   396
      __x = _S_right(__x);
williamr@4
   397
  }
williamr@4
   398
  return _M_insert(__y, __val, __x);
williamr@4
   399
}
williamr@4
   400
williamr@4
   401
williamr@4
   402
template <class _Key, class _Compare,
williamr@4
   403
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   404
pair<__iterator__, bool>
williamr@4
   405
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_unique(const _Value& __val) {
williamr@4
   406
  _Base_ptr __y = &this->_M_header._M_data;
williamr@4
   407
  _Base_ptr __x = _M_root();
williamr@4
   408
  bool __comp = true;
williamr@4
   409
  while (__x != 0) {
williamr@4
   410
    __y = __x;
williamr@4
   411
    __comp = _M_key_compare(_KeyOfValue()(__val), _S_key(__x));
williamr@4
   412
    __x = __comp ? _S_left(__x) : _S_right(__x);
williamr@4
   413
  }
williamr@4
   414
  iterator __j = iterator(__y);
williamr@4
   415
  if (__comp) {
williamr@4
   416
    if (__j == begin())
williamr@4
   417
      return pair<iterator,bool>(_M_insert(__y, __val, /* __x*/ __y), true);
williamr@4
   418
    else
williamr@4
   419
      --__j;
williamr@4
   420
  }
williamr@4
   421
  if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__val))) {
williamr@4
   422
    return pair<iterator,bool>(_M_insert(__y, __val, __x), true);
williamr@4
   423
  }
williamr@4
   424
  return pair<iterator,bool>(__j, false);
williamr@4
   425
}
williamr@4
   426
williamr@4
   427
// Modifications CRP 7/10/00 as noted to improve conformance and
williamr@4
   428
// efficiency.
williamr@4
   429
template <class _Key, class _Compare,
williamr@4
   430
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   431
__iterator__
williamr@4
   432
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_unique(iterator __position,
williamr@4
   433
                                                                          const _Value& __val) {
williamr@4
   434
  if (__position._M_node == this->_M_header._M_data._M_left) { // begin()
williamr@4
   435
williamr@4
   436
    // if the container is empty, fall back on insert_unique.
williamr@4
   437
    if (empty())
williamr@4
   438
      return insert_unique(__val).first;
williamr@4
   439
williamr@4
   440
    if (_M_key_compare(_KeyOfValue()(__val), _S_key(__position._M_node))) {
williamr@4
   441
      return _M_insert(__position._M_node, __val, __position._M_node);
williamr@4
   442
    }
williamr@4
   443
    // first argument just needs to be non-null
williamr@4
   444
    else {
williamr@4
   445
      bool __comp_pos_v = _M_key_compare( _S_key(__position._M_node), _KeyOfValue()(__val) );
williamr@4
   446
williamr@4
   447
      if (__comp_pos_v == false)  // compare > and compare < both false so compare equal
williamr@4
   448
        return __position;
williamr@4
   449
      //Below __comp_pos_v == true
williamr@4
   450
williamr@4
   451
      // Standard-conformance - does the insertion point fall immediately AFTER
williamr@4
   452
      // the hint?
williamr@4
   453
      iterator __after = __position;
williamr@4
   454
      ++__after;
williamr@4
   455
williamr@4
   456
      // Check for only one member -- in that case, __position points to itself,
williamr@4
   457
      // and attempting to increment will cause an infinite loop.
williamr@4
   458
      if (__after._M_node == &this->_M_header._M_data)
williamr@4
   459
        // Check guarantees exactly one member, so comparison was already
williamr@4
   460
        // performed and we know the result; skip repeating it in _M_insert
williamr@4
   461
        // by specifying a non-zero fourth argument.
williamr@4
   462
        return _M_insert(__position._M_node, __val, 0, __position._M_node);
williamr@4
   463
williamr@4
   464
      // All other cases:
williamr@4
   465
williamr@4
   466
      // Optimization to catch insert-equivalent -- save comparison results,
williamr@4
   467
      // and we get this for free.
williamr@4
   468
      if (_M_key_compare( _KeyOfValue()(__val), _S_key(__after._M_node) )) {
williamr@4
   469
        if (_S_right(__position._M_node) == 0)
williamr@4
   470
          return _M_insert(__position._M_node, __val, 0, __position._M_node);
williamr@4
   471
        else
williamr@4
   472
          return _M_insert(__after._M_node, __val, __after._M_node);
williamr@4
   473
      }
williamr@4
   474
      else {
williamr@4
   475
        return insert_unique(__val).first;
williamr@4
   476
      }
williamr@4
   477
    }
williamr@4
   478
  }
williamr@4
   479
  else if (__position._M_node == &this->_M_header._M_data) { // end()
williamr@4
   480
    if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__val))) {
williamr@4
   481
        // pass along to _M_insert that it can skip comparing
williamr@4
   482
        // v, Key ; since compare Key, v was true, compare v, Key must be false.
williamr@4
   483
        return _M_insert(_M_rightmost(), __val, 0, __position._M_node); // Last argument only needs to be non-null
williamr@4
   484
    }
williamr@4
   485
    else
williamr@4
   486
      return insert_unique(__val).first;
williamr@4
   487
  }
williamr@4
   488
  else {
williamr@4
   489
    iterator __before = __position;
williamr@4
   490
    --__before;
williamr@4
   491
williamr@4
   492
    bool __comp_v_pos = _M_key_compare(_KeyOfValue()(__val), _S_key(__position._M_node));
williamr@4
   493
williamr@4
   494
    if (__comp_v_pos
williamr@4
   495
        && _M_key_compare( _S_key(__before._M_node), _KeyOfValue()(__val) )) {
williamr@4
   496
williamr@4
   497
      if (_S_right(__before._M_node) == 0)
williamr@4
   498
        return _M_insert(__before._M_node, __val, 0, __before._M_node); // Last argument only needs to be non-null
williamr@4
   499
      else
williamr@4
   500
        return _M_insert(__position._M_node, __val, __position._M_node);
williamr@4
   501
      // first argument just needs to be non-null
williamr@4
   502
    }
williamr@4
   503
    else {
williamr@4
   504
      // Does the insertion point fall immediately AFTER the hint?
williamr@4
   505
      iterator __after = __position;
williamr@4
   506
      ++__after;
williamr@4
   507
      // Optimization to catch equivalent cases and avoid unnecessary comparisons
williamr@4
   508
      bool __comp_pos_v = !__comp_v_pos;  // Stored this result earlier
williamr@4
   509
      // If the earlier comparison was true, this comparison doesn't need to be
williamr@4
   510
      // performed because it must be false.  However, if the earlier comparison
williamr@4
   511
      // was false, we need to perform this one because in the equal case, both will
williamr@4
   512
      // be false.
williamr@4
   513
      if (!__comp_v_pos) {
williamr@4
   514
        __comp_pos_v = _M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__val));
williamr@4
   515
      }
williamr@4
   516
williamr@4
   517
      if ( (!__comp_v_pos) // comp_v_pos true implies comp_v_pos false
williamr@4
   518
          && __comp_pos_v
williamr@4
   519
          && (__after._M_node == &this->_M_header._M_data ||
williamr@4
   520
              _M_key_compare( _KeyOfValue()(__val), _S_key(__after._M_node) ))) {
williamr@4
   521
        if (_S_right(__position._M_node) == 0)
williamr@4
   522
          return _M_insert(__position._M_node, __val, 0, __position._M_node);
williamr@4
   523
        else
williamr@4
   524
          return _M_insert(__after._M_node, __val, __after._M_node);
williamr@4
   525
      } else {
williamr@4
   526
        // Test for equivalent case
williamr@4
   527
        if (__comp_v_pos == __comp_pos_v)
williamr@4
   528
          return __position;
williamr@4
   529
        else
williamr@4
   530
          return insert_unique(__val).first;
williamr@4
   531
      }
williamr@4
   532
    }
williamr@4
   533
  }
williamr@4
   534
}
williamr@4
   535
williamr@4
   536
template <class _Key, class _Compare,
williamr@4
   537
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   538
__iterator__
williamr@4
   539
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_equal(iterator __position,
williamr@4
   540
                                                                         const _Value& __val) {
williamr@4
   541
  if (__position._M_node == this->_M_header._M_data._M_left) { // begin()
williamr@4
   542
williamr@4
   543
    // Check for zero members
williamr@4
   544
    if (size() <= 0)
williamr@4
   545
        return insert_equal(__val);
williamr@4
   546
williamr@4
   547
    if (!_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__val)))
williamr@4
   548
      return _M_insert(__position._M_node, __val, __position._M_node);
williamr@4
   549
    else {
williamr@4
   550
      // Check for only one member
williamr@4
   551
      if (__position._M_node->_M_left == __position._M_node)
williamr@4
   552
        // Unlike insert_unique, can't avoid doing a comparison here.
williamr@4
   553
        return _M_insert(__position._M_node, __val);
williamr@4
   554
williamr@4
   555
      // All other cases:
williamr@4
   556
      // Standard-conformance - does the insertion point fall immediately AFTER
williamr@4
   557
      // the hint?
williamr@4
   558
      iterator __after = __position;
williamr@4
   559
      ++__after;
williamr@4
   560
williamr@4
   561
      // Already know that compare(pos, v) must be true!
williamr@4
   562
      // Therefore, we want to know if compare(after, v) is false.
williamr@4
   563
      // (i.e., we now pos < v, now we want to know if v <= after)
williamr@4
   564
      // If not, invalid hint.
williamr@4
   565
      if ( __after._M_node == &this->_M_header._M_data ||
williamr@4
   566
           !_M_key_compare( _S_key(__after._M_node), _KeyOfValue()(__val) ) ) {
williamr@4
   567
        if (_S_right(__position._M_node) == 0)
williamr@4
   568
          return _M_insert(__position._M_node, __val, 0, __position._M_node);
williamr@4
   569
        else
williamr@4
   570
          return _M_insert(__after._M_node, __val, __after._M_node);
williamr@4
   571
      }
williamr@4
   572
      else { // Invalid hint
williamr@4
   573
        return insert_equal(__val);
williamr@4
   574
      }
williamr@4
   575
    }
williamr@4
   576
  }
williamr@4
   577
  else if (__position._M_node == &this->_M_header._M_data) { // end()
williamr@4
   578
    if (!_M_key_compare(_KeyOfValue()(__val), _S_key(_M_rightmost())))
williamr@4
   579
      return _M_insert(_M_rightmost(), __val, 0, __position._M_node); // Last argument only needs to be non-null
williamr@4
   580
    else {
williamr@4
   581
      return insert_equal(__val);
williamr@4
   582
    }
williamr@4
   583
  }
williamr@4
   584
  else {
williamr@4
   585
    iterator __before = __position;
williamr@4
   586
    --__before;
williamr@4
   587
    // store the result of the comparison between pos and v so
williamr@4
   588
    // that we don't have to do it again later.  Note that this reverses the shortcut
williamr@4
   589
    // on the if, possibly harming efficiency in comparisons; I think the harm will
williamr@4
   590
    // be negligible, and to do what I want to do (save the result of a comparison so
williamr@4
   591
    // that it can be re-used) there is no alternative.  Test here is for before <= v <= pos.
williamr@4
   592
    bool __comp_pos_v = _M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__val));
williamr@4
   593
    if (!__comp_pos_v &&
williamr@4
   594
        !_M_key_compare(_KeyOfValue()(__val), _S_key(__before._M_node))) {
williamr@4
   595
      if (_S_right(__before._M_node) == 0)
williamr@4
   596
        return _M_insert(__before._M_node, __val, 0, __before._M_node); // Last argument only needs to be non-null
williamr@4
   597
      else
williamr@4
   598
        return _M_insert(__position._M_node, __val, __position._M_node);
williamr@4
   599
    }
williamr@4
   600
    else {
williamr@4
   601
      // Does the insertion point fall immediately AFTER the hint?
williamr@4
   602
      // Test for pos < v <= after
williamr@4
   603
      iterator __after = __position;
williamr@4
   604
      ++__after;
williamr@4
   605
williamr@4
   606
      if (__comp_pos_v &&
williamr@4
   607
          ( __after._M_node == &this->_M_header._M_data ||
williamr@4
   608
            !_M_key_compare( _S_key(__after._M_node), _KeyOfValue()(__val) ) ) ) {
williamr@4
   609
        if (_S_right(__position._M_node) == 0)
williamr@4
   610
          return _M_insert(__position._M_node, __val, 0, __position._M_node);
williamr@4
   611
        else
williamr@4
   612
          return _M_insert(__after._M_node, __val, __after._M_node);
williamr@4
   613
      }
williamr@4
   614
      else { // Invalid hint
williamr@4
   615
        return insert_equal(__val);
williamr@4
   616
      }
williamr@4
   617
    }
williamr@4
   618
  }
williamr@4
   619
}
williamr@4
   620
williamr@4
   621
template <class _Key, class _Compare,
williamr@4
   622
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   623
_Rb_tree_node_base*
williamr@4
   624
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::_M_copy(_Rb_tree_node_base* __x,
williamr@4
   625
                                                                    _Rb_tree_node_base* __p) {
williamr@4
   626
  // structural copy.  __x and __p must be non-null.
williamr@4
   627
  _Base_ptr __top = _M_clone_node(__x);
williamr@4
   628
  _S_parent(__top) = __p;
williamr@4
   629
williamr@4
   630
  _STLP_TRY {
williamr@4
   631
    if (_S_right(__x))
williamr@4
   632
      _S_right(__top) = _M_copy(_S_right(__x), __top);
williamr@4
   633
    __p = __top;
williamr@4
   634
    __x = _S_left(__x);
williamr@4
   635
williamr@4
   636
    while (__x != 0) {
williamr@4
   637
      _Base_ptr __y = _M_clone_node(__x);
williamr@4
   638
      _S_left(__p) = __y;
williamr@4
   639
      _S_parent(__y) = __p;
williamr@4
   640
      if (_S_right(__x))
williamr@4
   641
        _S_right(__y) = _M_copy(_S_right(__x), __y);
williamr@4
   642
      __p = __y;
williamr@4
   643
      __x = _S_left(__x);
williamr@4
   644
    }
williamr@4
   645
  }
williamr@4
   646
  _STLP_UNWIND(_M_erase(__top))
williamr@4
   647
williamr@4
   648
  return __top;
williamr@4
   649
}
williamr@4
   650
williamr@4
   651
// this has to stay out-of-line : it's recursive
williamr@4
   652
template <class _Key, class _Compare,
williamr@4
   653
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   654
void
williamr@4
   655
_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc>::_M_erase(_Rb_tree_node_base *__x) {
williamr@4
   656
  // erase without rebalancing
williamr@4
   657
  while (__x != 0) {
williamr@4
   658
    _M_erase(_S_right(__x));
williamr@4
   659
    _Base_ptr __y = _S_left(__x);
williamr@4
   660
    _STLP_STD::_Destroy(&_S_value(__x));
williamr@4
   661
    this->_M_header.deallocate(__STATIC_CAST(_Link_type, __x),1);
williamr@4
   662
    __x = __y;
williamr@4
   663
  }
williamr@4
   664
}
williamr@4
   665
williamr@4
   666
#if defined (_STLP_DEBUG)
williamr@4
   667
inline int
williamr@4
   668
__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) {
williamr@4
   669
  if (__node == 0)
williamr@4
   670
    return 0;
williamr@4
   671
  else {
williamr@4
   672
    int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0;
williamr@4
   673
    if (__node == __root)
williamr@4
   674
      return __bc;
williamr@4
   675
    else
williamr@4
   676
      return __bc + __black_count(__node->_M_parent, __root);
williamr@4
   677
  }
williamr@4
   678
}
williamr@4
   679
williamr@4
   680
template <class _Key, class _Compare,
williamr@4
   681
          class _Value, class _KeyOfValue, class _Traits, class _Alloc>
williamr@4
   682
bool _Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc>::__rb_verify() const {
williamr@4
   683
  if (_M_node_count == 0 || begin() == end())
williamr@4
   684
    return ((_M_node_count == 0) &&
williamr@4
   685
            (begin() == end()) &&
williamr@4
   686
            (this->_M_header._M_data._M_left == &this->_M_header._M_data) &&
williamr@4
   687
            (this->_M_header._M_data._M_right == &this->_M_header._M_data));
williamr@4
   688
williamr@4
   689
  int __len = __black_count(_M_leftmost(), _M_root());
williamr@4
   690
  for (const_iterator __it = begin(); __it != end(); ++__it) {
williamr@4
   691
    _Base_ptr __x = __it._M_node;
williamr@4
   692
    _Base_ptr __L = _S_left(__x);
williamr@4
   693
    _Base_ptr __R = _S_right(__x);
williamr@4
   694
williamr@4
   695
    if (__x->_M_color == _S_rb_tree_red)
williamr@4
   696
      if ((__L && __L->_M_color == _S_rb_tree_red) ||
williamr@4
   697
          (__R && __R->_M_color == _S_rb_tree_red))
williamr@4
   698
        return false;
williamr@4
   699
williamr@4
   700
    if (__L && _M_key_compare(_S_key(__x), _S_key(__L)))
williamr@4
   701
      return false;
williamr@4
   702
    if (__R && _M_key_compare(_S_key(__R), _S_key(__x)))
williamr@4
   703
      return false;
williamr@4
   704
williamr@4
   705
    if (!__L && !__R && __black_count(__x, _M_root()) != __len)
williamr@4
   706
      return false;
williamr@4
   707
  }
williamr@4
   708
williamr@4
   709
  if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
williamr@4
   710
    return false;
williamr@4
   711
  if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
williamr@4
   712
    return false;
williamr@4
   713
williamr@4
   714
  return true;
williamr@4
   715
}
williamr@4
   716
#endif /* _STLP_DEBUG */
williamr@4
   717
williamr@4
   718
_STLP_MOVE_TO_STD_NAMESPACE
williamr@4
   719
_STLP_END_NAMESPACE
williamr@4
   720
williamr@4
   721
#undef _Rb_tree
williamr@4
   722
#undef __iterator__
williamr@4
   723
#undef iterator
williamr@4
   724
#undef __size_type__
williamr@4
   725
williamr@4
   726
#endif /*  _STLP_TREE_C */
williamr@4
   727
williamr@4
   728
// Local Variables:
williamr@4
   729
// mode:C++
williamr@4
   730
// End: