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