Home | History | Annotate | Download | only in gp_hash_table_map_
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the terms
      7 // of the GNU General Public License as published by the Free Software
      8 // Foundation; either version 3, or (at your option) any later
      9 // version.
     10 
     11 // This library is distributed in the hope that it will be useful, but
     12 // WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 // General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
     26 
     27 // Permission to use, copy, modify, sell, and distribute this software
     28 // is hereby granted without fee, provided that the above copyright
     29 // notice appears in all copies, and that both that copyright notice
     30 // and this permission notice appear in supporting documentation. None
     31 // of the above authors, nor IBM Haifa Research Laboratories, make any
     32 // representation about the suitability of this software for any
     33 // purpose. It is provided "as is" without express or implied
     34 // warranty.
     35 
     36 /**
     37  * @file gp_ht_map_.hpp
     38  * Contains an implementation class for gp_ht_map_.
     39  */
     40 
     41 #include <ext/pb_ds/tag_and_trait.hpp>
     42 #include <ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp>
     43 #include <ext/pb_ds/detail/types_traits.hpp>
     44 #include <ext/pb_ds/exception.hpp>
     45 #include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp>
     46 #include <utility>
     47 #ifdef PB_DS_HT_MAP_TRACE_
     48 #include <iostream>
     49 #endif
     50 #ifdef _GLIBCXX_DEBUG
     51 #include <ext/pb_ds/detail/debug_map_base.hpp>
     52 #endif
     53 #include <debug/debug.h>
     54 
     55 namespace __gnu_pbds
     56 {
     57   namespace detail
     58   {
     59 #define PB_DS_CLASS_T_DEC \
     60     template<typename Key, typename Mapped, typename Hash_Fn, typename Eq_Fn, \
     61 	     typename Allocator, bool Store_Hash, typename Comb_Probe_Fn, \
     62 	     typename Probe_Fn,	typename Resize_Policy>
     63 
     64 #ifdef PB_DS_DATA_TRUE_INDICATOR
     65 #define PB_DS_CLASS_NAME gp_ht_map_data_
     66 #endif
     67 
     68 #ifdef PB_DS_DATA_FALSE_INDICATOR
     69 #define PB_DS_CLASS_NAME gp_ht_map_no_data_
     70 #endif
     71 
     72 #define PB_DS_CLASS_C_DEC \
     73     PB_DS_CLASS_NAME<Key, Mapped, Hash_Fn, Eq_Fn, Allocator,	\
     74 		     Store_Hash, Comb_Probe_Fn, Probe_Fn, Resize_Policy>
     75 
     76 #define PB_DS_HASH_EQ_FN_C_DEC \
     77     hash_eq_fn<Key, Eq_Fn, Allocator, Store_Hash>
     78 
     79 #define PB_DS_RANGED_PROBE_FN_C_DEC \
     80     ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, Probe_Fn, Store_Hash>
     81 
     82 #define PB_DS_TYPES_TRAITS_C_DEC \
     83     types_traits<Key, Mapped, Allocator, Store_Hash>
     84 
     85 #ifdef _GLIBCXX_DEBUG
     86 #define PB_DS_DEBUG_MAP_BASE_C_DEC \
     87     debug_map_base<Key, Eq_Fn, typename Allocator::template rebind<Key>::other::const_reference>
     88 #endif
     89 
     90 #ifdef PB_DS_DATA_TRUE_INDICATOR
     91 #define PB_DS_V2F(X) (X).first
     92 #define PB_DS_V2S(X) (X).second
     93 #endif
     94 
     95 #ifdef PB_DS_DATA_FALSE_INDICATOR
     96 #define PB_DS_V2F(X) (X)
     97 #define PB_DS_V2S(X) Mapped()
     98 #endif
     99 
    100     template<typename Key,
    101 	     typename Mapped,
    102 	     typename Hash_Fn,
    103 	     typename Eq_Fn,
    104 	     typename Allocator,
    105 	     bool Store_Hash,
    106 	     typename Comb_Probe_Fn,
    107 	     typename Probe_Fn,
    108 	     typename Resize_Policy>
    109     class PB_DS_CLASS_NAME :
    110 #ifdef _GLIBCXX_DEBUG
    111       protected PB_DS_DEBUG_MAP_BASE_C_DEC,
    112 #endif
    113       public PB_DS_HASH_EQ_FN_C_DEC,
    114       public Resize_Policy,
    115       public PB_DS_RANGED_PROBE_FN_C_DEC,
    116       public PB_DS_TYPES_TRAITS_C_DEC
    117     {
    118     private:
    119       typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;
    120       typedef typename traits_base::value_type value_type_;
    121       typedef typename traits_base::pointer pointer_;
    122       typedef typename traits_base::const_pointer const_pointer_;
    123       typedef typename traits_base::reference reference_;
    124       typedef typename traits_base::const_reference const_reference_;
    125       typedef typename traits_base::comp_hash comp_hash;
    126 
    127       enum entry_status
    128 	{
    129 	  empty_entry_status,
    130 	  valid_entry_status,
    131 	  erased_entry_status
    132 	} __attribute__ ((packed));
    133 
    134       struct entry : public traits_base::stored_value_type
    135       {
    136 	entry_status m_stat;
    137       };
    138 
    139       typedef typename Allocator::template rebind<entry>::other entry_allocator;
    140       typedef typename entry_allocator::pointer entry_pointer;
    141       typedef typename entry_allocator::const_pointer const_entry_pointer;
    142       typedef typename entry_allocator::reference entry_reference;
    143       typedef typename entry_allocator::const_reference const_entry_reference;
    144       typedef typename entry_allocator::pointer entry_array;
    145 
    146       typedef PB_DS_RANGED_PROBE_FN_C_DEC ranged_probe_fn_base;
    147 
    148 #ifdef _GLIBCXX_DEBUG
    149       typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base;
    150 #endif
    151 
    152       typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base;
    153       typedef Resize_Policy resize_base;
    154 
    155 #define PB_DS_GEN_POS typename Allocator::size_type
    156 
    157 #include <ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp>
    158 #include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp>
    159 #include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp>
    160 #include <ext/pb_ds/detail/unordered_iterator/iterator.hpp>
    161 
    162 #undef PB_DS_GEN_POS
    163 
    164     public:
    165       typedef Allocator allocator_type;
    166       typedef typename Allocator::size_type size_type;
    167       typedef typename Allocator::difference_type difference_type;
    168       typedef Hash_Fn hash_fn;
    169       typedef Eq_Fn eq_fn;
    170       typedef Probe_Fn probe_fn;
    171       typedef Comb_Probe_Fn comb_probe_fn;
    172       typedef Resize_Policy resize_policy;
    173 
    174       enum
    175 	{
    176 	  store_hash = Store_Hash
    177 	};
    178 
    179       typedef typename traits_base::key_type key_type;
    180       typedef typename traits_base::key_pointer key_pointer;
    181       typedef typename traits_base::const_key_pointer const_key_pointer;
    182       typedef typename traits_base::key_reference key_reference;
    183       typedef typename traits_base::const_key_reference const_key_reference;
    184       typedef typename traits_base::mapped_type mapped_type;
    185       typedef typename traits_base::mapped_pointer mapped_pointer;
    186       typedef typename traits_base::const_mapped_pointer const_mapped_pointer;
    187       typedef typename traits_base::mapped_reference mapped_reference;
    188       typedef typename traits_base::const_mapped_reference const_mapped_reference;
    189       typedef typename traits_base::value_type value_type;
    190       typedef typename traits_base::pointer pointer;
    191       typedef typename traits_base::const_pointer const_pointer;
    192       typedef typename traits_base::reference reference;
    193       typedef typename traits_base::const_reference const_reference;
    194 
    195 #ifdef PB_DS_DATA_TRUE_INDICATOR
    196       typedef point_iterator_ point_iterator;
    197 #endif
    198 
    199 #ifdef PB_DS_DATA_FALSE_INDICATOR
    200       typedef const_point_iterator_ point_iterator;
    201 #endif
    202 
    203       typedef const_point_iterator_ const_point_iterator;
    204 
    205 #ifdef PB_DS_DATA_TRUE_INDICATOR
    206       typedef iterator_ iterator;
    207 #endif
    208 
    209 #ifdef PB_DS_DATA_FALSE_INDICATOR
    210       typedef const_iterator_ iterator;
    211 #endif
    212 
    213       typedef const_iterator_ const_iterator;
    214 
    215       PB_DS_CLASS_NAME();
    216 
    217       PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&);
    218 
    219       PB_DS_CLASS_NAME(const Hash_Fn&);
    220 
    221       PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&);
    222 
    223       PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&);
    224 
    225       PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&,
    226 		       const Probe_Fn&);
    227 
    228       PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&,
    229 		       const Probe_Fn&, const Resize_Policy&);
    230 
    231       template<typename It>
    232       void
    233       copy_from_range(It first_it, It last_it);
    234 
    235       virtual
    236       ~PB_DS_CLASS_NAME();
    237 
    238       void
    239       swap(PB_DS_CLASS_C_DEC& other);
    240 
    241       inline size_type
    242       size() const;
    243 
    244       inline size_type
    245       max_size() const;
    246 
    247       inline bool
    248       empty() const;
    249 
    250       Hash_Fn&
    251       get_hash_fn();
    252 
    253       const Hash_Fn&
    254       get_hash_fn() const;
    255 
    256       Eq_Fn&
    257       get_eq_fn();
    258 
    259       const Eq_Fn&
    260       get_eq_fn() const;
    261 
    262       Probe_Fn&
    263       get_probe_fn();
    264 
    265       const Probe_Fn&
    266       get_probe_fn() const;
    267 
    268       Comb_Probe_Fn&
    269       get_comb_probe_fn();
    270 
    271       const Comb_Probe_Fn&
    272       get_comb_probe_fn() const;
    273 
    274       Resize_Policy&
    275       get_resize_policy();
    276 
    277       const Resize_Policy&
    278       get_resize_policy() const;
    279 
    280       inline std::pair<point_iterator, bool>
    281       insert(const_reference r_val)
    282       {
    283 	_GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();)
    284         return insert_imp(r_val, traits_base::m_store_extra_indicator);
    285       }
    286 
    287       inline mapped_reference
    288       operator[](const_key_reference r_key)
    289       {
    290 #ifdef PB_DS_DATA_TRUE_INDICATOR
    291 	return subscript_imp(r_key, traits_base::m_store_extra_indicator);
    292 #else
    293 	insert(r_key);
    294         return traits_base::s_null_mapped;
    295 #endif
    296       }
    297 
    298       inline point_iterator
    299       find(const_key_reference r_key);
    300 
    301       inline const_point_iterator
    302       find(const_key_reference r_key) const;
    303 
    304       inline point_iterator
    305       find_end();
    306 
    307       inline const_point_iterator
    308       find_end() const;
    309 
    310       inline bool
    311       erase(const_key_reference r_key);
    312 
    313       template<typename Pred>
    314       inline size_type
    315       erase_if(Pred prd);
    316 
    317       void
    318       clear();
    319 
    320       inline iterator
    321       begin();
    322 
    323       inline const_iterator
    324       begin() const;
    325 
    326       inline iterator
    327       end();
    328 
    329       inline const_iterator
    330       end() const;
    331 
    332 #ifdef _GLIBCXX_DEBUG
    333       void
    334       assert_valid() const;
    335 #endif
    336 
    337 #ifdef PB_DS_HT_MAP_TRACE_
    338       void
    339       trace() const;
    340 #endif
    341 
    342     private:
    343 #ifdef PB_DS_DATA_TRUE_INDICATOR
    344       friend class iterator_;
    345 #endif
    346 
    347       friend class const_iterator_;
    348 
    349       void
    350       deallocate_all();
    351 
    352       void
    353       initialize();
    354 
    355       void
    356       erase_all_valid_entries(entry_array, size_type);
    357 
    358       inline bool
    359       do_resize_if_needed();
    360 
    361       inline void
    362       do_resize_if_needed_no_throw();
    363 
    364       void
    365       resize_imp(size_type);
    366 
    367       virtual void
    368       do_resize(size_type);
    369 
    370       void
    371       resize_imp(entry_array, size_type);
    372 
    373       inline void
    374       resize_imp_reassign(entry_pointer, entry_array, false_type);
    375 
    376       inline void
    377       resize_imp_reassign(entry_pointer, entry_array, true_type);
    378 
    379       inline size_type
    380       find_ins_pos(const_key_reference, false_type);
    381 
    382       inline comp_hash
    383       find_ins_pos(const_key_reference, true_type);
    384 
    385       inline std::pair<point_iterator, bool>
    386       insert_imp(const_reference, false_type);
    387 
    388       inline std::pair<point_iterator, bool>
    389       insert_imp(const_reference, true_type);
    390 
    391       inline pointer
    392       insert_new_imp(const_reference r_val, size_type pos)
    393       {
    394 	_GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status);
    395 
    396 	if (do_resize_if_needed())
    397 	  pos = find_ins_pos(PB_DS_V2F(r_val),
    398 			     traits_base::m_store_extra_indicator);
    399 
    400 	_GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status);
    401 
    402 	entry* const p_e = m_entries + pos;
    403 	new (&p_e->m_value) value_type(r_val);
    404 	p_e->m_stat = valid_entry_status;
    405 	resize_base::notify_inserted(++m_num_used_e);
    406 
    407 	_GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));)
    408 
    409 	_GLIBCXX_DEBUG_ONLY(assert_valid();)
    410 	return &p_e->m_value;
    411       }
    412 
    413       inline pointer
    414       insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair)
    415       {
    416 	_GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat !=
    417 			 valid_entry_status);
    418 
    419 	if (do_resize_if_needed())
    420 	  r_pos_hash_pair = find_ins_pos(PB_DS_V2F(r_val),
    421 					 traits_base::m_store_extra_indicator);
    422 
    423 	_GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat !=
    424 			      valid_entry_status);
    425 
    426 	entry* const p_e = m_entries + r_pos_hash_pair.first;
    427 	new (&p_e->m_value) value_type(r_val);
    428 	p_e->m_hash = r_pos_hash_pair.second;
    429 	p_e->m_stat = valid_entry_status;
    430 
    431 	resize_base::notify_inserted(++m_num_used_e);
    432 
    433 	_GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));)
    434 
    435 	_GLIBCXX_DEBUG_ONLY(assert_valid();)
    436 	return &p_e->m_value;
    437       }
    438 
    439 #ifdef PB_DS_DATA_TRUE_INDICATOR
    440       inline mapped_reference
    441       subscript_imp(const_key_reference key, false_type)
    442       {
    443 	_GLIBCXX_DEBUG_ONLY(assert_valid();)
    444 
    445 	const size_type pos = find_ins_pos(key,
    446 					 traits_base::m_store_extra_indicator);
    447 
    448 	entry_pointer p_e = &m_entries[pos];
    449 	if (p_e->m_stat != valid_entry_status)
    450 	  return insert_new_imp(value_type(key, mapped_type()), pos)->second;
    451 
    452 	_GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(key);)
    453 	return p_e->m_value.second;
    454       }
    455 
    456       inline mapped_reference
    457       subscript_imp(const_key_reference key, true_type)
    458       {
    459 	_GLIBCXX_DEBUG_ONLY(assert_valid();)
    460 
    461 	comp_hash pos_hash_pair =
    462 	  find_ins_pos(key, traits_base::m_store_extra_indicator);
    463 
    464 	if (m_entries[pos_hash_pair.first].m_stat != valid_entry_status)
    465 	  return insert_new_imp(value_type(key, mapped_type()),
    466 				 pos_hash_pair)->second;
    467 
    468 	_GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(key));
    469 	return (m_entries + pos_hash_pair.first)->m_value.second;
    470       }
    471 #endif
    472 
    473       inline pointer
    474       find_key_pointer(const_key_reference key, false_type)
    475       {
    476 	const size_type hash = ranged_probe_fn_base::operator()(key);
    477 	size_type i;
    478 	resize_base::notify_find_search_start();
    479 
    480 	// Loop until entry is found or until all possible entries accessed.
    481 	for (i = 0; i < m_num_e; ++i)
    482 	  {
    483 	    const size_type pos = ranged_probe_fn_base::operator()(key, hash, i);
    484 
    485 	    entry* const p_e = m_entries + pos;
    486 	    switch (p_e->m_stat)
    487 	      {
    488 	      case empty_entry_status:
    489 		{
    490 		  resize_base::notify_find_search_end();
    491 		  _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(key);)
    492 
    493 		    return 0;
    494 		}
    495 		break;
    496 	      case valid_entry_status:
    497 		if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), key))
    498 		  {
    499 		    resize_base::notify_find_search_end();
    500 		    _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(key);)
    501 
    502 		    return pointer(&p_e->m_value);
    503 		  }
    504 		break;
    505 	      case erased_entry_status:
    506 		break;
    507 	      default:
    508 		_GLIBCXX_DEBUG_ASSERT(0);
    509 	      };
    510 
    511 	    resize_base::notify_find_search_collision();
    512 	  }
    513 
    514 	_GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(key);)
    515 	resize_base::notify_find_search_end();
    516 	return 0;
    517       }
    518 
    519       inline pointer
    520       find_key_pointer(const_key_reference key, true_type)
    521       {
    522 	comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(key);
    523 	size_type i;
    524 	resize_base::notify_find_search_start();
    525 
    526 	// Loop until entry is found or until all possible entries accessed.
    527 	for (i = 0; i < m_num_e; ++i)
    528 	  {
    529 	    const size_type pos =
    530 	      ranged_probe_fn_base::operator()(key, pos_hash_pair.second, i);
    531 
    532 	    entry* const p_e = m_entries + pos;
    533 
    534 	    switch(p_e->m_stat)
    535 	      {
    536 	      case empty_entry_status:
    537 		{
    538 		  resize_base::notify_find_search_end();
    539 		  _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(key);)
    540 
    541 		  return 0;
    542 		}
    543 		break;
    544 	      case valid_entry_status:
    545 		if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value),
    546 						p_e->m_hash,
    547 						key, pos_hash_pair.second))
    548 		  {
    549 		    resize_base::notify_find_search_end();
    550 		    _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(key);)
    551 		    return pointer(&p_e->m_value);
    552 		  }
    553 		break;
    554 	      case erased_entry_status:
    555 		break;
    556 	      default:
    557 		_GLIBCXX_DEBUG_ASSERT(0);
    558 	      };
    559 
    560 	    resize_base::notify_find_search_collision();
    561 	  }
    562 
    563 	_GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(key);)
    564 	resize_base::notify_find_search_end();
    565 	return 0;
    566       }
    567 
    568       inline bool
    569       erase_imp(const_key_reference, true_type);
    570 
    571       inline bool
    572       erase_imp(const_key_reference, false_type);
    573 
    574       inline void
    575       erase_entry(entry_pointer p_e);
    576 
    577 #ifdef PB_DS_DATA_TRUE_INDICATOR
    578       void
    579       inc_it_state(pointer& r_p_value, size_type& r_pos) const
    580       { inc_it_state((const_mapped_pointer& )r_p_value, r_pos); }
    581 #endif
    582 
    583       void
    584       inc_it_state(const_pointer& r_p_value, size_type& r_pos) const
    585       {
    586 	_GLIBCXX_DEBUG_ASSERT(r_p_value != 0);
    587 	for (++r_pos; r_pos < m_num_e; ++r_pos)
    588 	  {
    589 	    const_entry_pointer p_e =& m_entries[r_pos];
    590 	    if (p_e->m_stat == valid_entry_status)
    591 	      {
    592 		r_p_value =& p_e->m_value;
    593 		return;
    594 	      }
    595 	  }
    596 	r_p_value = 0;
    597       }
    598 
    599       void
    600       get_start_it_state(const_pointer& r_p_value, size_type& r_pos) const
    601       {
    602 	for (r_pos = 0; r_pos < m_num_e; ++r_pos)
    603 	  {
    604 	    const_entry_pointer p_e = &m_entries[r_pos];
    605 	    if (p_e->m_stat == valid_entry_status)
    606 	      {
    607 		r_p_value = &p_e->m_value;
    608 		return;
    609 	      }
    610 	  }
    611 	r_p_value = 0;
    612       }
    613 
    614       void
    615       get_start_it_state(pointer& r_p_value, size_type& r_pos)
    616       {
    617 	for (r_pos = 0; r_pos < m_num_e; ++r_pos)
    618 	  {
    619 	    entry_pointer p_e = &m_entries[r_pos];
    620 	    if (p_e->m_stat == valid_entry_status)
    621 	      {
    622 		r_p_value = &p_e->m_value;
    623 		return;
    624 	      }
    625 	  }
    626 	r_p_value = 0;
    627       }
    628 
    629 #ifdef _GLIBCXX_DEBUG
    630       void
    631       assert_entry_array_valid(const entry_array, false_type) const;
    632 
    633       void
    634       assert_entry_array_valid(const entry_array, true_type) const;
    635 #endif
    636 
    637       static entry_allocator 	s_entry_allocator;
    638       static iterator 		s_end_it;
    639       static const_iterator 	s_const_end_it;
    640 
    641       size_type 		m_num_e;
    642       size_type 		m_num_used_e;
    643       entry_pointer 		m_entries;
    644 
    645       enum
    646 	{
    647 	  store_hash_ok = !Store_Hash
    648 	                  || !is_same<Hash_Fn, __gnu_pbds::null_hash_fn>::value
    649 	};
    650 
    651       PB_DS_STATIC_ASSERT(sth, store_hash_ok);
    652     };
    653 
    654 #include <ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp>
    655 #include <ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp>
    656 #include <ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp>
    657 #include <ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp>
    658 #include <ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp>
    659 #include <ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp>
    660 #include <ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp>
    661 #include <ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp>
    662 #include <ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp>
    663 #include <ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp>
    664 
    665 #undef PB_DS_CLASS_T_DEC
    666 #undef PB_DS_CLASS_C_DEC
    667 #undef PB_DS_HASH_EQ_FN_C_DEC
    668 #undef PB_DS_RANGED_PROBE_FN_C_DEC
    669 #undef PB_DS_TYPES_TRAITS_C_DEC
    670 #undef PB_DS_DEBUG_MAP_BASE_C_DEC
    671 #undef PB_DS_CLASS_NAME
    672 #undef PB_DS_V2F
    673 #undef PB_DS_V2S
    674 
    675   } // namespace detail
    676 } // namespace __gnu_pbds
    677 
    678