google_hash 0.0.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 (85) hide show
  1. data/README +21 -0
  2. data/Rakefile +11 -0
  3. data/VERSION +1 -0
  4. data/ext/extconf.rb +15 -0
  5. data/ext/go.cpp +109 -0
  6. data/ext/sparsehash-1.5.2/AUTHORS +2 -0
  7. data/ext/sparsehash-1.5.2/COPYING +28 -0
  8. data/ext/sparsehash-1.5.2/ChangeLog +167 -0
  9. data/ext/sparsehash-1.5.2/INSTALL +236 -0
  10. data/ext/sparsehash-1.5.2/Makefile.am +157 -0
  11. data/ext/sparsehash-1.5.2/Makefile.in +1019 -0
  12. data/ext/sparsehash-1.5.2/NEWS +0 -0
  13. data/ext/sparsehash-1.5.2/README +149 -0
  14. data/ext/sparsehash-1.5.2/README.windows +25 -0
  15. data/ext/sparsehash-1.5.2/TODO +28 -0
  16. data/ext/sparsehash-1.5.2/aclocal.m4 +868 -0
  17. data/ext/sparsehash-1.5.2/compile +99 -0
  18. data/ext/sparsehash-1.5.2/config.guess +1516 -0
  19. data/ext/sparsehash-1.5.2/config.sub +1626 -0
  20. data/ext/sparsehash-1.5.2/configure +8054 -0
  21. data/ext/sparsehash-1.5.2/configure.ac +74 -0
  22. data/ext/sparsehash-1.5.2/depcomp +530 -0
  23. data/ext/sparsehash-1.5.2/doc/dense_hash_map.html +1591 -0
  24. data/ext/sparsehash-1.5.2/doc/dense_hash_set.html +1445 -0
  25. data/ext/sparsehash-1.5.2/doc/designstyle.css +115 -0
  26. data/ext/sparsehash-1.5.2/doc/implementation.html +365 -0
  27. data/ext/sparsehash-1.5.2/doc/index.html +69 -0
  28. data/ext/sparsehash-1.5.2/doc/performance.html +96 -0
  29. data/ext/sparsehash-1.5.2/doc/sparse_hash_map.html +1527 -0
  30. data/ext/sparsehash-1.5.2/doc/sparse_hash_set.html +1376 -0
  31. data/ext/sparsehash-1.5.2/doc/sparsetable.html +1393 -0
  32. data/ext/sparsehash-1.5.2/experimental/Makefile +9 -0
  33. data/ext/sparsehash-1.5.2/experimental/README +14 -0
  34. data/ext/sparsehash-1.5.2/experimental/example.c +54 -0
  35. data/ext/sparsehash-1.5.2/experimental/libchash.c +1537 -0
  36. data/ext/sparsehash-1.5.2/experimental/libchash.h +252 -0
  37. data/ext/sparsehash-1.5.2/google-sparsehash.sln +47 -0
  38. data/ext/sparsehash-1.5.2/install-sh +323 -0
  39. data/ext/sparsehash-1.5.2/m4/acx_pthread.m4 +363 -0
  40. data/ext/sparsehash-1.5.2/m4/google_namespace.m4 +42 -0
  41. data/ext/sparsehash-1.5.2/m4/namespaces.m4 +15 -0
  42. data/ext/sparsehash-1.5.2/m4/stl_hash.m4 +70 -0
  43. data/ext/sparsehash-1.5.2/m4/stl_hash_fun.m4 +36 -0
  44. data/ext/sparsehash-1.5.2/m4/stl_namespace.m4 +25 -0
  45. data/ext/sparsehash-1.5.2/missing +360 -0
  46. data/ext/sparsehash-1.5.2/mkinstalldirs +158 -0
  47. data/ext/sparsehash-1.5.2/packages/deb.sh +74 -0
  48. data/ext/sparsehash-1.5.2/packages/deb/README +7 -0
  49. data/ext/sparsehash-1.5.2/packages/deb/changelog +107 -0
  50. data/ext/sparsehash-1.5.2/packages/deb/compat +1 -0
  51. data/ext/sparsehash-1.5.2/packages/deb/control +17 -0
  52. data/ext/sparsehash-1.5.2/packages/deb/copyright +35 -0
  53. data/ext/sparsehash-1.5.2/packages/deb/docs +16 -0
  54. data/ext/sparsehash-1.5.2/packages/deb/rules +117 -0
  55. data/ext/sparsehash-1.5.2/packages/deb/sparsehash.dirs +2 -0
  56. data/ext/sparsehash-1.5.2/packages/deb/sparsehash.install +2 -0
  57. data/ext/sparsehash-1.5.2/packages/rpm.sh +86 -0
  58. data/ext/sparsehash-1.5.2/packages/rpm/rpm.spec +61 -0
  59. data/ext/sparsehash-1.5.2/src/config.h.in +131 -0
  60. data/ext/sparsehash-1.5.2/src/config.h.include +23 -0
  61. data/ext/sparsehash-1.5.2/src/google/dense_hash_map +310 -0
  62. data/ext/sparsehash-1.5.2/src/google/dense_hash_set +287 -0
  63. data/ext/sparsehash-1.5.2/src/google/sparse_hash_map +294 -0
  64. data/ext/sparsehash-1.5.2/src/google/sparse_hash_set +275 -0
  65. data/ext/sparsehash-1.5.2/src/google/sparsehash/densehashtable.h +1062 -0
  66. data/ext/sparsehash-1.5.2/src/google/sparsehash/sparsehashtable.h +1015 -0
  67. data/ext/sparsehash-1.5.2/src/google/sparsetable +1468 -0
  68. data/ext/sparsehash-1.5.2/src/google/type_traits.h +250 -0
  69. data/ext/sparsehash-1.5.2/src/hashtable_unittest.cc +1375 -0
  70. data/ext/sparsehash-1.5.2/src/simple_test.cc +103 -0
  71. data/ext/sparsehash-1.5.2/src/sparsetable_unittest.cc +696 -0
  72. data/ext/sparsehash-1.5.2/src/time_hash_map.cc +488 -0
  73. data/ext/sparsehash-1.5.2/src/type_traits_unittest.cc +492 -0
  74. data/ext/sparsehash-1.5.2/src/windows/config.h +149 -0
  75. data/ext/sparsehash-1.5.2/src/windows/google/sparsehash/sparseconfig.h +32 -0
  76. data/ext/sparsehash-1.5.2/src/windows/port.cc +63 -0
  77. data/ext/sparsehash-1.5.2/src/windows/port.h +81 -0
  78. data/ext/sparsehash-1.5.2/src/words +8944 -0
  79. data/ext/sparsehash-1.5.2/vsprojects/hashtable_unittest/hashtable_unittest.vcproj +187 -0
  80. data/ext/sparsehash-1.5.2/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +172 -0
  81. data/ext/sparsehash-1.5.2/vsprojects/time_hash_map/time_hash_map.vcproj +187 -0
  82. data/ext/sparsehash-1.5.2/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +169 -0
  83. data/ext/test.rb +10 -0
  84. data/test/spec.go +70 -0
  85. metadata +147 -0
@@ -0,0 +1,103 @@
1
+ // Copyright (c) 2007, 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 tests mostly that we can #include the files correctly
34
+ // and have them work. This unittest purposefully does not
35
+ // #include <config.h>; it's meant to emulate what a 'regular
36
+ // install' of sparsehash would be able to see.
37
+
38
+ #include <stdio.h>
39
+ #include <google/sparse_hash_set>
40
+ #include <google/sparse_hash_map>
41
+ #include <google/dense_hash_set>
42
+ #include <google/dense_hash_map>
43
+
44
+ #define CHECK_IFF(cond, when) do { \
45
+ if (when) { \
46
+ if (!(cond)) { \
47
+ puts("ERROR: " #cond " failed when " #when " is true\n"); \
48
+ exit(1); \
49
+ } \
50
+ } else { \
51
+ if (cond) { \
52
+ puts("ERROR: " #cond " succeeded when " #when " is false\n"); \
53
+ exit(1); \
54
+ } \
55
+ } \
56
+ } while (0)
57
+
58
+ int main(int argc, char** argv) {
59
+ // Run with an argument to get verbose output
60
+ const bool verbose = argc > 1;
61
+
62
+ google::sparse_hash_set<int> sset;
63
+ google::sparse_hash_map<int, int> smap;
64
+ google::dense_hash_set<int> dset;
65
+ google::dense_hash_map<int, int> dmap;
66
+ dset.set_empty_key(-1);
67
+ dmap.set_empty_key(-1);
68
+
69
+ for (int i = 0; i < 100; i += 10) { // go by tens
70
+ sset.insert(i);
71
+ smap[i] = i+1;
72
+ dset.insert(i + 5);
73
+ dmap[i+5] = i+6;
74
+ }
75
+
76
+ if (verbose) {
77
+ for (google::sparse_hash_set<int>::const_iterator it = sset.begin();
78
+ it != sset.end(); ++it)
79
+ printf("sset: %d\n", *it);
80
+ for (google::sparse_hash_map<int,int>::const_iterator it = smap.begin();
81
+ it != smap.end(); ++it)
82
+ printf("smap: %d -> %d\n", it->first, it->second);
83
+ for (google::dense_hash_set<int>::const_iterator it = dset.begin();
84
+ it != dset.end(); ++it)
85
+ printf("dset: %d\n", *it);
86
+ for (google::dense_hash_map<int,int>::const_iterator it = dmap.begin();
87
+ it != dmap.end(); ++it)
88
+ printf("dmap: %d -> %d\n", it->first, it->second);
89
+ }
90
+
91
+ for (int i = 0; i < 100; i++) {
92
+ CHECK_IFF(sset.find(i) != sset.end(), (i % 10) == 0);
93
+ CHECK_IFF(smap.find(i) != smap.end(), (i % 10) == 0);
94
+ CHECK_IFF(smap.find(i) != smap.end() && smap.find(i)->second == i+1,
95
+ (i % 10) == 0);
96
+ CHECK_IFF(dset.find(i) != dset.end(), (i % 10) == 5);
97
+ CHECK_IFF(dmap.find(i) != dmap.end(), (i % 10) == 5);
98
+ CHECK_IFF(dmap.find(i) != dmap.end() && dmap.find(i)->second == i+1,
99
+ (i % 10) == 5);
100
+ }
101
+ printf("PASS\n");
102
+ return 0;
103
+ }
@@ -0,0 +1,696 @@
1
+ // Copyright (c) 2005, 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 tests <google/sparsetable>
34
+ //
35
+ // Since sparsetable is templatized, it's important that we test every
36
+ // function in every class in this file -- not just to see if it
37
+ // works, but even if it compiles.
38
+
39
+ #include "config.h"
40
+ #include <string>
41
+ #include <stdio.h>
42
+ #include <string.h> // for memcmp()
43
+ #include <stdlib.h> // defines unlink() on some windows platforms(?)
44
+ #ifdef HAVE_UNISTD_H
45
+ #include <unistd.h> // for unlink()
46
+ #include <sys/types.h> // for size_t
47
+ #include <string>
48
+ #endif
49
+ #include <google/sparsetable>
50
+
51
+ using STL_NAMESPACE::string;
52
+ using GOOGLE_NAMESPACE::sparsetable;
53
+
54
+ // Many sparsetable operations return a size_t. Rather than have to
55
+ // use PRIuS everywhere, we'll just cast to a "big enough" value.
56
+ #define UL(x) ( static_cast<unsigned long>(x) )
57
+
58
+
59
+ static char outbuf[10240]; // big enough for these tests
60
+ static char* out = outbuf; // where to write next
61
+ #define LEFT (outbuf + sizeof(outbuf) - out)
62
+
63
+ #define TEST(cond) out += snprintf(out, LEFT, #cond "? %s\n", \
64
+ (cond) ? "yes" : "no");
65
+
66
+ inline string AsString(int n) {
67
+ const int N = 64;
68
+ char buf[N];
69
+ snprintf(buf, N, "%d", n);
70
+ return string(buf);
71
+ }
72
+
73
+ // Test sparsetable with a POD type, int.
74
+ void TestInt() {
75
+ out += snprintf(out, LEFT, "int test\n");
76
+ sparsetable<int> x(7), y(70), z;
77
+ x.set(4, 10);
78
+ y.set(12, -12);
79
+ y.set(47, -47);
80
+ y.set(48, -48);
81
+ y.set(49, -49);
82
+
83
+ const sparsetable<int> constx(x);
84
+ const sparsetable<int> consty(y);
85
+
86
+ // ----------------------------------------------------------------------
87
+ // Test the plain iterators
88
+
89
+ for ( sparsetable<int>::iterator it = x.begin(); it != x.end(); ++it ) {
90
+ out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(it - x.begin()), int(*it));
91
+ }
92
+ for ( sparsetable<int>::const_iterator it = x.begin(); it != x.end(); ++it ) {
93
+ out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(it - x.begin()), *it);
94
+ }
95
+ for ( sparsetable<int>::reverse_iterator it = x.rbegin(); it != x.rend(); ++it ) {
96
+ out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(x.rend()-1 - it), int(*it));
97
+ }
98
+ for ( sparsetable<int>::const_reverse_iterator it = constx.rbegin(); it != constx.rend(); ++it ) {
99
+ out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(constx.rend()-1 - it), *it);
100
+ }
101
+ for ( sparsetable<int>::iterator it = z.begin(); it != z.end(); ++it ) {
102
+ out += snprintf(out, LEFT, "z[%lu]: %d\n", UL(it - z.begin()), int(*it));
103
+ }
104
+
105
+ { // array version
106
+ out += snprintf(out, LEFT, "x[3]: %d\n", int(x[3]));
107
+ out += snprintf(out, LEFT, "x[4]: %d\n", int(x[4]));
108
+ out += snprintf(out, LEFT, "x[5]: %d\n", int(x[5]));
109
+ }
110
+ {
111
+ sparsetable<int>::iterator it; // non-const version
112
+ out += snprintf(out, LEFT, "x[4]: %d\n", int(x.begin()[4]));
113
+ it = x.begin() + 4; // should point to the non-zero value
114
+ out += snprintf(out, LEFT, "x[4]: %d\n", int(*it));
115
+ it--;
116
+ --it;
117
+ it += 5;
118
+ it -= 2;
119
+ it++;
120
+ ++it;
121
+ it = it - 3;
122
+ it = 1 + it; // now at 5
123
+ out += snprintf(out, LEFT, "x[3]: %d\n", int(it[-2]));
124
+ out += snprintf(out, LEFT, "x[4]: %d\n", int(it[-1]));
125
+ *it = 55;
126
+ out += snprintf(out, LEFT, "x[5]: %d\n", int(it[0]));
127
+ out += snprintf(out, LEFT, "x[5]: %d\n", int(*it));
128
+ int *x6 = &(it[1]);
129
+ *x6 = 66;
130
+ out += snprintf(out, LEFT, "x[6]: %d\n", int(*(it + 1)));
131
+ // Let's test comparitors as well
132
+ TEST(it == it);
133
+ TEST(!(it != it));
134
+ TEST(!(it < it));
135
+ TEST(!(it > it));
136
+ TEST(it <= it);
137
+ TEST(it >= it);
138
+
139
+ sparsetable<int>::iterator it_minus_1 = it - 1;
140
+ TEST(!(it == it_minus_1));
141
+ TEST(it != it_minus_1);
142
+ TEST(!(it < it_minus_1));
143
+ TEST(it > it_minus_1);
144
+ TEST(!(it <= it_minus_1));
145
+ TEST(it >= it_minus_1);
146
+ TEST(!(it_minus_1 == it));
147
+ TEST(it_minus_1 != it);
148
+ TEST(it_minus_1 < it);
149
+ TEST(!(it_minus_1 > it));
150
+ TEST(it_minus_1 <= it);
151
+ TEST(!(it_minus_1 >= it));
152
+
153
+ sparsetable<int>::iterator it_plus_1 = it + 1;
154
+ TEST(!(it == it_plus_1));
155
+ TEST(it != it_plus_1);
156
+ TEST(it < it_plus_1);
157
+ TEST(!(it > it_plus_1));
158
+ TEST(it <= it_plus_1);
159
+ TEST(!(it >= it_plus_1));
160
+ TEST(!(it_plus_1 == it));
161
+ TEST(it_plus_1 != it);
162
+ TEST(!(it_plus_1 < it));
163
+ TEST(it_plus_1 > it);
164
+ TEST(!(it_plus_1 <= it));
165
+ TEST(it_plus_1 >= it);
166
+ }
167
+ {
168
+ sparsetable<int>::const_iterator it; // const version
169
+ out += snprintf(out, LEFT, "x[4]: %d\n", int(x.begin()[4]));
170
+ it = x.begin() + 4; // should point to the non-zero value
171
+ out += snprintf(out, LEFT, "x[4]: %d\n", *it);
172
+ it--;
173
+ --it;
174
+ it += 5;
175
+ it -= 2;
176
+ it++;
177
+ ++it;
178
+ it = it - 3;
179
+ it = 1 + it; // now at 5
180
+ out += snprintf(out, LEFT, "x[3]: %d\n", it[-2]);
181
+ out += snprintf(out, LEFT, "x[4]: %d\n", it[-1]);
182
+ out += snprintf(out, LEFT, "x[5]: %d\n", *it);
183
+ out += snprintf(out, LEFT, "x[6]: %d\n", *(it + 1));
184
+ // Let's test comparitors as well
185
+ TEST(it == it);
186
+ TEST(!(it != it));
187
+ TEST(!(it < it));
188
+ TEST(!(it > it));
189
+ TEST(it <= it);
190
+ TEST(it >= it);
191
+
192
+ sparsetable<int>::const_iterator it_minus_1 = it - 1;
193
+ TEST(!(it == it_minus_1));
194
+ TEST(it != it_minus_1);
195
+ TEST(!(it < it_minus_1));
196
+ TEST(it > it_minus_1);
197
+ TEST(!(it <= it_minus_1));
198
+ TEST(it >= it_minus_1);
199
+ TEST(!(it_minus_1 == it));
200
+ TEST(it_minus_1 != it);
201
+ TEST(it_minus_1 < it);
202
+ TEST(!(it_minus_1 > it));
203
+ TEST(it_minus_1 <= it);
204
+ TEST(!(it_minus_1 >= it));
205
+
206
+ sparsetable<int>::const_iterator it_plus_1 = it + 1;
207
+ TEST(!(it == it_plus_1));
208
+ TEST(it != it_plus_1);
209
+ TEST(it < it_plus_1);
210
+ TEST(!(it > it_plus_1));
211
+ TEST(it <= it_plus_1);
212
+ TEST(!(it >= it_plus_1));
213
+ TEST(!(it_plus_1 == it));
214
+ TEST(it_plus_1 != it);
215
+ TEST(!(it_plus_1 < it));
216
+ TEST(it_plus_1 > it);
217
+ TEST(!(it_plus_1 <= it));
218
+ TEST(it_plus_1 >= it);
219
+ }
220
+
221
+ TEST(x.begin() == x.begin() + 1 - 1);
222
+ TEST(x.begin() < x.end());
223
+ TEST(z.begin() < z.end());
224
+ TEST(z.begin() <= z.end());
225
+ TEST(z.begin() == z.end());
226
+
227
+
228
+ // ----------------------------------------------------------------------
229
+ // Test the non-empty iterators
230
+
231
+ for ( sparsetable<int>::nonempty_iterator it = x.nonempty_begin(); it != x.nonempty_end(); ++it ) {
232
+ out += snprintf(out, LEFT, "x[??]: %d\n", *it);
233
+ }
234
+ for ( sparsetable<int>::const_nonempty_iterator it = y.nonempty_begin(); it != y.nonempty_end(); ++it ) {
235
+ out += snprintf(out, LEFT, "y[??]: %d\n", *it);
236
+ }
237
+ for ( sparsetable<int>::reverse_nonempty_iterator it = y.nonempty_rbegin(); it != y.nonempty_rend(); ++it ) {
238
+ out += snprintf(out, LEFT, "y[??]: %d\n", *it);
239
+ }
240
+ for ( sparsetable<int>::const_reverse_nonempty_iterator it = consty.nonempty_rbegin(); it != consty.nonempty_rend(); ++it ) {
241
+ out += snprintf(out, LEFT, "y[??]: %d\n", *it);
242
+ }
243
+ for ( sparsetable<int>::nonempty_iterator it = z.nonempty_begin(); it != z.nonempty_end(); ++it ) {
244
+ out += snprintf(out, LEFT, "z[??]: %d\n", *it);
245
+ }
246
+
247
+ {
248
+ sparsetable<int>::nonempty_iterator it; // non-const version
249
+ out += snprintf(out, LEFT, "first non-empty y: %d\n", *y.nonempty_begin());
250
+ out += snprintf(out, LEFT, "first non-empty x: %d\n", *x.nonempty_begin());
251
+ it = x.nonempty_begin();
252
+ ++it; // should be at end
253
+ --it;
254
+ out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
255
+ it--;
256
+ out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
257
+ }
258
+ {
259
+ sparsetable<int>::const_nonempty_iterator it; // non-const version
260
+ out += snprintf(out, LEFT, "first non-empty y: %d\n", *y.nonempty_begin());
261
+ out += snprintf(out, LEFT, "first non-empty x: %d\n", *x.nonempty_begin());
262
+ it = x.nonempty_begin();
263
+ ++it; // should be at end
264
+ --it;
265
+ out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
266
+ it--;
267
+ out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
268
+ }
269
+
270
+ TEST(x.begin() == x.begin() + 1 - 1);
271
+ TEST(z.begin() != z.end());
272
+
273
+ // ----------------------------------------------------------------------
274
+ // Test sparsetable functions
275
+ out += snprintf(out, LEFT, "x has %lu/%lu buckets, "
276
+ "y %lu/%lu, z %lu/%lu\n",
277
+ UL(x.num_nonempty()), UL(x.size()),
278
+ UL(y.num_nonempty()), UL(y.size()),
279
+ UL(z.num_nonempty()), UL(z.size()));
280
+
281
+ y.resize(48); // should get rid of 48 and 49
282
+ y.resize(70); // 48 and 49 should still be gone
283
+ out += snprintf(out, LEFT, "y shrank and grew: it's now %lu/%lu\n",
284
+ UL(y.num_nonempty()), UL(y.size()));
285
+ out += snprintf(out, LEFT, "y[12] = %d, y.get(12) = %d\n", int(y[12]), y.get(12));
286
+ y.erase(12);
287
+ out += snprintf(out, LEFT, "y[12] cleared. y now %lu/%lu. "
288
+ "y[12] = %d, y.get(12) = %d\n",
289
+ UL(y.num_nonempty()), UL(y.size()), int(y[12]), y.get(12));
290
+
291
+ swap(x, y);
292
+
293
+ y.clear();
294
+ TEST(y == z);
295
+
296
+ y.resize(70);
297
+ for ( int i = 10; i < 40; ++i )
298
+ y[i] = -i;
299
+ y.erase(y.begin() + 15, y.begin() + 30);
300
+ y.erase(y.begin() + 34);
301
+ y.erase(12);
302
+ y.resize(38);
303
+ y.resize(10000);
304
+ y[9898] = -9898;
305
+ for ( sparsetable<int>::const_iterator it = y.begin(); it != y.end(); ++it ) {
306
+ if ( y.test(it) )
307
+ out += snprintf(out, LEFT, "y[%lu] is set\n", UL(it - y.begin()));
308
+ }
309
+ out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y.num_nonempty()));
310
+
311
+ out += snprintf(out, LEFT, "Starting from y[32]...\n");
312
+ for ( sparsetable<int>::const_nonempty_iterator it = y.get_iter(32);
313
+ it != y.nonempty_end(); ++it )
314
+ out += snprintf(out, LEFT, "y[??] = %d\n", *it);
315
+
316
+ out += snprintf(out, LEFT, "From y[32] down...\n");
317
+ for ( sparsetable<int>::nonempty_iterator it = y.get_iter(32);
318
+ it != y.nonempty_begin(); )
319
+ out += snprintf(out, LEFT, "y[??] = %d\n", *--it);
320
+
321
+ // ----------------------------------------------------------------------
322
+ // Test I/O
323
+ string filestr = "/tmp/#sparsetable.test";
324
+ const char *file = filestr.c_str();
325
+ FILE *fp = fopen(file, "wb");
326
+ if ( fp == NULL ) {
327
+ // maybe we can't write to /tmp/. Try the current directory
328
+ file = "#sparsetable.test";
329
+ fp = fopen(file, "wb");
330
+ }
331
+ if ( fp == NULL ) {
332
+ out += snprintf(out, LEFT, "Can't open %s, skipping disk write...\n", file);
333
+ } else {
334
+ y.write_metadata(fp); // only write meta-information
335
+ y.write_nopointer_data(fp);
336
+ fclose(fp);
337
+ }
338
+ fp = fopen(file, "rb");
339
+ if ( fp == NULL ) {
340
+ out += snprintf(out, LEFT, "Can't open %s, skipping disk read...\n", file);
341
+ } else {
342
+ sparsetable<int> y2;
343
+ y2.read_metadata(fp);
344
+ y2.read_nopointer_data(fp);
345
+ fclose(fp);
346
+
347
+ for ( sparsetable<int>::const_iterator it = y2.begin(); it != y2.end(); ++it ) {
348
+ if ( y2.test(it) )
349
+ out += snprintf(out, LEFT, "y2[%lu] is %d\n", UL(it - y2.begin()), *it);
350
+ }
351
+ out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y2.num_nonempty()));
352
+ }
353
+ unlink(file);
354
+ }
355
+
356
+ // Test sparsetable with a non-POD type, std::string
357
+ void TestString() {
358
+ out += snprintf(out, LEFT, "string test\n");
359
+ sparsetable<string> x(7), y(70), z;
360
+ x.set(4, "foo");
361
+ y.set(12, "orange");
362
+ y.set(47, "grape");
363
+ y.set(48, "pear");
364
+ y.set(49, "apple");
365
+
366
+ // ----------------------------------------------------------------------
367
+ // Test the plain iterators
368
+
369
+ for ( sparsetable<string>::iterator it = x.begin(); it != x.end(); ++it ) {
370
+ out += snprintf(out, LEFT, "x[%lu]: %s\n",
371
+ UL(it - x.begin()), static_cast<string>(*it).c_str());
372
+ }
373
+ for ( sparsetable<string>::iterator it = z.begin(); it != z.end(); ++it ) {
374
+ out += snprintf(out, LEFT, "z[%lu]: %s\n",
375
+ UL(it - z.begin()), static_cast<string>(*it).c_str());
376
+ }
377
+
378
+ TEST(x.begin() == x.begin() + 1 - 1);
379
+ TEST(x.begin() < x.end());
380
+ TEST(z.begin() < z.end());
381
+ TEST(z.begin() <= z.end());
382
+ TEST(z.begin() == z.end());
383
+
384
+ // ----------------------------------------------------------------------
385
+ // Test the non-empty iterators
386
+ for ( sparsetable<string>::nonempty_iterator it = x.nonempty_begin(); it != x.nonempty_end(); ++it ) {
387
+ out += snprintf(out, LEFT, "x[??]: %s\n", it->c_str());
388
+ }
389
+ for ( sparsetable<string>::const_nonempty_iterator it = y.nonempty_begin(); it != y.nonempty_end(); ++it ) {
390
+ out += snprintf(out, LEFT, "y[??]: %s\n", it->c_str());
391
+ }
392
+ for ( sparsetable<string>::nonempty_iterator it = z.nonempty_begin(); it != z.nonempty_end(); ++it ) {
393
+ out += snprintf(out, LEFT, "z[??]: %s\n", it->c_str());
394
+ }
395
+
396
+ // ----------------------------------------------------------------------
397
+ // Test sparsetable functions
398
+ out += snprintf(out, LEFT, "x has %lu/%lu buckets, y %lu/%lu, z %lu/%lu\n",
399
+ UL(x.num_nonempty()), UL(x.size()),
400
+ UL(y.num_nonempty()), UL(y.size()),
401
+ UL(z.num_nonempty()), UL(z.size()));
402
+
403
+ y.resize(48); // should get rid of 48 and 49
404
+ y.resize(70); // 48 and 49 should still be gone
405
+ out += snprintf(out, LEFT, "y shrank and grew: it's now %lu/%lu\n",
406
+ UL(y.num_nonempty()), UL(y.size()));
407
+ out += snprintf(out, LEFT, "y[12] = %s, y.get(12) = %s\n",
408
+ static_cast<string>(y[12]).c_str(), y.get(12).c_str());
409
+ y.erase(12);
410
+ out += snprintf(out, LEFT, "y[12] cleared. y now %lu/%lu. "
411
+ "y[12] = %s, y.get(12) = %s\n",
412
+ UL(y.num_nonempty()), UL(y.size()),
413
+ static_cast<string>(y[12]).c_str(),
414
+ static_cast<string>(y.get(12)).c_str());
415
+ swap(x, y);
416
+
417
+ y.clear();
418
+ TEST(y == z);
419
+
420
+ y.resize(70);
421
+ for ( int i = 10; i < 40; ++i )
422
+ y.set(i, AsString(-i));
423
+ y.erase(y.begin() + 15, y.begin() + 30);
424
+ y.erase(y.begin() + 34);
425
+ y.erase(12);
426
+ y.resize(38);
427
+ y.resize(10000);
428
+ y.set(9898, AsString(-9898));
429
+ for ( sparsetable<string>::const_iterator it = y.begin(); it != y.end(); ++it ) {
430
+ if ( y.test(it) )
431
+ out += snprintf(out, LEFT, "y[%lu] is set\n", UL(it - y.begin()));
432
+ }
433
+ out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y.num_nonempty()));
434
+
435
+ out += snprintf(out, LEFT, "Starting from y[32]...\n");
436
+ for ( sparsetable<string>::const_nonempty_iterator it = y.get_iter(32);
437
+ it != y.nonempty_end(); ++it )
438
+ out += snprintf(out, LEFT, "y[??] = %s\n", it->c_str());
439
+
440
+ out += snprintf(out, LEFT, "From y[32] down...\n");
441
+ for ( sparsetable<string>::nonempty_iterator it = y.get_iter(32);
442
+ it != y.nonempty_begin(); )
443
+ out += snprintf(out, LEFT, "y[??] = %s\n", (*--it).c_str());
444
+ }
445
+
446
+ // The expected output from all of the above: TestInt() and TestString()
447
+ static const char g_expected[] = (
448
+ "int test\n"
449
+ "x[0]: 0\n"
450
+ "x[1]: 0\n"
451
+ "x[2]: 0\n"
452
+ "x[3]: 0\n"
453
+ "x[4]: 10\n"
454
+ "x[5]: 0\n"
455
+ "x[6]: 0\n"
456
+ "x[0]: 0\n"
457
+ "x[1]: 0\n"
458
+ "x[2]: 0\n"
459
+ "x[3]: 0\n"
460
+ "x[4]: 10\n"
461
+ "x[5]: 0\n"
462
+ "x[6]: 0\n"
463
+ "x[6]: 0\n"
464
+ "x[5]: 0\n"
465
+ "x[4]: 10\n"
466
+ "x[3]: 0\n"
467
+ "x[2]: 0\n"
468
+ "x[1]: 0\n"
469
+ "x[0]: 0\n"
470
+ "x[6]: 0\n"
471
+ "x[5]: 0\n"
472
+ "x[4]: 10\n"
473
+ "x[3]: 0\n"
474
+ "x[2]: 0\n"
475
+ "x[1]: 0\n"
476
+ "x[0]: 0\n"
477
+ "x[3]: 0\n"
478
+ "x[4]: 10\n"
479
+ "x[5]: 0\n"
480
+ "x[4]: 10\n"
481
+ "x[4]: 10\n"
482
+ "x[3]: 0\n"
483
+ "x[4]: 10\n"
484
+ "x[5]: 55\n"
485
+ "x[5]: 55\n"
486
+ "x[6]: 66\n"
487
+ "it == it? yes\n"
488
+ "!(it != it)? yes\n"
489
+ "!(it < it)? yes\n"
490
+ "!(it > it)? yes\n"
491
+ "it <= it? yes\n"
492
+ "it >= it? yes\n"
493
+ "!(it == it_minus_1)? yes\n"
494
+ "it != it_minus_1? yes\n"
495
+ "!(it < it_minus_1)? yes\n"
496
+ "it > it_minus_1? yes\n"
497
+ "!(it <= it_minus_1)? yes\n"
498
+ "it >= it_minus_1? yes\n"
499
+ "!(it_minus_1 == it)? yes\n"
500
+ "it_minus_1 != it? yes\n"
501
+ "it_minus_1 < it? yes\n"
502
+ "!(it_minus_1 > it)? yes\n"
503
+ "it_minus_1 <= it? yes\n"
504
+ "!(it_minus_1 >= it)? yes\n"
505
+ "!(it == it_plus_1)? yes\n"
506
+ "it != it_plus_1? yes\n"
507
+ "it < it_plus_1? yes\n"
508
+ "!(it > it_plus_1)? yes\n"
509
+ "it <= it_plus_1? yes\n"
510
+ "!(it >= it_plus_1)? yes\n"
511
+ "!(it_plus_1 == it)? yes\n"
512
+ "it_plus_1 != it? yes\n"
513
+ "!(it_plus_1 < it)? yes\n"
514
+ "it_plus_1 > it? yes\n"
515
+ "!(it_plus_1 <= it)? yes\n"
516
+ "it_plus_1 >= it? yes\n"
517
+ "x[4]: 10\n"
518
+ "x[4]: 10\n"
519
+ "x[3]: 0\n"
520
+ "x[4]: 10\n"
521
+ "x[5]: 55\n"
522
+ "x[6]: 66\n"
523
+ "it == it? yes\n"
524
+ "!(it != it)? yes\n"
525
+ "!(it < it)? yes\n"
526
+ "!(it > it)? yes\n"
527
+ "it <= it? yes\n"
528
+ "it >= it? yes\n"
529
+ "!(it == it_minus_1)? yes\n"
530
+ "it != it_minus_1? yes\n"
531
+ "!(it < it_minus_1)? yes\n"
532
+ "it > it_minus_1? yes\n"
533
+ "!(it <= it_minus_1)? yes\n"
534
+ "it >= it_minus_1? yes\n"
535
+ "!(it_minus_1 == it)? yes\n"
536
+ "it_minus_1 != it? yes\n"
537
+ "it_minus_1 < it? yes\n"
538
+ "!(it_minus_1 > it)? yes\n"
539
+ "it_minus_1 <= it? yes\n"
540
+ "!(it_minus_1 >= it)? yes\n"
541
+ "!(it == it_plus_1)? yes\n"
542
+ "it != it_plus_1? yes\n"
543
+ "it < it_plus_1? yes\n"
544
+ "!(it > it_plus_1)? yes\n"
545
+ "it <= it_plus_1? yes\n"
546
+ "!(it >= it_plus_1)? yes\n"
547
+ "!(it_plus_1 == it)? yes\n"
548
+ "it_plus_1 != it? yes\n"
549
+ "!(it_plus_1 < it)? yes\n"
550
+ "it_plus_1 > it? yes\n"
551
+ "!(it_plus_1 <= it)? yes\n"
552
+ "it_plus_1 >= it? yes\n"
553
+ "x.begin() == x.begin() + 1 - 1? yes\n"
554
+ "x.begin() < x.end()? yes\n"
555
+ "z.begin() < z.end()? no\n"
556
+ "z.begin() <= z.end()? yes\n"
557
+ "z.begin() == z.end()? yes\n"
558
+ "x[??]: 10\n"
559
+ "x[??]: 55\n"
560
+ "x[??]: 66\n"
561
+ "y[??]: -12\n"
562
+ "y[??]: -47\n"
563
+ "y[??]: -48\n"
564
+ "y[??]: -49\n"
565
+ "y[??]: -49\n"
566
+ "y[??]: -48\n"
567
+ "y[??]: -47\n"
568
+ "y[??]: -12\n"
569
+ "y[??]: -49\n"
570
+ "y[??]: -48\n"
571
+ "y[??]: -47\n"
572
+ "y[??]: -12\n"
573
+ "first non-empty y: -12\n"
574
+ "first non-empty x: 10\n"
575
+ "first non-empty x: 10\n"
576
+ "first non-empty x: 10\n"
577
+ "first non-empty y: -12\n"
578
+ "first non-empty x: 10\n"
579
+ "first non-empty x: 10\n"
580
+ "first non-empty x: 10\n"
581
+ "x.begin() == x.begin() + 1 - 1? yes\n"
582
+ "z.begin() != z.end()? no\n"
583
+ "x has 3/7 buckets, y 4/70, z 0/0\n"
584
+ "y shrank and grew: it's now 2/70\n"
585
+ "y[12] = -12, y.get(12) = -12\n"
586
+ "y[12] cleared. y now 1/70. y[12] = 0, y.get(12) = 0\n"
587
+ "y == z? no\n"
588
+ "y[10] is set\n"
589
+ "y[11] is set\n"
590
+ "y[13] is set\n"
591
+ "y[14] is set\n"
592
+ "y[30] is set\n"
593
+ "y[31] is set\n"
594
+ "y[32] is set\n"
595
+ "y[33] is set\n"
596
+ "y[35] is set\n"
597
+ "y[36] is set\n"
598
+ "y[37] is set\n"
599
+ "y[9898] is set\n"
600
+ "That's 12 set buckets\n"
601
+ "Starting from y[32]...\n"
602
+ "y[??] = -32\n"
603
+ "y[??] = -33\n"
604
+ "y[??] = -35\n"
605
+ "y[??] = -36\n"
606
+ "y[??] = -37\n"
607
+ "y[??] = -9898\n"
608
+ "From y[32] down...\n"
609
+ "y[??] = -31\n"
610
+ "y[??] = -30\n"
611
+ "y[??] = -14\n"
612
+ "y[??] = -13\n"
613
+ "y[??] = -11\n"
614
+ "y[??] = -10\n"
615
+ "y2[10] is -10\n"
616
+ "y2[11] is -11\n"
617
+ "y2[13] is -13\n"
618
+ "y2[14] is -14\n"
619
+ "y2[30] is -30\n"
620
+ "y2[31] is -31\n"
621
+ "y2[32] is -32\n"
622
+ "y2[33] is -33\n"
623
+ "y2[35] is -35\n"
624
+ "y2[36] is -36\n"
625
+ "y2[37] is -37\n"
626
+ "y2[9898] is -9898\n"
627
+ "That's 12 set buckets\n"
628
+ "string test\n"
629
+ "x[0]: \n"
630
+ "x[1]: \n"
631
+ "x[2]: \n"
632
+ "x[3]: \n"
633
+ "x[4]: foo\n"
634
+ "x[5]: \n"
635
+ "x[6]: \n"
636
+ "x.begin() == x.begin() + 1 - 1? yes\n"
637
+ "x.begin() < x.end()? yes\n"
638
+ "z.begin() < z.end()? no\n"
639
+ "z.begin() <= z.end()? yes\n"
640
+ "z.begin() == z.end()? yes\n"
641
+ "x[??]: foo\n"
642
+ "y[??]: orange\n"
643
+ "y[??]: grape\n"
644
+ "y[??]: pear\n"
645
+ "y[??]: apple\n"
646
+ "x has 1/7 buckets, y 4/70, z 0/0\n"
647
+ "y shrank and grew: it's now 2/70\n"
648
+ "y[12] = orange, y.get(12) = orange\n"
649
+ "y[12] cleared. y now 1/70. y[12] = , y.get(12) = \n"
650
+ "y == z? no\n"
651
+ "y[10] is set\n"
652
+ "y[11] is set\n"
653
+ "y[13] is set\n"
654
+ "y[14] is set\n"
655
+ "y[30] is set\n"
656
+ "y[31] is set\n"
657
+ "y[32] is set\n"
658
+ "y[33] is set\n"
659
+ "y[35] is set\n"
660
+ "y[36] is set\n"
661
+ "y[37] is set\n"
662
+ "y[9898] is set\n"
663
+ "That's 12 set buckets\n"
664
+ "Starting from y[32]...\n"
665
+ "y[??] = -32\n"
666
+ "y[??] = -33\n"
667
+ "y[??] = -35\n"
668
+ "y[??] = -36\n"
669
+ "y[??] = -37\n"
670
+ "y[??] = -9898\n"
671
+ "From y[32] down...\n"
672
+ "y[??] = -31\n"
673
+ "y[??] = -30\n"
674
+ "y[??] = -14\n"
675
+ "y[??] = -13\n"
676
+ "y[??] = -11\n"
677
+ "y[??] = -10\n"
678
+ );
679
+
680
+ // defined at bottom of file for ease of maintainence
681
+ int main(int argc, char **argv) { // though we ignore the args
682
+ TestInt();
683
+ TestString();
684
+
685
+ // Finally, check to see if our output (in out) is what it's supposed to be.
686
+ const size_t r = sizeof(g_expected) - 1;
687
+ if ( r != out - outbuf || // output not the same size
688
+ memcmp(outbuf, g_expected, r) ) { // or bytes differed
689
+ fprintf(stderr, "TESTS FAILED\n\nEXPECTED:\n\n%s\n\nACTUAL:\n\n%s\n\n",
690
+ g_expected, outbuf);
691
+ return 1;
692
+ } else {
693
+ printf("PASS.\n");
694
+ return 0;
695
+ }
696
+ }