Home | History | Annotate | Download | only in cc_hash_table_map_
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005-2013 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 cc_hash_table_map_/cc_ht_map_.hpp
     38  * Contains an implementation class for cc_ht_map_.
     39  */
     40 
     41 #include <utility>
     42 #include <iterator>
     43 #include <ext/pb_ds/detail/cond_dealtor.hpp>
     44 #include <ext/pb_ds/tag_and_trait.hpp>
     45 #include <ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp>
     46 #include <ext/pb_ds/detail/types_traits.hpp>
     47 #include <ext/pb_ds/exception.hpp>
     48 #include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp>
     49 #ifdef _GLIBCXX_DEBUG
     50 #include <ext/pb_ds/detail/debug_map_base.hpp>
     51 #endif
     52 #ifdef PB_DS_HT_MAP_TRACE_
     53 #include <iostream>
     54 #endif
     55 #include <debug/debug.h>
     56 
     57 namespace __gnu_pbds
     58 {
     59   namespace detail
     60   {
     61 #ifdef PB_DS_DATA_TRUE_INDICATOR
     62 #define PB_DS_CC_HASH_NAME cc_ht_map
     63 #endif
     64 
     65 #ifdef PB_DS_DATA_FALSE_INDICATOR
     66 #define PB_DS_CC_HASH_NAME cc_ht_set
     67 #endif
     68 
     69 #define PB_DS_CLASS_T_DEC \
     70     template<typename Key, typename Mapped, typename Hash_Fn, \
     71 	     typename Eq_Fn, typename _Alloc, bool Store_Hash, \
     72 	     typename Comb_Hash_Fn, typename Resize_Policy>
     73 
     74 #define PB_DS_CLASS_C_DEC \
     75     PB_DS_CC_HASH_NAME<Key, Mapped, Hash_Fn, Eq_Fn, _Alloc,	\
     76 		     Store_Hash, Comb_Hash_Fn, Resize_Policy>
     77 
     78 #define PB_DS_HASH_EQ_FN_C_DEC \
     79     hash_eq_fn<Key, Eq_Fn, _Alloc, Store_Hash>
     80 
     81 #define PB_DS_RANGED_HASH_FN_C_DEC \
     82     ranged_hash_fn<Key,	Hash_Fn, _Alloc, Comb_Hash_Fn, Store_Hash>
     83 
     84 #define PB_DS_CC_HASH_TRAITS_BASE \
     85     types_traits<Key, Mapped, _Alloc, Store_Hash>
     86 
     87 #ifdef _GLIBCXX_DEBUG
     88 #define PB_DS_DEBUG_MAP_BASE_C_DEC \
     89     debug_map_base<Key,	Eq_Fn, \
     90 		  typename _Alloc::template rebind<Key>::other::const_reference>
     91 #endif
     92 
     93 
     94     /**
     95      *  A collision-chaining hash-based container.
     96      *
     97      *
     98      *  @ingroup hash-detail
     99      *
    100      *  @tparam Key 	    	Key type.
    101      *
    102      *  @tparam Mapped 	    	Map type.
    103      *
    104      *  @tparam Hash_Fn	      	Hashing functor.
    105      *                          Default is __gnu_cxx::hash.
    106      *
    107      *  @tparam Eq_Fn	      	Equal functor.
    108      *                          Default std::equal_to<Key>
    109      *
    110      *  @tparam _Alloc 	    	Allocator type.
    111      *
    112      *  @tparam Store_Hash    	If key type stores extra metadata.
    113      *                          Defaults to false.
    114      *
    115      *  @tparam Comb_Hash_Fn	Combining hash functor.
    116      *                          If Hash_Fn is not null_type, then this
    117      *                          is the ranged-hash functor; otherwise,
    118      *                          this is the range-hashing functor.
    119      *                    XXX(See Design::Hash-Based Containers::Hash Policies.)
    120      *                          Default direct_mask_range_hashing.
    121      *
    122      *  @tparam Resize_Policy 	Resizes hash.
    123      *                          Defaults to hash_standard_resize_policy,
    124      *                          using hash_exponential_size_policy and
    125      *                          hash_load_check_resize_trigger.
    126      *
    127      *
    128      *  Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_hash_fn,
    129      *             detail::types_traits. (Optional: detail::debug_map_base.)
    130      */
    131     template<typename Key,
    132 	     typename Mapped,
    133 	     typename Hash_Fn,
    134 	     typename Eq_Fn,
    135 	     typename _Alloc,
    136 	     bool Store_Hash,
    137 	     typename Comb_Hash_Fn,
    138 	     typename Resize_Policy >
    139     class PB_DS_CC_HASH_NAME:
    140 #ifdef _GLIBCXX_DEBUG
    141       protected PB_DS_DEBUG_MAP_BASE_C_DEC,
    142 #endif
    143       public PB_DS_HASH_EQ_FN_C_DEC,
    144       public Resize_Policy,
    145       public PB_DS_RANGED_HASH_FN_C_DEC,
    146       public PB_DS_CC_HASH_TRAITS_BASE
    147     {
    148     private:
    149       typedef PB_DS_CC_HASH_TRAITS_BASE	       	traits_base;
    150       typedef typename traits_base::comp_hash 	comp_hash;
    151       typedef typename traits_base::value_type 	value_type_;
    152       typedef typename traits_base::pointer 	pointer_;
    153       typedef typename traits_base::const_pointer const_pointer_;
    154       typedef typename traits_base::reference 	reference_;
    155       typedef typename traits_base::const_reference const_reference_;
    156 
    157       struct entry : public traits_base::stored_data_type
    158       {
    159 	typename _Alloc::template rebind<entry>::other::pointer m_p_next;
    160       };
    161 
    162       typedef cond_dealtor<entry, _Alloc> 	cond_dealtor_t;
    163 
    164       typedef typename _Alloc::template rebind<entry>::other entry_allocator;
    165       typedef typename entry_allocator::pointer entry_pointer;
    166       typedef typename entry_allocator::const_pointer const_entry_pointer;
    167       typedef typename entry_allocator::reference entry_reference;
    168       typedef typename entry_allocator::const_reference const_entry_reference;
    169 
    170       typedef typename _Alloc::template rebind<entry_pointer>::other entry_pointer_allocator;
    171       typedef typename entry_pointer_allocator::pointer entry_pointer_array;
    172 
    173       typedef PB_DS_RANGED_HASH_FN_C_DEC ranged_hash_fn_base;
    174       typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base;
    175       typedef Resize_Policy resize_base;
    176 
    177 #ifdef _GLIBCXX_DEBUG
    178       typedef PB_DS_DEBUG_MAP_BASE_C_DEC 	debug_base;
    179 #endif
    180 
    181 #define PB_DS_GEN_POS std::pair<entry_pointer, typename _Alloc::size_type>
    182 
    183 #include <ext/pb_ds/detail/unordered_iterator/point_const_iterator.hpp>
    184 #include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp>
    185 #include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp>
    186 #include <ext/pb_ds/detail/unordered_iterator/iterator.hpp>
    187 
    188 #undef PB_DS_GEN_POS
    189 
    190     public:
    191       typedef _Alloc 				allocator_type;
    192       typedef typename _Alloc::size_type 	size_type;
    193       typedef typename _Alloc::difference_type 	difference_type;
    194       typedef Hash_Fn 				hash_fn;
    195       typedef Eq_Fn 				eq_fn;
    196       typedef Comb_Hash_Fn 			comb_hash_fn;
    197       typedef Resize_Policy 			resize_policy;
    198 
    199       /// Value stores hash, true or false.
    200       enum
    201 	{
    202 	  store_hash = Store_Hash
    203 	};
    204 
    205       typedef typename traits_base::key_type key_type;
    206       typedef typename traits_base::key_pointer key_pointer;
    207       typedef typename traits_base::key_const_pointer key_const_pointer;
    208       typedef typename traits_base::key_reference key_reference;
    209       typedef typename traits_base::key_const_reference key_const_reference;
    210       typedef typename traits_base::mapped_type mapped_type;
    211       typedef typename traits_base::mapped_pointer mapped_pointer;
    212       typedef typename traits_base::mapped_const_pointer mapped_const_pointer;
    213       typedef typename traits_base::mapped_reference mapped_reference;
    214       typedef typename traits_base::mapped_const_reference mapped_const_reference;
    215       typedef typename traits_base::value_type 	value_type;
    216       typedef typename traits_base::pointer 	pointer;
    217       typedef typename traits_base::const_pointer const_pointer;
    218       typedef typename traits_base::reference 	reference;
    219       typedef typename traits_base::const_reference const_reference;
    220 
    221 #ifdef PB_DS_DATA_TRUE_INDICATOR
    222       typedef point_iterator_ 			point_iterator;
    223 #endif
    224 
    225 #ifdef PB_DS_DATA_FALSE_INDICATOR
    226       typedef point_const_iterator_ 		point_iterator;
    227 #endif
    228 
    229       typedef point_const_iterator_ 		point_const_iterator;
    230 
    231 #ifdef PB_DS_DATA_TRUE_INDICATOR
    232       typedef iterator_ 			iterator;
    233 #endif
    234 
    235 #ifdef PB_DS_DATA_FALSE_INDICATOR
    236       typedef const_iterator_ 			iterator;
    237 #endif
    238 
    239       typedef const_iterator_ 			const_iterator;
    240 
    241       PB_DS_CC_HASH_NAME();
    242 
    243       PB_DS_CC_HASH_NAME(const Hash_Fn&);
    244 
    245       PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&);
    246 
    247       PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&);
    248 
    249       PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&,
    250 		       const Resize_Policy&);
    251 
    252       PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC&);
    253 
    254       virtual
    255       ~PB_DS_CC_HASH_NAME();
    256 
    257       void
    258       swap(PB_DS_CLASS_C_DEC&);
    259 
    260       template<typename It>
    261       void
    262       copy_from_range(It, It);
    263 
    264       void
    265       initialize();
    266 
    267       inline size_type
    268       size() const;
    269 
    270       inline size_type
    271       max_size() const;
    272 
    273       /// True if size() == 0.
    274       inline bool
    275       empty() const;
    276 
    277       /// Return current hash_fn.
    278       Hash_Fn&
    279       get_hash_fn();
    280 
    281       /// Return current const hash_fn.
    282       const Hash_Fn&
    283       get_hash_fn() const;
    284 
    285       /// Return current eq_fn.
    286       Eq_Fn&
    287       get_eq_fn();
    288 
    289       /// Return current const eq_fn.
    290       const Eq_Fn&
    291       get_eq_fn() const;
    292 
    293       /// Return current comb_hash_fn.
    294       Comb_Hash_Fn&
    295       get_comb_hash_fn();
    296 
    297       /// Return current const comb_hash_fn.
    298       const Comb_Hash_Fn&
    299       get_comb_hash_fn() const;
    300 
    301       /// Return current resize_policy.
    302       Resize_Policy&
    303       get_resize_policy();
    304 
    305       /// Return current const resize_policy.
    306       const Resize_Policy&
    307       get_resize_policy() const;
    308 
    309       inline std::pair<point_iterator, bool>
    310       insert(const_reference r_val)
    311       { return insert_imp(r_val, traits_base::m_store_extra_indicator); }
    312 
    313       inline mapped_reference
    314       operator[](key_const_reference r_key)
    315       {
    316 #ifdef PB_DS_DATA_TRUE_INDICATOR
    317 	return (subscript_imp(r_key, traits_base::m_store_extra_indicator));
    318 #else
    319 	insert(r_key);
    320 	return traits_base::s_null_type;
    321 #endif
    322       }
    323 
    324       inline point_iterator
    325       find(key_const_reference);
    326 
    327       inline point_const_iterator
    328       find(key_const_reference) const;
    329 
    330       inline point_iterator
    331       find_end();
    332 
    333       inline point_const_iterator
    334       find_end() const;
    335 
    336       inline bool
    337       erase(key_const_reference);
    338 
    339       template<typename Pred>
    340       inline size_type
    341       erase_if(Pred);
    342 
    343       void
    344       clear();
    345 
    346       inline iterator
    347       begin();
    348 
    349       inline const_iterator
    350       begin() const;
    351 
    352       inline iterator
    353       end();
    354 
    355       inline const_iterator
    356       end() const;
    357 
    358 #ifdef _GLIBCXX_DEBUG
    359       void
    360       assert_valid(const char*, int) const;
    361 #endif
    362 
    363 #ifdef PB_DS_HT_MAP_TRACE_
    364       void
    365       trace() const;
    366 #endif
    367 
    368     private:
    369       void
    370       deallocate_all();
    371 
    372       inline bool
    373       do_resize_if_needed();
    374 
    375       inline void
    376       do_resize_if_needed_no_throw();
    377 
    378       void
    379       resize_imp(size_type);
    380 
    381       void
    382       do_resize(size_type);
    383 
    384       void
    385       resize_imp_no_exceptions(size_type, entry_pointer_array, size_type);
    386 
    387       inline entry_pointer
    388       resize_imp_no_exceptions_reassign_pointer(entry_pointer,
    389 						entry_pointer_array,
    390 						false_type);
    391 
    392       inline entry_pointer
    393       resize_imp_no_exceptions_reassign_pointer(entry_pointer,
    394 						entry_pointer_array,
    395 						true_type);
    396 
    397       void
    398       deallocate_links_in_list(entry_pointer);
    399 
    400       inline entry_pointer
    401       get_entry(const_reference, false_type);
    402 
    403       inline entry_pointer
    404       get_entry(const_reference, true_type);
    405 
    406       inline void
    407       rels_entry(entry_pointer);
    408 
    409 #ifdef PB_DS_DATA_TRUE_INDICATOR
    410       inline mapped_reference
    411       subscript_imp(key_const_reference r_key, false_type)
    412       {
    413 	_GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);)
    414 	const size_type pos = ranged_hash_fn_base::operator()(r_key);
    415 	entry_pointer p_e = m_entries[pos];
    416 	resize_base::notify_insert_search_start();
    417 
    418 	while (p_e != 0
    419 	       && !hash_eq_fn_base::operator()(p_e->m_value.first, r_key))
    420 	  {
    421 	    resize_base::notify_insert_search_collision();
    422 	    p_e = p_e->m_p_next;
    423 	  }
    424 
    425 	resize_base::notify_insert_search_end();
    426 	if (p_e != 0)
    427 	  {
    428 	    PB_DS_CHECK_KEY_EXISTS(r_key)
    429 	    return (p_e->m_value.second);
    430 	  }
    431 
    432 	PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
    433 	return insert_new_imp(value_type(r_key, mapped_type()), pos)->second;
    434       }
    435 
    436       inline mapped_reference
    437       subscript_imp(key_const_reference r_key, true_type)
    438       {
    439 	_GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);)
    440 	comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key);
    441 	entry_pointer p_e = m_entries[pos_hash_pair.first];
    442 	resize_base::notify_insert_search_start();
    443 	while (p_e != 0 &&
    444 	       !hash_eq_fn_base::operator()(p_e->m_value.first, p_e->m_hash,
    445 					    r_key, pos_hash_pair.second))
    446 	  {
    447 	    resize_base::notify_insert_search_collision();
    448 	    p_e = p_e->m_p_next;
    449 	  }
    450 
    451 	resize_base::notify_insert_search_end();
    452 	if (p_e != 0)
    453 	  {
    454 	    PB_DS_CHECK_KEY_EXISTS(r_key)
    455 	    return p_e->m_value.second;
    456 	  }
    457 
    458 	PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
    459 	return insert_new_imp(value_type(r_key, mapped_type()),
    460 			      pos_hash_pair)->second;
    461       }
    462 #endif
    463 
    464       inline std::pair<point_iterator, bool>
    465       insert_imp(const_reference, false_type);
    466 
    467       inline std::pair<point_iterator, bool>
    468       insert_imp(const_reference, true_type);
    469 
    470       inline pointer
    471       insert_new_imp(const_reference r_val, size_type pos)
    472       {
    473 	if (do_resize_if_needed())
    474 	  pos = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val));
    475 
    476 	// Following lines might throw an exception.
    477 	entry_pointer p_e = get_entry(r_val,
    478 				      traits_base::m_no_throw_copies_indicator);
    479 
    480 	// At this point no exceptions can be thrown.
    481 	p_e->m_p_next = m_entries[pos];
    482 	m_entries[pos] = p_e;
    483 	resize_base::notify_inserted(++m_num_used_e);
    484 
    485 	_GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));)
    486 	_GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);)
    487 	return &p_e->m_value;
    488       }
    489 
    490       inline pointer
    491       insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair)
    492       {
    493 	// Following lines might throw an exception.
    494 	if (do_resize_if_needed())
    495 	  r_pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val));
    496 
    497 	entry_pointer p_e = get_entry(r_val,
    498 				      traits_base::m_no_throw_copies_indicator);
    499 
    500 	// At this point no exceptions can be thrown.
    501 	p_e->m_hash = r_pos_hash_pair.second;
    502 	p_e->m_p_next = m_entries[r_pos_hash_pair.first];
    503 	m_entries[r_pos_hash_pair.first] = p_e;
    504 	resize_base::notify_inserted(++m_num_used_e);
    505 	_GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));)
    506 	_GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);)
    507 	return &p_e->m_value;
    508       }
    509 
    510       inline pointer
    511       find_key_pointer(key_const_reference r_key, false_type)
    512       {
    513 	entry_pointer p_e = m_entries[ranged_hash_fn_base::operator()(r_key)];
    514 	resize_base::notify_find_search_start();
    515 	while (p_e != 0 &&
    516 	       !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key))
    517 	  {
    518 	    resize_base::notify_find_search_collision();
    519 	    p_e = p_e->m_p_next;
    520 	  }
    521 
    522 	resize_base::notify_find_search_end();
    523 
    524 #ifdef _GLIBCXX_DEBUG
    525 	if (p_e == 0)
    526 	  PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
    527 	else
    528 	  PB_DS_CHECK_KEY_EXISTS(r_key)
    529 #endif
    530 	return &p_e->m_value;
    531       }
    532 
    533       inline pointer
    534       find_key_pointer(key_const_reference r_key, true_type)
    535       {
    536 	comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key);
    537 	entry_pointer p_e = m_entries[pos_hash_pair.first];
    538 	resize_base::notify_find_search_start();
    539 	while (p_e != 0 &&
    540 	       !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value),
    541 					    p_e->m_hash,
    542 					    r_key, pos_hash_pair.second))
    543 	  {
    544 	    resize_base::notify_find_search_collision();
    545 	    p_e = p_e->m_p_next;
    546 	  }
    547 
    548 	resize_base::notify_find_search_end();
    549 
    550 #ifdef _GLIBCXX_DEBUG
    551 	if (p_e == 0)
    552 	  PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
    553 	else
    554 	  PB_DS_CHECK_KEY_EXISTS(r_key)
    555 #endif
    556 	return &p_e->m_value;
    557       }
    558 
    559       inline bool
    560       erase_in_pos_imp(key_const_reference, size_type);
    561 
    562       inline bool
    563       erase_in_pos_imp(key_const_reference, const comp_hash&);
    564 
    565       inline void
    566       erase_entry_pointer(entry_pointer&);
    567 
    568 #ifdef PB_DS_DATA_TRUE_INDICATOR
    569       void
    570       inc_it_state(pointer& r_p_value,
    571 		   std::pair<entry_pointer, size_type>& r_pos) const
    572       {
    573 	inc_it_state((mapped_const_pointer& )r_p_value, r_pos);
    574       }
    575 #endif
    576 
    577       void
    578       inc_it_state(const_pointer& r_p_value,
    579 		   std::pair<entry_pointer, size_type>& r_pos) const
    580       {
    581 	_GLIBCXX_DEBUG_ASSERT(r_p_value != 0);
    582 	r_pos.first = r_pos.first->m_p_next;
    583 	if (r_pos.first != 0)
    584 	  {
    585 	    r_p_value = &r_pos.first->m_value;
    586 	    return;
    587 	  }
    588 
    589 	for (++r_pos.second; r_pos.second < m_num_e; ++r_pos.second)
    590 	  if (m_entries[r_pos.second] != 0)
    591 	    {
    592 	      r_pos.first = m_entries[r_pos.second];
    593 	      r_p_value = &r_pos.first->m_value;
    594 	      return;
    595 	    }
    596 	r_p_value = 0;
    597       }
    598 
    599       void
    600       get_start_it_state(pointer& r_p_value,
    601 			 std::pair<entry_pointer, size_type>& r_pos) const
    602       {
    603 	for (r_pos.second = 0; r_pos.second < m_num_e; ++r_pos.second)
    604 	  if (m_entries[r_pos.second] != 0)
    605 	    {
    606 	      r_pos.first = m_entries[r_pos.second];
    607 	      r_p_value = &r_pos.first->m_value;
    608 	      return;
    609 	    }
    610 	r_p_value = 0;
    611       }
    612 
    613 #ifdef _GLIBCXX_DEBUG
    614       void
    615       assert_entry_pointer_array_valid(const entry_pointer_array,
    616 				       const char*, int) const;
    617 
    618       void
    619       assert_entry_pointer_valid(const entry_pointer, true_type,
    620 				 const char*, int) const;
    621 
    622       void
    623       assert_entry_pointer_valid(const entry_pointer, false_type,
    624 				 const char*, int) const;
    625 #endif
    626 
    627 #ifdef PB_DS_HT_MAP_TRACE_
    628       void
    629       trace_list(const_entry_pointer) const;
    630 #endif
    631 
    632     private:
    633 #ifdef PB_DS_DATA_TRUE_INDICATOR
    634       friend class iterator_;
    635 #endif
    636 
    637       friend class const_iterator_;
    638 
    639       static entry_allocator 		s_entry_allocator;
    640       static entry_pointer_allocator 	s_entry_pointer_allocator;
    641       static iterator 			s_end_it;
    642       static const_iterator 		s_const_end_it;
    643       static point_iterator 		s_find_end_it;
    644       static point_const_iterator 	s_const_find_end_it;
    645 
    646       size_type 			m_num_e;
    647       size_type 			m_num_used_e;
    648       entry_pointer_array 		m_entries;
    649 
    650       enum
    651 	{
    652 	  store_hash_ok = !Store_Hash
    653 			  || !is_same<Hash_Fn, __gnu_pbds::null_type>::value
    654 	};
    655 
    656       PB_DS_STATIC_ASSERT(sth, store_hash_ok);
    657     };
    658 
    659 #include <ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp>
    660 #include <ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp>
    661 #include <ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp>
    662 #include <ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp>
    663 #include <ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp>
    664 #include <ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp>
    665 #include <ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp>
    666 #include <ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp>
    667 #include <ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp>
    668 #include <ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp>
    669 #include <ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp>
    670 
    671 #undef PB_DS_CLASS_T_DEC
    672 #undef PB_DS_CLASS_C_DEC
    673 #undef PB_DS_HASH_EQ_FN_C_DEC
    674 #undef PB_DS_RANGED_HASH_FN_C_DEC
    675 #undef PB_DS_CC_HASH_TRAITS_BASE
    676 #undef PB_DS_DEBUG_MAP_BASE_C_DEC
    677 #undef PB_DS_CC_HASH_NAME
    678   } // namespace detail
    679 } // namespace __gnu_pbds
    680