74 std::unordered_set<std::string> keys; |
74 std::unordered_set<std::string> keys; |
75 cx_foreach(CxDataPtr*, elem, keyiter) { |
75 cx_foreach(CxDataPtr*, elem, keyiter) { |
76 // we use that our test keys contain NULL-terminated strings |
76 // we use that our test keys contain NULL-terminated strings |
77 keys.insert(std::string(reinterpret_cast<const char *>(elem->data))); |
77 keys.insert(std::string(reinterpret_cast<const char *>(elem->data))); |
78 } |
78 } |
|
79 EXPECT_EQ(keyiter.index, map->size); |
79 ASSERT_EQ(keys.size(), map->size); |
80 ASSERT_EQ(keys.size(), map->size); |
80 for (auto &&k: keys) { |
81 for (auto &&k: keys) { |
81 EXPECT_NE(refmap.find(k), refmap.end()); |
82 EXPECT_NE(refmap.find(k), refmap.end()); |
82 } |
83 } |
83 } |
84 } |
87 auto valiter = cxMapIteratorValues(map); |
88 auto valiter = cxMapIteratorValues(map); |
88 std::unordered_set<std::string> values; // we use that the values in our test data are unique strings |
89 std::unordered_set<std::string> values; // we use that the values in our test data are unique strings |
89 cx_foreach(char const*, elem, valiter) { |
90 cx_foreach(char const*, elem, valiter) { |
90 values.insert(std::string(elem)); |
91 values.insert(std::string(elem)); |
91 } |
92 } |
|
93 EXPECT_EQ(valiter.index, map->size); |
92 ASSERT_EQ(values.size(), map->size); |
94 ASSERT_EQ(values.size(), map->size); |
93 for (auto &&v: values) { |
95 for (auto &&v: values) { |
94 EXPECT_NE(std::find_if(refmap.begin(), refmap.end(), |
96 EXPECT_NE(std::find_if(refmap.begin(), refmap.end(), |
95 [v](auto const &e) { return e.second == v; }), refmap.end()); |
97 [v](auto const &e) { return e.second == v; }), refmap.end()); |
96 } |
98 } |
101 auto pairiter = cxMapIterator(map); |
103 auto pairiter = cxMapIterator(map); |
102 std::unordered_map<std::string, std::string> pairs; |
104 std::unordered_map<std::string, std::string> pairs; |
103 cx_foreach(CxMapEntry*, entry, pairiter) { |
105 cx_foreach(CxMapEntry*, entry, pairiter) { |
104 pairs[std::string((char const *) entry->key->data)] = std::string((char *) entry->value); |
106 pairs[std::string((char const *) entry->key->data)] = std::string((char *) entry->value); |
105 } |
107 } |
|
108 EXPECT_EQ(pairiter.index, map->size); |
106 ASSERT_EQ(pairs.size(), refmap.size()); |
109 ASSERT_EQ(pairs.size(), refmap.size()); |
107 for (auto &&p: pairs) { |
110 for (auto &&p: pairs) { |
108 ASSERT_EQ(p.second, refmap.at(p.first)); |
111 ASSERT_EQ(p.second, refmap.at(p.first)); |
109 } |
112 } |
110 } |
113 } |
139 // verify iterators for empty map |
142 // verify iterators for empty map |
140 verify_map_contents(map, refmap); |
143 verify_map_contents(map, refmap); |
141 |
144 |
142 // execute operations and verify results |
145 // execute operations and verify results |
143 for (auto &&op: ops) { |
146 for (auto &&op: ops) { |
144 CxDataPtr key = {reinterpret_cast<const unsigned char *>(op.key), 1 + strlen(op.key)}; |
147 CxDataPtr key = cxMapKeyStr(op.key); |
145 if (op.op == map_operation::put) { |
148 if (op.op == map_operation::put) { |
146 // execute a put operation and verify that the exact value can be read back |
149 // execute a put operation and verify that the exact value can be read back |
147 refmap[std::string(op.key)] = std::string(op.value); |
150 refmap[std::string(op.key)] = std::string(op.value); |
148 int result = cxMapPut(map, key, (void *) op.value); |
151 int result = cxMapPut(map, key, (void *) op.value); |
149 EXPECT_EQ(result, 0); |
152 EXPECT_EQ(result, 0); |
166 |
169 |
167 // destroy the map and verify the memory (de)allocations |
170 // destroy the map and verify the memory (de)allocations |
168 cxMapDestroy(map); |
171 cxMapDestroy(map); |
169 EXPECT_TRUE(allocator.verify()); |
172 EXPECT_TRUE(allocator.verify()); |
170 } |
173 } |
|
174 |
|
175 TEST(CxHashMap, RemoveViaIterator) { |
|
176 CxTestingAllocator allocator; |
|
177 auto map = cxHashMapCreate(&allocator, 4); |
|
178 |
|
179 cxMapPut(map, cxMapKeyStr("key 1"), (void *) "val 1"); |
|
180 cxMapPut(map, cxMapKeyStr("key 2"), (void *) "val 2"); |
|
181 cxMapPut(map, cxMapKeyStr("key 3"), (void *) "val 3"); |
|
182 cxMapPut(map, cxMapKeyStr("key 4"), (void *) "val 4"); |
|
183 cxMapPut(map, cxMapKeyStr("key 5"), (void *) "val 5"); |
|
184 cxMapPut(map, cxMapKeyStr("key 6"), (void *) "val 6"); |
|
185 |
|
186 auto iter = cxMapIterator(map); |
|
187 cx_foreach(CxMapEntry*, entry, iter) { |
|
188 if (entry->key->data[4] % 2 == 1) iter.remove = true; |
|
189 } |
|
190 EXPECT_EQ(map->size, 3); |
|
191 EXPECT_EQ(iter.index, map->size); |
|
192 |
|
193 EXPECT_EQ(cxMapGet(map, cxMapKeyStr("key 1")), nullptr); |
|
194 EXPECT_NE(cxMapGet(map, cxMapKeyStr("key 2")), nullptr); |
|
195 EXPECT_EQ(cxMapGet(map, cxMapKeyStr("key 3")), nullptr); |
|
196 EXPECT_NE(cxMapGet(map, cxMapKeyStr("key 4")), nullptr); |
|
197 EXPECT_EQ(cxMapGet(map, cxMapKeyStr("key 5")), nullptr); |
|
198 EXPECT_NE(cxMapGet(map, cxMapKeyStr("key 6")), nullptr); |
|
199 |
|
200 cxMapDestroy(map); |
|
201 EXPECT_TRUE(allocator.verify()); |
|
202 } |