OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [ext/] [pb_ds/] [detail/] [rb_tree_map_/] [split_join_fn_imps.hpp] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// -*- C++ -*-
2
 
3
// Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the terms
7
// of the GNU General Public License as published by the Free Software
8
// Foundation; either version 3, or (at your option) any later
9
// version.
10
 
11
// This library is distributed in the hope that it will be useful, but
12
// WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
// General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// <http://www.gnu.org/licenses/>.
24
 
25
// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
26
 
27
// Permission to use, copy, modify, sell, and distribute this software
28
// is hereby granted without fee, provided that the above copyright
29
// notice appears in all copies, and that both that copyright notice
30
// and this permission notice appear in supporting documentation. None
31
// of the above authors, nor IBM Haifa Research Laboratories, make any
32
// representation about the suitability of this software for any
33
// purpose. It is provided "as is" without express or implied
34
// warranty.
35
 
36
/**
37
 * @file rb_tree_map_/split_join_fn_imps.hpp
38
 * Contains an implementation for rb_tree_.
39
 */
40
 
41
PB_DS_CLASS_T_DEC
42
inline void
43
PB_DS_CLASS_C_DEC::
44
join(PB_DS_CLASS_C_DEC& other)
45
{
46
  PB_DS_ASSERT_VALID((*this))
47
  PB_DS_ASSERT_VALID(other)
48
  if (base_type::join_prep(other) == false)
49
    {
50
      PB_DS_ASSERT_VALID((*this))
51
      PB_DS_ASSERT_VALID(other)
52
      return;
53
    }
54
 
55
  const node_pointer p_x = other.split_min();
56
  join_imp(p_x, other.m_p_head->m_p_parent);
57
  base_type::join_finish(other);
58
  PB_DS_ASSERT_VALID((*this))
59
  PB_DS_ASSERT_VALID(other)
60
 }
61
 
62
PB_DS_CLASS_T_DEC
63
void
64
PB_DS_CLASS_C_DEC::
65
join_imp(node_pointer p_x, node_pointer p_r)
66
{
67
  _GLIBCXX_DEBUG_ASSERT(p_x != 0);
68
  if (p_r != 0)
69
    p_r->m_red = false;
70
 
71
  const size_type h = black_height(base_type::m_p_head->m_p_parent);
72
  const size_type other_h = black_height(p_r);
73
  node_pointer p_x_l;
74
  node_pointer p_x_r;
75
  std::pair<node_pointer, node_pointer> join_pos;
76
  const bool right_join = h >= other_h;
77
  if (right_join)
78
    {
79
      join_pos = find_join_pos_right(base_type::m_p_head->m_p_parent,
80
                                     h, other_h);
81
      p_x_l = join_pos.first;
82
      p_x_r = p_r;
83
    }
84
  else
85
    {
86
      p_x_l = base_type::m_p_head->m_p_parent;
87
      base_type::m_p_head->m_p_parent = p_r;
88
      if (p_r != 0)
89
        p_r->m_p_parent = base_type::m_p_head;
90
 
91
      join_pos = find_join_pos_left(base_type::m_p_head->m_p_parent,
92
                                    h, other_h);
93
      p_x_r = join_pos.first;
94
    }
95
 
96
  node_pointer p_parent = join_pos.second;
97
  if (p_parent == base_type::m_p_head)
98
    {
99
      base_type::m_p_head->m_p_parent = p_x;
100
      p_x->m_p_parent = base_type::m_p_head;
101
    }
102
  else
103
    {
104
      p_x->m_p_parent = p_parent;
105
      if (right_join)
106
        p_x->m_p_parent->m_p_right = p_x;
107
      else
108
        p_x->m_p_parent->m_p_left = p_x;
109
    }
110
 
111
  p_x->m_p_left = p_x_l;
112
  if (p_x_l != 0)
113
    p_x_l->m_p_parent = p_x;
114
 
115
  p_x->m_p_right = p_x_r;
116
  if (p_x_r != 0)
117
    p_x_r->m_p_parent = p_x;
118
 
119
  p_x->m_red = true;
120
 
121
  base_type::initialize_min_max();
122
  PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
123
  base_type::update_to_top(p_x, (node_update* )this);
124
  insert_fixup(p_x);
125
  PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
126
}
127
 
128
PB_DS_CLASS_T_DEC
129
inline typename PB_DS_CLASS_C_DEC::node_pointer
130
PB_DS_CLASS_C_DEC::
131
split_min()
132
{
133
  node_pointer p_min = base_type::m_p_head->m_p_left;
134
 
135
#ifdef _GLIBCXX_DEBUG
136
  const node_pointer p_head = base_type::m_p_head;
137
  _GLIBCXX_DEBUG_ASSERT(p_min != p_head);
138
#endif 
139
 
140
  remove_node(p_min);
141
  return p_min;
142
}
143
 
144
PB_DS_CLASS_T_DEC
145
std::pair<
146
  typename PB_DS_CLASS_C_DEC::node_pointer,
147
  typename PB_DS_CLASS_C_DEC::node_pointer>
148
PB_DS_CLASS_C_DEC::
149
find_join_pos_right(node_pointer p_l, size_type h_l, size_type h_r)
150
{
151
  _GLIBCXX_DEBUG_ASSERT(h_l >= h_r);
152
 
153
  if (base_type::m_p_head->m_p_parent == 0)
154
    return (std::make_pair((node_pointer)0, base_type::m_p_head));
155
 
156
  node_pointer p_l_parent = base_type::m_p_head;
157
  while (h_l > h_r)
158
    {
159
      if (p_l->m_red == false)
160
        {
161
          _GLIBCXX_DEBUG_ASSERT(h_l > 0);
162
          --h_l;
163
        }
164
 
165
      p_l_parent = p_l;
166
      p_l = p_l->m_p_right;
167
    }
168
 
169
  if (!is_effectively_black(p_l))
170
    {
171
      p_l_parent = p_l;
172
      p_l = p_l->m_p_right;
173
    }
174
 
175
  _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_l));
176
  _GLIBCXX_DEBUG_ASSERT(black_height(p_l) == h_r);
177
  _GLIBCXX_DEBUG_ASSERT(p_l == 0 || p_l->m_p_parent == p_l_parent);
178
  return std::make_pair(p_l, p_l_parent);
179
}
180
 
181
PB_DS_CLASS_T_DEC
182
std::pair<
183
  typename PB_DS_CLASS_C_DEC::node_pointer,
184
  typename PB_DS_CLASS_C_DEC::node_pointer>
185
PB_DS_CLASS_C_DEC::
186
find_join_pos_left(node_pointer p_r, size_type h_l, size_type h_r)
187
{
188
  _GLIBCXX_DEBUG_ASSERT(h_r > h_l);
189
  if (base_type::m_p_head->m_p_parent == 0)
190
    return (std::make_pair((node_pointer)0,
191
                           base_type::m_p_head));
192
  node_pointer p_r_parent = base_type::m_p_head;
193
  while (h_r > h_l)
194
    {
195
      if (p_r->m_red == false)
196
        {
197
          _GLIBCXX_DEBUG_ASSERT(h_r > 0);
198
          --h_r;
199
        }
200
 
201
      p_r_parent = p_r;
202
      p_r = p_r->m_p_left;
203
    }
204
 
205
  if (!is_effectively_black(p_r))
206
    {
207
      p_r_parent = p_r;
208
      p_r = p_r->m_p_left;
209
    }
210
 
211
  _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_r));
212
  _GLIBCXX_DEBUG_ASSERT(black_height(p_r) == h_l);
213
  _GLIBCXX_DEBUG_ASSERT(p_r == 0 || p_r->m_p_parent == p_r_parent);
214
  return std::make_pair(p_r, p_r_parent);
215
}
216
 
217
PB_DS_CLASS_T_DEC
218
inline typename PB_DS_CLASS_C_DEC::size_type
219
PB_DS_CLASS_C_DEC::
220
black_height(node_pointer p_nd)
221
{
222
  size_type h = 1;
223
  while (p_nd != 0)
224
    {
225
      if (p_nd->m_red == false)
226
        ++h;
227
      p_nd = p_nd->m_p_left;
228
    }
229
  return h;
230
}
231
 
232
PB_DS_CLASS_T_DEC
233
void
234
PB_DS_CLASS_C_DEC::
235
split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other)
236
{
237
  PB_DS_ASSERT_VALID((*this))
238
  PB_DS_ASSERT_VALID(other)
239
 
240
  if (base_type::split_prep(r_key, other) == false)
241
    {
242
      PB_DS_ASSERT_VALID((*this))
243
      PB_DS_ASSERT_VALID(other)
244
      return;
245
    }
246
 
247
  PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
248
  PB_DS_STRUCT_ONLY_ASSERT_VALID(other)
249
  node_pointer p_nd = this->upper_bound(r_key).m_p_nd;
250
  do
251
    {
252
      node_pointer p_next_nd = p_nd->m_p_parent;
253
      if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value)))
254
        split_at_node(p_nd, other);
255
 
256
      PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
257
      PB_DS_STRUCT_ONLY_ASSERT_VALID(other)
258
      p_nd = p_next_nd;
259
    }
260
  while (p_nd != base_type::m_p_head);
261
 
262
  base_type::split_finish(other);
263
  PB_DS_ASSERT_VALID((*this))
264
}
265
 
266
PB_DS_CLASS_T_DEC
267
void
268
PB_DS_CLASS_C_DEC::
269
split_at_node(node_pointer p_nd, PB_DS_CLASS_C_DEC& other)
270
{
271
  _GLIBCXX_DEBUG_ASSERT(p_nd != 0);
272
 
273
  node_pointer p_l = p_nd->m_p_left;
274
  node_pointer p_r = p_nd->m_p_right;
275
  node_pointer p_parent = p_nd->m_p_parent;
276
  if (p_parent == base_type::m_p_head)
277
    {
278
      base_type::m_p_head->m_p_parent = p_l;
279
      if (p_l != 0)
280
        {
281
          p_l->m_p_parent = base_type::m_p_head;
282
          p_l->m_red = false;
283
        }
284
    }
285
  else
286
    {
287
      if (p_parent->m_p_left == p_nd)
288
        p_parent->m_p_left = p_l;
289
      else
290
        p_parent->m_p_right = p_l;
291
 
292
      if (p_l != 0)
293
        p_l->m_p_parent = p_parent;
294
 
295
      this->update_to_top(p_parent, (node_update* )this);
296
 
297
      if (!p_nd->m_red)
298
        remove_fixup(p_l, p_parent);
299
    }
300
 
301
  base_type::initialize_min_max();
302
  other.join_imp(p_nd, p_r);
303
  PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
304
  PB_DS_STRUCT_ONLY_ASSERT_VALID(other)
305
}
306
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.