libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005, 2006, 2007, 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_/cc_ht_map_.hpp 00039 * Contains an implementation class for cc_ht_map_. 00040 */ 00041 00042 #include <utility> 00043 #include <iterator> 00044 #include <ext/pb_ds/detail/cond_dealtor.hpp> 00045 #include <ext/pb_ds/tag_and_trait.hpp> 00046 #include <ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp> 00047 #include <ext/pb_ds/detail/types_traits.hpp> 00048 #include <ext/pb_ds/exception.hpp> 00049 #include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp> 00050 #ifdef _GLIBCXX_DEBUG 00051 #include <ext/pb_ds/detail/debug_map_base.hpp> 00052 #endif 00053 #ifdef PB_DS_HT_MAP_TRACE_ 00054 #include <iostream> 00055 #endif 00056 #include <debug/debug.h> 00057 00058 namespace __gnu_pbds 00059 { 00060 namespace detail 00061 { 00062 #ifdef PB_DS_DATA_TRUE_INDICATOR 00063 #define PB_DS_CC_HASH_NAME cc_ht_map 00064 #endif 00065 00066 #ifdef PB_DS_DATA_FALSE_INDICATOR 00067 #define PB_DS_CC_HASH_NAME cc_ht_set 00068 #endif 00069 00070 #define PB_DS_CLASS_T_DEC \ 00071 template<typename Key, typename Mapped, typename Hash_Fn, \ 00072 typename Eq_Fn, typename _Alloc, bool Store_Hash, \ 00073 typename Comb_Hash_Fn, typename Resize_Policy> 00074 00075 #define PB_DS_CLASS_C_DEC \ 00076 PB_DS_CC_HASH_NAME<Key, Mapped, Hash_Fn, Eq_Fn, _Alloc, \ 00077 Store_Hash, Comb_Hash_Fn, Resize_Policy> 00078 00079 #define PB_DS_HASH_EQ_FN_C_DEC \ 00080 hash_eq_fn<Key, Eq_Fn, _Alloc, Store_Hash> 00081 00082 #define PB_DS_RANGED_HASH_FN_C_DEC \ 00083 ranged_hash_fn<Key, Hash_Fn, _Alloc, Comb_Hash_Fn, Store_Hash> 00084 00085 #define PB_DS_CC_HASH_TRAITS_BASE \ 00086 types_traits<Key, Mapped, _Alloc, Store_Hash> 00087 00088 #ifdef _GLIBCXX_DEBUG 00089 #define PB_DS_DEBUG_MAP_BASE_C_DEC \ 00090 debug_map_base<Key, Eq_Fn, \ 00091 typename _Alloc::template rebind<Key>::other::const_reference> 00092 #endif 00093 00094 00095 /** 00096 * A collision-chaining hash-based container. 00097 * 00098 * 00099 * @ingroup hash-detail 00100 * 00101 * @tparam Key Key type. 00102 * 00103 * @tparam Mapped Map type. 00104 * 00105 * @tparam Hash_Fn Hashing functor. 00106 * Default is __gnu_cxx::hash. 00107 * 00108 * @tparam Eq_Fn Equal functor. 00109 * Default std::equal_to<Key> 00110 * 00111 * @tparam _Alloc Allocator type. 00112 * 00113 * @tparam Store_Hash If key type stores extra metadata. 00114 * Defaults to false. 00115 * 00116 * @tparam Comb_Hash_Fn Combining hash functor. 00117 * If Hash_Fn is not null_type, then this 00118 * is the ranged-hash functor; otherwise, 00119 * this is the range-hashing functor. 00120 * XXX(See Design::Hash-Based Containers::Hash Policies.) 00121 * Default direct_mask_range_hashing. 00122 * 00123 * @tparam Resize_Policy Resizes hash. 00124 * Defaults to hash_standard_resize_policy, 00125 * using hash_exponential_size_policy and 00126 * hash_load_check_resize_trigger. 00127 * 00128 * 00129 * Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_hash_fn, 00130 * detail::types_traits. (Optional: detail::debug_map_base.) 00131 */ 00132 template<typename Key, 00133 typename Mapped, 00134 typename Hash_Fn, 00135 typename Eq_Fn, 00136 typename _Alloc, 00137 bool Store_Hash, 00138 typename Comb_Hash_Fn, 00139 typename Resize_Policy > 00140 class PB_DS_CC_HASH_NAME: 00141 #ifdef _GLIBCXX_DEBUG 00142 protected PB_DS_DEBUG_MAP_BASE_C_DEC, 00143 #endif 00144 public PB_DS_HASH_EQ_FN_C_DEC, 00145 public Resize_Policy, 00146 public PB_DS_RANGED_HASH_FN_C_DEC, 00147 public PB_DS_CC_HASH_TRAITS_BASE 00148 { 00149 private: 00150 typedef PB_DS_CC_HASH_TRAITS_BASE traits_base; 00151 typedef typename traits_base::comp_hash comp_hash; 00152 typedef typename traits_base::value_type value_type_; 00153 typedef typename traits_base::pointer pointer_; 00154 typedef typename traits_base::const_pointer const_pointer_; 00155 typedef typename traits_base::reference reference_; 00156 typedef typename traits_base::const_reference const_reference_; 00157 00158 struct entry : public traits_base::stored_data_type 00159 { 00160 typename _Alloc::template rebind<entry>::other::pointer m_p_next; 00161 }; 00162 00163 typedef cond_dealtor<entry, _Alloc> cond_dealtor_t; 00164 00165 typedef typename _Alloc::template rebind<entry>::other entry_allocator; 00166 typedef typename entry_allocator::pointer entry_pointer; 00167 typedef typename entry_allocator::const_pointer const_entry_pointer; 00168 typedef typename entry_allocator::reference entry_reference; 00169 typedef typename entry_allocator::const_reference const_entry_reference; 00170 00171 typedef typename _Alloc::template rebind<entry_pointer>::other entry_pointer_allocator; 00172 typedef typename entry_pointer_allocator::pointer entry_pointer_array; 00173 00174 typedef PB_DS_RANGED_HASH_FN_C_DEC ranged_hash_fn_base; 00175 typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; 00176 typedef Resize_Policy resize_base; 00177 00178 #ifdef _GLIBCXX_DEBUG 00179 typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; 00180 #endif 00181 00182 #define PB_DS_GEN_POS std::pair<entry_pointer, typename _Alloc::size_type> 00183 00184 #include <ext/pb_ds/detail/unordered_iterator/point_const_iterator.hpp> 00185 #include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> 00186 #include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> 00187 #include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> 00188 00189 #undef PB_DS_GEN_POS 00190 00191 public: 00192 typedef _Alloc allocator_type; 00193 typedef typename _Alloc::size_type size_type; 00194 typedef typename _Alloc::difference_type difference_type; 00195 typedef Hash_Fn hash_fn; 00196 typedef Eq_Fn eq_fn; 00197 typedef Comb_Hash_Fn comb_hash_fn; 00198 typedef Resize_Policy resize_policy; 00199 00200 /// Value stores hash, true or false. 00201 enum 00202 { 00203 store_hash = Store_Hash 00204 }; 00205 00206 typedef typename traits_base::key_type key_type; 00207 typedef typename traits_base::key_pointer key_pointer; 00208 typedef typename traits_base::key_const_pointer key_const_pointer; 00209 typedef typename traits_base::key_reference key_reference; 00210 typedef typename traits_base::key_const_reference key_const_reference; 00211 typedef typename traits_base::mapped_type mapped_type; 00212 typedef typename traits_base::mapped_pointer mapped_pointer; 00213 typedef typename traits_base::mapped_const_pointer mapped_const_pointer; 00214 typedef typename traits_base::mapped_reference mapped_reference; 00215 typedef typename traits_base::mapped_const_reference mapped_const_reference; 00216 typedef typename traits_base::value_type value_type; 00217 typedef typename traits_base::pointer pointer; 00218 typedef typename traits_base::const_pointer const_pointer; 00219 typedef typename traits_base::reference reference; 00220 typedef typename traits_base::const_reference const_reference; 00221 00222 #ifdef PB_DS_DATA_TRUE_INDICATOR 00223 typedef point_iterator_ point_iterator; 00224 #endif 00225 00226 #ifdef PB_DS_DATA_FALSE_INDICATOR 00227 typedef point_const_iterator_ point_iterator; 00228 #endif 00229 00230 typedef point_const_iterator_ point_const_iterator; 00231 00232 #ifdef PB_DS_DATA_TRUE_INDICATOR 00233 typedef iterator_ iterator; 00234 #endif 00235 00236 #ifdef PB_DS_DATA_FALSE_INDICATOR 00237 typedef const_iterator_ iterator; 00238 #endif 00239 00240 typedef const_iterator_ const_iterator; 00241 00242 PB_DS_CC_HASH_NAME(); 00243 00244 PB_DS_CC_HASH_NAME(const Hash_Fn&); 00245 00246 PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&); 00247 00248 PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&); 00249 00250 PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&, 00251 const Resize_Policy&); 00252 00253 PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC&); 00254 00255 virtual 00256 ~PB_DS_CC_HASH_NAME(); 00257 00258 void 00259 swap(PB_DS_CLASS_C_DEC&); 00260 00261 template<typename It> 00262 void 00263 copy_from_range(It, It); 00264 00265 void 00266 initialize(); 00267 00268 inline size_type 00269 size() const; 00270 00271 inline size_type 00272 max_size() const; 00273 00274 /// True if size() == 0. 00275 inline bool 00276 empty() const; 00277 00278 /// Return current hash_fn. 00279 Hash_Fn& 00280 get_hash_fn(); 00281 00282 /// Return current const hash_fn. 00283 const Hash_Fn& 00284 get_hash_fn() const; 00285 00286 /// Return current eq_fn. 00287 Eq_Fn& 00288 get_eq_fn(); 00289 00290 /// Return current const eq_fn. 00291 const Eq_Fn& 00292 get_eq_fn() const; 00293 00294 /// Return current comb_hash_fn. 00295 Comb_Hash_Fn& 00296 get_comb_hash_fn(); 00297 00298 /// Return current const comb_hash_fn. 00299 const Comb_Hash_Fn& 00300 get_comb_hash_fn() const; 00301 00302 /// Return current resize_policy. 00303 Resize_Policy& 00304 get_resize_policy(); 00305 00306 /// Return current const resize_policy. 00307 const Resize_Policy& 00308 get_resize_policy() const; 00309 00310 inline std::pair<point_iterator, bool> 00311 insert(const_reference r_val) 00312 { return insert_imp(r_val, traits_base::m_store_extra_indicator); } 00313 00314 inline mapped_reference 00315 operator[](key_const_reference r_key) 00316 { 00317 #ifdef PB_DS_DATA_TRUE_INDICATOR 00318 return (subscript_imp(r_key, traits_base::m_store_extra_indicator)); 00319 #else 00320 insert(r_key); 00321 return traits_base::s_null_type; 00322 #endif 00323 } 00324 00325 inline point_iterator 00326 find(key_const_reference); 00327 00328 inline point_const_iterator 00329 find(key_const_reference) const; 00330 00331 inline point_iterator 00332 find_end(); 00333 00334 inline point_const_iterator 00335 find_end() const; 00336 00337 inline bool 00338 erase(key_const_reference); 00339 00340 template<typename Pred> 00341 inline size_type 00342 erase_if(Pred); 00343 00344 void 00345 clear(); 00346 00347 inline iterator 00348 begin(); 00349 00350 inline const_iterator 00351 begin() const; 00352 00353 inline iterator 00354 end(); 00355 00356 inline const_iterator 00357 end() const; 00358 00359 #ifdef _GLIBCXX_DEBUG 00360 void 00361 assert_valid(const char*, int) const; 00362 #endif 00363 00364 #ifdef PB_DS_HT_MAP_TRACE_ 00365 void 00366 trace() const; 00367 #endif 00368 00369 private: 00370 void 00371 deallocate_all(); 00372 00373 inline bool 00374 do_resize_if_needed(); 00375 00376 inline void 00377 do_resize_if_needed_no_throw(); 00378 00379 void 00380 resize_imp(size_type); 00381 00382 void 00383 do_resize(size_type); 00384 00385 void 00386 resize_imp_no_exceptions(size_type, entry_pointer_array, size_type); 00387 00388 inline entry_pointer 00389 resize_imp_no_exceptions_reassign_pointer(entry_pointer, 00390 entry_pointer_array, 00391 false_type); 00392 00393 inline entry_pointer 00394 resize_imp_no_exceptions_reassign_pointer(entry_pointer, 00395 entry_pointer_array, 00396 true_type); 00397 00398 void 00399 deallocate_links_in_list(entry_pointer); 00400 00401 inline entry_pointer 00402 get_entry(const_reference, false_type); 00403 00404 inline entry_pointer 00405 get_entry(const_reference, true_type); 00406 00407 inline void 00408 rels_entry(entry_pointer); 00409 00410 #ifdef PB_DS_DATA_TRUE_INDICATOR 00411 inline mapped_reference 00412 subscript_imp(key_const_reference r_key, false_type) 00413 { 00414 _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) 00415 const size_type pos = ranged_hash_fn_base::operator()(r_key); 00416 entry_pointer p_e = m_entries[pos]; 00417 resize_base::notify_insert_search_start(); 00418 00419 while (p_e != 0 00420 && !hash_eq_fn_base::operator()(p_e->m_value.first, r_key)) 00421 { 00422 resize_base::notify_insert_search_collision(); 00423 p_e = p_e->m_p_next; 00424 } 00425 00426 resize_base::notify_insert_search_end(); 00427 if (p_e != 0) 00428 { 00429 PB_DS_CHECK_KEY_EXISTS(r_key) 00430 return (p_e->m_value.second); 00431 } 00432 00433 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00434 return insert_new_imp(value_type(r_key, mapped_type()), pos)->second; 00435 } 00436 00437 inline mapped_reference 00438 subscript_imp(key_const_reference r_key, true_type) 00439 { 00440 _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) 00441 comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); 00442 entry_pointer p_e = m_entries[pos_hash_pair.first]; 00443 resize_base::notify_insert_search_start(); 00444 while (p_e != 0 && 00445 !hash_eq_fn_base::operator()(p_e->m_value.first, p_e->m_hash, 00446 r_key, pos_hash_pair.second)) 00447 { 00448 resize_base::notify_insert_search_collision(); 00449 p_e = p_e->m_p_next; 00450 } 00451 00452 resize_base::notify_insert_search_end(); 00453 if (p_e != 0) 00454 { 00455 PB_DS_CHECK_KEY_EXISTS(r_key) 00456 return p_e->m_value.second; 00457 } 00458 00459 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00460 return insert_new_imp(value_type(r_key, mapped_type()), 00461 pos_hash_pair)->second; 00462 } 00463 #endif 00464 00465 inline std::pair<point_iterator, bool> 00466 insert_imp(const_reference, false_type); 00467 00468 inline std::pair<point_iterator, bool> 00469 insert_imp(const_reference, true_type); 00470 00471 inline pointer 00472 insert_new_imp(const_reference r_val, size_type pos) 00473 { 00474 if (do_resize_if_needed()) 00475 pos = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); 00476 00477 // Following lines might throw an exception. 00478 entry_pointer p_e = get_entry(r_val, 00479 traits_base::m_no_throw_copies_indicator); 00480 00481 // At this point no exceptions can be thrown. 00482 p_e->m_p_next = m_entries[pos]; 00483 m_entries[pos] = p_e; 00484 resize_base::notify_inserted(++m_num_used_e); 00485 00486 _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) 00487 _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) 00488 return &p_e->m_value; 00489 } 00490 00491 inline pointer 00492 insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) 00493 { 00494 // Following lines might throw an exception. 00495 if (do_resize_if_needed()) 00496 r_pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); 00497 00498 entry_pointer p_e = get_entry(r_val, 00499 traits_base::m_no_throw_copies_indicator); 00500 00501 // At this point no exceptions can be thrown. 00502 p_e->m_hash = r_pos_hash_pair.second; 00503 p_e->m_p_next = m_entries[r_pos_hash_pair.first]; 00504 m_entries[r_pos_hash_pair.first] = p_e; 00505 resize_base::notify_inserted(++m_num_used_e); 00506 _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) 00507 _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) 00508 return &p_e->m_value; 00509 } 00510 00511 inline pointer 00512 find_key_pointer(key_const_reference r_key, false_type) 00513 { 00514 entry_pointer p_e = m_entries[ranged_hash_fn_base::operator()(r_key)]; 00515 resize_base::notify_find_search_start(); 00516 while (p_e != 0 && 00517 !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) 00518 { 00519 resize_base::notify_find_search_collision(); 00520 p_e = p_e->m_p_next; 00521 } 00522 00523 resize_base::notify_find_search_end(); 00524 00525 #ifdef _GLIBCXX_DEBUG 00526 if (p_e == 0) 00527 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00528 else 00529 PB_DS_CHECK_KEY_EXISTS(r_key) 00530 #endif 00531 return &p_e->m_value; 00532 } 00533 00534 inline pointer 00535 find_key_pointer(key_const_reference r_key, true_type) 00536 { 00537 comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); 00538 entry_pointer p_e = m_entries[pos_hash_pair.first]; 00539 resize_base::notify_find_search_start(); 00540 while (p_e != 0 && 00541 !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), 00542 p_e->m_hash, 00543 r_key, pos_hash_pair.second)) 00544 { 00545 resize_base::notify_find_search_collision(); 00546 p_e = p_e->m_p_next; 00547 } 00548 00549 resize_base::notify_find_search_end(); 00550 00551 #ifdef _GLIBCXX_DEBUG 00552 if (p_e == 0) 00553 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00554 else 00555 PB_DS_CHECK_KEY_EXISTS(r_key) 00556 #endif 00557 return &p_e->m_value; 00558 } 00559 00560 inline bool 00561 erase_in_pos_imp(key_const_reference, size_type); 00562 00563 inline bool 00564 erase_in_pos_imp(key_const_reference, const comp_hash&); 00565 00566 inline void 00567 erase_entry_pointer(entry_pointer&); 00568 00569 #ifdef PB_DS_DATA_TRUE_INDICATOR 00570 void 00571 inc_it_state(pointer& r_p_value, 00572 std::pair<entry_pointer, size_type>& r_pos) const 00573 { 00574 inc_it_state((mapped_const_pointer& )r_p_value, r_pos); 00575 } 00576 #endif 00577 00578 void 00579 inc_it_state(const_pointer& r_p_value, 00580 std::pair<entry_pointer, size_type>& r_pos) const 00581 { 00582 _GLIBCXX_DEBUG_ASSERT(r_p_value != 0); 00583 r_pos.first = r_pos.first->m_p_next; 00584 if (r_pos.first != 0) 00585 { 00586 r_p_value = &r_pos.first->m_value; 00587 return; 00588 } 00589 00590 for (++r_pos.second; r_pos.second < m_num_e; ++r_pos.second) 00591 if (m_entries[r_pos.second] != 0) 00592 { 00593 r_pos.first = m_entries[r_pos.second]; 00594 r_p_value = &r_pos.first->m_value; 00595 return; 00596 } 00597 r_p_value = 0; 00598 } 00599 00600 void 00601 get_start_it_state(pointer& r_p_value, 00602 std::pair<entry_pointer, size_type>& r_pos) const 00603 { 00604 for (r_pos.second = 0; r_pos.second < m_num_e; ++r_pos.second) 00605 if (m_entries[r_pos.second] != 0) 00606 { 00607 r_pos.first = m_entries[r_pos.second]; 00608 r_p_value = &r_pos.first->m_value; 00609 return; 00610 } 00611 r_p_value = 0; 00612 } 00613 00614 #ifdef _GLIBCXX_DEBUG 00615 void 00616 assert_entry_pointer_array_valid(const entry_pointer_array, 00617 const char*, int) const; 00618 00619 void 00620 assert_entry_pointer_valid(const entry_pointer, true_type, 00621 const char*, int) const; 00622 00623 void 00624 assert_entry_pointer_valid(const entry_pointer, false_type, 00625 const char*, int) const; 00626 #endif 00627 00628 #ifdef PB_DS_HT_MAP_TRACE_ 00629 void 00630 trace_list(const_entry_pointer) const; 00631 #endif 00632 00633 private: 00634 #ifdef PB_DS_DATA_TRUE_INDICATOR 00635 friend class iterator_; 00636 #endif 00637 00638 friend class const_iterator_; 00639 00640 static entry_allocator s_entry_allocator; 00641 static entry_pointer_allocator s_entry_pointer_allocator; 00642 static iterator s_end_it; 00643 static const_iterator s_const_end_it; 00644 static point_iterator s_find_end_it; 00645 static point_const_iterator s_const_find_end_it; 00646 00647 size_type m_num_e; 00648 size_type m_num_used_e; 00649 entry_pointer_array m_entries; 00650 00651 enum 00652 { 00653 store_hash_ok = !Store_Hash 00654 || !is_same<Hash_Fn, __gnu_pbds::null_type>::value 00655 }; 00656 00657 PB_DS_STATIC_ASSERT(sth, store_hash_ok); 00658 }; 00659 00660 #include <ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp> 00661 #include <ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp> 00662 #include <ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp> 00663 #include <ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp> 00664 #include <ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp> 00665 #include <ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp> 00666 #include <ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp> 00667 #include <ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp> 00668 #include <ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp> 00669 #include <ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp> 00670 #include <ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp> 00671 00672 #undef PB_DS_CLASS_T_DEC 00673 #undef PB_DS_CLASS_C_DEC 00674 #undef PB_DS_HASH_EQ_FN_C_DEC 00675 #undef PB_DS_RANGED_HASH_FN_C_DEC 00676 #undef PB_DS_CC_HASH_TRAITS_BASE 00677 #undef PB_DS_DEBUG_MAP_BASE_C_DEC 00678 #undef PB_DS_CC_HASH_NAME 00679 } // namespace detail 00680 } // namespace __gnu_pbds