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