libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the terms 00008 // of the GNU General Public License as published by the Free Software 00009 // Foundation; either version 3, or (at your option) any later 00010 // version. 00011 00012 // This library is distributed in the hope that it will be useful, but 00013 // WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 // General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 00027 00028 // Permission to use, copy, modify, sell, and distribute this software 00029 // is hereby granted without fee, provided that the above copyright 00030 // notice appears in all copies, and that both that copyright notice 00031 // and this permission notice appear in supporting documentation. None 00032 // of the above authors, nor IBM Haifa Research Laboratories, make any 00033 // representation about the suitability of this software for any 00034 // purpose. It is provided "as is" without express or implied 00035 // warranty. 00036 00037 /** 00038 * @file gp_hash_table_map_/resize_fn_imps.hpp 00039 * Contains implementations of gp_ht_map_'s resize related functions. 00040 */ 00041 00042 PB_DS_CLASS_T_DEC 00043 inline bool 00044 PB_DS_CLASS_C_DEC:: 00045 do_resize_if_needed() 00046 { 00047 if (!resize_base::is_resize_needed()) 00048 return false; 00049 resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); 00050 return true; 00051 } 00052 00053 PB_DS_CLASS_T_DEC 00054 void 00055 PB_DS_CLASS_C_DEC:: 00056 do_resize(size_type n) 00057 { resize_imp(resize_base::get_nearest_larger_size(n)); } 00058 00059 PB_DS_CLASS_T_DEC 00060 inline void 00061 PB_DS_CLASS_C_DEC:: 00062 do_resize_if_needed_no_throw() 00063 { 00064 if (!resize_base::is_resize_needed()) 00065 return; 00066 00067 __try 00068 { 00069 resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); 00070 } 00071 __catch(...) 00072 { } 00073 00074 PB_DS_ASSERT_VALID((*this)) 00075 } 00076 00077 PB_DS_CLASS_T_DEC 00078 void 00079 PB_DS_CLASS_C_DEC:: 00080 resize_imp(size_type new_size) 00081 { 00082 #ifdef PB_DS_REGRESSION 00083 typename _Alloc::group_adjustor adjust(m_num_e); 00084 #endif 00085 00086 if (new_size == m_num_e) 00087 return; 00088 00089 PB_DS_ASSERT_VALID((*this)) 00090 const size_type old_size = m_num_e; 00091 entry_array a_entries_resized = 0; 00092 00093 // Following line might throw an exception. 00094 a_entries_resized = s_entry_allocator.allocate(new_size); 00095 00096 ranged_probe_fn_base::notify_resized(new_size); 00097 m_num_e = new_size; 00098 00099 for (size_type i = 0; i < m_num_e; ++i) 00100 a_entries_resized[i].m_stat = empty_entry_status; 00101 00102 __try 00103 { 00104 resize_imp(a_entries_resized, old_size); 00105 } 00106 __catch(...) 00107 { 00108 erase_all_valid_entries(a_entries_resized, new_size); 00109 m_num_e = old_size; 00110 s_entry_allocator.deallocate(a_entries_resized, new_size); 00111 ranged_probe_fn_base::notify_resized(old_size); 00112 __throw_exception_again; 00113 } 00114 00115 // At this point no exceptions can be thrown. 00116 _GLIBCXX_DEBUG_ONLY(assert_entry_array_valid(a_entries_resized, 00117 traits_base::m_store_extra_indicator, 00118 __FILE__, __LINE__);) 00119 00120 Resize_Policy::notify_resized(new_size); 00121 erase_all_valid_entries(m_entries, old_size); 00122 s_entry_allocator.deallocate(m_entries, old_size); 00123 m_entries = a_entries_resized; 00124 PB_DS_ASSERT_VALID((*this)) 00125 } 00126 00127 PB_DS_CLASS_T_DEC 00128 void 00129 PB_DS_CLASS_C_DEC:: 00130 resize_imp(entry_array a_entries_resized, size_type old_size) 00131 { 00132 for (size_type pos = 0; pos < old_size; ++pos) 00133 if (m_entries[pos].m_stat == valid_entry_status) 00134 resize_imp_reassign(m_entries + pos, a_entries_resized, 00135 traits_base::m_store_extra_indicator); 00136 } 00137 00138 #include <ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp> 00139 #include <ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp> 00140