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 cc_hash_table_map_/resize_fn_imps.hpp 00039 * Contains implementations of cc_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 len) 00057 { resize_imp(resize_base::get_nearest_larger_size(len)); } 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 PB_DS_ASSERT_VALID((*this)) 00083 if (new_size == m_num_e) 00084 return; 00085 00086 const size_type old_size = m_num_e; 00087 entry_pointer_array a_p_entries_resized; 00088 00089 // Following line might throw an exception. 00090 ranged_hash_fn_base::notify_resized(new_size); 00091 00092 __try 00093 { 00094 // Following line might throw an exception. 00095 a_p_entries_resized = s_entry_pointer_allocator.allocate(new_size); 00096 m_num_e = new_size; 00097 } 00098 __catch(...) 00099 { 00100 ranged_hash_fn_base::notify_resized(old_size); 00101 __throw_exception_again; 00102 } 00103 00104 // At this point no exceptions can be thrown. 00105 resize_imp_no_exceptions(new_size, a_p_entries_resized, old_size); 00106 Resize_Policy::notify_resized(new_size); 00107 PB_DS_ASSERT_VALID((*this)) 00108 } 00109 00110 PB_DS_CLASS_T_DEC 00111 void 00112 PB_DS_CLASS_C_DEC:: 00113 resize_imp_no_exceptions(size_type new_size, entry_pointer_array a_p_entries_resized, size_type old_size) 00114 { 00115 std::fill(a_p_entries_resized, a_p_entries_resized + m_num_e, 00116 entry_pointer(0)); 00117 00118 for (size_type pos = 0; pos < old_size; ++pos) 00119 { 00120 entry_pointer p_e = m_entries[pos]; 00121 while (p_e != 0) 00122 p_e = resize_imp_no_exceptions_reassign_pointer(p_e, a_p_entries_resized, traits_base::m_store_extra_indicator); 00123 } 00124 00125 m_num_e = new_size; 00126 _GLIBCXX_DEBUG_ONLY(assert_entry_pointer_array_valid(a_p_entries_resized, 00127 __FILE__, __LINE__);) 00128 s_entry_pointer_allocator.deallocate(m_entries, old_size); 00129 m_entries = a_p_entries_resized; 00130 PB_DS_ASSERT_VALID((*this)) 00131 } 00132 00133 #include <ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp> 00134 #include <ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp> 00135