TPIE

v1.1rc1-6-g0c97303
hash_map.h
Go to the documentation of this file.
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2010, 2011, 2012 The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 #ifndef __TPIE_HASHMAP_H__
20 #define __TPIE_HASHMAP_H__
21 
25 
26 #include <tpie/array.h>
27 #include <tpie/unused.h>
28 #include <cmath>
29 #include <algorithm>
30 #include <iostream>
31 #include <tpie/prime.h>
32 
33 namespace tpie {
34 
39 template <typename T>
40 struct hash {
44  inline size_t operator()(const T & e) const {return static_cast<size_t>(e * 103841);}
45 };
46 
52 template <typename T1, typename T2>
53 struct hash<std::pair<T1,T2> > {
54  hash<T1> h1;
55  hash<T2> h2;
56 
61  inline size_t operator()(const std::pair<T1,T2> & e) const {
62  return h1(e.first) + h2(e.second) * 99181;
63  }
64 };
65 
69 template <>
70 struct hash<const char *> {
75  inline size_t operator()(const char * s) const {
76  uint32_t r = 1;
77  for(int i=0; s[i]; i++){
78  r = r*13+s[i]*7;
79  }
80  return r;
81  }
82 };
83 
87 template <>
88 struct hash<std::string> {
94  inline size_t operator()(const std::string & s) const {
95  return h(s.c_str());
96  }
97 };
98 
106 template <typename value_t, typename hash_t, typename equal_t, typename index_t>
108 private:
109  static const float sc;
110 
111 #pragma pack(push, 1)
112  struct bucket_t {
116  value_t value;
117  index_t next;
118  };
119 #pragma pack(pop)
120 
121  size_t first_free;
122  array<index_t> list;
123  array<bucket_t> buckets;
124 
125  hash_t h;
126  equal_t e;
127 public:
129  size_t size;
130 
132  value_t unused;
133 
138  static double memory_coefficient() {
140  }
141 
146  static double memory_overhead() {
147  return array<index_t>::memory_coefficient() * 100.0
150  - sizeof(array<index_t>)
151  - sizeof(array<bucket_t>);
152  }
153 
158  inline value_t & get(size_t idx) {return buckets[idx].value;}
159 
164  inline const value_t & get(size_t idx) const {return buckets[idx].value;}
165 
169  void clear() {
170  first_free = 0;
171  for (size_t i=0; i < buckets.size(); ++i) {
172  buckets[i].value = unused;
173  buckets[i].next = static_cast<index_t>(i+1);
174  }
175  for (typename array<index_t>::iterator i=list.begin(); i != list.end(); ++i)
176  *i = std::numeric_limits<index_t>::max();
177  }
178 
183  void resize(size_t z) {
184  buckets.resize(z);
185  size_t x=static_cast<size_t>(99+static_cast<double>(z)*sc)|1;
186  while (!is_prime(x)) x -= 2;
187  list.resize(x);
188  clear();
189  }
190 
199  value_t u,
200  const hash_t & hash,
201  const equal_t & equal): h(hash), e(equal), size(0), unused(u) {resize(ee);};
202 
206  inline size_t begin() {
207  if (size == 0) return buckets.size();
208  for(size_t i=0; true; ++i)
209  if (buckets[i].value != unused) return i;
210  }
211 
215  inline size_t end() const {return buckets.size();}
216 
221  inline size_t find(const value_t & value) const {
222  size_t v = list[h(value) % list.size()];
223  while (v != std::numeric_limits<index_t>::max()) {
224  if (e(buckets[v].value, value)) return v;
225  v = buckets[v].next;
226  }
227  return buckets.size();
228  }
229 
236  inline std::pair<size_t, bool> insert(const value_t & val) {
237  // First, look for the value in table.
238  size_t hv = h(val) % list.size();
239  size_t v = list[hv];
240  while (v != std::numeric_limits<index_t>::max()) {
241  if (e(buckets[v].value, val)) return std::make_pair(v, false);
242  v = buckets[v].next;
243  }
244  // It wasn't found. Insert into free bucket.
245  v = first_free;
246  first_free = buckets[v].next;
247  buckets[v].value = val;
248  buckets[v].next = list[hv];
249  list[hv] = v;
250  ++size;
251  return std::make_pair(v, true);
252  }
253 
258  inline void erase(const value_t & val) {
259  size_t hv = h(val) % list.size();
260  size_t cur = list[hv];
261  size_t prev = std::numeric_limits<size_t>::max();
262 
263  while (!e(buckets[cur].value, val)) {
264  prev = cur;
265  cur = buckets[cur].next;
266  }
267 
268  if (prev == std::numeric_limits<size_t>::max())
269  list[hv] = buckets[cur].next;
270  else
271  buckets[prev].next = buckets[cur].next;
272 
273  buckets[cur].next = first_free;
274  buckets[cur].value = unused;
275  first_free = cur;
276  --size;
277  }
278 };
279 
287 template <typename value_t, typename hash_t, typename equal_t, typename index_t>
289 private:
290  static const float sc;
291  array<value_t> elements;
292  hash_t h;
293  equal_t e;
294 public:
296  size_t size;
297 
299  value_t unused;
300 
305  static double memory_coefficient() {
307  }
308 
313  static double memory_overhead() {
314  return array<value_t>::memory_coefficient() * 100.0
316  }
317 
322  void clear() {
323  for (typename array<value_t>::iterator i=elements.begin(); i != elements.end(); ++i)
324  *i = unused;
325  }
326 
331  void resize(size_t element_count) {
332  size_t x=(99+static_cast<size_t>(static_cast<float>(element_count)*sc))|1;
333  while (!is_prime(x)) x -= 2;
334  elements.resize(x, unused);
335  }
336 
341  linear_probing_hash_table(size_t ee, value_t u,
342  const hash_t & hash, const equal_t & equal):
343  h(hash), e(equal), size(0), unused(u) {resize(ee);}
344 
349  inline size_t find(const value_t & value) const {
350  size_t v = h(value) % elements.size();
351  while (elements[v] != unused) {
352  if (e(elements[v], value)) return v;
353  v = (v + 1) % elements.size();
354  }
355  return elements.size();
356  }
357 
358 
363  inline size_t end() const {return elements.size();}
364 
369  inline size_t begin() const {
370  if (size == 0) return elements.size();
371  for(size_t i=0; true; ++i)
372  if (elements[i] != unused) return i;
373  }
374 
379  value_t & get(size_t idx) {return elements[idx];}
380 
385  const value_t & get(size_t idx) const {return elements[idx];}
386 
391  inline std::pair<size_t, bool> insert(const value_t & val) {
392  size_t v = h(val) % elements.size();
393  while (elements[v] != unused) {
394  if (e(elements[v],val)) {return std::make_pair(v, false);}
395  v = (v + 1) % elements.size();
396  }
397  ++size;
398  elements[v] = val;
399  return std::make_pair(v, true);
400  }
401 
406  inline void erase(const value_t & val) {
407  size_t slot = find(val);
408  size_t cur = (slot+1) % elements.size();
409  assert(size < elements.size());
410  while (elements[cur] != unused) {
411  size_t x = h(elements[cur]) % elements.size();
412  if (x <= slot && (cur > slot || x > cur)) {
413  elements[slot] = elements[cur];
414  slot = cur;
415  }
416  cur = (cur+1) % elements.size();
417  }
418  elements[slot] = unused;
419  --size;
420  }
421 };
422 
433 template <typename key_t,
434  typename data_t,
435  typename hash_t=hash<key_t>,
436  typename equal_t=std::equal_to<key_t>,
437  typename index_t=size_t,
438  template <typename, typename, typename, typename> class table_t = chaining_hash_table
439  >
440 class hash_map: public linear_memory_base< hash_map<key_t, data_t, hash_t, equal_t, index_t, table_t> > {
441 public:
442  typedef std::pair<key_t, data_t> value_t;
443 private:
447  struct key_equal_t {
448  equal_t e;
449  key_equal_t(const equal_t & equal): e(equal) {}
450  inline bool operator()(const value_t & a, const value_t & b) const {
451  return e(a.first, b.first);
452  }
453  };
454 
458  struct key_hash_t {
459  hash_t h;
460  key_hash_t(const hash_t & hash): h(hash) {}
461  inline size_t operator()(const value_t & a) const {
462  return h(a.first);
463  }
464  };
465 
466  typedef table_t<value_t, key_hash_t, key_equal_t, index_t> tbl_t;
467 
468  tbl_t tbl;
469 
473  template <typename IT>
474  class iter_base {
475  protected:
476  IT & tbl;
477  size_t cur;
478  iter_base(IT & t, size_t c): tbl(t), cur(c) {};
479  friend class hash_map::iterator;
480  friend class hash_map;
481  public:
482  inline const key_t & key() const {return tbl.get(cur).first;}
483  inline const data_t & value() const {return tbl.get(cur).second;}
484  inline const value_t & operator*() const {return tbl.get(cur);}
485  inline const value_t * operator->() const {return &tbl.get(cur);}
486 
487  template <typename IIT>
488  inline bool operator==(const iter_base<IIT> & o) const {return o.cur == cur;}
489  template <typename IIT>
490  inline bool operator!=(const iter_base<IIT> & o) const {return o.cur != cur;}
491  inline void operator++() {
492  ++cur;
493  while (cur != tbl.end()) {
494  if (tbl.get(cur) != tbl.unused) break;
495  ++cur;
496  }
497  }
498  };
499 public:
501  typedef iter_base<const tbl_t> const_iterator;
502 
506  class iterator: public iter_base<tbl_t> {
507  private:
508  typedef iter_base<tbl_t> p_t;
509  friend class hash_map;
510  inline iterator(tbl_t & tbl, size_t cur): p_t(tbl, cur) {}
511  using p_t::tbl;
512  using p_t::cur;
513  public:
514  inline key_t & key() {return tbl.get(cur)->first;}
515  inline data_t & value() {return tbl.get(cur)->second;}
516  inline value_t & operator*() {return tbl.get(cur);}
517  inline value_t * operator->() {return &tbl.get(cur);}
518  inline operator const_iterator() const {return const_iterator(tbl, cur);}
519  inline bool operator==(const const_iterator & o) const {return o.cur == cur;}
520  inline bool operator!=(const const_iterator & o) const {return o.cur != cur;}
521  };
522 
523 
528  static double memory_coefficient() {
529  return tbl_t::memory_coefficient();
530  }
531 
536  static double memory_overhead() {
537  return tbl_t::memory_overhead() - sizeof(tbl_t) + sizeof(hash_map);
538  }
539 
547  inline hash_map(size_t size=0, const hash_t & hash=hash_t(),
548  const equal_t & equal=equal_t(),
549  value_t u=default_unused<value_t>::v() ):
550  tbl(size, u, key_hash_t(hash), key_equal_t(equal)) {}
551 
556  inline void resize(size_t size) {tbl.resize(size);}
557 
562  inline void erase(const key_t & key) {
563  tbl.erase(value_t(key, tbl.unused.second));
564  }
565 
570  inline void erase(const iterator & iter) {erase(iter.key());}
571 
577  inline bool insert(const key_t & key, const data_t & data) {
578  return tbl.insert(value_t(key, data)).second;
579  }
580 
586  inline data_t & operator[](const key_t & key) {
587  return tbl.get(tbl.insert(value_t(key, tbl.unused.second)).first).second;
588  }
589 
594  inline const data_t & operator[](const key_t & key) const {
595  return tbl.get(tbl.find(key))->second;
596  }
597 
602  inline iterator find(const key_t & key) {
603  return iterator(tbl, tbl.find(value_t(key, tbl.unused.second)));
604  }
605 
610  inline const_iterator find(const key_t & key) const {
611  return const_iterator(tbl, tbl.find(value_t(key, tbl.unused.second)));
612  }
613 
619  inline bool contains(const key_t & key) const {
620  return tbl.find(value_t(key, tbl.unused.second)) != tbl.end();
621  }
622 
626  inline iterator begin() {return iterator(tbl, tbl.begin());}
627 
631  inline const_iterator begin() const {return const_iterator(tbl, tbl.begin());}
632 
636  inline const_iterator cbegin() const {return const_iterator(tbl, tbl.begin());}
637 
641  inline iterator end() {return iterator(tbl, tbl.end());}
642 
646  inline const_iterator end() const {return const_iterator(tbl, tbl.end());}
647 
651  inline const_iterator cend() const {return const_iterator(tbl, tbl.end());}
652 
656  inline size_t size() const {return tbl.size;}
657 
661  inline void clear() const {tbl.clear();}
662 };
663 
673 template <typename key_t,
674  typename hash_t=hash<key_t>,
675  typename equal_t=std::equal_to<key_t>,
676  typename index_t=size_t,
677  template <typename, typename, typename, typename> class table_t=linear_probing_hash_table>
678 class hash_set {
679 private:
680  typedef table_t<key_t, hash_t, equal_t, index_t> tbl_t;
681  tbl_t tbl;
682  typedef key_t value_t;
683 
687  template <typename IT>
688  class iter_base {
689  protected:
690  IT & tbl;
691  size_t cur;
692  iter_base(IT & t, size_t c): tbl(t), cur(c) {};
693  //friend class hash_set::iterator;
694  friend class hash_set;
695  public:
696  inline const value_t & operator*() const {return tbl.get(cur);}
697  inline const value_t * operator->() const {return &tbl.get(cur);}
698  inline bool operator==(iter_base & o) const {return o.cur == cur;}
699  inline bool operator!=(iter_base & o) const {return o.cur != cur;}
700  inline void operator++() {
701  while (cur != tbl.end()) {
702  ++cur;
703  if (tbl.get(cur) != tbl.unused) break;
704  }
705  }
706  };
707 public:
709  typedef iter_base<const tbl_t> const_iterator;
710 
714  class iterator: public iter_base<tbl_t> {
715  private:
716  typedef iter_base<tbl_t> p_t;
717  friend class hash_set;
718  inline iterator(tbl_t & tbl, size_t cur): p_t(tbl, cur) {}
719  using p_t::tbl;
720  using p_t::cur;
721  public:
722  inline value_t & operator*() {return tbl.get(cur);}
723  inline value_t * operator->() {return &tbl.get(cur);}
724  inline operator const_iterator() const {return const_iterator(tbl, cur);}
725  inline bool operator==(const const_iterator & o) const {return o.cur == cur;}
726  inline bool operator!=(const const_iterator & o) const {return o.cur != cur;}
727  };
728 
729 
734  static double memory_coefficient() {
735  return tbl_t::memory_coefficient();
736  }
737 
742  static double memory_overhead() {
743  return tbl_t::memory_overhead() - sizeof(tbl_t) + sizeof(hash_set);
744  }
745 
753  inline hash_set(size_t size=0,
754  const hash_t & hash=hash_t(), const equal_t & equal=equal_t(),
755  value_t u=default_unused<value_t>::v()):
756  tbl(size, u, hash, equal) {}
757 
762  inline void resize(size_t size) {tbl.resize(size);}
763 
768  inline void erase(const key_t & key) {tbl.erase(key);}
769 
774  inline void erase(const iterator & iter) {erase(iter.key());}
775 
780  inline bool insert(const key_t & key) {
781  return tbl.insert(key).second;
782  }
783 
788  inline iterator find(const key_t & key) {
789  return iterator(tbl, tbl.find(key));
790  }
791 
796  inline const_iterator find(const key_t & key) const {
797  return const_iterator(tbl, tbl.find(key));
798  }
799 
805  inline bool contains(const key_t & key) const {return tbl.find(key) != tbl.end();}
806 
810  inline iterator begin() {return iterator(tbl, tbl.begin());}
811 
815  inline const_iterator begin() const {return const_iterator(tbl, tbl.begin());}
816 
820  inline const_iterator cbegin() const {return const_iterator(tbl, tbl.begin());}
821 
825  inline iterator end() {return iterator(tbl, tbl.end());}
826 
830  inline const_iterator end() const {return const_iterator(tbl, tbl.end());}
831 
835  inline const_iterator cend() const {return const_iterator(tbl, tbl.end());}
836 
840  inline size_t size() const {return tbl.size;}
841 
845  inline void clear() const {tbl.clear();}
846 };
847 
848 
849 template <typename value_t, typename hash_t, typename equal_t, typename index_t>
850 const float linear_probing_hash_table<value_t, hash_t, equal_t, index_t>::sc = 2.0f;
851 
852 template <typename value_t, typename hash_t, typename equal_t, typename index_t>
853 const float chaining_hash_table<value_t, hash_t, equal_t, index_t>::sc = 2.f;
854 
855 }
856 #endif //__TPIE_HASHMAP_H__
Hash table handling hash collisions by chaining.
Definition: hash_map.h:107
void erase(const iterator &iter)
Erase entry from hash set by iterator.
Definition: hash_map.h:774
static double memory_overhead()
Return the memory overhead of the structure.
Definition: hash_map.h:313
const_iterator begin() const
Return const iterator to beginning of map.
Definition: hash_map.h:631
static double memory_overhead()
Return the memory overhead of the structure.
Definition: hash_map.h:742
bool is_prime(size_type i)
Check if i is a prime.
void resize(size_t size)
Resize hash map to given size and remove all entries.
Definition: hash_map.h:556
const_iterator find(const key_t &key) const
Get const iterator to element.
Definition: hash_map.h:796
void clear() const
Clear hash set.
Definition: hash_map.h:845
Base class of data structures with linear memory usage.
Definition: util.h:73
static double memory_coefficient()
Return the memory coefficient of the structure.
Definition: hash_map.h:305
linear_probing_hash_table(size_t ee, value_t u, const hash_t &hash, const equal_t &equal)
Construct a hash table.
Definition: hash_map.h:341
iterator end()
Return iterator to end of set.
Definition: hash_map.h:825
size_t operator()(const char *s) const
Calculate string hash.
Definition: hash_map.h:75
Hash map implementation backed by a template parameterized hash table.
Definition: hash_map.h:440
void clear() const
Clear hash map.
Definition: hash_map.h:661
iterator begin()
Return iterator to beginning of set.
Definition: hash_map.h:810
void resize(size_t element_count)
Resize table to given number of buckets and clear contents.
Definition: hash_map.h:331
size_t begin()
Return first bucket entry in use.
Definition: hash_map.h:206
size_t operator()(const std::string &s) const
Calculate string hash by using std::string::c_str().
Definition: hash_map.h:94
Non-const iterator type.
Definition: hash_map.h:714
static double memory_coefficient()
Return the memory coefficient of the structure.
Definition: hash_map.h:734
static double memory_coefficient()
Return the memory coefficient of the structure.
Definition: hash_map.h:528
const_iterator cbegin() const
Return const iterator to beginning of set.
Definition: hash_map.h:820
data_t & operator[](const key_t &key)
Look up data by key, creating an unused entry if it does not exist.
Definition: hash_map.h:586
size_t begin() const
Return first bucket entry in use.
Definition: hash_map.h:369
bool contains(const key_t &key) const
Search for key.
Definition: hash_map.h:805
size_t size() const
Return number of keys in set.
Definition: hash_map.h:840
hash_map(size_t size=0, const hash_t &hash=hash_t(), const equal_t &equal=equal_t(), value_t u=default_unused< value_t >::v())
Construct hash map.
Definition: hash_map.h:547
void erase(const key_t &key)
Erase entry from hash map by key.
Definition: hash_map.h:562
Generic internal array with known memory requirements.
bool contains(const key_t &key) const
Search for element with key.
Definition: hash_map.h:619
iterator find(const key_t &key)
Get iterator to element.
Definition: hash_map.h:602
const data_t & operator[](const key_t &key) const
Look up data by key.
Definition: hash_map.h:594
const_iterator cend() const
Return const iterator to end of map.
Definition: hash_map.h:651
Default hashing function for integral (size_t-castable) types.
Definition: hash_map.h:40
chaining_hash_table(size_t ee, value_t u, const hash_t &hash, const equal_t &equal)
Construct a hash table.
Definition: hash_map.h:198
iterator end()
Return iterator to end of map.
Definition: hash_map.h:641
static double memory_overhead()
Return the memory overhead of the structure.
Definition: hash_map.h:146
void erase(const value_t &val)
Erase value from table.
Definition: hash_map.h:406
size_t end() const
Return index greater than any buckets in use.
Definition: hash_map.h:215
void clear()
Clear contents of hash table.
Definition: hash_map.h:169
const_iterator end() const
Return const iterator to end of set.
Definition: hash_map.h:830
Hash set implementation backed by a template parameterized hash table.
Definition: hash_map.h:678
iterator begin()
Return iterator to beginning of map.
Definition: hash_map.h:626
Default hashing function for C-style strings.
Definition: hash_map.h:70
void clear()
Clear contents of hash table.
Definition: hash_map.h:322
size_t operator()(const std::pair< T1, T2 > &e) const
Calculate std::pair hash.
Definition: hash_map.h:61
bool insert(const key_t &key)
Insert key into set.
Definition: hash_map.h:780
void erase(const iterator &iter)
Erase entry from hash map by iterator.
Definition: hash_map.h:570
Computations related to prime numbers.
value_t unused
Special constant indicating an unused table entry.
Definition: hash_map.h:299
static double memory_coefficient()
Return the memory coefficient of the structure.
Definition: array.h:360
Non-const iterator type.
Definition: hash_map.h:506
void erase(const value_t &val)
Erase value from table.
Definition: hash_map.h:258
std::pair< size_t, bool > insert(const value_t &val)
Insert value into hash table.
Definition: hash_map.h:236
void resize(size_t size, const T &elm)
Change the size of the array.
Definition: array.h:431
std::pair< size_t, bool > insert(const value_t &val)
Insert value into hash table.
Definition: hash_map.h:391
void erase(const key_t &key)
Erase entry from hash set by key.
Definition: hash_map.h:768
size_t size
Number of buckets in hash table.
Definition: hash_map.h:296
iter_base< const tbl_t > const_iterator
Const iterator type.
Definition: hash_map.h:709
static double memory_overhead()
Return the memory overhead of the structure.
Definition: array.h:367
iter_base< const tbl_t > const_iterator
Const iterator type.
Definition: hash_map.h:501
static double memory_coefficient()
Return the memory coefficient of the structure.
Definition: hash_map.h:138
size_t find(const value_t &value) const
Find bucket entry containing given value, or end() if not found.
Definition: hash_map.h:221
const_iterator begin() const
Return const iterator to beginning of set.
Definition: hash_map.h:815
hash_set(size_t size=0, const hash_t &hash=hash_t(), const equal_t &equal=equal_t(), value_t u=default_unused< value_t >::v())
Construct hash set.
Definition: hash_map.h:753
Hash table handling hash collisions by linear probing.
Definition: hash_map.h:288
const_iterator cbegin() const
Return const iterator to beginning of map.
Definition: hash_map.h:636
iterator end()
Return an iterator to the end of the array.
Definition: array.h:288
size_t operator()(const T &e) const
Calculate integer hash.
Definition: hash_map.h:44
const_iterator end() const
Return const iterator to end of map.
Definition: hash_map.h:646
size_t size
Number of buckets in hash table.
Definition: hash_map.h:129
iterator begin()
Return an iterator to the beginning of the array.
Definition: array.h:274
size_type size() const
Return the size of the array.
Definition: array.h:472
iterator find(const key_t &key)
Get iterator to element.
Definition: hash_map.h:788
static double memory_overhead()
Return the memory overhead of the structure.
Definition: hash_map.h:536
const_iterator find(const key_t &key) const
Get iterator to element.
Definition: hash_map.h:610
size_t find(const value_t &value) const
Find bucket entry containing given value, or end() if not found.
Definition: hash_map.h:349
size_t end() const
Return index greater than any buckets in use.
Definition: hash_map.h:363
value_t unused
Special constant indicating an unused table entry.
Definition: hash_map.h:132
size_t size() const
Return number of elements in map.
Definition: hash_map.h:656
bool insert(const key_t &key, const data_t &data)
Insert data into the hash map.
Definition: hash_map.h:577
const_iterator cend() const
Return const iterator to end of set.
Definition: hash_map.h:835
void resize(size_t z)
Resize table to given number of buckets and clear contents.
Definition: hash_map.h:183
void resize(size_t size)
Resize hash set to given size and remove all entries.
Definition: hash_map.h:762
Default special unused values for standard types.