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 class for a pairing 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  node_pointer p_new_root = join_node_children(base_type::m_p_root);
56169691Skan  _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_new_root, false);)
57169691Skan  if (p_new_root != NULL)
58169691Skan    p_new_root->m_p_prev_or_parent = NULL;
59169691Skan
60169691Skan  base_type::actual_erase_node(base_type::m_p_root);
61169691Skan  base_type::m_p_root = p_new_root;
62169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
63169691Skan}
64169691Skan
65169691SkanPB_DS_CLASS_T_DEC
66169691Skanvoid
67169691SkanPB_DS_CLASS_C_DEC::
68169691Skanerase(point_iterator it)
69169691Skan{
70169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
71169691Skan  _GLIBCXX_DEBUG_ASSERT(!base_type::empty());
72169691Skan  remove_node(it.m_p_nd);
73169691Skan  base_type::actual_erase_node(it.m_p_nd);
74169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
75169691Skan}
76169691Skan
77169691SkanPB_DS_CLASS_T_DEC
78169691Skanvoid
79169691SkanPB_DS_CLASS_C_DEC::
80169691Skanremove_node(node_pointer p_nd)
81169691Skan{
82169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
83169691Skan  _GLIBCXX_DEBUG_ASSERT(!base_type::empty());
84169691Skan  node_pointer p_new_child = join_node_children(p_nd);
85169691Skan
86169691Skan#ifdef _GLIBCXX_DEBUG
87169691Skan  if (p_new_child != NULL)
88169691Skan    base_type::assert_node_consistent(p_new_child, false);
89169691Skan#endif
90169691Skan
91169691Skan  if (p_nd == base_type::m_p_root)
92169691Skan    {
93169691Skan      if (p_new_child != NULL)
94169691Skan	p_new_child->m_p_prev_or_parent = NULL;
95169691Skan      base_type::m_p_root = p_new_child;
96169691Skan      _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(base_type::m_p_root, false);)
97169691Skan      return;
98169691Skan    }
99169691Skan
100169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent != NULL);
101169691Skan  if (p_nd->m_p_prev_or_parent->m_p_l_child == p_nd)
102169691Skan    {
103169691Skan      if (p_new_child != NULL)
104169691Skan        {
105169691Skan	  p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent;
106169691Skan	  p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling;
107169691Skan	  if (p_new_child->m_p_next_sibling != NULL)
108169691Skan	    p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child;
109169691Skan	  p_nd->m_p_prev_or_parent->m_p_l_child = p_new_child;
110169691Skan	  _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);)
111169691Skan          return;
112169691Skan        }
113169691Skan
114169691Skan      p_nd->m_p_prev_or_parent->m_p_l_child = p_nd->m_p_next_sibling;
115169691Skan      if (p_nd->m_p_next_sibling != NULL)
116169691Skan	p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent;
117169691Skan      _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);)
118169691Skan      return;
119169691Skan    }
120169691Skan
121169691Skan  if (p_new_child != NULL)
122169691Skan    {
123169691Skan      p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent;
124169691Skan      p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling;
125169691Skan      if (p_new_child->m_p_next_sibling != NULL)
126169691Skan	p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child;
127169691Skan      p_new_child->m_p_prev_or_parent->m_p_next_sibling = p_new_child;
128169691Skan      _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);)
129169691Skan      return;
130169691Skan    }
131169691Skan
132169691Skan  p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling;
133169691Skan  if (p_nd->m_p_next_sibling != NULL)
134169691Skan    p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent;
135169691Skan  _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);)
136169691Skan}
137169691Skan
138169691SkanPB_DS_CLASS_T_DEC
139169691Skantypename PB_DS_CLASS_C_DEC::node_pointer
140169691SkanPB_DS_CLASS_C_DEC::
141169691Skanjoin_node_children(node_pointer p_nd)
142169691Skan{
143169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd != NULL);
144169691Skan  node_pointer p_ret = p_nd->m_p_l_child;
145169691Skan  if (p_ret == NULL)
146169691Skan    return NULL;
147169691Skan  while (p_ret->m_p_next_sibling != NULL)
148169691Skan    p_ret = forward_join(p_ret, p_ret->m_p_next_sibling);
149169691Skan  while (p_ret->m_p_prev_or_parent != p_nd)
150169691Skan    p_ret = back_join(p_ret->m_p_prev_or_parent, p_ret);
151169691Skan  _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_ret, false);)
152169691Skan  return p_ret;
153169691Skan}
154169691Skan
155169691SkanPB_DS_CLASS_T_DEC
156169691Skantypename PB_DS_CLASS_C_DEC::node_pointer
157169691SkanPB_DS_CLASS_C_DEC::
158169691Skanforward_join(node_pointer p_nd, node_pointer p_next)
159169691Skan{
160169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd != NULL);
161169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == p_next);
162169691Skan  if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value))
163169691Skan    {
164169691Skan      p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent;
165169691Skan      base_type::make_child_of(p_nd, p_next);
166169691Skan      return p_next->m_p_next_sibling == NULL
167169691Skan	? p_next : p_next->m_p_next_sibling;
168169691Skan    }
169169691Skan
170169691Skan  if (p_next->m_p_next_sibling != NULL)
171169691Skan    {
172169691Skan      p_next->m_p_next_sibling->m_p_prev_or_parent = p_nd;
173169691Skan      p_nd->m_p_next_sibling = p_next->m_p_next_sibling;
174169691Skan      base_type::make_child_of(p_next, p_nd);
175169691Skan      return p_nd->m_p_next_sibling;
176169691Skan    }
177169691Skan
178169691Skan  p_nd->m_p_next_sibling = NULL;
179169691Skan  base_type::make_child_of(p_next, p_nd);
180169691Skan  _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false));
181169691Skan  return p_nd;
182169691Skan}
183169691Skan
184169691SkanPB_DS_CLASS_T_DEC
185169691Skantypename PB_DS_CLASS_C_DEC::node_pointer
186169691SkanPB_DS_CLASS_C_DEC::
187169691Skanback_join(node_pointer p_nd, node_pointer p_next)
188169691Skan{
189169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd != NULL);
190169691Skan  _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == NULL);
191169691Skan
192169691Skan  if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value))
193169691Skan    {
194169691Skan      p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent;
195169691Skan      base_type::make_child_of(p_nd, p_next);
196169691Skan      _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_next, false));
197169691Skan      return p_next;
198169691Skan    }
199169691Skan
200169691Skan  p_nd->m_p_next_sibling = NULL;
201169691Skan  base_type::make_child_of(p_next, p_nd);
202169691Skan  _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false));
203169691Skan  return p_nd;
204169691Skan}
205169691Skan
206169691SkanPB_DS_CLASS_T_DEC
207169691Skantemplate<typename Pred>
208169691Skantypename PB_DS_CLASS_C_DEC::size_type
209169691SkanPB_DS_CLASS_C_DEC::
210169691Skanerase_if(Pred pred)
211169691Skan{
212169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
213169691Skan    if (base_type::empty())
214169691Skan      {
215169691Skan        _GLIBCXX_DEBUG_ONLY(assert_valid();)
216169691Skan	return 0;
217169691Skan      }
218169691Skan  base_type::to_linked_list();
219169691Skan  node_pointer p_out = base_type::prune(pred);
220169691Skan  size_type ersd = 0;
221169691Skan  while (p_out != NULL)
222169691Skan    {
223169691Skan      ++ersd;
224169691Skan      node_pointer p_next = p_out->m_p_next_sibling;
225169691Skan      base_type::actual_erase_node(p_out);
226169691Skan      p_out = p_next;
227169691Skan    }
228169691Skan
229169691Skan  node_pointer p_cur = base_type::m_p_root;
230169691Skan  base_type::m_p_root = NULL;
231169691Skan  while (p_cur != NULL)
232169691Skan    {
233169691Skan      node_pointer p_next = p_cur->m_p_next_sibling;
234169691Skan      p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = NULL;
235169691Skan
236169691Skan      push_imp(p_cur);
237169691Skan      p_cur = p_next;
238169691Skan    }
239169691Skan  _GLIBCXX_DEBUG_ONLY(assert_valid();)
240169691Skan  return ersd;
241169691Skan}
242169691Skan
243