libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the terms 00007 // of the GNU General Public License as published by the Free Software 00008 // Foundation; either version 3, or (at your option) any later 00009 // version. 00010 00011 // This library is distributed in the hope that it will be useful, but 00012 // WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 // General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 00026 00027 // Permission to use, copy, modify, sell, and distribute this software 00028 // is hereby granted without fee, provided that the above copyright 00029 // notice appears in all copies, and that both that copyright notice 00030 // and this permission notice appear in supporting documentation. None 00031 // of the above authors, nor IBM Haifa Research Laboratories, make any 00032 // representation about the suitability of this software for any 00033 // purpose. It is provided "as is" without express or implied 00034 // warranty. 00035 00036 /** 00037 * @file thin_heap_/erase_fn_imps.hpp 00038 * Contains an implementation for thin_heap_. 00039 */ 00040 00041 PB_DS_CLASS_T_DEC 00042 void 00043 PB_DS_CLASS_C_DEC:: 00044 pop() 00045 { 00046 PB_DS_ASSERT_VALID((*this)) 00047 _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); 00048 _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); 00049 00050 node_pointer p_nd = m_p_max; 00051 remove_max_node(); 00052 base_type::actual_erase_node(p_nd); 00053 PB_DS_ASSERT_VALID((*this)) 00054 } 00055 00056 PB_DS_CLASS_T_DEC 00057 inline void 00058 PB_DS_CLASS_C_DEC:: 00059 remove_max_node() 00060 { 00061 to_aux_except_max(); 00062 make_from_aux(); 00063 } 00064 00065 PB_DS_CLASS_T_DEC 00066 void 00067 PB_DS_CLASS_C_DEC:: 00068 to_aux_except_max() 00069 { 00070 node_pointer p_add = base_type::m_p_root; 00071 while (p_add != m_p_max) 00072 { 00073 node_pointer p_next_add = p_add->m_p_next_sibling; 00074 add_to_aux(p_add); 00075 p_add = p_next_add; 00076 } 00077 00078 p_add = m_p_max->m_p_l_child; 00079 while (p_add != 0) 00080 { 00081 node_pointer p_next_add = p_add->m_p_next_sibling; 00082 p_add->m_metadata = p_add->m_p_l_child == 0 ? 00083 0 : p_add->m_p_l_child->m_metadata + 1; 00084 00085 add_to_aux(p_add); 00086 p_add = p_next_add; 00087 } 00088 00089 p_add = m_p_max->m_p_next_sibling; 00090 while (p_add != 0) 00091 { 00092 node_pointer p_next_add = p_add->m_p_next_sibling; 00093 add_to_aux(p_add); 00094 p_add = p_next_add; 00095 } 00096 } 00097 00098 PB_DS_CLASS_T_DEC 00099 inline void 00100 PB_DS_CLASS_C_DEC:: 00101 add_to_aux(node_pointer p_nd) 00102 { 00103 size_type r = p_nd->m_metadata; 00104 while (m_a_aux[r] != 0) 00105 { 00106 _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); 00107 if (Cmp_Fn::operator()(m_a_aux[r]->m_value, p_nd->m_value)) 00108 make_child_of(m_a_aux[r], p_nd); 00109 else 00110 { 00111 make_child_of(p_nd, m_a_aux[r]); 00112 p_nd = m_a_aux[r]; 00113 } 00114 00115 m_a_aux[r] = 0; 00116 ++r; 00117 } 00118 00119 _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); 00120 00121 m_a_aux[r] = p_nd; 00122 } 00123 00124 PB_DS_CLASS_T_DEC 00125 inline void 00126 PB_DS_CLASS_C_DEC:: 00127 make_child_of(node_pointer p_nd, node_pointer p_new_parent) 00128 { 00129 _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_new_parent->m_metadata); 00130 _GLIBCXX_DEBUG_ASSERT(m_a_aux[p_nd->m_metadata] == p_nd || 00131 m_a_aux[p_nd->m_metadata] == p_new_parent); 00132 00133 ++p_new_parent->m_metadata; 00134 base_type::make_child_of(p_nd, p_new_parent); 00135 } 00136 00137 PB_DS_CLASS_T_DEC 00138 inline void 00139 PB_DS_CLASS_C_DEC:: 00140 make_from_aux() 00141 { 00142 base_type::m_p_root = m_p_max = 0; 00143 const size_type rnk_bnd = rank_bound(); 00144 size_type i = 0; 00145 while (i < rnk_bnd) 00146 { 00147 if (m_a_aux[i] != 0) 00148 { 00149 make_root_and_link(m_a_aux[i]); 00150 m_a_aux[i] = 0; 00151 } 00152 ++i; 00153 } 00154 00155 PB_DS_ASSERT_AUX_NULL((*this)) 00156 } 00157 00158 PB_DS_CLASS_T_DEC 00159 inline void 00160 PB_DS_CLASS_C_DEC:: 00161 remove_node(node_pointer p_nd) 00162 { 00163 node_pointer p_parent = p_nd; 00164 while (base_type::parent(p_parent) != 0) 00165 p_parent = base_type::parent(p_parent); 00166 00167 base_type::bubble_to_top(p_nd); 00168 m_p_max = p_nd; 00169 00170 node_pointer p_fix = base_type::m_p_root; 00171 while (p_fix != 0&& p_fix->m_p_next_sibling != p_parent) 00172 p_fix = p_fix->m_p_next_sibling; 00173 00174 if (p_fix != 0) 00175 p_fix->m_p_next_sibling = p_nd; 00176 00177 remove_max_node(); 00178 } 00179 00180 PB_DS_CLASS_T_DEC 00181 inline void 00182 PB_DS_CLASS_C_DEC:: 00183 clear() 00184 { 00185 base_type::clear(); 00186 m_p_max = 0; 00187 } 00188 00189 PB_DS_CLASS_T_DEC 00190 void 00191 PB_DS_CLASS_C_DEC:: 00192 erase(point_iterator it) 00193 { 00194 PB_DS_ASSERT_VALID((*this)) 00195 _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); 00196 00197 node_pointer p_nd = it.m_p_nd; 00198 remove_node(p_nd); 00199 base_type::actual_erase_node(p_nd); 00200 PB_DS_ASSERT_VALID((*this)) 00201 } 00202 00203 PB_DS_CLASS_T_DEC 00204 template<typename Pred> 00205 typename PB_DS_CLASS_C_DEC::size_type 00206 PB_DS_CLASS_C_DEC:: 00207 erase_if(Pred pred) 00208 { 00209 PB_DS_ASSERT_VALID((*this)) 00210 if (base_type::empty()) 00211 { 00212 PB_DS_ASSERT_VALID((*this)) 00213 return 0; 00214 } 00215 00216 base_type::to_linked_list(); 00217 node_pointer p_out = base_type::prune(pred); 00218 size_type ersd = 0; 00219 while (p_out != 0) 00220 { 00221 ++ersd; 00222 node_pointer p_next = p_out->m_p_next_sibling; 00223 base_type::actual_erase_node(p_out); 00224 p_out = p_next; 00225 } 00226 00227 node_pointer p_cur = base_type::m_p_root; 00228 m_p_max = base_type::m_p_root = 0; 00229 while (p_cur != 0) 00230 { 00231 node_pointer p_next = p_cur->m_p_next_sibling; 00232 make_root_and_link(p_cur); 00233 p_cur = p_next; 00234 } 00235 00236 PB_DS_ASSERT_VALID((*this)) 00237 return ersd; 00238 } 00239 00240 PB_DS_CLASS_T_DEC 00241 inline typename PB_DS_CLASS_C_DEC::size_type 00242 PB_DS_CLASS_C_DEC:: 00243 rank_bound() 00244 { 00245 using namespace std; 00246 const size_t* const p_upper = 00247 std::upper_bound(g_a_rank_bounds, 00248 g_a_rank_bounds + num_distinct_rank_bounds, 00249 base_type::m_size); 00250 00251 if (p_upper == g_a_rank_bounds + num_distinct_rank_bounds) 00252 return max_rank; 00253 00254 return (p_upper - g_a_rank_bounds); 00255 }