google_hash 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }