usearch 1.1.1 → 1.2.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.
- package/.github/workflows/prerelease.yml +3 -3
- package/.github/workflows/release.yml +3 -3
- package/.github/workflows/update_version.sh +1 -1
- package/.gitmodules +1 -4
- package/Cargo.toml +1 -1
- package/Package.swift +2 -1
- package/README.md +86 -42
- package/binding.gyp +16 -12
- package/build.gradle +1 -1
- package/build.rs +0 -1
- package/c/CMakeLists.txt +11 -7
- package/c/lib.cpp +36 -24
- package/c/usearch.h +42 -12
- package/cluster.ipynb +167 -0
- package/conanfile.py +1 -1
- package/cpp/CMakeLists.txt +8 -3
- package/cpp/bench.cpp +2 -2
- package/cpp/test.cpp +42 -25
- package/docs/benchmarks.md +8 -0
- package/docs/compilation.md +7 -7
- package/docs/conf.py +27 -24
- package/docs/javascript/reference.rst +3 -0
- package/golang/README.md +31 -7
- package/golang/lib.go +1 -1
- package/include/usearch/index.hpp +348 -69
- package/include/usearch/index_dense.hpp +587 -179
- package/include/usearch/index_plugins.hpp +194 -16
- package/java/cloud/unum/usearch/Index.java +13 -0
- package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +40 -9
- package/java/cloud/unum/usearch/cloud_unum_usearch_Index.h +16 -0
- package/javascript/docs.js +111 -0
- package/javascript/lib.cpp +29 -9
- package/javascript/usearch.d.ts +9 -1
- package/objc/USearchObjective.mm +11 -11
- package/package.json +2 -2
- package/pyproject.toml +1 -1
- package/python/lib.cpp +488 -158
- package/python/scripts/index_faiss.py +3 -3
- package/python/scripts/join.py +6 -6
- package/python/scripts/test_index.py +219 -0
- package/python/scripts/test_sparse.py +21 -21
- package/python/scripts/test_tooling.py +111 -0
- package/python/usearch/eval.py +9 -5
- package/python/usearch/index.py +491 -216
- package/rust/lib.cpp +6 -24
- package/rust/lib.hpp +1 -3
- package/rust/lib.rs +89 -0
- package/setup.py +5 -6
- package/wasm/CMakeLists.txt +0 -1
- package/wasmer.toml +1 -1
- package/python/scripts/test.py +0 -364
- package/robin-map/.codecov.yml +0 -5
- package/robin-map/.github/workflows/ci.yml +0 -136
- package/robin-map/CMakeLists.txt +0 -86
- package/robin-map/LICENSE +0 -21
- package/robin-map/README.md +0 -483
- package/robin-map/cmake/tsl-robin-mapConfig.cmake.in +0 -9
- package/robin-map/doxygen.conf +0 -2483
- package/robin-map/include/tsl/robin_growth_policy.h +0 -406
- package/robin-map/include/tsl/robin_hash.h +0 -1639
- package/robin-map/include/tsl/robin_map.h +0 -807
- package/robin-map/include/tsl/robin_set.h +0 -660
- package/robin-map/tests/CMakeLists.txt +0 -26
- package/robin-map/tests/custom_allocator_tests.cpp +0 -138
- package/robin-map/tests/main.cpp +0 -26
- package/robin-map/tests/policy_tests.cpp +0 -97
- package/robin-map/tests/robin_map_tests.cpp +0 -1451
- package/robin-map/tests/robin_set_tests.cpp +0 -164
- package/robin-map/tests/utils.h +0 -443
- package/robin-map/tsl-robin-map.natvis +0 -78
|
@@ -1,1451 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MIT License
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
|
|
5
|
-
*
|
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
* furnished to do so, subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be included in
|
|
14
|
-
* all copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
* SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
#include <tsl/robin_map.h>
|
|
25
|
-
|
|
26
|
-
#include <boost/mpl/list.hpp>
|
|
27
|
-
#include <boost/test/unit_test.hpp>
|
|
28
|
-
#include <cstddef>
|
|
29
|
-
#include <cstdint>
|
|
30
|
-
#include <functional>
|
|
31
|
-
#include <iterator>
|
|
32
|
-
#include <memory>
|
|
33
|
-
#include <stdexcept>
|
|
34
|
-
#include <string>
|
|
35
|
-
#include <tuple>
|
|
36
|
-
#include <type_traits>
|
|
37
|
-
#include <utility>
|
|
38
|
-
#include <vector>
|
|
39
|
-
|
|
40
|
-
#include "utils.h"
|
|
41
|
-
|
|
42
|
-
BOOST_AUTO_TEST_SUITE(test_robin_map)
|
|
43
|
-
|
|
44
|
-
using test_types = boost::mpl::list<
|
|
45
|
-
tsl::robin_map<std::int64_t, std::int64_t>,
|
|
46
|
-
tsl::robin_map<std::string, std::string>,
|
|
47
|
-
// Test with hash having a lot of collisions
|
|
48
|
-
tsl::robin_map<std::int64_t, std::int64_t, mod_hash<9>>,
|
|
49
|
-
tsl::robin_map<std::string, std::string, mod_hash<9>>,
|
|
50
|
-
tsl::robin_map<move_only_test, move_only_test, mod_hash<9>>,
|
|
51
|
-
tsl::robin_map<copy_only_test, copy_only_test, mod_hash<9>>,
|
|
52
|
-
tsl::robin_map<self_reference_member_test, self_reference_member_test,
|
|
53
|
-
mod_hash<9>>,
|
|
54
|
-
|
|
55
|
-
// other GrowthPolicy
|
|
56
|
-
tsl::robin_map<move_only_test, move_only_test, mod_hash<9>,
|
|
57
|
-
std::equal_to<move_only_test>,
|
|
58
|
-
std::allocator<std::pair<move_only_test, move_only_test>>,
|
|
59
|
-
true, tsl::rh::power_of_two_growth_policy<4>>,
|
|
60
|
-
tsl::robin_pg_map<move_only_test, move_only_test, mod_hash<9>>,
|
|
61
|
-
tsl::robin_map<move_only_test, move_only_test, mod_hash<9>,
|
|
62
|
-
std::equal_to<move_only_test>,
|
|
63
|
-
std::allocator<std::pair<move_only_test, move_only_test>>,
|
|
64
|
-
false, tsl::rh::mod_growth_policy<>>,
|
|
65
|
-
|
|
66
|
-
tsl::robin_map<copy_only_test, copy_only_test, mod_hash<9>,
|
|
67
|
-
std::equal_to<copy_only_test>,
|
|
68
|
-
std::allocator<std::pair<copy_only_test, copy_only_test>>,
|
|
69
|
-
false, tsl::rh::power_of_two_growth_policy<4>>,
|
|
70
|
-
tsl::robin_pg_map<copy_only_test, copy_only_test, mod_hash<9>>,
|
|
71
|
-
tsl::robin_map<copy_only_test, copy_only_test, mod_hash<9>,
|
|
72
|
-
std::equal_to<copy_only_test>,
|
|
73
|
-
std::allocator<std::pair<copy_only_test, copy_only_test>>,
|
|
74
|
-
true, tsl::rh::mod_growth_policy<>>>;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* insert
|
|
78
|
-
*/
|
|
79
|
-
BOOST_AUTO_TEST_CASE_TEMPLATE(test_insert, HMap, test_types) {
|
|
80
|
-
// insert x values, insert them again, check values
|
|
81
|
-
using key_t = typename HMap::key_type;
|
|
82
|
-
using value_t = typename HMap::mapped_type;
|
|
83
|
-
|
|
84
|
-
const std::size_t nb_values = 1000;
|
|
85
|
-
HMap map(0);
|
|
86
|
-
BOOST_CHECK_EQUAL(map.bucket_count(), 0);
|
|
87
|
-
|
|
88
|
-
typename HMap::iterator it;
|
|
89
|
-
bool inserted;
|
|
90
|
-
|
|
91
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
92
|
-
std::tie(it, inserted) =
|
|
93
|
-
map.insert({utils::get_key<key_t>(i), utils::get_value<value_t>(i)});
|
|
94
|
-
|
|
95
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
|
|
96
|
-
BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
|
|
97
|
-
BOOST_CHECK(inserted);
|
|
98
|
-
}
|
|
99
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
100
|
-
|
|
101
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
102
|
-
std::tie(it, inserted) = map.insert(
|
|
103
|
-
{utils::get_key<key_t>(i), utils::get_value<value_t>(i + 1)});
|
|
104
|
-
|
|
105
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
|
|
106
|
-
BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
|
|
107
|
-
BOOST_CHECK(!inserted);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
111
|
-
it = map.find(utils::get_key<key_t>(i));
|
|
112
|
-
|
|
113
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
|
|
114
|
-
BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
BOOST_AUTO_TEST_CASE(test_range_insert) {
|
|
119
|
-
// create a vector<std::pair> of values to insert, insert part of them in the
|
|
120
|
-
// map, check values
|
|
121
|
-
const int nb_values = 1000;
|
|
122
|
-
std::vector<std::pair<int, int>> values_to_insert(nb_values);
|
|
123
|
-
for (int i = 0; i < nb_values; i++) {
|
|
124
|
-
values_to_insert[i] = std::make_pair(i, i + 1);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
tsl::robin_map<int, int> map = {{-1, 1}, {-2, 2}};
|
|
128
|
-
map.insert(std::next(values_to_insert.begin(), 10),
|
|
129
|
-
values_to_insert.end() - 5);
|
|
130
|
-
|
|
131
|
-
BOOST_CHECK_EQUAL(map.size(), 987);
|
|
132
|
-
|
|
133
|
-
BOOST_CHECK_EQUAL(map.at(-1), 1);
|
|
134
|
-
BOOST_CHECK_EQUAL(map.at(-2), 2);
|
|
135
|
-
|
|
136
|
-
for (int i = 10; i < nb_values - 5; i++) {
|
|
137
|
-
BOOST_CHECK_EQUAL(map.at(i), i + 1);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
BOOST_AUTO_TEST_CASE(test_rehash_0) {
|
|
142
|
-
tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
|
|
143
|
-
std::allocator<std::pair<int, int>>, true>
|
|
144
|
-
map;
|
|
145
|
-
map.rehash(0);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
BOOST_AUTO_TEST_CASE(test_insert_with_hint) {
|
|
149
|
-
tsl::robin_map<int, int> map{{1, 0}, {2, 1}, {3, 2}};
|
|
150
|
-
|
|
151
|
-
// Wrong hint
|
|
152
|
-
BOOST_CHECK(map.insert(map.find(2), std::make_pair(3, 4)) == map.find(3));
|
|
153
|
-
|
|
154
|
-
// Good hint
|
|
155
|
-
BOOST_CHECK(map.insert(map.find(2), std::make_pair(2, 4)) == map.find(2));
|
|
156
|
-
|
|
157
|
-
// end() hint
|
|
158
|
-
BOOST_CHECK(map.insert(map.find(10), std::make_pair(2, 4)) == map.find(2));
|
|
159
|
-
|
|
160
|
-
BOOST_CHECK_EQUAL(map.size(), 3);
|
|
161
|
-
|
|
162
|
-
// end() hint, new value
|
|
163
|
-
BOOST_CHECK_EQUAL(map.insert(map.find(10), std::make_pair(4, 3))->first, 4);
|
|
164
|
-
|
|
165
|
-
// Wrong hint, new value
|
|
166
|
-
BOOST_CHECK_EQUAL(map.insert(map.find(2), std::make_pair(5, 4))->first, 5);
|
|
167
|
-
|
|
168
|
-
BOOST_CHECK_EQUAL(map.size(), 5);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* emplace_hint
|
|
173
|
-
*/
|
|
174
|
-
BOOST_AUTO_TEST_CASE(test_emplace_hint) {
|
|
175
|
-
tsl::robin_map<int, int> map{{1, 0}, {2, 1}, {3, 2}};
|
|
176
|
-
|
|
177
|
-
// Wrong hint
|
|
178
|
-
BOOST_CHECK(map.emplace_hint(map.find(2), std::piecewise_construct,
|
|
179
|
-
std::forward_as_tuple(3),
|
|
180
|
-
std::forward_as_tuple(4)) == map.find(3));
|
|
181
|
-
|
|
182
|
-
// Good hint
|
|
183
|
-
BOOST_CHECK(map.emplace_hint(map.find(2), std::piecewise_construct,
|
|
184
|
-
std::forward_as_tuple(2),
|
|
185
|
-
std::forward_as_tuple(4)) == map.find(2));
|
|
186
|
-
|
|
187
|
-
// end() hint
|
|
188
|
-
BOOST_CHECK(map.emplace_hint(map.find(10), std::piecewise_construct,
|
|
189
|
-
std::forward_as_tuple(2),
|
|
190
|
-
std::forward_as_tuple(4)) == map.find(2));
|
|
191
|
-
|
|
192
|
-
BOOST_CHECK_EQUAL(map.size(), 3);
|
|
193
|
-
|
|
194
|
-
// end() hint, new value
|
|
195
|
-
BOOST_CHECK_EQUAL(
|
|
196
|
-
map.emplace_hint(map.find(10), std::piecewise_construct,
|
|
197
|
-
std::forward_as_tuple(4), std::forward_as_tuple(3))
|
|
198
|
-
->first,
|
|
199
|
-
4);
|
|
200
|
-
|
|
201
|
-
// Wrong hint, new value
|
|
202
|
-
BOOST_CHECK_EQUAL(
|
|
203
|
-
map.emplace_hint(map.find(2), std::piecewise_construct,
|
|
204
|
-
std::forward_as_tuple(5), std::forward_as_tuple(4))
|
|
205
|
-
->first,
|
|
206
|
-
5);
|
|
207
|
-
|
|
208
|
-
BOOST_CHECK_EQUAL(map.size(), 5);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* emplace
|
|
213
|
-
*/
|
|
214
|
-
BOOST_AUTO_TEST_CASE(test_emplace) {
|
|
215
|
-
tsl::robin_map<std::int64_t, move_only_test> map;
|
|
216
|
-
tsl::robin_map<std::int64_t, move_only_test>::iterator it;
|
|
217
|
-
bool inserted;
|
|
218
|
-
|
|
219
|
-
std::tie(it, inserted) =
|
|
220
|
-
map.emplace(std::piecewise_construct, std::forward_as_tuple(10),
|
|
221
|
-
std::forward_as_tuple(1));
|
|
222
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
223
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
224
|
-
BOOST_CHECK(inserted);
|
|
225
|
-
|
|
226
|
-
std::tie(it, inserted) =
|
|
227
|
-
map.emplace(std::piecewise_construct, std::forward_as_tuple(10),
|
|
228
|
-
std::forward_as_tuple(3));
|
|
229
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
230
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
231
|
-
BOOST_CHECK(!inserted);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* try_emplace
|
|
236
|
-
*/
|
|
237
|
-
BOOST_AUTO_TEST_CASE(test_try_emplace) {
|
|
238
|
-
tsl::robin_map<std::int64_t, move_only_test> map;
|
|
239
|
-
tsl::robin_map<std::int64_t, move_only_test>::iterator it;
|
|
240
|
-
bool inserted;
|
|
241
|
-
|
|
242
|
-
std::tie(it, inserted) = map.try_emplace(10, 1);
|
|
243
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
244
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
245
|
-
BOOST_CHECK(inserted);
|
|
246
|
-
|
|
247
|
-
std::tie(it, inserted) = map.try_emplace(10, 3);
|
|
248
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
249
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
250
|
-
BOOST_CHECK(!inserted);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
BOOST_AUTO_TEST_CASE(test_try_emplace_2) {
|
|
254
|
-
// Insert x values with try_emplace, insert them again, check with find.
|
|
255
|
-
tsl::robin_map<std::string, move_only_test> map;
|
|
256
|
-
tsl::robin_map<std::string, move_only_test>::iterator it;
|
|
257
|
-
bool inserted;
|
|
258
|
-
|
|
259
|
-
const std::size_t nb_values = 1000;
|
|
260
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
261
|
-
std::tie(it, inserted) = map.try_emplace(utils::get_key<std::string>(i), i);
|
|
262
|
-
|
|
263
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<std::string>(i));
|
|
264
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(i));
|
|
265
|
-
BOOST_CHECK(inserted);
|
|
266
|
-
}
|
|
267
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
268
|
-
|
|
269
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
270
|
-
std::tie(it, inserted) =
|
|
271
|
-
map.try_emplace(utils::get_key<std::string>(i), i + 1);
|
|
272
|
-
|
|
273
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<std::string>(i));
|
|
274
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(i));
|
|
275
|
-
BOOST_CHECK(!inserted);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
279
|
-
it = map.find(utils::get_key<std::string>(i));
|
|
280
|
-
|
|
281
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<std::string>(i));
|
|
282
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(i));
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
BOOST_AUTO_TEST_CASE(test_try_emplace_hint) {
|
|
287
|
-
tsl::robin_map<std::int64_t, move_only_test> map(0);
|
|
288
|
-
|
|
289
|
-
// end() hint, new value
|
|
290
|
-
auto it = map.try_emplace(map.find(10), 10, 1);
|
|
291
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
292
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
293
|
-
|
|
294
|
-
// Good hint
|
|
295
|
-
it = map.try_emplace(map.find(10), 10, 3);
|
|
296
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
297
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
298
|
-
|
|
299
|
-
// Wrong hint, new value
|
|
300
|
-
it = map.try_emplace(map.find(10), 1, 3);
|
|
301
|
-
BOOST_CHECK_EQUAL(it->first, 1);
|
|
302
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(3));
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* insert_or_assign
|
|
307
|
-
*/
|
|
308
|
-
BOOST_AUTO_TEST_CASE(test_insert_or_assign) {
|
|
309
|
-
tsl::robin_map<std::int64_t, move_only_test> map;
|
|
310
|
-
tsl::robin_map<std::int64_t, move_only_test>::iterator it;
|
|
311
|
-
bool inserted;
|
|
312
|
-
|
|
313
|
-
std::tie(it, inserted) = map.insert_or_assign(10, move_only_test(1));
|
|
314
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
315
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
316
|
-
BOOST_CHECK(inserted);
|
|
317
|
-
|
|
318
|
-
std::tie(it, inserted) = map.insert_or_assign(10, move_only_test(3));
|
|
319
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
320
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(3));
|
|
321
|
-
BOOST_CHECK(!inserted);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
BOOST_AUTO_TEST_CASE(test_insert_or_assign_hint) {
|
|
325
|
-
tsl::robin_map<std::int64_t, move_only_test> map(0);
|
|
326
|
-
|
|
327
|
-
// end() hint, new value
|
|
328
|
-
auto it = map.insert_or_assign(map.find(10), 10, move_only_test(1));
|
|
329
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
330
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(1));
|
|
331
|
-
|
|
332
|
-
// Good hint
|
|
333
|
-
it = map.insert_or_assign(map.find(10), 10, move_only_test(3));
|
|
334
|
-
BOOST_CHECK_EQUAL(it->first, 10);
|
|
335
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(3));
|
|
336
|
-
|
|
337
|
-
// Bad hint, new value
|
|
338
|
-
it = map.insert_or_assign(map.find(10), 1, move_only_test(3));
|
|
339
|
-
BOOST_CHECK_EQUAL(it->first, 1);
|
|
340
|
-
BOOST_CHECK_EQUAL(it->second, move_only_test(3));
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* erase
|
|
345
|
-
*/
|
|
346
|
-
BOOST_AUTO_TEST_CASE(test_range_erase_all) {
|
|
347
|
-
// insert x values, delete all with iterators
|
|
348
|
-
using HMap = tsl::robin_map<std::string, std::int64_t>;
|
|
349
|
-
|
|
350
|
-
const std::size_t nb_values = 1000;
|
|
351
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
352
|
-
|
|
353
|
-
auto it = map.erase(map.begin(), map.end());
|
|
354
|
-
BOOST_CHECK(it == map.end());
|
|
355
|
-
BOOST_CHECK(map.empty());
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
BOOST_AUTO_TEST_CASE(test_range_erase) {
|
|
359
|
-
// insert x values, delete all with iterators except 10 first and 780 last
|
|
360
|
-
// values
|
|
361
|
-
using HMap = tsl::robin_map<std::string, std::int64_t>;
|
|
362
|
-
|
|
363
|
-
const std::size_t nb_values = 1000;
|
|
364
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
365
|
-
|
|
366
|
-
auto it_first = std::next(map.begin(), 10);
|
|
367
|
-
auto it_last = std::next(map.begin(), 220);
|
|
368
|
-
|
|
369
|
-
auto it = map.erase(it_first, it_last);
|
|
370
|
-
BOOST_CHECK_EQUAL(std::distance(it, map.end()), 780);
|
|
371
|
-
BOOST_CHECK_EQUAL(map.size(), 790);
|
|
372
|
-
BOOST_CHECK_EQUAL(std::distance(map.begin(), map.end()), 790);
|
|
373
|
-
|
|
374
|
-
for (auto& val : map) {
|
|
375
|
-
BOOST_CHECK_EQUAL(map.count(val.first), 1);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
BOOST_AUTO_TEST_CASE_TEMPLATE(test_erase_loop, HMap, test_types) {
|
|
380
|
-
// insert x values, delete all one by one with iterator
|
|
381
|
-
std::size_t nb_values = 1000;
|
|
382
|
-
|
|
383
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
384
|
-
HMap map2 = utils::get_filled_hash_map<HMap>(nb_values);
|
|
385
|
-
|
|
386
|
-
auto it = map.begin();
|
|
387
|
-
// Use second map to check for key after delete as we may not copy the key
|
|
388
|
-
// with move-only types.
|
|
389
|
-
auto it2 = map2.begin();
|
|
390
|
-
while (it != map.end()) {
|
|
391
|
-
it = map.erase(it);
|
|
392
|
-
--nb_values;
|
|
393
|
-
|
|
394
|
-
BOOST_CHECK_EQUAL(map.count(it2->first), 0);
|
|
395
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
396
|
-
++it2;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
BOOST_CHECK(map.empty());
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
BOOST_AUTO_TEST_CASE_TEMPLATE(test_erase_loop_range, HMap, test_types) {
|
|
403
|
-
// insert x values, delete all five by five with iterators
|
|
404
|
-
const std::size_t hop = 5;
|
|
405
|
-
std::size_t nb_values = 1000;
|
|
406
|
-
|
|
407
|
-
BOOST_REQUIRE_EQUAL(nb_values % hop, 0);
|
|
408
|
-
|
|
409
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
410
|
-
|
|
411
|
-
auto it = map.begin();
|
|
412
|
-
while (it != map.end()) {
|
|
413
|
-
it = map.erase(it, std::next(it, hop));
|
|
414
|
-
nb_values -= hop;
|
|
415
|
-
|
|
416
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
BOOST_CHECK(map.empty());
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
BOOST_AUTO_TEST_CASE_TEMPLATE(test_insert_erase_insert, HMap, test_types) {
|
|
423
|
-
// insert x/2 values, delete x/4 values, insert x/2 values, find each value
|
|
424
|
-
using key_t = typename HMap::key_type;
|
|
425
|
-
using value_t = typename HMap::mapped_type;
|
|
426
|
-
|
|
427
|
-
const std::size_t nb_values = 2000;
|
|
428
|
-
HMap map(10);
|
|
429
|
-
typename HMap::iterator it;
|
|
430
|
-
bool inserted;
|
|
431
|
-
|
|
432
|
-
// Insert nb_values/2
|
|
433
|
-
for (std::size_t i = 0; i < nb_values / 2; i++) {
|
|
434
|
-
std::tie(it, inserted) =
|
|
435
|
-
map.insert({utils::get_key<key_t>(i), utils::get_value<value_t>(i)});
|
|
436
|
-
|
|
437
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
|
|
438
|
-
BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
|
|
439
|
-
BOOST_CHECK(inserted);
|
|
440
|
-
}
|
|
441
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values / 2);
|
|
442
|
-
|
|
443
|
-
// Delete nb_values/4
|
|
444
|
-
for (std::size_t i = 0; i < nb_values / 2; i++) {
|
|
445
|
-
if (i % 2 == 0) {
|
|
446
|
-
BOOST_CHECK_EQUAL(map.erase(utils::get_key<key_t>(i)), 1);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values / 4);
|
|
450
|
-
|
|
451
|
-
// Insert nb_values/2
|
|
452
|
-
for (std::size_t i = nb_values / 2; i < nb_values; i++) {
|
|
453
|
-
std::tie(it, inserted) =
|
|
454
|
-
map.insert({utils::get_key<key_t>(i), utils::get_value<value_t>(i)});
|
|
455
|
-
|
|
456
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
|
|
457
|
-
BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
|
|
458
|
-
BOOST_CHECK(inserted);
|
|
459
|
-
}
|
|
460
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values - nb_values / 4);
|
|
461
|
-
|
|
462
|
-
// Find
|
|
463
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
464
|
-
if (i % 2 == 0 && i < nb_values / 2) {
|
|
465
|
-
it = map.find(utils::get_key<key_t>(i));
|
|
466
|
-
|
|
467
|
-
BOOST_CHECK(it == map.end());
|
|
468
|
-
} else {
|
|
469
|
-
it = map.find(utils::get_key<key_t>(i));
|
|
470
|
-
|
|
471
|
-
BOOST_REQUIRE(it != map.end());
|
|
472
|
-
BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
|
|
473
|
-
BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
BOOST_AUTO_TEST_CASE(test_range_erase_same_iterators) {
|
|
479
|
-
// insert x values, test erase with same iterator as each parameter, check if
|
|
480
|
-
// returned mutable iterator is valid.
|
|
481
|
-
const std::size_t nb_values = 100;
|
|
482
|
-
auto map =
|
|
483
|
-
utils::get_filled_hash_map<tsl::robin_map<std::int64_t, std::int64_t>>(
|
|
484
|
-
nb_values);
|
|
485
|
-
|
|
486
|
-
tsl::robin_map<std::int64_t, std::int64_t>::const_iterator it_const =
|
|
487
|
-
map.cbegin();
|
|
488
|
-
std::advance(it_const, 10);
|
|
489
|
-
|
|
490
|
-
tsl::robin_map<std::int64_t, std::int64_t>::iterator it_mutable =
|
|
491
|
-
map.erase(it_const, it_const);
|
|
492
|
-
BOOST_CHECK(it_const == it_mutable);
|
|
493
|
-
BOOST_CHECK(map.mutable_iterator(it_const) == it_mutable);
|
|
494
|
-
BOOST_CHECK_EQUAL(map.size(), 100);
|
|
495
|
-
|
|
496
|
-
it_mutable.value() = -100;
|
|
497
|
-
BOOST_CHECK_EQUAL(it_const.value(), -100);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
* max_load_factor
|
|
502
|
-
*/
|
|
503
|
-
BOOST_AUTO_TEST_CASE(test_max_load_factor_extreme_factors) {
|
|
504
|
-
tsl::robin_map<std::int64_t, std::int64_t> map;
|
|
505
|
-
|
|
506
|
-
map.max_load_factor(0.0f);
|
|
507
|
-
BOOST_CHECK_GT(map.max_load_factor(), 0.0f);
|
|
508
|
-
|
|
509
|
-
map.max_load_factor(10.0f);
|
|
510
|
-
BOOST_CHECK_LT(map.max_load_factor(), 1.0f);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* min_load_factor
|
|
515
|
-
*/
|
|
516
|
-
BOOST_AUTO_TEST_CASE(test_min_load_factor_extreme_factors) {
|
|
517
|
-
tsl::robin_map<std::int64_t, std::int64_t> map;
|
|
518
|
-
|
|
519
|
-
BOOST_CHECK_EQUAL(map.min_load_factor(), 0.0f);
|
|
520
|
-
BOOST_CHECK_LT(map.min_load_factor(), map.max_load_factor());
|
|
521
|
-
|
|
522
|
-
map.min_load_factor(-10.0f);
|
|
523
|
-
BOOST_CHECK_EQUAL(map.min_load_factor(), 0.0f);
|
|
524
|
-
|
|
525
|
-
map.min_load_factor(0.9f);
|
|
526
|
-
map.max_load_factor(0.1f);
|
|
527
|
-
|
|
528
|
-
// max_load_factor should always be > min_load_factor.
|
|
529
|
-
// Factors should have been clamped.
|
|
530
|
-
BOOST_CHECK_LT(map.min_load_factor(), map.max_load_factor());
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
BOOST_AUTO_TEST_CASE(test_min_load_factor) {
|
|
534
|
-
// set min_load_factor to 0.15 and max_load_factor to 0.5.
|
|
535
|
-
// rehash to 100 buckets, insert 50 elements, erase until load_factor() <
|
|
536
|
-
// min_load_factor(), insert an element, check if map has shrinked.
|
|
537
|
-
const std::size_t nb_values = 50;
|
|
538
|
-
tsl::robin_map<std::int64_t, std::int64_t> map;
|
|
539
|
-
|
|
540
|
-
map.min_load_factor(0.15f);
|
|
541
|
-
BOOST_CHECK_EQUAL(map.min_load_factor(), 0.15f);
|
|
542
|
-
|
|
543
|
-
map.max_load_factor(0.5f);
|
|
544
|
-
BOOST_CHECK_EQUAL(map.max_load_factor(), 0.5f);
|
|
545
|
-
|
|
546
|
-
map.rehash(nb_values * 2);
|
|
547
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
548
|
-
map.insert(
|
|
549
|
-
{utils::get_key<std::int64_t>(i), utils::get_value<std::int64_t>(i)});
|
|
550
|
-
}
|
|
551
|
-
BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
|
|
552
|
-
|
|
553
|
-
while (map.load_factor() >= map.min_load_factor()) {
|
|
554
|
-
map.erase(map.begin());
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
// Shrink is done on insert.
|
|
558
|
-
map.insert({utils::get_key<std::int64_t>(map.bucket_count()),
|
|
559
|
-
utils::get_value<std::int64_t>(map.bucket_count())});
|
|
560
|
-
BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
BOOST_AUTO_TEST_CASE(test_min_load_factor_range_erase) {
|
|
564
|
-
// set min_load_factor to 0.15 and max_load_factor to 0.5.
|
|
565
|
-
// rehash to 100 buckets, insert 50 elements, erase 40 with range erase,
|
|
566
|
-
// insert an element, check if map has shrinked.
|
|
567
|
-
const std::size_t nb_values = 50;
|
|
568
|
-
const std::size_t nb_values_erase = 40;
|
|
569
|
-
tsl::robin_map<std::int64_t, std::int64_t> map;
|
|
570
|
-
|
|
571
|
-
map.min_load_factor(0.15f);
|
|
572
|
-
BOOST_CHECK_EQUAL(map.min_load_factor(), 0.15f);
|
|
573
|
-
|
|
574
|
-
map.max_load_factor(0.5f);
|
|
575
|
-
BOOST_CHECK_EQUAL(map.max_load_factor(), 0.5f);
|
|
576
|
-
|
|
577
|
-
map.rehash(nb_values * 2);
|
|
578
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
579
|
-
map.insert(
|
|
580
|
-
{utils::get_key<std::int64_t>(i), utils::get_value<std::int64_t>(i)});
|
|
581
|
-
}
|
|
582
|
-
BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
|
|
583
|
-
|
|
584
|
-
map.erase(std::next(map.begin(), nb_values - nb_values_erase), map.end());
|
|
585
|
-
|
|
586
|
-
// Shrink is done on insert.
|
|
587
|
-
map.insert({utils::get_key<std::int64_t>(map.bucket_count()),
|
|
588
|
-
utils::get_value<std::int64_t>(map.bucket_count())});
|
|
589
|
-
BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
|
|
590
|
-
BOOST_CHECK_LT(map.bucket_count(), nb_values * 2);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
/**
|
|
594
|
-
* rehash
|
|
595
|
-
*/
|
|
596
|
-
BOOST_AUTO_TEST_CASE(test_rehash_empty) {
|
|
597
|
-
// test rehash(0), test find/erase/insert on map.
|
|
598
|
-
const std::size_t nb_values = 100;
|
|
599
|
-
auto map =
|
|
600
|
-
utils::get_filled_hash_map<tsl::robin_map<std::int64_t, std::int64_t>>(
|
|
601
|
-
nb_values);
|
|
602
|
-
|
|
603
|
-
const std::size_t bucket_count = map.bucket_count();
|
|
604
|
-
BOOST_CHECK(bucket_count >= nb_values);
|
|
605
|
-
|
|
606
|
-
map.clear();
|
|
607
|
-
BOOST_CHECK_EQUAL(map.bucket_count(), bucket_count);
|
|
608
|
-
BOOST_CHECK(map.empty());
|
|
609
|
-
|
|
610
|
-
map.rehash(0);
|
|
611
|
-
BOOST_CHECK_EQUAL(map.bucket_count(), 0);
|
|
612
|
-
BOOST_CHECK(map.empty());
|
|
613
|
-
|
|
614
|
-
BOOST_CHECK(map.find(1) == map.end());
|
|
615
|
-
BOOST_CHECK_EQUAL(map.erase(1), 0);
|
|
616
|
-
BOOST_CHECK(map.insert({1, 10}).second);
|
|
617
|
-
BOOST_CHECK_EQUAL(map.at(1), 10);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
/**
|
|
621
|
-
* operator== and operator!=
|
|
622
|
-
*/
|
|
623
|
-
BOOST_AUTO_TEST_CASE(test_compare) {
|
|
624
|
-
const tsl::robin_map<std::string, std::int64_t> map1 = {
|
|
625
|
-
{"a", 1}, {"e", 5}, {"d", 4}, {"c", 3}, {"b", 2}};
|
|
626
|
-
const tsl::robin_map<std::string, std::int64_t> map1_copy = {
|
|
627
|
-
{"e", 5}, {"c", 3}, {"b", 2}, {"a", 1}, {"d", 4}};
|
|
628
|
-
const tsl::robin_map<std::string, std::int64_t> map2 = {
|
|
629
|
-
{"e", 5}, {"c", 3}, {"b", 2}, {"a", 1}, {"d", 4}, {"f", 6}};
|
|
630
|
-
const tsl::robin_map<std::string, std::int64_t> map3 = {
|
|
631
|
-
{"e", 5}, {"c", 3}, {"b", 2}, {"a", 1}};
|
|
632
|
-
const tsl::robin_map<std::string, std::int64_t> map4 = {
|
|
633
|
-
{"a", 1}, {"e", 5}, {"d", 4}, {"c", 3}, {"b", 26}};
|
|
634
|
-
const tsl::robin_map<std::string, std::int64_t> map5 = {
|
|
635
|
-
{"a", 1}, {"e", 5}, {"d", 4}, {"c", 3}, {"z", 2}};
|
|
636
|
-
|
|
637
|
-
BOOST_CHECK(map1 == map1_copy);
|
|
638
|
-
BOOST_CHECK(map1_copy == map1);
|
|
639
|
-
|
|
640
|
-
BOOST_CHECK(map1 != map2);
|
|
641
|
-
BOOST_CHECK(map2 != map1);
|
|
642
|
-
|
|
643
|
-
BOOST_CHECK(map1 != map3);
|
|
644
|
-
BOOST_CHECK(map3 != map1);
|
|
645
|
-
|
|
646
|
-
BOOST_CHECK(map1 != map4);
|
|
647
|
-
BOOST_CHECK(map4 != map1);
|
|
648
|
-
|
|
649
|
-
BOOST_CHECK(map1 != map5);
|
|
650
|
-
BOOST_CHECK(map5 != map1);
|
|
651
|
-
|
|
652
|
-
BOOST_CHECK(map2 != map3);
|
|
653
|
-
BOOST_CHECK(map3 != map2);
|
|
654
|
-
|
|
655
|
-
BOOST_CHECK(map2 != map4);
|
|
656
|
-
BOOST_CHECK(map4 != map2);
|
|
657
|
-
|
|
658
|
-
BOOST_CHECK(map2 != map5);
|
|
659
|
-
BOOST_CHECK(map5 != map2);
|
|
660
|
-
|
|
661
|
-
BOOST_CHECK(map3 != map4);
|
|
662
|
-
BOOST_CHECK(map4 != map3);
|
|
663
|
-
|
|
664
|
-
BOOST_CHECK(map3 != map5);
|
|
665
|
-
BOOST_CHECK(map5 != map3);
|
|
666
|
-
|
|
667
|
-
BOOST_CHECK(map4 != map5);
|
|
668
|
-
BOOST_CHECK(map5 != map4);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* clear
|
|
673
|
-
*/
|
|
674
|
-
BOOST_AUTO_TEST_CASE(test_clear) {
|
|
675
|
-
// insert x values, clear map, test insert
|
|
676
|
-
using HMap = tsl::robin_map<std::int64_t, std::int64_t>;
|
|
677
|
-
|
|
678
|
-
const std::size_t nb_values = 1000;
|
|
679
|
-
auto map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
680
|
-
|
|
681
|
-
map.clear();
|
|
682
|
-
BOOST_CHECK_EQUAL(map.size(), 0);
|
|
683
|
-
BOOST_CHECK_EQUAL(std::distance(map.begin(), map.end()), 0);
|
|
684
|
-
|
|
685
|
-
map.insert({5, -5});
|
|
686
|
-
map.insert({{1, -1}, {2, -1}, {4, -4}, {3, -3}});
|
|
687
|
-
|
|
688
|
-
BOOST_CHECK(map == (HMap({{5, -5}, {1, -1}, {2, -1}, {4, -4}, {3, -3}})));
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
BOOST_AUTO_TEST_CASE(test_clear_with_min_load_factor) {
|
|
692
|
-
// insert x values, clear map, test insert
|
|
693
|
-
using HMap = tsl::robin_map<std::int64_t, std::int64_t>;
|
|
694
|
-
|
|
695
|
-
const std::size_t nb_values = 1000;
|
|
696
|
-
auto map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
697
|
-
map.min_load_factor(0.1f);
|
|
698
|
-
|
|
699
|
-
map.clear();
|
|
700
|
-
BOOST_CHECK_EQUAL(map.bucket_count(), 0);
|
|
701
|
-
BOOST_CHECK_EQUAL(map.size(), 0);
|
|
702
|
-
BOOST_CHECK_EQUAL(std::distance(map.begin(), map.end()), 0);
|
|
703
|
-
|
|
704
|
-
map.insert({5, -5});
|
|
705
|
-
map.insert({{1, -1}, {2, -1}, {4, -4}, {3, -3}});
|
|
706
|
-
|
|
707
|
-
BOOST_CHECK(map == (HMap({{5, -5}, {1, -1}, {2, -1}, {4, -4}, {3, -3}})));
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
/**
|
|
711
|
-
* iterator.value()
|
|
712
|
-
*/
|
|
713
|
-
BOOST_AUTO_TEST_CASE(test_modify_value_through_iterator) {
|
|
714
|
-
// insert x values, modify value of even keys with iterators, check values
|
|
715
|
-
const std::size_t nb_values = 100;
|
|
716
|
-
auto map =
|
|
717
|
-
utils::get_filled_hash_map<tsl::robin_map<std::int64_t, std::int64_t>>(
|
|
718
|
-
nb_values);
|
|
719
|
-
|
|
720
|
-
for (auto it = map.begin(); it != map.end(); it++) {
|
|
721
|
-
if (it.key() % 2 == 0) {
|
|
722
|
-
it.value() = -1;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
for (auto& val : map) {
|
|
727
|
-
if (val.first % 2 == 0) {
|
|
728
|
-
BOOST_CHECK_EQUAL(val.second, -1);
|
|
729
|
-
} else {
|
|
730
|
-
BOOST_CHECK_NE(val.second, -1);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
BOOST_AUTO_TEST_CASE(test_modify_value_through_iterator_with_const_qualifier) {
|
|
736
|
-
tsl::robin_map<int, int> map = {{0, 1}};
|
|
737
|
-
const auto it = map.begin();
|
|
738
|
-
|
|
739
|
-
BOOST_CHECK_EQUAL(it->second, 1);
|
|
740
|
-
it.value() += 10;
|
|
741
|
-
BOOST_CHECK_EQUAL(it->second, 11);
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
/**
|
|
745
|
-
* constructor
|
|
746
|
-
*/
|
|
747
|
-
|
|
748
|
-
BOOST_AUTO_TEST_CASE(test_extreme_bucket_count_value_construction) {
|
|
749
|
-
// std::bad_alloc or std::length_error will be thrown depending on the
|
|
750
|
-
// platform overcommit
|
|
751
|
-
TSL_RH_CHECK_THROW_EITHER(
|
|
752
|
-
(tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
|
|
753
|
-
std::allocator<std::pair<int, int>>, false,
|
|
754
|
-
tsl::rh::power_of_two_growth_policy<2>>(
|
|
755
|
-
std::numeric_limits<std::size_t>::max())),
|
|
756
|
-
std::bad_alloc, std::length_error);
|
|
757
|
-
|
|
758
|
-
TSL_RH_CHECK_THROW_EITHER(
|
|
759
|
-
(tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
|
|
760
|
-
std::allocator<std::pair<int, int>>, false,
|
|
761
|
-
tsl::rh::power_of_two_growth_policy<2>>(
|
|
762
|
-
std::numeric_limits<std::size_t>::max() / 2 + 1)),
|
|
763
|
-
std::bad_alloc, std::length_error);
|
|
764
|
-
|
|
765
|
-
TSL_RH_CHECK_THROW_EITHER(
|
|
766
|
-
(tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
|
|
767
|
-
std::allocator<std::pair<int, int>>, false,
|
|
768
|
-
tsl::rh::prime_growth_policy>(
|
|
769
|
-
std::numeric_limits<std::size_t>::max())),
|
|
770
|
-
std::bad_alloc, std::length_error);
|
|
771
|
-
|
|
772
|
-
TSL_RH_CHECK_THROW_EITHER(
|
|
773
|
-
(tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
|
|
774
|
-
std::allocator<std::pair<int, int>>, false,
|
|
775
|
-
tsl::rh::prime_growth_policy>(
|
|
776
|
-
std::numeric_limits<std::size_t>::max() / 2)),
|
|
777
|
-
std::bad_alloc, std::length_error);
|
|
778
|
-
|
|
779
|
-
TSL_RH_CHECK_THROW_EITHER(
|
|
780
|
-
(tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
|
|
781
|
-
std::allocator<std::pair<int, int>>, false,
|
|
782
|
-
tsl::rh::mod_growth_policy<>>(
|
|
783
|
-
std::numeric_limits<std::size_t>::max())),
|
|
784
|
-
std::bad_alloc, std::length_error);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
BOOST_AUTO_TEST_CASE(test_range_construct) {
|
|
788
|
-
tsl::robin_map<int, int> map = {{2, 1}, {1, 0}, {3, 2}};
|
|
789
|
-
|
|
790
|
-
tsl::robin_map<int, int> map2(map.begin(), map.end());
|
|
791
|
-
tsl::robin_map<int, int> map3(map.cbegin(), map.cend());
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
* operator=(std::initializer_list)
|
|
796
|
-
*/
|
|
797
|
-
BOOST_AUTO_TEST_CASE(test_assign_operator) {
|
|
798
|
-
tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
|
|
799
|
-
BOOST_CHECK_EQUAL(map.size(), 2);
|
|
800
|
-
|
|
801
|
-
map = {{1, 3}, {2, 4}};
|
|
802
|
-
BOOST_CHECK_EQUAL(map.size(), 2);
|
|
803
|
-
BOOST_CHECK_EQUAL(map.at(1), 3);
|
|
804
|
-
BOOST_CHECK_EQUAL(map.at(2), 4);
|
|
805
|
-
BOOST_CHECK(map.find(0) == map.end());
|
|
806
|
-
|
|
807
|
-
map = {};
|
|
808
|
-
BOOST_CHECK(map.empty());
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
/**
|
|
812
|
-
* move/copy constructor/operator
|
|
813
|
-
*/
|
|
814
|
-
BOOST_AUTO_TEST_CASE(test_move_constructor) {
|
|
815
|
-
// insert x values in map, move map into map_move with move constructor, check
|
|
816
|
-
// map and map_move, insert additional values in map_move, check map_move
|
|
817
|
-
using HMap = tsl::robin_map<std::string, move_only_test>;
|
|
818
|
-
|
|
819
|
-
const std::size_t nb_values = 100;
|
|
820
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
821
|
-
HMap map_move(std::move(map));
|
|
822
|
-
|
|
823
|
-
BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values));
|
|
824
|
-
BOOST_CHECK(map == (HMap()));
|
|
825
|
-
|
|
826
|
-
for (std::size_t i = nb_values; i < nb_values * 2; i++) {
|
|
827
|
-
map_move.insert(
|
|
828
|
-
{utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
BOOST_CHECK_EQUAL(map_move.size(), nb_values * 2);
|
|
832
|
-
BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values * 2));
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
BOOST_AUTO_TEST_CASE(test_move_constructor_empty) {
|
|
836
|
-
tsl::robin_map<std::string, move_only_test> map(0);
|
|
837
|
-
tsl::robin_map<std::string, move_only_test> map_move(std::move(map));
|
|
838
|
-
|
|
839
|
-
BOOST_CHECK(map.empty());
|
|
840
|
-
BOOST_CHECK(map_move.empty());
|
|
841
|
-
|
|
842
|
-
BOOST_CHECK(map.find("") == map.end());
|
|
843
|
-
BOOST_CHECK(map_move.find("") == map_move.end());
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
BOOST_AUTO_TEST_CASE(test_move_operator) {
|
|
847
|
-
// insert x values in map, move map into map_move with move operator, check
|
|
848
|
-
// map and map_move, insert additional values in map_move, check map_move
|
|
849
|
-
using HMap = tsl::robin_map<std::string, move_only_test>;
|
|
850
|
-
|
|
851
|
-
const std::size_t nb_values = 100;
|
|
852
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
853
|
-
HMap map_move = utils::get_filled_hash_map<HMap>(1);
|
|
854
|
-
map_move = std::move(map);
|
|
855
|
-
|
|
856
|
-
BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values));
|
|
857
|
-
BOOST_CHECK(map == (HMap()));
|
|
858
|
-
|
|
859
|
-
for (std::size_t i = nb_values; i < nb_values * 2; i++) {
|
|
860
|
-
map_move.insert(
|
|
861
|
-
{utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
BOOST_CHECK_EQUAL(map_move.size(), nb_values * 2);
|
|
865
|
-
BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values * 2));
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
BOOST_AUTO_TEST_CASE(test_move_operator_empty) {
|
|
869
|
-
tsl::robin_map<std::string, move_only_test> map(0);
|
|
870
|
-
tsl::robin_map<std::string, move_only_test> map_move;
|
|
871
|
-
map_move = (std::move(map));
|
|
872
|
-
|
|
873
|
-
BOOST_CHECK(map.empty());
|
|
874
|
-
BOOST_CHECK(map_move.empty());
|
|
875
|
-
|
|
876
|
-
BOOST_CHECK(map.find("") == map.end());
|
|
877
|
-
BOOST_CHECK(map_move.find("") == map_move.end());
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
BOOST_AUTO_TEST_CASE(test_reassign_moved_object_move_constructor) {
|
|
881
|
-
using HMap = tsl::robin_map<std::string, std::string>;
|
|
882
|
-
|
|
883
|
-
HMap map = {{"Key1", "Value1"}, {"Key2", "Value2"}, {"Key3", "Value3"}};
|
|
884
|
-
HMap map_move(std::move(map));
|
|
885
|
-
|
|
886
|
-
BOOST_CHECK_EQUAL(map_move.size(), 3);
|
|
887
|
-
BOOST_CHECK_EQUAL(map.size(), 0);
|
|
888
|
-
|
|
889
|
-
map = {{"Key4", "Value4"}, {"Key5", "Value5"}};
|
|
890
|
-
BOOST_CHECK(map == (HMap({{"Key4", "Value4"}, {"Key5", "Value5"}})));
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
BOOST_AUTO_TEST_CASE(test_reassign_moved_object_move_operator) {
|
|
894
|
-
using HMap = tsl::robin_map<std::string, std::string>;
|
|
895
|
-
|
|
896
|
-
HMap map = {{"Key1", "Value1"}, {"Key2", "Value2"}, {"Key3", "Value3"}};
|
|
897
|
-
HMap map_move = std::move(map);
|
|
898
|
-
|
|
899
|
-
BOOST_CHECK_EQUAL(map_move.size(), 3);
|
|
900
|
-
BOOST_CHECK_EQUAL(map.size(), 0);
|
|
901
|
-
|
|
902
|
-
map = {{"Key4", "Value4"}, {"Key5", "Value5"}};
|
|
903
|
-
BOOST_CHECK(map == (HMap({{"Key4", "Value4"}, {"Key5", "Value5"}})));
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
BOOST_AUTO_TEST_CASE(test_use_after_move_constructor) {
|
|
907
|
-
using HMap = tsl::robin_map<std::string, move_only_test>;
|
|
908
|
-
|
|
909
|
-
const std::size_t nb_values = 100;
|
|
910
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
911
|
-
HMap map_move(std::move(map));
|
|
912
|
-
|
|
913
|
-
BOOST_CHECK(map == (HMap()));
|
|
914
|
-
BOOST_CHECK_EQUAL(map.size(), 0);
|
|
915
|
-
BOOST_CHECK_EQUAL(map.bucket_count(), 0);
|
|
916
|
-
BOOST_CHECK_EQUAL(map.erase("a"), 0);
|
|
917
|
-
BOOST_CHECK(map.find("a") == map.end());
|
|
918
|
-
|
|
919
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
920
|
-
map.insert(
|
|
921
|
-
{utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
925
|
-
BOOST_CHECK(map == map_move);
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
BOOST_AUTO_TEST_CASE(test_use_after_move_operator) {
|
|
929
|
-
using HMap = tsl::robin_map<std::string, move_only_test>;
|
|
930
|
-
|
|
931
|
-
const std::size_t nb_values = 100;
|
|
932
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
933
|
-
HMap map_move(0);
|
|
934
|
-
map_move = std::move(map);
|
|
935
|
-
|
|
936
|
-
BOOST_CHECK(map == (HMap()));
|
|
937
|
-
BOOST_CHECK_EQUAL(map.size(), 0);
|
|
938
|
-
BOOST_CHECK_EQUAL(map.bucket_count(), 0);
|
|
939
|
-
BOOST_CHECK_EQUAL(map.erase("a"), 0);
|
|
940
|
-
BOOST_CHECK(map.find("a") == map.end());
|
|
941
|
-
|
|
942
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
943
|
-
map.insert(
|
|
944
|
-
{utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
948
|
-
BOOST_CHECK(map == map_move);
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
BOOST_AUTO_TEST_CASE(test_copy_constructor_and_operator) {
|
|
952
|
-
using HMap = tsl::robin_map<std::string, std::string, mod_hash<9>>;
|
|
953
|
-
|
|
954
|
-
const std::size_t nb_values = 100;
|
|
955
|
-
HMap map = utils::get_filled_hash_map<HMap>(nb_values);
|
|
956
|
-
|
|
957
|
-
HMap map_copy = map;
|
|
958
|
-
HMap map_copy2(map);
|
|
959
|
-
HMap map_copy3 = utils::get_filled_hash_map<HMap>(1);
|
|
960
|
-
map_copy3 = map;
|
|
961
|
-
|
|
962
|
-
BOOST_CHECK(map == map_copy);
|
|
963
|
-
map.clear();
|
|
964
|
-
|
|
965
|
-
BOOST_CHECK(map_copy == map_copy2);
|
|
966
|
-
BOOST_CHECK(map_copy == map_copy3);
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
BOOST_AUTO_TEST_CASE(test_copy_constructor_empty) {
|
|
970
|
-
tsl::robin_map<std::string, int> map(0);
|
|
971
|
-
tsl::robin_map<std::string, int> map_copy(map);
|
|
972
|
-
|
|
973
|
-
BOOST_CHECK(map.empty());
|
|
974
|
-
BOOST_CHECK(map_copy.empty());
|
|
975
|
-
|
|
976
|
-
BOOST_CHECK(map.find("") == map.end());
|
|
977
|
-
BOOST_CHECK(map_copy.find("") == map_copy.end());
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
BOOST_AUTO_TEST_CASE(test_copy_operator_empty) {
|
|
981
|
-
tsl::robin_map<std::string, int> map(0);
|
|
982
|
-
tsl::robin_map<std::string, int> map_copy(16);
|
|
983
|
-
map_copy = map;
|
|
984
|
-
|
|
985
|
-
BOOST_CHECK(map.empty());
|
|
986
|
-
BOOST_CHECK(map_copy.empty());
|
|
987
|
-
|
|
988
|
-
BOOST_CHECK(map.find("") == map.end());
|
|
989
|
-
BOOST_CHECK(map_copy.find("") == map_copy.end());
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
/**
|
|
993
|
-
* at
|
|
994
|
-
*/
|
|
995
|
-
BOOST_AUTO_TEST_CASE(test_at) {
|
|
996
|
-
// insert x values, use at for known and unknown values.
|
|
997
|
-
const tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
|
|
998
|
-
|
|
999
|
-
BOOST_CHECK_EQUAL(map.at(0), 10);
|
|
1000
|
-
BOOST_CHECK_EQUAL(map.at(-2), 20);
|
|
1001
|
-
TSL_RH_CHECK_THROW(map.at(1), std::out_of_range);
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
/**
|
|
1005
|
-
* contains
|
|
1006
|
-
*/
|
|
1007
|
-
BOOST_AUTO_TEST_CASE(test_contains) {
|
|
1008
|
-
tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
|
|
1009
|
-
|
|
1010
|
-
BOOST_CHECK(map.contains(0));
|
|
1011
|
-
BOOST_CHECK(map.contains(-2));
|
|
1012
|
-
BOOST_CHECK(!map.contains(-3));
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
/**
|
|
1016
|
-
* equal_range
|
|
1017
|
-
*/
|
|
1018
|
-
BOOST_AUTO_TEST_CASE(test_equal_range) {
|
|
1019
|
-
const tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
|
|
1020
|
-
|
|
1021
|
-
auto it_pair = map.equal_range(0);
|
|
1022
|
-
BOOST_REQUIRE_EQUAL(std::distance(it_pair.first, it_pair.second), 1);
|
|
1023
|
-
BOOST_CHECK_EQUAL(it_pair.first->second, 10);
|
|
1024
|
-
|
|
1025
|
-
it_pair = map.equal_range(1);
|
|
1026
|
-
BOOST_CHECK(it_pair.first == it_pair.second);
|
|
1027
|
-
BOOST_CHECK(it_pair.first == map.end());
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
/**
|
|
1031
|
-
* operator[]
|
|
1032
|
-
*/
|
|
1033
|
-
BOOST_AUTO_TEST_CASE(test_access_operator) {
|
|
1034
|
-
// insert x values, use at for known and unknown values.
|
|
1035
|
-
tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
|
|
1036
|
-
|
|
1037
|
-
BOOST_CHECK_EQUAL(map[0], 10);
|
|
1038
|
-
BOOST_CHECK_EQUAL(map[-2], 20);
|
|
1039
|
-
BOOST_CHECK_EQUAL(map[2], std::int64_t());
|
|
1040
|
-
|
|
1041
|
-
BOOST_CHECK_EQUAL(map.size(), 3);
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
/**
|
|
1045
|
-
* swap
|
|
1046
|
-
*/
|
|
1047
|
-
BOOST_AUTO_TEST_CASE(test_swap) {
|
|
1048
|
-
tsl::robin_map<std::int64_t, std::int64_t> map = {{1, 10}, {8, 80}, {3, 30}};
|
|
1049
|
-
tsl::robin_map<std::int64_t, std::int64_t> map2 = {{4, 40}, {5, 50}};
|
|
1050
|
-
|
|
1051
|
-
using std::swap;
|
|
1052
|
-
swap(map, map2);
|
|
1053
|
-
|
|
1054
|
-
BOOST_CHECK(map ==
|
|
1055
|
-
(tsl::robin_map<std::int64_t, std::int64_t>{{4, 40}, {5, 50}}));
|
|
1056
|
-
BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
|
|
1057
|
-
{1, 10}, {8, 80}, {3, 30}}));
|
|
1058
|
-
|
|
1059
|
-
map.insert({6, 60});
|
|
1060
|
-
map2.insert({4, 40});
|
|
1061
|
-
|
|
1062
|
-
BOOST_CHECK(map == (tsl::robin_map<std::int64_t, std::int64_t>{
|
|
1063
|
-
{4, 40}, {5, 50}, {6, 60}}));
|
|
1064
|
-
BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
|
|
1065
|
-
{1, 10}, {8, 80}, {3, 30}, {4, 40}}));
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
BOOST_AUTO_TEST_CASE(test_swap_empty) {
|
|
1069
|
-
tsl::robin_map<std::int64_t, std::int64_t> map = {{1, 10}, {8, 80}, {3, 30}};
|
|
1070
|
-
tsl::robin_map<std::int64_t, std::int64_t> map2;
|
|
1071
|
-
|
|
1072
|
-
using std::swap;
|
|
1073
|
-
swap(map, map2);
|
|
1074
|
-
|
|
1075
|
-
BOOST_CHECK(map == (tsl::robin_map<std::int64_t, std::int64_t>{}));
|
|
1076
|
-
BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
|
|
1077
|
-
{1, 10}, {8, 80}, {3, 30}}));
|
|
1078
|
-
|
|
1079
|
-
map.insert({6, 60});
|
|
1080
|
-
map2.insert({4, 40});
|
|
1081
|
-
|
|
1082
|
-
BOOST_CHECK(map == (tsl::robin_map<std::int64_t, std::int64_t>{{6, 60}}));
|
|
1083
|
-
BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
|
|
1084
|
-
{1, 10}, {8, 80}, {3, 30}, {4, 40}}));
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
/**
|
|
1088
|
-
* serialize and deserialize
|
|
1089
|
-
*/
|
|
1090
|
-
BOOST_AUTO_TEST_CASE(test_serialize_desearialize_empty) {
|
|
1091
|
-
// serialize empty map; deserialize in new map; check equal.
|
|
1092
|
-
// for deserialization, test it with and without hash compatibility.
|
|
1093
|
-
const tsl::robin_map<std::string, move_only_test> empty_map(0);
|
|
1094
|
-
|
|
1095
|
-
serializer serial;
|
|
1096
|
-
empty_map.serialize(serial);
|
|
1097
|
-
|
|
1098
|
-
deserializer dserial(serial.str());
|
|
1099
|
-
auto empty_map_deserialized = decltype(empty_map)::deserialize(dserial, true);
|
|
1100
|
-
BOOST_CHECK(empty_map_deserialized == empty_map);
|
|
1101
|
-
|
|
1102
|
-
deserializer dserial2(serial.str());
|
|
1103
|
-
empty_map_deserialized = decltype(empty_map)::deserialize(dserial2, false);
|
|
1104
|
-
BOOST_CHECK(empty_map_deserialized == empty_map);
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
BOOST_AUTO_TEST_CASE(test_serialize_desearialize) {
|
|
1108
|
-
// insert x values; delete some values; serialize map; deserialize in new map;
|
|
1109
|
-
// check equal. for deserialization, test it with and without hash
|
|
1110
|
-
// compatibility.
|
|
1111
|
-
const std::size_t nb_values = 1000;
|
|
1112
|
-
|
|
1113
|
-
tsl::robin_map<std::int32_t, move_only_test> map;
|
|
1114
|
-
for (std::size_t i = 0; i < nb_values + 40; i++) {
|
|
1115
|
-
map.insert(
|
|
1116
|
-
{utils::get_key<std::int32_t>(i), utils::get_value<move_only_test>(i)});
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
for (std::size_t i = nb_values; i < nb_values + 40; i++) {
|
|
1120
|
-
map.erase(utils::get_key<std::int32_t>(i));
|
|
1121
|
-
}
|
|
1122
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
1123
|
-
|
|
1124
|
-
serializer serial;
|
|
1125
|
-
map.serialize(serial);
|
|
1126
|
-
|
|
1127
|
-
deserializer dserial(serial.str());
|
|
1128
|
-
auto map_deserialized = decltype(map)::deserialize(dserial, true);
|
|
1129
|
-
BOOST_CHECK(map == map_deserialized);
|
|
1130
|
-
|
|
1131
|
-
deserializer dserial2(serial.str());
|
|
1132
|
-
map_deserialized = decltype(map)::deserialize(dserial2, false);
|
|
1133
|
-
BOOST_CHECK(map_deserialized == map);
|
|
1134
|
-
|
|
1135
|
-
// Deserializing a map with StoreHash=true from a map serialized with
|
|
1136
|
-
// StoreHash=false with hash_compatible=true should throw an exception.
|
|
1137
|
-
deserializer dserial3(serial.str());
|
|
1138
|
-
TSL_RH_CHECK_THROW(
|
|
1139
|
-
(tsl::robin_map<std::int32_t, move_only_test, std::hash<std::int32_t>,
|
|
1140
|
-
std::equal_to<std::int32_t>,
|
|
1141
|
-
std::allocator<std::pair<std::int32_t, move_only_test>>,
|
|
1142
|
-
true>::deserialize(dserial3, true)),
|
|
1143
|
-
std::runtime_error);
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
BOOST_AUTO_TEST_CASE(test_serialize_desearialize_with_store_hash) {
|
|
1147
|
-
// insert x values; delete some values; serialize map; deserialize in new map;
|
|
1148
|
-
// check equal. for deserialization, test it with and without hash
|
|
1149
|
-
// compatibility.
|
|
1150
|
-
const std::size_t nb_values = 1000;
|
|
1151
|
-
|
|
1152
|
-
tsl::robin_map<std::int32_t, move_only_test, std::hash<std::int32_t>,
|
|
1153
|
-
std::equal_to<std::int32_t>,
|
|
1154
|
-
std::allocator<std::pair<std::int32_t, move_only_test>>, true>
|
|
1155
|
-
map;
|
|
1156
|
-
for (std::size_t i = 0; i < nb_values + 40; i++) {
|
|
1157
|
-
map.insert(
|
|
1158
|
-
{utils::get_key<std::int32_t>(i), utils::get_value<move_only_test>(i)});
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
for (std::size_t i = nb_values; i < nb_values + 40; i++) {
|
|
1162
|
-
map.erase(utils::get_key<std::int32_t>(i));
|
|
1163
|
-
}
|
|
1164
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
1165
|
-
|
|
1166
|
-
serializer serial;
|
|
1167
|
-
map.serialize(serial);
|
|
1168
|
-
|
|
1169
|
-
deserializer dserial(serial.str());
|
|
1170
|
-
auto map_deserialized = decltype(map)::deserialize(dserial, true);
|
|
1171
|
-
BOOST_CHECK(map == map_deserialized);
|
|
1172
|
-
|
|
1173
|
-
deserializer dserial2(serial.str());
|
|
1174
|
-
map_deserialized = decltype(map)::deserialize(dserial2, false);
|
|
1175
|
-
BOOST_CHECK(map_deserialized == map);
|
|
1176
|
-
|
|
1177
|
-
// Deserializing a map with StoreHash=false from a map serialized with
|
|
1178
|
-
// StoreHash=true with hash_compatible=true should throw an exception.
|
|
1179
|
-
deserializer dserial3(serial.str());
|
|
1180
|
-
TSL_RH_CHECK_THROW((tsl::robin_map<std::int32_t, move_only_test>::deserialize(
|
|
1181
|
-
dserial3, true)),
|
|
1182
|
-
std::runtime_error);
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
BOOST_AUTO_TEST_CASE(test_serialize_desearialize_with_different_hash) {
|
|
1186
|
-
// insert x values; serialize map; deserialize in new map which has a
|
|
1187
|
-
// different hash; check equal
|
|
1188
|
-
struct hash_str_diff {
|
|
1189
|
-
std::size_t operator()(const std::string& str) const {
|
|
1190
|
-
return std::hash<std::string>()(str) + 123;
|
|
1191
|
-
}
|
|
1192
|
-
};
|
|
1193
|
-
|
|
1194
|
-
const std::size_t nb_values = 1000;
|
|
1195
|
-
|
|
1196
|
-
tsl::robin_map<std::string, move_only_test> map;
|
|
1197
|
-
for (std::size_t i = 0; i < nb_values; i++) {
|
|
1198
|
-
map.insert(
|
|
1199
|
-
{utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
|
|
1200
|
-
}
|
|
1201
|
-
BOOST_CHECK_EQUAL(map.size(), nb_values);
|
|
1202
|
-
|
|
1203
|
-
serializer serial;
|
|
1204
|
-
map.serialize(serial);
|
|
1205
|
-
|
|
1206
|
-
deserializer dserial(serial.str());
|
|
1207
|
-
auto map_deserialized =
|
|
1208
|
-
tsl::robin_map<std::string, move_only_test, hash_str_diff>::deserialize(
|
|
1209
|
-
dserial, false);
|
|
1210
|
-
|
|
1211
|
-
BOOST_CHECK_EQUAL(map_deserialized.size(), map.size());
|
|
1212
|
-
for (const auto& val : map) {
|
|
1213
|
-
BOOST_CHECK(map_deserialized.find(val.first) != map_deserialized.end());
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
/**
|
|
1218
|
-
* KeyEqual
|
|
1219
|
-
*/
|
|
1220
|
-
BOOST_AUTO_TEST_CASE(test_key_equal) {
|
|
1221
|
-
// Use a KeyEqual and Hash where any odd unsigned number 'x' is equal to
|
|
1222
|
-
// 'x-1'. Make sure that KeyEqual is called (and not ==).
|
|
1223
|
-
struct hash {
|
|
1224
|
-
std::size_t operator()(std::uint64_t v) const {
|
|
1225
|
-
if (v % 2u == 1u) {
|
|
1226
|
-
return std::hash<std::uint64_t>()(v - 1);
|
|
1227
|
-
} else {
|
|
1228
|
-
return std::hash<std::uint64_t>()(v);
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
};
|
|
1232
|
-
|
|
1233
|
-
struct key_equal {
|
|
1234
|
-
bool operator()(std::uint64_t lhs, std::uint64_t rhs) const {
|
|
1235
|
-
if (lhs % 2u == 1u) {
|
|
1236
|
-
lhs--;
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
if (rhs % 2u == 1u) {
|
|
1240
|
-
rhs--;
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
return lhs == rhs;
|
|
1244
|
-
}
|
|
1245
|
-
};
|
|
1246
|
-
|
|
1247
|
-
tsl::robin_map<std::uint64_t, std::uint64_t, hash, key_equal> map;
|
|
1248
|
-
BOOST_CHECK(map.insert({2, 10}).second);
|
|
1249
|
-
BOOST_CHECK_EQUAL(map.at(2), 10);
|
|
1250
|
-
BOOST_CHECK_EQUAL(map.at(3), 10);
|
|
1251
|
-
BOOST_CHECK(!map.insert({3, 10}).second);
|
|
1252
|
-
|
|
1253
|
-
BOOST_CHECK_EQUAL(map.size(), 1);
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
/**
|
|
1257
|
-
* other
|
|
1258
|
-
*/
|
|
1259
|
-
BOOST_AUTO_TEST_CASE(test_heterogeneous_lookups) {
|
|
1260
|
-
struct hash_ptr {
|
|
1261
|
-
std::size_t operator()(const std::unique_ptr<int>& p) const {
|
|
1262
|
-
return std::hash<std::uintptr_t>()(
|
|
1263
|
-
reinterpret_cast<std::uintptr_t>(p.get()));
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
std::size_t operator()(std::uintptr_t p) const {
|
|
1267
|
-
return std::hash<std::uintptr_t>()(p);
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
std::size_t operator()(const int* const& p) const {
|
|
1271
|
-
return std::hash<std::uintptr_t>()(reinterpret_cast<std::uintptr_t>(p));
|
|
1272
|
-
}
|
|
1273
|
-
};
|
|
1274
|
-
|
|
1275
|
-
struct equal_to_ptr {
|
|
1276
|
-
using is_transparent = std::true_type;
|
|
1277
|
-
|
|
1278
|
-
bool operator()(const std::unique_ptr<int>& p1,
|
|
1279
|
-
const std::unique_ptr<int>& p2) const {
|
|
1280
|
-
return p1 == p2;
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
bool operator()(const std::unique_ptr<int>& p1, std::uintptr_t p2) const {
|
|
1284
|
-
return reinterpret_cast<std::uintptr_t>(p1.get()) == p2;
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
bool operator()(std::uintptr_t p1, const std::unique_ptr<int>& p2) const {
|
|
1288
|
-
return p1 == reinterpret_cast<std::uintptr_t>(p2.get());
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
bool operator()(const std::unique_ptr<int>& p1,
|
|
1292
|
-
const int* const& p2) const {
|
|
1293
|
-
return p1.get() == p2;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
bool operator()(const int* const& p1,
|
|
1297
|
-
const std::unique_ptr<int>& p2) const {
|
|
1298
|
-
return p1 == p2.get();
|
|
1299
|
-
}
|
|
1300
|
-
};
|
|
1301
|
-
|
|
1302
|
-
std::unique_ptr<int> ptr1(new int(1));
|
|
1303
|
-
std::unique_ptr<int> ptr2(new int(2));
|
|
1304
|
-
std::unique_ptr<int> ptr3(new int(3));
|
|
1305
|
-
int other = -1;
|
|
1306
|
-
|
|
1307
|
-
const std::uintptr_t addr1 = reinterpret_cast<std::uintptr_t>(ptr1.get());
|
|
1308
|
-
const int* const addr2 = ptr2.get();
|
|
1309
|
-
const int* const addr_unknown = &other;
|
|
1310
|
-
|
|
1311
|
-
tsl::robin_map<std::unique_ptr<int>, int, hash_ptr, equal_to_ptr> map;
|
|
1312
|
-
map.insert({std::move(ptr1), 4});
|
|
1313
|
-
map.insert({std::move(ptr2), 5});
|
|
1314
|
-
map.insert({std::move(ptr3), 6});
|
|
1315
|
-
|
|
1316
|
-
BOOST_CHECK_EQUAL(map.size(), 3);
|
|
1317
|
-
|
|
1318
|
-
BOOST_CHECK_EQUAL(map.at(addr1), 4);
|
|
1319
|
-
BOOST_CHECK_EQUAL(map.at(addr2), 5);
|
|
1320
|
-
TSL_RH_CHECK_THROW(map.at(addr_unknown), std::out_of_range);
|
|
1321
|
-
|
|
1322
|
-
BOOST_REQUIRE(map.find(addr1) != map.end());
|
|
1323
|
-
BOOST_CHECK_EQUAL(*map.find(addr1)->first, 1);
|
|
1324
|
-
|
|
1325
|
-
BOOST_REQUIRE(map.find(addr2) != map.end());
|
|
1326
|
-
BOOST_CHECK_EQUAL(*map.find(addr2)->first, 2);
|
|
1327
|
-
|
|
1328
|
-
BOOST_CHECK(map.find(addr_unknown) == map.end());
|
|
1329
|
-
|
|
1330
|
-
BOOST_CHECK_EQUAL(map.count(addr1), 1);
|
|
1331
|
-
BOOST_CHECK_EQUAL(map.count(addr2), 1);
|
|
1332
|
-
BOOST_CHECK_EQUAL(map.count(addr_unknown), 0);
|
|
1333
|
-
|
|
1334
|
-
BOOST_CHECK_EQUAL(map.erase(addr1), 1);
|
|
1335
|
-
BOOST_CHECK_EQUAL(map.erase(addr2), 1);
|
|
1336
|
-
BOOST_CHECK_EQUAL(map.erase(addr_unknown), 0);
|
|
1337
|
-
|
|
1338
|
-
BOOST_CHECK_EQUAL(map.size(), 1);
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
/**
|
|
1342
|
-
* Various operations on empty map
|
|
1343
|
-
*/
|
|
1344
|
-
BOOST_AUTO_TEST_CASE(test_empty_map) {
|
|
1345
|
-
tsl::robin_map<std::string, int> map(0);
|
|
1346
|
-
|
|
1347
|
-
BOOST_CHECK_EQUAL(map.bucket_count(), 0);
|
|
1348
|
-
BOOST_CHECK_EQUAL(map.size(), 0);
|
|
1349
|
-
BOOST_CHECK_EQUAL(map.load_factor(), 0);
|
|
1350
|
-
BOOST_CHECK(map.empty());
|
|
1351
|
-
|
|
1352
|
-
BOOST_CHECK(map.begin() == map.end());
|
|
1353
|
-
BOOST_CHECK(map.begin() == map.cend());
|
|
1354
|
-
BOOST_CHECK(map.cbegin() == map.cend());
|
|
1355
|
-
|
|
1356
|
-
BOOST_CHECK(map.find("") == map.end());
|
|
1357
|
-
BOOST_CHECK(map.find("test") == map.end());
|
|
1358
|
-
|
|
1359
|
-
BOOST_CHECK_EQUAL(map.count(""), 0);
|
|
1360
|
-
BOOST_CHECK_EQUAL(map.count("test"), 0);
|
|
1361
|
-
|
|
1362
|
-
BOOST_CHECK(!map.contains(""));
|
|
1363
|
-
BOOST_CHECK(!map.contains("test"));
|
|
1364
|
-
|
|
1365
|
-
TSL_RH_CHECK_THROW(map.at(""), std::out_of_range);
|
|
1366
|
-
TSL_RH_CHECK_THROW(map.at("test"), std::out_of_range);
|
|
1367
|
-
|
|
1368
|
-
auto range = map.equal_range("test");
|
|
1369
|
-
BOOST_CHECK(range.first == range.second);
|
|
1370
|
-
|
|
1371
|
-
BOOST_CHECK_EQUAL(map.erase("test"), 0);
|
|
1372
|
-
BOOST_CHECK(map.erase(map.begin(), map.end()) == map.end());
|
|
1373
|
-
|
|
1374
|
-
BOOST_CHECK_EQUAL(map["new value"], int{});
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
/**
|
|
1378
|
-
* Test precalculated hash
|
|
1379
|
-
*/
|
|
1380
|
-
BOOST_AUTO_TEST_CASE(test_precalculated_hash) {
|
|
1381
|
-
tsl::robin_map<int, int, identity_hash<int>> map = {
|
|
1382
|
-
{1, -1}, {2, -2}, {3, -3}, {4, -4}, {5, -5}, {6, -6}};
|
|
1383
|
-
const tsl::robin_map<int, int, identity_hash<int>> map_const = map;
|
|
1384
|
-
|
|
1385
|
-
/**
|
|
1386
|
-
* find
|
|
1387
|
-
*/
|
|
1388
|
-
BOOST_REQUIRE(map.find(3, map.hash_function()(3)) != map.end());
|
|
1389
|
-
BOOST_CHECK_EQUAL(map.find(3, map.hash_function()(3))->second, -3);
|
|
1390
|
-
|
|
1391
|
-
BOOST_REQUIRE(map_const.find(3, map_const.hash_function()(3)) !=
|
|
1392
|
-
map_const.end());
|
|
1393
|
-
BOOST_CHECK_EQUAL(map_const.find(3, map_const.hash_function()(3))->second,
|
|
1394
|
-
-3);
|
|
1395
|
-
|
|
1396
|
-
BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
|
|
1397
|
-
BOOST_CHECK(map.find(3, map.hash_function()(2)) == map.end());
|
|
1398
|
-
|
|
1399
|
-
/**
|
|
1400
|
-
* at
|
|
1401
|
-
*/
|
|
1402
|
-
BOOST_CHECK_EQUAL(map.at(3, map.hash_function()(3)), -3);
|
|
1403
|
-
BOOST_CHECK_EQUAL(map_const.at(3, map_const.hash_function()(3)), -3);
|
|
1404
|
-
|
|
1405
|
-
BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
|
|
1406
|
-
TSL_RH_CHECK_THROW(map.at(3, map.hash_function()(2)), std::out_of_range);
|
|
1407
|
-
|
|
1408
|
-
/**
|
|
1409
|
-
* contains
|
|
1410
|
-
*/
|
|
1411
|
-
BOOST_CHECK(map.contains(3, map.hash_function()(3)));
|
|
1412
|
-
BOOST_CHECK(map_const.contains(3, map_const.hash_function()(3)));
|
|
1413
|
-
|
|
1414
|
-
BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
|
|
1415
|
-
BOOST_CHECK(!map.contains(3, map.hash_function()(2)));
|
|
1416
|
-
|
|
1417
|
-
/**
|
|
1418
|
-
* count
|
|
1419
|
-
*/
|
|
1420
|
-
BOOST_CHECK_EQUAL(map.count(3, map.hash_function()(3)), 1);
|
|
1421
|
-
BOOST_CHECK_EQUAL(map_const.count(3, map_const.hash_function()(3)), 1);
|
|
1422
|
-
|
|
1423
|
-
BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
|
|
1424
|
-
BOOST_CHECK_EQUAL(map.count(3, map.hash_function()(2)), 0);
|
|
1425
|
-
|
|
1426
|
-
/**
|
|
1427
|
-
* equal_range
|
|
1428
|
-
*/
|
|
1429
|
-
auto it_range = map.equal_range(3, map.hash_function()(3));
|
|
1430
|
-
BOOST_REQUIRE_EQUAL(std::distance(it_range.first, it_range.second), 1);
|
|
1431
|
-
BOOST_CHECK_EQUAL(it_range.first->second, -3);
|
|
1432
|
-
|
|
1433
|
-
auto it_range_const = map_const.equal_range(3, map_const.hash_function()(3));
|
|
1434
|
-
BOOST_REQUIRE_EQUAL(
|
|
1435
|
-
std::distance(it_range_const.first, it_range_const.second), 1);
|
|
1436
|
-
BOOST_CHECK_EQUAL(it_range_const.first->second, -3);
|
|
1437
|
-
|
|
1438
|
-
it_range = map.equal_range(3, map.hash_function()(2));
|
|
1439
|
-
BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
|
|
1440
|
-
BOOST_CHECK_EQUAL(std::distance(it_range.first, it_range.second), 0);
|
|
1441
|
-
|
|
1442
|
-
/**
|
|
1443
|
-
* erase
|
|
1444
|
-
*/
|
|
1445
|
-
BOOST_CHECK_EQUAL(map.erase(3, map.hash_function()(3)), 1);
|
|
1446
|
-
|
|
1447
|
-
BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(4));
|
|
1448
|
-
BOOST_CHECK_EQUAL(map.erase(4, map.hash_function()(2)), 0);
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
BOOST_AUTO_TEST_SUITE_END()
|