Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6554 serge 1
// -*- C++ -*-
2
 
3
// Copyright (C) 2005-2015 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
// .
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 pat_trie_/erase_fn_imps.hpp
38
 * Contains an implementation class for pat_trie.
39
 */
40
 
41
PB_DS_CLASS_T_DEC
42
inline bool
43
PB_DS_CLASS_C_DEC::
44
erase(key_const_reference r_key)
45
{
46
  node_pointer p_nd = find_imp(r_key);
47
  if (p_nd == 0 || p_nd->m_type == i_node)
48
    {
49
      PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
50
      return false;
51
    }
52
 
53
  _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node);
54
  if (!synth_access_traits::equal_keys(PB_DS_V2F(reinterpret_cast(p_nd)->value()), r_key))
55
    {
56
      PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
57
      return false;
58
    }
59
 
60
  PB_DS_CHECK_KEY_EXISTS(r_key)
61
  erase_leaf(static_cast(p_nd));
62
  PB_DS_ASSERT_VALID((*this))
63
  return true;
64
}
65
 
66
PB_DS_CLASS_T_DEC
67
void
68
PB_DS_CLASS_C_DEC::
69
erase_fixup(inode_pointer p_nd)
70
{
71
  _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) >= 1);
72
  if (std::distance(p_nd->begin(), p_nd->end()) == 1)
73
    {
74
      node_pointer p_parent = p_nd->m_p_parent;
75
      if (p_parent == m_p_head)
76
	m_p_head->m_p_parent = *p_nd->begin();
77
      else
78
	{
79
	  _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node);
80
	  node_pointer p_new_child = *p_nd->begin();
81
 
82
	  typedef inode_pointer inode_ptr;
83
	  inode_ptr p_internal = static_cast(p_parent);
84
	  p_internal->replace_child(p_new_child, pref_begin(p_new_child),
85
				    pref_end(p_new_child), this);
86
	}
87
      (*p_nd->begin())->m_p_parent = p_nd->m_p_parent;
88
      p_nd->~inode();
89
      s_inode_allocator.deallocate(p_nd, 1);
90
 
91
      if (p_parent == m_p_head)
92
	return;
93
 
94
      _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node);
95
      p_nd = static_cast(p_parent);
96
    }
97
 
98
  while (true)
99
    {
100
      _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) > 1);
101
      p_nd->update_prefixes(this);
102
      apply_update(p_nd, (node_update*)this);
103
      PB_DS_ASSERT_NODE_VALID(p_nd)
104
      if (p_nd->m_p_parent->m_type == head_node)
105
	return;
106
 
107
      _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent->m_type == i_node);
108
 
109
      p_nd = static_cast(p_nd->m_p_parent);
110
    }
111
}
112
 
113
PB_DS_CLASS_T_DEC
114
inline void
115
PB_DS_CLASS_C_DEC::
116
actual_erase_leaf(leaf_pointer p_l)
117
{
118
  _GLIBCXX_DEBUG_ASSERT(m_size > 0);
119
  --m_size;
120
  _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_l->value())));
121
  p_l->~leaf();
122
  s_leaf_allocator.deallocate(p_l, 1);
123
}
124
 
125
PB_DS_CLASS_T_DEC
126
void
127
PB_DS_CLASS_C_DEC::
128
clear()
129
{
130
  if (!empty())
131
    {
132
      clear_imp(m_p_head->m_p_parent);
133
      m_size = 0;
134
      initialize();
135
      _GLIBCXX_DEBUG_ONLY(debug_base::clear();)
136
      PB_DS_ASSERT_VALID((*this))
137
    }
138
}
139
 
140
PB_DS_CLASS_T_DEC
141
void
142
PB_DS_CLASS_C_DEC::
143
clear_imp(node_pointer p_nd)
144
{
145
  if (p_nd->m_type == i_node)
146
    {
147
      _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node);
148
      for (typename inode::iterator it =
149
	     static_cast(p_nd)->begin();
150
	   it != static_cast(p_nd)->end();
151
	   ++it)
152
	{
153
	  node_pointer p_child =* it;
154
	  clear_imp(p_child);
155
	}
156
      s_inode_allocator.deallocate(static_cast(p_nd), 1);
157
      return;
158
    }
159
 
160
  _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node);
161
  static_cast(p_nd)->~leaf();
162
  s_leaf_allocator.deallocate(static_cast(p_nd), 1);
163
}
164
 
165
PB_DS_CLASS_T_DEC
166
inline typename PB_DS_CLASS_C_DEC::const_iterator
167
PB_DS_CLASS_C_DEC::
168
erase(const_iterator it)
169
{
170
  PB_DS_ASSERT_VALID((*this))
171
 
172
  if (it == end())
173
    return it;
174
 
175
  const_iterator ret_it = it;
176
  ++ret_it;
177
  _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node);
178
  erase_leaf(static_cast(it.m_p_nd));
179
  PB_DS_ASSERT_VALID((*this))
180
  return ret_it;
181
}
182
 
183
#ifdef PB_DS_DATA_TRUE_INDICATOR
184
PB_DS_CLASS_T_DEC
185
inline typename PB_DS_CLASS_C_DEC::iterator
186
PB_DS_CLASS_C_DEC::
187
erase(iterator it)
188
{
189
  PB_DS_ASSERT_VALID((*this))
190
 
191
  if (it == end())
192
    return it;
193
  iterator ret_it = it;
194
  ++ret_it;
195
  _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node);
196
  erase_leaf(static_cast(it.m_p_nd));
197
  PB_DS_ASSERT_VALID((*this))
198
  return ret_it;
199
}
200
#endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
201
 
202
PB_DS_CLASS_T_DEC
203
inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator
204
PB_DS_CLASS_C_DEC::
205
erase(const_reverse_iterator it)
206
{
207
  PB_DS_ASSERT_VALID((*this))
208
 
209
  if (it.m_p_nd == m_p_head)
210
    return it;
211
  const_reverse_iterator ret_it = it;
212
  ++ret_it;
213
 
214
  _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node);
215
  erase_leaf(static_cast(it.m_p_nd));
216
  PB_DS_ASSERT_VALID((*this))
217
  return ret_it;
218
}
219
 
220
#ifdef PB_DS_DATA_TRUE_INDICATOR
221
PB_DS_CLASS_T_DEC
222
inline typename PB_DS_CLASS_C_DEC::reverse_iterator
223
PB_DS_CLASS_C_DEC::
224
erase(reverse_iterator it)
225
{
226
  PB_DS_ASSERT_VALID((*this))
227
 
228
  if (it.m_p_nd == m_p_head)
229
    return it;
230
  reverse_iterator ret_it = it;
231
  ++ret_it;
232
 
233
  _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node);
234
  erase_leaf(static_cast(it.m_p_nd));
235
  PB_DS_ASSERT_VALID((*this))
236
  return ret_it;
237
}
238
#endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
239
 
240
PB_DS_CLASS_T_DEC
241
template
242
inline typename PB_DS_CLASS_C_DEC::size_type
243
PB_DS_CLASS_C_DEC::
244
erase_if(Pred pred)
245
{
246
  size_type num_ersd = 0;
247
  PB_DS_ASSERT_VALID((*this))
248
 
249
  iterator it = begin();
250
  while (it != end())
251
    {
252
      PB_DS_ASSERT_VALID((*this))
253
      if (pred(*it))
254
	{
255
	  ++num_ersd;
256
	  it = erase(it);
257
	}
258
      else
259
	++it;
260
    }
261
 
262
  PB_DS_ASSERT_VALID((*this))
263
  return num_ersd;
264
}
265
 
266
PB_DS_CLASS_T_DEC
267
void
268
PB_DS_CLASS_C_DEC::
269
erase_leaf(leaf_pointer p_l)
270
{
271
  update_min_max_for_erased_leaf(p_l);
272
  if (p_l->m_p_parent->m_type == head_node)
273
    {
274
      _GLIBCXX_DEBUG_ASSERT(size() == 1);
275
      clear();
276
      return;
277
    }
278
 
279
  _GLIBCXX_DEBUG_ASSERT(size() > 1);
280
  _GLIBCXX_DEBUG_ASSERT(p_l->m_p_parent->m_type == i_node);
281
 
282
  inode_pointer p_parent = static_cast(p_l->m_p_parent);
283
 
284
  p_parent->remove_child(p_l);
285
  erase_fixup(p_parent);
286
  actual_erase_leaf(p_l);
287
}
288
 
289
PB_DS_CLASS_T_DEC
290
void
291
PB_DS_CLASS_C_DEC::
292
update_min_max_for_erased_leaf(leaf_pointer p_l)
293
{
294
  if (m_size == 1)
295
    {
296
      m_p_head->m_p_min = m_p_head;
297
      m_p_head->m_p_max = m_p_head;
298
      return;
299
    }
300
 
301
  if (p_l == static_cast(m_p_head->m_p_min))
302
    {
303
      iterator it(p_l);
304
      ++it;
305
      m_p_head->m_p_min = it.m_p_nd;
306
      return;
307
    }
308
 
309
  if (p_l == static_cast(m_p_head->m_p_max))
310
    {
311
      iterator it(p_l);
312
      --it;
313
      m_p_head->m_p_max = it.m_p_nd;
314
    }
315
}