google_hash 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. data/README +61 -27
  2. data/Rakefile +4 -1
  3. data/TODO +5 -0
  4. data/VERSION +1 -1
  5. data/changelog +3 -0
  6. data/ext/extconf.rb +10 -5
  7. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/AUTHORS +0 -0
  8. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/COPYING +0 -0
  9. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/ChangeLog +47 -0
  10. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/INSTALL +0 -0
  11. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.am +29 -14
  12. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.in +77 -42
  13. data/ext/sparsehash-1.8.1/NEWS +71 -0
  14. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/README +0 -0
  15. data/ext/{sparsehash-1.5.2/README.windows → sparsehash-1.8.1/README_windows.txt} +25 -25
  16. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/TODO +0 -0
  17. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/aclocal.m4 +0 -0
  18. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/compile +0 -0
  19. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.guess +0 -0
  20. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.sub +0 -0
  21. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure +3690 -4560
  22. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure.ac +1 -1
  23. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/depcomp +0 -0
  24. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_map.html +65 -5
  25. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_set.html +65 -5
  26. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/designstyle.css +0 -0
  27. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/implementation.html +11 -5
  28. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/index.html +0 -0
  29. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/performance.html +0 -0
  30. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_map.html +65 -5
  31. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_set.html +65 -5
  32. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparsetable.html +0 -0
  33. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/Makefile +0 -0
  34. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/README +0 -0
  35. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/example.c +0 -0
  36. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.c +0 -0
  37. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.h +0 -0
  38. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/google-sparsehash.sln +17 -1
  39. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/install-sh +0 -0
  40. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/acx_pthread.m4 +0 -0
  41. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/google_namespace.m4 +0 -0
  42. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/namespaces.m4 +0 -0
  43. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash.m4 +0 -0
  44. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash_fun.m4 +0 -0
  45. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_namespace.m4 +0 -0
  46. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/missing +0 -0
  47. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/mkinstalldirs +0 -0
  48. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb.sh +0 -0
  49. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/README +0 -0
  50. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/changelog +24 -0
  51. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/compat +0 -0
  52. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/control +1 -1
  53. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/copyright +0 -0
  54. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/docs +0 -0
  55. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/rules +0 -0
  56. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.dirs +0 -0
  57. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.install +0 -0
  58. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm.sh +0 -0
  59. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm/rpm.spec +1 -1
  60. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.in +3 -0
  61. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.include +0 -0
  62. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_map +43 -27
  63. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_set +40 -19
  64. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_map +32 -23
  65. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_set +31 -21
  66. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/densehashtable.h +481 -298
  67. data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +178 -0
  68. data/ext/sparsehash-1.8.1/src/google/sparsehash/libc_allocator_with_realloc.h +121 -0
  69. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/sparsehashtable.h +404 -233
  70. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsetable +173 -83
  71. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/type_traits.h +3 -29
  72. data/ext/sparsehash-1.8.1/src/hash_test_interface.h +1011 -0
  73. data/ext/sparsehash-1.8.1/src/hashtable_test.cc +1733 -0
  74. data/ext/sparsehash-1.8.1/src/libc_allocator_with_realloc_test.cc +129 -0
  75. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/simple_test.cc +1 -1
  76. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/sparsetable_unittest.cc +202 -6
  77. data/ext/sparsehash-1.8.1/src/testutil.h +251 -0
  78. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/time_hash_map.cc +128 -54
  79. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/type_traits_unittest.cc +30 -20
  80. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/config.h +0 -0
  81. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/google/sparsehash/sparseconfig.h +0 -0
  82. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.cc +0 -0
  83. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.h +0 -0
  84. data/ext/sparsehash-1.8.1/vsprojects/hashtable_test/hashtable_test.vcproj +197 -0
  85. data/ext/{sparsehash-1.5.2/vsprojects/hashtable_unittest/hashtable_unittest.vcproj → sparsehash-1.8.1/vsprojects/simple_test/simple_test.vcproj} +9 -8
  86. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +0 -2
  87. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/time_hash_map/time_hash_map.vcproj +3 -2
  88. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +0 -2
  89. data/ext/template/google_hash.cpp.erb +2 -1
  90. data/ext/template/main.cpp.erb +1 -1
  91. data/results.txt +6 -22
  92. data/spec/benchmark.rb +57 -0
  93. data/spec/spec.google_hash.rb +1 -8
  94. metadata +140 -130
  95. data/ext/benchmark.rb +0 -47
  96. data/ext/sparsehash-1.5.2/NEWS +0 -0
  97. data/ext/sparsehash-1.5.2/src/hashtable_unittest.cc +0 -1375
  98. data/ext/sparsehash-1.5.2/src/words +0 -8944
  99. data/types.txt +0 -18
@@ -45,6 +45,7 @@
45
45
  // remove_cv
46
46
  // remove_reference
47
47
  // remove_pointer
48
+ // is_same
48
49
  // is_convertible
49
50
  // We can add more type traits as required.
50
51
 
@@ -215,35 +216,8 @@ template<typename T> struct remove_pointer<T* const volatile> {
215
216
  typedef T type; };
216
217
 
217
218
  // Specified by TR1 [4.6] Relationships between types
218
- #ifndef _MSC_VER
219
- namespace internal {
220
-
221
- // This class is an implementation detail for is_convertible, and you
222
- // don't need to know how it works to use is_convertible. For those
223
- // who care: we declare two different functions, one whose argument is
224
- // of type To and one with a variadic argument list. We give them
225
- // return types of different size, so we can use sizeof to trick the
226
- // compiler into telling us which function it would have chosen if we
227
- // had called it with an argument of type From. See Alexandrescu's
228
- // _Modern C++ Design_ for more details on this sort of trick.
229
-
230
- template <typename From, typename To>
231
- struct ConvertHelper {
232
- static small_ Test(To);
233
- static big_ Test(...);
234
- static From Create();
235
- };
236
- } // namespace internal
237
-
238
- // Inherits from true_type if From is convertible to To, false_type otherwise.
239
- template <typename From, typename To>
240
- struct is_convertible
241
- : integral_constant<bool,
242
- sizeof(internal::ConvertHelper<From, To>::Test(
243
- internal::ConvertHelper<From, To>::Create()))
244
- == sizeof(small_)> {
245
- };
246
- #endif
219
+ template<typename T, typename U> struct is_same : public false_type { };
220
+ template<typename T> struct is_same<T, T> : public true_type { };
247
221
 
248
222
  _END_GOOGLE_NAMESPACE_
249
223
 
@@ -0,0 +1,1011 @@
1
+ // Copyright (c) 2010, Google Inc.
2
+ // All rights reserved.
3
+ //
4
+ // Redistribution and use in source and binary forms, with or without
5
+ // modification, are permitted provided that the following conditions are
6
+ // met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright
9
+ // notice, this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above
11
+ // copyright notice, this list of conditions and the following disclaimer
12
+ // in the documentation and/or other materials provided with the
13
+ // distribution.
14
+ // * Neither the name of Google Inc. nor the names of its
15
+ // contributors may be used to endorse or promote products derived from
16
+ // this software without specific prior written permission.
17
+ //
18
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ // ----
31
+ // Author: Craig Silverstein
32
+ //
33
+ // This implements a uniform interface for all 6 hash implementations:
34
+ // dense_hashtable, dense_hash_map, dense_hash_set
35
+ // sparse_hashtable, sparse_hash_map, sparse_hash_set
36
+ // This is intended to be used for testing, to provide a single routine
37
+ // that can easily test all 6 implementations.
38
+ //
39
+ // The main reasons to specialize are to (1) provide dummy
40
+ // implementations for methods that are only needed for some of the
41
+ // implementations (for instance, set_empty_key()), and (2) provide a
42
+ // uniform interface to just the keys -- for instance, we provide
43
+ // wrappers around the iterators that define it.key, which gives the
44
+ // "key" part of the bucket (*it or it->first, depending on the class).
45
+
46
+ #ifndef UTIL_GTL_HASH_TEST_INTERFACE_H_
47
+ #define UTIL_GTL_HASH_TEST_INTERFACE_H_
48
+
49
+ #include "config.h"
50
+ #include HASH_MAP_H // for hash<>
51
+ #include <functional> // for equal_to<>
52
+ #include <google/sparsehash/sparsehashtable.h>
53
+ #include <google/sparse_hash_map>
54
+ #include <google/sparse_hash_set>
55
+ #include <google/sparsehash/densehashtable.h>
56
+ #include <google/dense_hash_map>
57
+ #include <google/dense_hash_set>
58
+
59
+ _START_GOOGLE_NAMESPACE_
60
+
61
+ // This is the "default" interface, which just passes everything
62
+ // through to the underlying hashtable. You'll need to subclass it to
63
+ // specialize behavior for an individual hashtable.
64
+ template <class HT>
65
+ class BaseHashtableInterface {
66
+ public:
67
+ virtual ~BaseHashtableInterface() {}
68
+
69
+ typedef typename HT::key_type key_type;
70
+ typedef typename HT::value_type value_type;
71
+ typedef typename HT::hasher hasher;
72
+ typedef typename HT::key_equal key_equal;
73
+ typedef typename HT::allocator_type allocator_type;
74
+
75
+ typedef typename HT::size_type size_type;
76
+ typedef typename HT::difference_type difference_type;
77
+ typedef typename HT::pointer pointer;
78
+ typedef typename HT::const_pointer const_pointer;
79
+ typedef typename HT::reference reference;
80
+ typedef typename HT::const_reference const_reference;
81
+
82
+ class const_iterator;
83
+
84
+ class iterator : public HT::iterator {
85
+ public:
86
+ iterator() : parent_(NULL) { } // this allows code like "iterator it;"
87
+ iterator(typename HT::iterator it,
88
+ const BaseHashtableInterface* parent)
89
+ : HT::iterator(it), parent_(parent) { }
90
+ key_type key() { return parent_->it_to_key(*this); }
91
+ private:
92
+ friend class BaseHashtableInterface::const_iterator; // for its ctor
93
+ const BaseHashtableInterface* parent_;
94
+ };
95
+
96
+ class const_iterator : public HT::const_iterator {
97
+ public:
98
+ const_iterator() : parent_(NULL) { }
99
+ const_iterator(typename HT::const_iterator it,
100
+ const BaseHashtableInterface* parent)
101
+ : HT::const_iterator(it), parent_(parent) { }
102
+ const_iterator(typename HT::iterator it,
103
+ BaseHashtableInterface* parent)
104
+ : HT::const_iterator(it), parent_(parent) { }
105
+ // The parameter type here *should* just be "iterator", but MSVC
106
+ // gets confused by that, so I'm overly specific.
107
+ const_iterator(typename BaseHashtableInterface<HT>::iterator it)
108
+ : HT::const_iterator(it), parent_(it.parent_) { }
109
+ key_type key() { return parent_->it_to_key(*this); }
110
+ private:
111
+ const BaseHashtableInterface* parent_;
112
+ };
113
+
114
+ class const_local_iterator;
115
+
116
+ class local_iterator : public HT::local_iterator {
117
+ public:
118
+ local_iterator() : parent_(NULL) { }
119
+ local_iterator(typename HT::local_iterator it,
120
+ const BaseHashtableInterface* parent)
121
+ : HT::local_iterator(it), parent_(parent) { }
122
+ key_type key() { return parent_->it_to_key(*this); }
123
+ private:
124
+ friend class BaseHashtableInterface::const_local_iterator; // for its ctor
125
+ const BaseHashtableInterface* parent_;
126
+ };
127
+
128
+ class const_local_iterator : public HT::const_local_iterator {
129
+ public:
130
+ const_local_iterator() : parent_(NULL) { }
131
+ const_local_iterator(typename HT::const_local_iterator it,
132
+ const BaseHashtableInterface* parent)
133
+ : HT::const_local_iterator(it), parent_(parent) { }
134
+ const_local_iterator(typename HT::local_iterator it,
135
+ BaseHashtableInterface* parent)
136
+ : HT::const_local_iterator(it), parent_(parent) { }
137
+ const_local_iterator(local_iterator it)
138
+ : HT::const_local_iterator(it), parent_(it.parent_) { }
139
+ key_type key() { return parent_->it_to_key(*this); }
140
+ private:
141
+ const BaseHashtableInterface* parent_;
142
+ };
143
+
144
+ iterator begin() {
145
+ return iterator(ht_.begin(), this);
146
+ }
147
+ iterator end() {
148
+ return iterator(ht_.end(), this);
149
+ }
150
+ const_iterator begin() const {
151
+ return const_iterator(ht_.begin(), this);
152
+ }
153
+ const_iterator end() const {
154
+ return const_iterator(ht_.end(), this);
155
+ }
156
+ local_iterator begin(size_type i) {
157
+ return local_iterator(ht_.begin(i), this);
158
+ }
159
+ local_iterator end(size_type i) {
160
+ return local_iterator(ht_.end(i), this);
161
+ }
162
+ const_local_iterator begin(size_type i) const {
163
+ return const_local_iterator(ht_.begin(i), this);
164
+ }
165
+ const_local_iterator end(size_type i) const {
166
+ return const_local_iterator(ht_.end(i), this);
167
+ }
168
+
169
+ hasher hash_funct() const { return ht_.hash_funct(); }
170
+ hasher hash_function() const { return ht_.hash_function(); }
171
+ key_equal key_eq() const { return ht_.key_eq(); }
172
+ allocator_type get_allocator() const { return ht_.get_allocator(); }
173
+
174
+ BaseHashtableInterface(size_type expected_max_items_in_table,
175
+ const hasher& hf,
176
+ const key_equal& eql,
177
+ const allocator_type& alloc)
178
+ : ht_(expected_max_items_in_table, hf, eql, alloc) { }
179
+
180
+ // Not all ht_'s support this constructor: you should only call it
181
+ // from a subclass if you know your ht supports it. Otherwise call
182
+ // the previous constructor, followed by 'insert(f, l);'.
183
+ template <class InputIterator>
184
+ BaseHashtableInterface(InputIterator f, InputIterator l,
185
+ size_type expected_max_items_in_table,
186
+ const hasher& hf,
187
+ const key_equal& eql,
188
+ const allocator_type& alloc)
189
+ : ht_(f, l, expected_max_items_in_table, hf, eql, alloc) {
190
+ }
191
+
192
+ // This is the version of the constructor used by dense_*, which
193
+ // requires an empty key in the constructor.
194
+ template <class InputIterator>
195
+ BaseHashtableInterface(InputIterator f, InputIterator l, key_type empty_k,
196
+ size_type expected_max_items_in_table,
197
+ const hasher& hf,
198
+ const key_equal& eql,
199
+ const allocator_type& alloc)
200
+ : ht_(f, l, empty_k, expected_max_items_in_table, hf, eql, alloc) {
201
+ }
202
+
203
+ // This is the constructor appropriate for {dense,sparse}hashtable.
204
+ template <class ExtractKey, class SetKey>
205
+ BaseHashtableInterface(size_type expected_max_items_in_table,
206
+ const hasher& hf,
207
+ const key_equal& eql,
208
+ const ExtractKey& ek,
209
+ const SetKey& sk,
210
+ const allocator_type& alloc)
211
+ : ht_(expected_max_items_in_table, hf, eql, ek, sk, alloc) { }
212
+
213
+
214
+ void clear() { ht_.clear(); }
215
+ void swap(BaseHashtableInterface& other) { ht_.swap(other.ht_); }
216
+
217
+ // Only part of the API for some hashtable implementations.
218
+ void clear_no_resize() { clear(); }
219
+
220
+ size_type size() const { return ht_.size(); }
221
+ size_type max_size() const { return ht_.max_size(); }
222
+ bool empty() const { return ht_.empty(); }
223
+ size_type bucket_count() const { return ht_.bucket_count(); }
224
+ size_type max_bucket_count() const { return ht_.max_bucket_count(); }
225
+
226
+ size_type bucket_size(size_type i) const {
227
+ return ht_.bucket_size(i);
228
+ }
229
+ size_type bucket(const key_type& key) const {
230
+ return ht_.bucket(key);
231
+ }
232
+
233
+ float load_factor() const { return ht_.load_factor(); }
234
+ float max_load_factor() const { return ht_.max_load_factor(); }
235
+ void max_load_factor(float grow) { ht_.max_load_factor(grow); }
236
+ float min_load_factor() const { return ht_.min_load_factor(); }
237
+ void min_load_factor(float shrink) { ht_.min_load_factor(shrink); }
238
+ void set_resizing_parameters(float shrink, float grow) {
239
+ ht_.set_resizing_parameters(shrink, grow);
240
+ }
241
+
242
+ void resize(size_type hint) { ht_.resize(hint); }
243
+ void rehash(size_type hint) { ht_.rehash(hint); }
244
+
245
+ iterator find(const key_type& key) {
246
+ return iterator(ht_.find(key), this);
247
+ }
248
+ const_iterator find(const key_type& key) const {
249
+ return const_iterator(ht_.find(key), this);
250
+ }
251
+
252
+ // Rather than try to implement operator[], which doesn't make much
253
+ // sense for set types, we implement two methods: bracket_equal and
254
+ // bracket_assign. By default, bracket_equal(a, b) returns true if
255
+ // ht[a] == b, and false otherwise. (Note that this follows
256
+ // operator[] semantics exactly, including inserting a if it's not
257
+ // already in the hashtable, before doing the equality test.) For
258
+ // sets, which have no operator[], b is ignored, and bracket_equal
259
+ // returns true if key is in the set and false otherwise.
260
+ // bracket_assign(a, b) is equivalent to ht[a] = b. For sets, b is
261
+ // ignored, and bracket_assign is equivalent to ht.insert(a).
262
+ template<typename AssignValue>
263
+ bool bracket_equal(const key_type& key, const AssignValue& expected) {
264
+ return ht_[key] == expected;
265
+ }
266
+
267
+ template<typename AssignValue>
268
+ void bracket_assign(const key_type& key, const AssignValue& value) {
269
+ ht_[key] = value;
270
+ }
271
+
272
+ size_type count(const key_type& key) const { return ht_.count(key); }
273
+
274
+ pair<iterator, iterator> equal_range(const key_type& key) {
275
+ pair<typename HT::iterator, typename HT::iterator> r
276
+ = ht_.equal_range(key);
277
+ return pair<iterator, iterator>(iterator(r.first, this),
278
+ iterator(r.second, this));
279
+ }
280
+ pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
281
+ pair<typename HT::const_iterator, typename HT::const_iterator> r
282
+ = ht_.equal_range(key);
283
+ return pair<const_iterator, const_iterator>(const_iterator(r.first, this),
284
+ const_iterator(r.second, this));
285
+ }
286
+
287
+ const_iterator random_element(class ACMRandom* r) const {
288
+ return const_iterator(ht_.random_element(r), this);
289
+ }
290
+ iterator random_element(class ACMRandom* r) {
291
+ return iterator(ht_.random_element(r), this);
292
+ }
293
+
294
+ pair<iterator, bool> insert(const value_type& obj) {
295
+ pair<typename HT::iterator, bool> r = ht_.insert(obj);
296
+ return pair<iterator, bool>(iterator(r.first, this), r.second);
297
+ }
298
+ template <class InputIterator>
299
+ void insert(InputIterator f, InputIterator l) {
300
+ ht_.insert(f, l);
301
+ }
302
+ void insert(typename HT::const_iterator f, typename HT::const_iterator l) {
303
+ ht_.insert(f, l);
304
+ }
305
+ iterator insert(typename HT::iterator, const value_type& obj) {
306
+ return iterator(insert(obj).first, this);
307
+ }
308
+
309
+ // These will commonly need to be overridden by the child.
310
+ void set_empty_key(const key_type& k) { ht_.set_empty_key(k); }
311
+ void clear_empty_key() { ht_.clear_empty_key(); }
312
+ key_type empty_key() const { return ht_.empty_key(); }
313
+
314
+ void set_deleted_key(const key_type& k) { ht_.set_deleted_key(k); }
315
+ void clear_deleted_key() { ht_.clear_deleted_key(); }
316
+ key_type deleted_key() const { return ht_.deleted_key(); }
317
+
318
+ size_type erase(const key_type& key) { return ht_.erase(key); }
319
+ void erase(typename HT::iterator it) { ht_.erase(it); }
320
+ void erase(typename HT::iterator f, typename HT::iterator l) {
321
+ ht_.erase(f, l);
322
+ }
323
+
324
+ bool operator==(const BaseHashtableInterface& other) const {
325
+ return ht_ == other.ht_;
326
+ }
327
+ bool operator!=(const BaseHashtableInterface& other) const {
328
+ return ht_ != other.ht_;
329
+ }
330
+
331
+ template <typename OUTPUT>
332
+ bool write_metadata(OUTPUT *fp) {
333
+ return ht_.write_metadata(fp);
334
+ }
335
+ template <typename INPUT>
336
+ bool read_metadata(INPUT *fp) {
337
+ return ht_.read_metadata(fp);
338
+ }
339
+ template <typename OUTPUT>
340
+ bool write_nopointer_data(OUTPUT *fp) {
341
+ return ht_.write_nopointer_data(fp);
342
+ }
343
+ template <typename INPUT>
344
+ bool read_nopointer_data(INPUT *fp) {
345
+ return ht_.read_nopointer_data(fp);
346
+ }
347
+
348
+ // low-level stats
349
+ int num_table_copies() const { return ht_.num_table_copies(); }
350
+
351
+ // Not part of the hashtable API, but is provided to make testing easier.
352
+ virtual key_type get_key(const value_type& value) const = 0;
353
+ // All subclasses should define get_data(value_type) as well. I don't
354
+ // provide an abstract-virtual definition here, because the return type
355
+ // differs between subclasses (not all subclasses define data_type).
356
+ //virtual data_type get_data(const value_type& value) const = 0;
357
+ //virtual data_type default_data() const = 0;
358
+
359
+ // These allow introspection into the interface. "Supports" means
360
+ // that the implementation of this functionality isn't a noop.
361
+ virtual bool supports_clear_no_resize() const = 0;
362
+ virtual bool supports_empty_key() const = 0;
363
+ virtual bool supports_deleted_key() const = 0;
364
+ virtual bool supports_brackets() const = 0; // has a 'real' operator[]
365
+ virtual bool supports_readwrite() const = 0;
366
+ virtual bool supports_num_table_copies() const = 0;
367
+
368
+ protected:
369
+ HT ht_;
370
+
371
+ // These are what subclasses have to define to get class-specific behavior
372
+ virtual key_type it_to_key(const iterator& it) const = 0;
373
+ virtual key_type it_to_key(const const_iterator& it) const = 0;
374
+ virtual key_type it_to_key(const local_iterator& it) const = 0;
375
+ virtual key_type it_to_key(const const_local_iterator& it) const = 0;
376
+ };
377
+
378
+ // ---------------------------------------------------------------------
379
+
380
+ template <class Key, class T,
381
+ class HashFcn = HASH_NAMESPACE::hash<Key>,
382
+ class EqualKey = STL_NAMESPACE::equal_to<Key>,
383
+ class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
384
+ class HashtableInterface_SparseHashMap
385
+ : public BaseHashtableInterface< sparse_hash_map<Key, T, HashFcn,
386
+ EqualKey, Alloc> > {
387
+ private:
388
+ typedef sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc> ht;
389
+ typedef BaseHashtableInterface<ht> p; // parent
390
+
391
+ public:
392
+ explicit HashtableInterface_SparseHashMap(
393
+ typename p::size_type expected_max_items = 0,
394
+ const typename p::hasher& hf = typename p::hasher(),
395
+ const typename p::key_equal& eql = typename p::key_equal(),
396
+ const typename p::allocator_type& alloc = typename p::allocator_type())
397
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
398
+
399
+ template <class InputIterator>
400
+ HashtableInterface_SparseHashMap(
401
+ InputIterator f, InputIterator l,
402
+ typename p::size_type expected_max_items = 0,
403
+ const typename p::hasher& hf = typename p::hasher(),
404
+ const typename p::key_equal& eql = typename p::key_equal(),
405
+ const typename p::allocator_type& alloc = typename p::allocator_type())
406
+ : BaseHashtableInterface<ht>(f, l, expected_max_items, hf, eql, alloc) { }
407
+
408
+ typename p::key_type get_key(const typename p::value_type& value) const {
409
+ return value.first;
410
+ }
411
+ typename ht::data_type get_data(const typename p::value_type& value) const {
412
+ return value.second;
413
+ }
414
+ typename ht::data_type default_data() const {
415
+ return typename ht::data_type();
416
+ }
417
+
418
+ bool supports_clear_no_resize() const { return false; }
419
+ bool supports_empty_key() const { return false; }
420
+ bool supports_deleted_key() const { return true; }
421
+ bool supports_brackets() const { return true; }
422
+ bool supports_readwrite() const { return true; }
423
+ bool supports_num_table_copies() const { return false; }
424
+
425
+ void set_empty_key(const typename p::key_type& k) { }
426
+ void clear_empty_key() { }
427
+ typename p::key_type empty_key() const { return typename p::key_type(); }
428
+ int num_table_copies() const { return 0; }
429
+
430
+ protected:
431
+ template <class K2, class T2, class H2, class E2, class A2>
432
+ friend void swap(HashtableInterface_SparseHashMap<K2,T2,H2,E2,A2>& a,
433
+ HashtableInterface_SparseHashMap<K2,T2,H2,E2,A2>& b);
434
+
435
+ typename p::key_type it_to_key(const typename p::iterator& it) const {
436
+ return it->first;
437
+ }
438
+ typename p::key_type it_to_key(const typename p::const_iterator& it) const {
439
+ return it->first;
440
+ }
441
+ typename p::key_type it_to_key(const typename p::local_iterator& it) const {
442
+ return it->first;
443
+ }
444
+ typename p::key_type it_to_key(const typename p::const_local_iterator& it)
445
+ const {
446
+ return it->first;
447
+ }
448
+ };
449
+
450
+ template <class K, class T, class H, class E, class A>
451
+ void swap(HashtableInterface_SparseHashMap<K,T,H,E,A>& a,
452
+ HashtableInterface_SparseHashMap<K,T,H,E,A>& b) {
453
+ swap(a.ht_, b.ht_);
454
+ }
455
+
456
+ // ---------------------------------------------------------------------
457
+
458
+ template <class Value,
459
+ class HashFcn = HASH_NAMESPACE::hash<Value>,
460
+ class EqualKey = STL_NAMESPACE::equal_to<Value>,
461
+ class Alloc = libc_allocator_with_realloc<Value> >
462
+ class HashtableInterface_SparseHashSet
463
+ : public BaseHashtableInterface< sparse_hash_set<Value, HashFcn,
464
+ EqualKey, Alloc> > {
465
+ private:
466
+ typedef sparse_hash_set<Value, HashFcn, EqualKey, Alloc> ht;
467
+ typedef BaseHashtableInterface<ht> p; // parent
468
+
469
+ public:
470
+ // Bizarrely, MSVC 8.0 has trouble with the (perfectly fine)
471
+ // typename's in this constructor, and this constructor alone, out
472
+ // of all the ones in the file. So for MSVC, we take some typenames
473
+ // out, which is technically invalid C++, but MSVC doesn't seem to
474
+ // mind.
475
+ #ifdef _MSC_VER
476
+ explicit HashtableInterface_SparseHashSet(
477
+ typename p::size_type expected_max_items = 0,
478
+ const typename p::hasher& hf = p::hasher(),
479
+ const typename p::key_equal& eql = p::key_equal(),
480
+ const typename p::allocator_type& alloc = p::allocator_type())
481
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
482
+ #else
483
+ explicit HashtableInterface_SparseHashSet(
484
+ typename p::size_type expected_max_items = 0,
485
+ const typename p::hasher& hf = typename p::hasher(),
486
+ const typename p::key_equal& eql = typename p::key_equal(),
487
+ const typename p::allocator_type& alloc = typename p::allocator_type())
488
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
489
+ #endif
490
+
491
+ template <class InputIterator>
492
+ HashtableInterface_SparseHashSet(
493
+ InputIterator f, InputIterator l,
494
+ typename p::size_type expected_max_items = 0,
495
+ const typename p::hasher& hf = typename p::hasher(),
496
+ const typename p::key_equal& eql = typename p::key_equal(),
497
+ const typename p::allocator_type& alloc = typename p::allocator_type())
498
+ : BaseHashtableInterface<ht>(f, l, expected_max_items, hf, eql, alloc) { }
499
+
500
+ template<typename AssignValue>
501
+ bool bracket_equal(const typename p::key_type& key, const AssignValue&) {
502
+ return this->ht_.find(key) != this->ht_.end();
503
+ }
504
+
505
+ template<typename AssignValue>
506
+ void bracket_assign(const typename p::key_type& key, const AssignValue&) {
507
+ this->ht_.insert(key);
508
+ }
509
+
510
+ typename p::key_type get_key(const typename p::value_type& value) const {
511
+ return value;
512
+ }
513
+ // For sets, the only 'data' is that an item is actually inserted.
514
+ bool get_data(const typename p::value_type&) const {
515
+ return true;
516
+ }
517
+ bool default_data() const {
518
+ return true;
519
+ }
520
+
521
+ bool supports_clear_no_resize() const { return false; }
522
+ bool supports_empty_key() const { return false; }
523
+ bool supports_deleted_key() const { return true; }
524
+ bool supports_brackets() const { return false; }
525
+ bool supports_readwrite() const { return true; }
526
+ bool supports_num_table_copies() const { return false; }
527
+
528
+ void set_empty_key(const typename p::key_type& k) { }
529
+ void clear_empty_key() { }
530
+ typename p::key_type empty_key() const { return typename p::key_type(); }
531
+ int num_table_copies() const { return 0; }
532
+
533
+ protected:
534
+ template <class K2, class H2, class E2, class A2>
535
+ friend void swap(HashtableInterface_SparseHashSet<K2,H2,E2,A2>& a,
536
+ HashtableInterface_SparseHashSet<K2,H2,E2,A2>& b);
537
+
538
+ typename p::key_type it_to_key(const typename p::iterator& it) const {
539
+ return *it;
540
+ }
541
+ typename p::key_type it_to_key(const typename p::const_iterator& it) const {
542
+ return *it;
543
+ }
544
+ typename p::key_type it_to_key(const typename p::local_iterator& it) const {
545
+ return *it;
546
+ }
547
+ typename p::key_type it_to_key(const typename p::const_local_iterator& it)
548
+ const {
549
+ return *it;
550
+ }
551
+ };
552
+
553
+ template <class K, class H, class E, class A>
554
+ void swap(HashtableInterface_SparseHashSet<K,H,E,A>& a,
555
+ HashtableInterface_SparseHashSet<K,H,E,A>& b) {
556
+ swap(a.ht_, b.ht_);
557
+ }
558
+
559
+ // ---------------------------------------------------------------------
560
+
561
+ template <class Value, class Key, class HashFcn, class ExtractKey,
562
+ class SetKey, class EqualKey, class Alloc>
563
+ class HashtableInterface_SparseHashtable
564
+ : public BaseHashtableInterface< sparse_hashtable<Value, Key, HashFcn,
565
+ ExtractKey, SetKey,
566
+ EqualKey, Alloc> > {
567
+ private:
568
+ typedef sparse_hashtable<Value, Key, HashFcn, ExtractKey, SetKey,
569
+ EqualKey, Alloc> ht;
570
+ typedef BaseHashtableInterface<ht> p; // parent
571
+
572
+ public:
573
+ explicit HashtableInterface_SparseHashtable(
574
+ typename p::size_type expected_max_items = 0,
575
+ const typename p::hasher& hf = typename p::hasher(),
576
+ const typename p::key_equal& eql = typename p::key_equal(),
577
+ const typename p::allocator_type& alloc = typename p::allocator_type())
578
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
579
+ ExtractKey(), SetKey(), alloc) { }
580
+
581
+ template <class InputIterator>
582
+ HashtableInterface_SparseHashtable(
583
+ InputIterator f, InputIterator l,
584
+ typename p::size_type expected_max_items = 0,
585
+ const typename p::hasher& hf = typename p::hasher(),
586
+ const typename p::key_equal& eql = typename p::key_equal(),
587
+ const typename p::allocator_type& alloc = typename p::allocator_type())
588
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
589
+ ExtractKey(), SetKey(), alloc) {
590
+ this->insert(f, l);
591
+ }
592
+
593
+ float max_load_factor() const {
594
+ float shrink, grow;
595
+ this->ht_.get_resizing_parameters(&shrink, &grow);
596
+ return grow;
597
+ }
598
+ void max_load_factor(float new_grow) {
599
+ float shrink, grow;
600
+ this->ht_.get_resizing_parameters(&shrink, &grow);
601
+ this->ht_.set_resizing_parameters(shrink, new_grow);
602
+ }
603
+ float min_load_factor() const {
604
+ float shrink, grow;
605
+ this->ht_.get_resizing_parameters(&shrink, &grow);
606
+ return shrink;
607
+ }
608
+ void min_load_factor(float new_shrink) {
609
+ float shrink, grow;
610
+ this->ht_.get_resizing_parameters(&shrink, &grow);
611
+ this->ht_.set_resizing_parameters(new_shrink, grow);
612
+ }
613
+
614
+ template<typename AssignValue>
615
+ bool bracket_equal(const typename p::key_type&, const AssignValue&) {
616
+ return false;
617
+ }
618
+
619
+ template<typename AssignValue>
620
+ void bracket_assign(const typename p::key_type&, const AssignValue&) {
621
+ }
622
+
623
+ typename p::key_type get_key(const typename p::value_type& value) const {
624
+ return extract_key(value);
625
+ }
626
+ typename p::value_type get_data(const typename p::value_type& value) const {
627
+ return value;
628
+ }
629
+ typename p::value_type default_data() const {
630
+ return typename p::value_type();
631
+ }
632
+
633
+ bool supports_clear_no_resize() const { return false; }
634
+ bool supports_empty_key() const { return false; }
635
+ bool supports_deleted_key() const { return true; }
636
+ bool supports_brackets() const { return false; }
637
+ bool supports_readwrite() const { return true; }
638
+ bool supports_num_table_copies() const { return true; }
639
+
640
+ void set_empty_key(const typename p::key_type& k) { }
641
+ void clear_empty_key() { }
642
+ typename p::key_type empty_key() const { return typename p::key_type(); }
643
+
644
+ // These tr1 names aren't defined for sparse_hashtable.
645
+ typename p::hasher hash_function() { return this->hash_funct(); }
646
+ void rehash(typename p::size_type hint) { this->resize(hint); }
647
+
648
+ // TODO(csilvers): also support/test destructive_begin()/destructive_end()?
649
+
650
+ protected:
651
+ template <class V2, class K2, class HF2, class EK2, class SK2, class Eq2,
652
+ class A2>
653
+ friend void swap(
654
+ HashtableInterface_SparseHashtable<V2,K2,HF2,EK2,SK2,Eq2,A2>& a,
655
+ HashtableInterface_SparseHashtable<V2,K2,HF2,EK2,SK2,Eq2,A2>& b);
656
+
657
+ typename p::key_type it_to_key(const typename p::iterator& it) const {
658
+ return extract_key(*it);
659
+ }
660
+ typename p::key_type it_to_key(const typename p::const_iterator& it) const {
661
+ return extract_key(*it);
662
+ }
663
+ typename p::key_type it_to_key(const typename p::local_iterator& it) const {
664
+ return extract_key(*it);
665
+ }
666
+ typename p::key_type it_to_key(const typename p::const_local_iterator& it)
667
+ const {
668
+ return extract_key(*it);
669
+ }
670
+
671
+ private:
672
+ ExtractKey extract_key;
673
+ };
674
+
675
+ template <class V, class K, class HF, class EK, class SK, class Eq, class A>
676
+ void swap(HashtableInterface_SparseHashtable<V,K,HF,EK,SK,Eq,A>& a,
677
+ HashtableInterface_SparseHashtable<V,K,HF,EK,SK,Eq,A>& b) {
678
+ swap(a.ht_, b.ht_);
679
+ }
680
+
681
+ // ---------------------------------------------------------------------
682
+
683
+ // Unlike dense_hash_map, the wrapper class takes an extra template
684
+ // value saying what the empty key is.
685
+
686
+ template <class Key, class T, const Key& EMPTY_KEY,
687
+ class HashFcn = HASH_NAMESPACE::hash<Key>,
688
+ class EqualKey = STL_NAMESPACE::equal_to<Key>,
689
+ class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
690
+ class HashtableInterface_DenseHashMap
691
+ : public BaseHashtableInterface< dense_hash_map<Key, T, HashFcn,
692
+ EqualKey, Alloc> > {
693
+ private:
694
+ typedef dense_hash_map<Key, T, HashFcn, EqualKey, Alloc> ht;
695
+ typedef BaseHashtableInterface<ht> p; // parent
696
+
697
+ public:
698
+ explicit HashtableInterface_DenseHashMap(
699
+ typename p::size_type expected_max_items = 0,
700
+ const typename p::hasher& hf = typename p::hasher(),
701
+ const typename p::key_equal& eql = typename p::key_equal(),
702
+ const typename p::allocator_type& alloc = typename p::allocator_type())
703
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) {
704
+ this->set_empty_key(EMPTY_KEY);
705
+ }
706
+
707
+ template <class InputIterator>
708
+ HashtableInterface_DenseHashMap(
709
+ InputIterator f, InputIterator l,
710
+ typename p::size_type expected_max_items = 0,
711
+ const typename p::hasher& hf = typename p::hasher(),
712
+ const typename p::key_equal& eql = typename p::key_equal(),
713
+ const typename p::allocator_type& alloc = typename p::allocator_type())
714
+ : BaseHashtableInterface<ht>(f, l, EMPTY_KEY,
715
+ expected_max_items, hf, eql, alloc) {
716
+ }
717
+
718
+ void clear_no_resize() { this->ht_.clear_no_resize(); }
719
+
720
+ typename p::key_type get_key(const typename p::value_type& value) const {
721
+ return value.first;
722
+ }
723
+ typename ht::data_type get_data(const typename p::value_type& value) const {
724
+ return value.second;
725
+ }
726
+ typename ht::data_type default_data() const {
727
+ return typename ht::data_type();
728
+ }
729
+
730
+ bool supports_clear_no_resize() const { return true; }
731
+ bool supports_empty_key() const { return true; }
732
+ bool supports_deleted_key() const { return true; }
733
+ bool supports_brackets() const { return true; }
734
+ bool supports_readwrite() const { return false; }
735
+ bool supports_num_table_copies() const { return false; }
736
+
737
+ template <typename OUTPUT> bool write_metadata(OUTPUT *fp) { return false; }
738
+ template <typename INPUT> bool read_metadata(INPUT *fp) { return false; }
739
+ template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
740
+ return false;
741
+ }
742
+ template <typename INPUT> bool read_nopointer_data(INPUT *) {
743
+ return false;
744
+ }
745
+ int num_table_copies() const { return 0; }
746
+
747
+ protected:
748
+ template <class K2, class T2, const K2& Empty2, class H2, class E2, class A2>
749
+ friend void swap(HashtableInterface_DenseHashMap<K2,T2,Empty2,H2,E2,A2>& a,
750
+ HashtableInterface_DenseHashMap<K2,T2,Empty2,H2,E2,A2>& b);
751
+
752
+ typename p::key_type it_to_key(const typename p::iterator& it) const {
753
+ return it->first;
754
+ }
755
+ typename p::key_type it_to_key(const typename p::const_iterator& it) const {
756
+ return it->first;
757
+ }
758
+ typename p::key_type it_to_key(const typename p::local_iterator& it) const {
759
+ return it->first;
760
+ }
761
+ typename p::key_type it_to_key(const typename p::const_local_iterator& it)
762
+ const {
763
+ return it->first;
764
+ }
765
+ };
766
+
767
+ template <class K, class T, const K& Empty, class H, class E, class A>
768
+ void swap(HashtableInterface_DenseHashMap<K,T,Empty,H,E,A>& a,
769
+ HashtableInterface_DenseHashMap<K,T,Empty,H,E,A>& b) {
770
+ swap(a.ht_, b.ht_);
771
+ }
772
+
773
+ // ---------------------------------------------------------------------
774
+
775
+ // Unlike dense_hash_set, the wrapper class takes an extra template
776
+ // value saying what the empty key is.
777
+
778
+ template <class Value, const Value& EMPTY_KEY,
779
+ class HashFcn = HASH_NAMESPACE::hash<Value>,
780
+ class EqualKey = STL_NAMESPACE::equal_to<Value>,
781
+ class Alloc = libc_allocator_with_realloc<Value> >
782
+ class HashtableInterface_DenseHashSet
783
+ : public BaseHashtableInterface< dense_hash_set<Value, HashFcn,
784
+ EqualKey, Alloc> > {
785
+ private:
786
+ typedef dense_hash_set<Value, HashFcn, EqualKey, Alloc> ht;
787
+ typedef BaseHashtableInterface<ht> p; // parent
788
+
789
+ public:
790
+ explicit HashtableInterface_DenseHashSet(
791
+ typename p::size_type expected_max_items = 0,
792
+ const typename p::hasher& hf = typename p::hasher(),
793
+ const typename p::key_equal& eql = typename p::key_equal(),
794
+ const typename p::allocator_type& alloc = typename p::allocator_type())
795
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) {
796
+ this->set_empty_key(EMPTY_KEY);
797
+ }
798
+
799
+ template <class InputIterator>
800
+ HashtableInterface_DenseHashSet(
801
+ InputIterator f, InputIterator l,
802
+ typename p::size_type expected_max_items = 0,
803
+ const typename p::hasher& hf = typename p::hasher(),
804
+ const typename p::key_equal& eql = typename p::key_equal(),
805
+ const typename p::allocator_type& alloc = typename p::allocator_type())
806
+ : BaseHashtableInterface<ht>(f, l, EMPTY_KEY,
807
+ expected_max_items, hf, eql, alloc) {
808
+ }
809
+
810
+ void clear_no_resize() { this->ht_.clear_no_resize(); }
811
+
812
+ template<typename AssignValue>
813
+ bool bracket_equal(const typename p::key_type& key, const AssignValue&) {
814
+ return this->ht_.find(key) != this->ht_.end();
815
+ }
816
+
817
+ template<typename AssignValue>
818
+ void bracket_assign(const typename p::key_type& key, const AssignValue&) {
819
+ this->ht_.insert(key);
820
+ }
821
+
822
+ typename p::key_type get_key(const typename p::value_type& value) const {
823
+ return value;
824
+ }
825
+ bool get_data(const typename p::value_type&) const {
826
+ return true;
827
+ }
828
+ bool default_data() const {
829
+ return true;
830
+ }
831
+
832
+ bool supports_clear_no_resize() const { return true; }
833
+ bool supports_empty_key() const { return true; }
834
+ bool supports_deleted_key() const { return true; }
835
+ bool supports_brackets() const { return false; }
836
+ bool supports_readwrite() const { return false; }
837
+ bool supports_num_table_copies() const { return false; }
838
+
839
+ template <typename OUTPUT> bool write_metadata(OUTPUT *fp) { return false; }
840
+ template <typename INPUT> bool read_metadata(INPUT *fp) { return false; }
841
+ template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
842
+ return false;
843
+ }
844
+ template <typename INPUT> bool read_nopointer_data(INPUT *) {
845
+ return false;
846
+ }
847
+ int num_table_copies() const { return 0; }
848
+
849
+ protected:
850
+ template <class K2, const K2& Empty2, class H2, class E2, class A2>
851
+ friend void swap(HashtableInterface_DenseHashSet<K2,Empty2,H2,E2,A2>& a,
852
+ HashtableInterface_DenseHashSet<K2,Empty2,H2,E2,A2>& b);
853
+
854
+ typename p::key_type it_to_key(const typename p::iterator& it) const {
855
+ return *it;
856
+ }
857
+ typename p::key_type it_to_key(const typename p::const_iterator& it) const {
858
+ return *it;
859
+ }
860
+ typename p::key_type it_to_key(const typename p::local_iterator& it) const {
861
+ return *it;
862
+ }
863
+ typename p::key_type it_to_key(const typename p::const_local_iterator& it)
864
+ const {
865
+ return *it;
866
+ }
867
+ };
868
+
869
+ template <class K, const K& Empty, class H, class E, class A>
870
+ void swap(HashtableInterface_DenseHashSet<K,Empty,H,E,A>& a,
871
+ HashtableInterface_DenseHashSet<K,Empty,H,E,A>& b) {
872
+ swap(a.ht_, b.ht_);
873
+ }
874
+
875
+ // ---------------------------------------------------------------------
876
+
877
+ // Unlike dense_hashtable, the wrapper class takes an extra template
878
+ // value saying what the empty key is.
879
+
880
+ template <class Value, class Key, const Key& EMPTY_KEY, class HashFcn,
881
+ class ExtractKey, class SetKey, class EqualKey, class Alloc>
882
+ class HashtableInterface_DenseHashtable
883
+ : public BaseHashtableInterface< dense_hashtable<Value, Key, HashFcn,
884
+ ExtractKey, SetKey,
885
+ EqualKey, Alloc> > {
886
+ private:
887
+ typedef dense_hashtable<Value, Key, HashFcn, ExtractKey, SetKey,
888
+ EqualKey, Alloc> ht;
889
+ typedef BaseHashtableInterface<ht> p; // parent
890
+
891
+ public:
892
+ explicit HashtableInterface_DenseHashtable(
893
+ typename p::size_type expected_max_items = 0,
894
+ const typename p::hasher& hf = typename p::hasher(),
895
+ const typename p::key_equal& eql = typename p::key_equal(),
896
+ const typename p::allocator_type& alloc = typename p::allocator_type())
897
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
898
+ ExtractKey(), SetKey(), alloc) {
899
+ this->set_empty_key(EMPTY_KEY);
900
+ }
901
+
902
+ template <class InputIterator>
903
+ HashtableInterface_DenseHashtable(
904
+ InputIterator f, InputIterator l,
905
+ typename p::size_type expected_max_items = 0,
906
+ const typename p::hasher& hf = typename p::hasher(),
907
+ const typename p::key_equal& eql = typename p::key_equal(),
908
+ const typename p::allocator_type& alloc = typename p::allocator_type())
909
+ : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
910
+ ExtractKey(), SetKey(), alloc) {
911
+ this->set_empty_key(EMPTY_KEY);
912
+ this->insert(f, l);
913
+ }
914
+
915
+ void clear_no_resize() { this->ht_.clear_no_resize(); }
916
+
917
+ float max_load_factor() const {
918
+ float shrink, grow;
919
+ this->ht_.get_resizing_parameters(&shrink, &grow);
920
+ return grow;
921
+ }
922
+ void max_load_factor(float new_grow) {
923
+ float shrink, grow;
924
+ this->ht_.get_resizing_parameters(&shrink, &grow);
925
+ this->ht_.set_resizing_parameters(shrink, new_grow);
926
+ }
927
+ float min_load_factor() const {
928
+ float shrink, grow;
929
+ this->ht_.get_resizing_parameters(&shrink, &grow);
930
+ return shrink;
931
+ }
932
+ void min_load_factor(float new_shrink) {
933
+ float shrink, grow;
934
+ this->ht_.get_resizing_parameters(&shrink, &grow);
935
+ this->ht_.set_resizing_parameters(new_shrink, grow);
936
+ }
937
+
938
+ template<typename AssignValue>
939
+ bool bracket_equal(const typename p::key_type&, const AssignValue&) {
940
+ return false;
941
+ }
942
+
943
+ template<typename AssignValue>
944
+ void bracket_assign(const typename p::key_type&, const AssignValue&) {
945
+ }
946
+
947
+ typename p::key_type get_key(const typename p::value_type& value) const {
948
+ return extract_key(value);
949
+ }
950
+ typename p::value_type get_data(const typename p::value_type& value) const {
951
+ return value;
952
+ }
953
+ typename p::value_type default_data() const {
954
+ return typename p::value_type();
955
+ }
956
+
957
+ bool supports_clear_no_resize() const { return true; }
958
+ bool supports_empty_key() const { return true; }
959
+ bool supports_deleted_key() const { return true; }
960
+ bool supports_brackets() const { return false; }
961
+ bool supports_readwrite() const { return false; }
962
+ bool supports_num_table_copies() const { return true; }
963
+
964
+ template <typename OUTPUT> bool write_metadata(OUTPUT *fp) { return false; }
965
+ template <typename INPUT> bool read_metadata(INPUT *fp) { return false; }
966
+ template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
967
+ return false;
968
+ }
969
+ template <typename INPUT> bool read_nopointer_data(INPUT *) {
970
+ return false;
971
+ }
972
+
973
+ // These tr1 names aren't defined for dense_hashtable.
974
+ typename p::hasher hash_function() { return this->hash_funct(); }
975
+ void rehash(typename p::size_type hint) { this->resize(hint); }
976
+
977
+ protected:
978
+ template <class V2, class K2, const K2& Empty2,
979
+ class HF2, class EK2, class SK2, class Eq2, class A2>
980
+ friend void swap(
981
+ HashtableInterface_DenseHashtable<V2,K2,Empty2,HF2,EK2,SK2,Eq2,A2>& a,
982
+ HashtableInterface_DenseHashtable<V2,K2,Empty2,HF2,EK2,SK2,Eq2,A2>& b);
983
+
984
+ typename p::key_type it_to_key(const typename p::iterator& it) const {
985
+ return extract_key(*it);
986
+ }
987
+ typename p::key_type it_to_key(const typename p::const_iterator& it) const {
988
+ return extract_key(*it);
989
+ }
990
+ typename p::key_type it_to_key(const typename p::local_iterator& it) const {
991
+ return extract_key(*it);
992
+ }
993
+ typename p::key_type it_to_key(const typename p::const_local_iterator& it)
994
+ const {
995
+ return extract_key(*it);
996
+ }
997
+
998
+ private:
999
+ ExtractKey extract_key;
1000
+ };
1001
+
1002
+ template <class V, class K, const K& Empty,
1003
+ class HF, class EK, class SK, class Eq, class A>
1004
+ void swap(HashtableInterface_DenseHashtable<V,K,Empty,HF,EK,SK,Eq,A>& a,
1005
+ HashtableInterface_DenseHashtable<V,K,Empty,HF,EK,SK,Eq,A>& b) {
1006
+ swap(a.ht_, b.ht_);
1007
+ }
1008
+
1009
+ _END_GOOGLE_NAMESPACE_
1010
+
1011
+ #endif // UTIL_GTL_HASH_TEST_INTERFACE_H_