1 // -*- C++ -*- 2 3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2011 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the terms 8 // of the GNU General Public License as published by the Free Software 9 // Foundation; either version 3, or (at your option) any later 10 // version. 11 12 // This library is distributed in the hope that it will be useful, but 13 // WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 // General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 27 28 // Permission to use, copy, modify, sell, and distribute this software 29 // is hereby granted without fee, provided that the above copyright 30 // notice appears in all copies, and that both that copyright notice 31 // and this permission notice appear in supporting documentation. None 32 // of the above authors, nor IBM Haifa Research Laboratories, make any 33 // representation about the suitability of this software for any 34 // purpose. It is provided "as is" without express or implied 35 // warranty. 36 37 /** 38 * @file gp_hash_table_map_/constructor_destructor_fn_imps.hpp 39 * Contains implementations of gp_ht_map_'s constructors, destructor, 40 * and related functions. 41 */ 42 43 PB_DS_CLASS_T_DEC 44 typename PB_DS_CLASS_C_DEC::entry_allocator 45 PB_DS_CLASS_C_DEC::s_entry_allocator; 46 47 PB_DS_CLASS_T_DEC 48 template<typename It> 49 void 50 PB_DS_CLASS_C_DEC:: 51 copy_from_range(It first_it, It last_it) 52 { 53 while (first_it != last_it) 54 insert(*(first_it++)); 55 } 56 57 PB_DS_CLASS_T_DEC 58 PB_DS_CLASS_C_DEC:: 59 PB_DS_GP_HASH_NAME() 60 : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1)), 61 m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), 62 m_entries(s_entry_allocator.allocate(m_num_e)) 63 { 64 initialize(); 65 PB_DS_ASSERT_VALID((*this)) 66 } 67 68 PB_DS_CLASS_T_DEC 69 PB_DS_CLASS_C_DEC:: 70 PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn) 71 : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), 72 m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), 73 m_entries(s_entry_allocator.allocate(m_num_e)) 74 { 75 initialize(); 76 PB_DS_ASSERT_VALID((*this)) 77 } 78 79 PB_DS_CLASS_T_DEC 80 PB_DS_CLASS_C_DEC:: 81 PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) 82 : hash_eq_fn_base(r_eq_fn), 83 ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), 84 m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), 85 m_entries(s_entry_allocator.allocate(m_num_e)) 86 { 87 initialize(); 88 PB_DS_ASSERT_VALID((*this)) 89 } 90 91 PB_DS_CLASS_T_DEC 92 PB_DS_CLASS_C_DEC:: 93 PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, 94 const Comb_Probe_Fn& r_comb_hash_fn) 95 : hash_eq_fn_base(r_eq_fn), 96 ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), 97 r_hash_fn, r_comb_hash_fn), 98 m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), 99 m_entries(s_entry_allocator.allocate(m_num_e)) 100 { 101 initialize(); 102 PB_DS_ASSERT_VALID((*this)) 103 } 104 105 PB_DS_CLASS_T_DEC 106 PB_DS_CLASS_C_DEC:: 107 PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, 108 const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober) 109 : hash_eq_fn_base(r_eq_fn), 110 ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), 111 r_hash_fn, comb_hash_fn, prober), 112 m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), 113 m_entries(s_entry_allocator.allocate(m_num_e)) 114 { 115 initialize(); 116 PB_DS_ASSERT_VALID((*this)) 117 } 118 119 PB_DS_CLASS_T_DEC 120 PB_DS_CLASS_C_DEC:: 121 PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, 122 const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober, 123 const Resize_Policy& r_resize_policy) 124 : hash_eq_fn_base(r_eq_fn), resize_base(r_resize_policy), 125 ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), 126 r_hash_fn, comb_hash_fn, prober), 127 m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), 128 m_entries(s_entry_allocator.allocate(m_num_e)) 129 { 130 initialize(); 131 PB_DS_ASSERT_VALID((*this)) 132 } 133 134 PB_DS_CLASS_T_DEC 135 PB_DS_CLASS_C_DEC:: 136 PB_DS_GP_HASH_NAME(const PB_DS_CLASS_C_DEC& other) : 137 #ifdef _GLIBCXX_DEBUG 138 debug_base(other), 139 #endif 140 hash_eq_fn_base(other), 141 resize_base(other), 142 ranged_probe_fn_base(other), 143 m_num_e(other.m_num_e), 144 m_num_used_e(other.m_num_used_e), 145 m_entries(s_entry_allocator.allocate(m_num_e)) 146 { 147 for (size_type i = 0; i < m_num_e; ++i) 148 m_entries[i].m_stat = (entry_status)empty_entry_status; 149 150 __try 151 { 152 for (size_type i = 0; i < m_num_e; ++i) 153 { 154 m_entries[i].m_stat = other.m_entries[i].m_stat; 155 if (m_entries[i].m_stat == valid_entry_status) 156 new (m_entries + i) entry(other.m_entries[i]); 157 } 158 } 159 __catch(...) 160 { 161 deallocate_all(); 162 __throw_exception_again; 163 } 164 PB_DS_ASSERT_VALID((*this)) 165 } 166 167 PB_DS_CLASS_T_DEC 168 PB_DS_CLASS_C_DEC:: 169 ~PB_DS_GP_HASH_NAME() 170 { deallocate_all(); } 171 172 PB_DS_CLASS_T_DEC 173 void 174 PB_DS_CLASS_C_DEC:: 175 swap(PB_DS_CLASS_C_DEC& other) 176 { 177 PB_DS_ASSERT_VALID((*this)) 178 PB_DS_ASSERT_VALID(other) 179 std::swap(m_num_e, other.m_num_e); 180 std::swap(m_num_used_e, other.m_num_used_e); 181 std::swap(m_entries, other.m_entries); 182 ranged_probe_fn_base::swap(other); 183 hash_eq_fn_base::swap(other); 184 resize_base::swap(other); 185 _GLIBCXX_DEBUG_ONLY(debug_base::swap(other)); 186 PB_DS_ASSERT_VALID((*this)) 187 PB_DS_ASSERT_VALID(other) 188 } 189 190 PB_DS_CLASS_T_DEC 191 void 192 PB_DS_CLASS_C_DEC:: 193 deallocate_all() 194 { 195 clear(); 196 erase_all_valid_entries(m_entries, m_num_e); 197 s_entry_allocator.deallocate(m_entries, m_num_e); 198 } 199 200 PB_DS_CLASS_T_DEC 201 void 202 PB_DS_CLASS_C_DEC:: 203 erase_all_valid_entries(entry_array a_entries_resized, size_type len) 204 { 205 for (size_type pos = 0; pos < len; ++pos) 206 { 207 entry_pointer p_e = &a_entries_resized[pos]; 208 if (p_e->m_stat == valid_entry_status) 209 p_e->m_value.~value_type(); 210 } 211 } 212 213 PB_DS_CLASS_T_DEC 214 void 215 PB_DS_CLASS_C_DEC:: 216 initialize() 217 { 218 Resize_Policy::notify_resized(m_num_e); 219 Resize_Policy::notify_cleared(); 220 ranged_probe_fn_base::notify_resized(m_num_e); 221 for (size_type i = 0; i < m_num_e; ++i) 222 m_entries[i].m_stat = empty_entry_status; 223 } 224 225