1169691Skan// -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the terms
7169691Skan// of the GNU General Public License as published by the Free Software
8169691Skan// Foundation; either version 2, or (at your option) any later
9169691Skan// version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful, but
12169691Skan// WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14169691Skan// General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License
17169691Skan// along with this library; see the file COPYING.  If not, write to
18169691Skan// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19169691Skan// MA 02111-1307, USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free
22169691Skan// software library without restriction.  Specifically, if other files
23169691Skan// instantiate templates or use macros or inline functions from this
24169691Skan// file, or you compile this file and link it with other files to
25169691Skan// produce an executable, this file does not by itself cause the
26169691Skan// resulting executable to be covered by the GNU General Public
27169691Skan// License.  This exception does not however invalidate any other
28169691Skan// reasons why the executable file might be covered by the GNU General
29169691Skan// Public License.
30169691Skan
31169691Skan// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
32169691Skan
33169691Skan// Permission to use, copy, modify, sell, and distribute this software
34169691Skan// is hereby granted without fee, provided that the above copyright
35169691Skan// notice appears in all copies, and that both that copyright notice
36169691Skan// and this permission notice appear in supporting documentation. None
37169691Skan// of the above authors, nor IBM Haifa Research Laboratories, make any
38169691Skan// representation about the suitability of this software for any
39169691Skan// purpose. It is provided "as is" without express or implied
40169691Skan// warranty.
41169691Skan
42169691Skan/**
43169691Skan * @file erase_fn_imps.hpp
44169691Skan * Contains an implementation for thin_heap_.
45169691Skan */
46169691Skan
47169691SkanPB_DS_CLASS_T_DEC
48169691Skanvoid
49169691SkanPB_DS_CLASS_C_DEC::
50169691Skanpop()
51169691Skan{
52169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
53169691Skan    _GLIBCXX_DEBUG_ASSERT(!base_type::empty());
54169691Skan
55169691Skan  _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL);
56169691Skan
57169691Skan  node_pointer p_nd = m_p_max;
58169691Skan
59169691Skan  remove_max_node();
60169691Skan
61169691Skan  base_type::actual_erase_node(p_nd);
62169691Skan
63169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
64169691Skan    }
65169691Skan
66169691SkanPB_DS_CLASS_T_DEC
67169691Skaninline void
68169691SkanPB_DS_CLASS_C_DEC::
69169691Skanremove_max_node()
70169691Skan{
71169691Skan  to_aux_except_max();
72169691Skan
73169691Skan  make_from_aux();
74169691Skan}
75169691Skan
76169691SkanPB_DS_CLASS_T_DEC
77169691Skanvoid
78169691SkanPB_DS_CLASS_C_DEC::
79169691Skanto_aux_except_max()
80169691Skan{
81169691Skan  node_pointer p_add = base_type::m_p_root;
82169691Skan
83169691Skan  while (p_add != m_p_max)
84169691Skan    {
85169691Skan      node_pointer p_next_add = p_add->m_p_next_sibling;
86169691Skan
87169691Skan      add_to_aux(p_add);
88169691Skan
89169691Skan      p_add = p_next_add;
90169691Skan    }
91169691Skan
92169691Skan  p_add = m_p_max->m_p_l_child;
93169691Skan
94169691Skan  while (p_add != NULL)
95169691Skan    {
96169691Skan      node_pointer p_next_add = p_add->m_p_next_sibling;
97169691Skan
98169691Skan      p_add->m_metadata = p_add->m_p_l_child == NULL?
99169691Skan	0 :
100169691Skan	p_add->m_p_l_child->m_metadata + 1;
101169691Skan
102169691Skan      add_to_aux(p_add);
103169691Skan
104169691Skan      p_add = p_next_add;
105169691Skan    }
106169691Skan
107169691Skan  p_add = m_p_max->m_p_next_sibling;
108169691Skan
109169691Skan  while (p_add != NULL)
110169691Skan    {
111169691Skan      node_pointer p_next_add = p_add->m_p_next_sibling;
112169691Skan
113169691Skan      add_to_aux(p_add);
114169691Skan
115169691Skan      p_add = p_next_add;
116169691Skan    }
117169691Skan}
118169691Skan
119169691SkanPB_DS_CLASS_T_DEC
120169691Skaninline void
121169691SkanPB_DS_CLASS_C_DEC::
122169691Skanadd_to_aux(node_pointer p_nd)
123169691Skan{
124169691Skan  size_type r = p_nd->m_metadata;
125169691Skan
126169691Skan  while (m_a_aux[r] != NULL)
127169691Skan    {
128169691Skan      _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound());
129169691Skan
130169691Skan      if (Cmp_Fn::operator()(m_a_aux[r]->m_value, p_nd->m_value))
131169691Skan	make_child_of(m_a_aux[r], p_nd);
132169691Skan      else
133169691Skan        {
134169691Skan	  make_child_of(p_nd, m_a_aux[r]);
135169691Skan
136169691Skan	  p_nd = m_a_aux[r];
137169691Skan        }
138169691Skan
139169691Skan      m_a_aux[r] = NULL;
140169691Skan
141169691Skan      ++r;
142169691Skan    }
143169691Skan
144169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound());
145169691Skan
146169691Skan  m_a_aux[r] = p_nd;
147169691Skan}
148169691Skan
149169691SkanPB_DS_CLASS_T_DEC
150169691Skaninline void
151169691SkanPB_DS_CLASS_C_DEC::
152169691Skanmake_child_of(node_pointer p_nd, node_pointer p_new_parent)
153169691Skan{
154169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_new_parent->m_metadata);
155169691Skan  _GLIBCXX_DEBUG_ASSERT(m_a_aux[p_nd->m_metadata] == p_nd ||
156169691Skan		   m_a_aux[p_nd->m_metadata] == p_new_parent);
157169691Skan
158169691Skan  ++p_new_parent->m_metadata;
159169691Skan
160169691Skan  base_type::make_child_of(p_nd, p_new_parent);
161169691Skan}
162169691Skan
163169691SkanPB_DS_CLASS_T_DEC
164169691Skaninline void
165169691SkanPB_DS_CLASS_C_DEC::
166169691Skanmake_from_aux()
167169691Skan{
168169691Skan  base_type::m_p_root = m_p_max = NULL;
169169691Skan
170169691Skan  const size_type rnk_bnd = rank_bound();
171169691Skan
172169691Skan  size_type i = 0;
173169691Skan
174169691Skan  while (i < rnk_bnd)
175169691Skan    {
176169691Skan      if (m_a_aux[i] != NULL)
177169691Skan        {
178169691Skan	  make_root_and_link(m_a_aux[i]);
179169691Skan
180169691Skan	  m_a_aux[i] = NULL;
181169691Skan        }
182169691Skan
183169691Skan      ++i;
184169691Skan    }
185169691Skan
186169691Skan  _GLIBCXX_DEBUG_ONLY(assert_aux_null();)
187169691Skan    }
188169691Skan
189169691SkanPB_DS_CLASS_T_DEC
190169691Skaninline void
191169691SkanPB_DS_CLASS_C_DEC::
192169691Skanremove_node(node_pointer p_nd)
193169691Skan{
194169691Skan  node_pointer p_parent = p_nd;
195169691Skan  while (base_type::parent(p_parent) != NULL)
196169691Skan    p_parent = base_type::parent(p_parent);
197169691Skan
198169691Skan  base_type::bubble_to_top(p_nd);
199169691Skan
200169691Skan  m_p_max = p_nd;
201169691Skan
202169691Skan  node_pointer p_fix = base_type::m_p_root;
203169691Skan  while (p_fix != NULL&&  p_fix->m_p_next_sibling != p_parent)
204169691Skan    p_fix = p_fix->m_p_next_sibling;
205169691Skan
206169691Skan  if (p_fix != NULL)
207169691Skan    p_fix->m_p_next_sibling = p_nd;
208169691Skan
209169691Skan  remove_max_node();
210169691Skan}
211169691Skan
212169691SkanPB_DS_CLASS_T_DEC
213169691Skaninline void
214169691SkanPB_DS_CLASS_C_DEC::
215169691Skanclear()
216169691Skan{
217169691Skan  base_type::clear();
218169691Skan
219169691Skan  m_p_max = NULL;
220169691Skan}
221169691Skan
222169691SkanPB_DS_CLASS_T_DEC
223169691Skanvoid
224169691SkanPB_DS_CLASS_C_DEC::
225169691Skanerase(point_iterator it)
226169691Skan{
227169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
228169691Skan    _GLIBCXX_DEBUG_ASSERT(!base_type::empty());
229169691Skan
230169691Skan  node_pointer p_nd = it.m_p_nd;
231169691Skan
232169691Skan  remove_node(p_nd);
233169691Skan
234169691Skan  base_type::actual_erase_node(p_nd);
235169691Skan
236169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
237169691Skan    }
238169691Skan
239169691SkanPB_DS_CLASS_T_DEC
240169691Skantemplate<typename Pred>
241169691Skantypename PB_DS_CLASS_C_DEC::size_type
242169691SkanPB_DS_CLASS_C_DEC::
243169691Skanerase_if(Pred pred)
244169691Skan{
245169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
246169691Skan
247169691Skan    if (base_type::empty())
248169691Skan      {
249169691Skan        _GLIBCXX_DEBUG_ONLY(assert_valid();)
250169691Skan
251169691Skan	  return 0;
252169691Skan      }
253169691Skan
254169691Skan  base_type::to_linked_list();
255169691Skan
256169691Skan  node_pointer p_out = base_type::prune(pred);
257169691Skan
258169691Skan  size_type ersd = 0;
259169691Skan
260169691Skan  while (p_out != NULL)
261169691Skan    {
262169691Skan      ++ersd;
263169691Skan
264169691Skan      node_pointer p_next = p_out->m_p_next_sibling;
265169691Skan
266169691Skan      base_type::actual_erase_node(p_out);
267169691Skan
268169691Skan      p_out = p_next;
269169691Skan    }
270169691Skan
271169691Skan  node_pointer p_cur = base_type::m_p_root;
272169691Skan
273169691Skan  m_p_max = base_type::m_p_root = NULL;
274169691Skan
275169691Skan  while (p_cur != NULL)
276169691Skan    {
277169691Skan      node_pointer p_next = p_cur->m_p_next_sibling;
278169691Skan
279169691Skan      make_root_and_link(p_cur);
280169691Skan
281169691Skan      p_cur = p_next;
282169691Skan    }
283169691Skan
284169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
285169691Skan
286169691Skan    return ersd;
287169691Skan}
288169691Skan
289169691SkanPB_DS_CLASS_T_DEC
290169691Skaninline typename PB_DS_CLASS_C_DEC::size_type
291169691SkanPB_DS_CLASS_C_DEC::
292169691Skanrank_bound()
293169691Skan{
294169691Skan  const std::size_t* const p_upper =
295169691Skan    std::upper_bound(            g_a_rank_bounds, g_a_rank_bounds + num_distinct_rank_bounds, base_type::m_size);
296169691Skan
297169691Skan  if (p_upper == g_a_rank_bounds + num_distinct_rank_bounds)
298169691Skan    return max_rank;
299169691Skan
300169691Skan  return (p_upper - g_a_rank_bounds);
301169691Skan}
302169691Skan
303