|
@@ -1,331 +1,419 @@
|
|
|
-#include "../Tests.h"
|
|
|
-#include "core/HashMap.h"
|
|
|
-#include "core/ToString.h"
|
|
|
+#include "../Tests.hpp"
|
|
|
+#include "core/ProbingHashMap.hpp"
|
|
|
+#include "core/Test.hpp"
|
|
|
|
|
|
-HASHMAP(size_t, size_t, Size)
|
|
|
+template struct Core::ProbingHashMap<int, int>;
|
|
|
+using ProbingIntMap = Core::ProbingHashMap<int, int>;
|
|
|
|
|
|
-typedef struct {
|
|
|
- size_t a;
|
|
|
- size_t b;
|
|
|
-} A;
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-static size_t hashA(A key) {
|
|
|
- return key.a ^ key.b;
|
|
|
-}
|
|
|
-
|
|
|
-static bool equalA(A a, A b) {
|
|
|
- return a.a == b.a && a.b == b.b;
|
|
|
-}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-static bool isInvalidKeyA(A key) {
|
|
|
- return key.a == 0 && key.b == 0;
|
|
|
-}
|
|
|
-
|
|
|
-HASHMAP(A, int, A)
|
|
|
-HASHMAP_SOURCE(A, int, A)
|
|
|
-
|
|
|
-static HashMapSize getTestSizeMap() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
- *putHashMapKeySize(&map, 1) = 3;
|
|
|
- *putHashMapKeySize(&map, 2) = 4;
|
|
|
- *putHashMapKeySize(&map, 3) = 5;
|
|
|
- *putHashMapKeySize(&map, 0) = 20;
|
|
|
+template<typename T>
|
|
|
+static T getTestIntMap() {
|
|
|
+ T map;
|
|
|
+ map.add(1, 3).add(2, 4).add(3, 5).add(0, 20);
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
-static void checkSizeMap(HashMapSize* map) {
|
|
|
- size_t* a = searchHashMapKeySize(map, 1);
|
|
|
- size_t* b = searchHashMapKeySize(map, 2);
|
|
|
- size_t* c = searchHashMapKeySize(map, 3);
|
|
|
- size_t* d = searchHashMapKeySize(map, 0);
|
|
|
+template<typename T>
|
|
|
+static void checkIntMap(T& map) {
|
|
|
+ int* a = map.search(1);
|
|
|
+ int* b = map.search(2);
|
|
|
+ int* c = map.search(3);
|
|
|
+ int* d = map.search(0);
|
|
|
if(TEST_NOT_NULL(a) && TEST_NOT_NULL(b) && TEST_NOT_NULL(c) &&
|
|
|
TEST_NOT_NULL(d)) {
|
|
|
- TEST_SIZE(3, *a);
|
|
|
- TEST_SIZE(4, *b);
|
|
|
- TEST_SIZE(5, *c);
|
|
|
- TEST_SIZE(20, *d);
|
|
|
+ TEST(3, *a);
|
|
|
+ TEST(4, *b);
|
|
|
+ TEST(5, *c);
|
|
|
+ TEST(20, *d);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+template<typename T>
|
|
|
static void testAdd() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
- *putHashMapKeySize(&map, 5) = 4;
|
|
|
- size_t* value = searchHashMapKeySize(&map, 5);
|
|
|
+ T map;
|
|
|
+ map.add(5, 4);
|
|
|
+ int* value = map.search(5);
|
|
|
if(TEST_NOT_NULL(value)) {
|
|
|
- TEST_SIZE(4, *value);
|
|
|
+ TEST(4, *value);
|
|
|
}
|
|
|
- destroyHashMapSize(&map);
|
|
|
}
|
|
|
|
|
|
+template<typename T>
|
|
|
static void testMultipleAdd() {
|
|
|
- HashMapSize map = getTestSizeMap();
|
|
|
- TEST_NOT_NULL(searchHashMapKeySize(&map, 0));
|
|
|
- TEST_NOT_NULL(searchHashMapKeySize(&map, 1));
|
|
|
- TEST_NOT_NULL(searchHashMapKeySize(&map, 2));
|
|
|
- TEST_NOT_NULL(searchHashMapKeySize(&map, 3));
|
|
|
- checkSizeMap(&map);
|
|
|
- destroyHashMapSize(&map);
|
|
|
+ T map = getTestIntMap<T>();
|
|
|
+ TEST_TRUE(map.contains(0));
|
|
|
+ TEST_TRUE(map.contains(1));
|
|
|
+ TEST_TRUE(map.contains(2));
|
|
|
+ TEST_TRUE(map.contains(3));
|
|
|
+ checkIntMap(map);
|
|
|
}
|
|
|
|
|
|
+template<typename T>
|
|
|
static void testSearch() {
|
|
|
- HashMapSize map = getTestSizeMap();
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 6));
|
|
|
- *putHashMapKeySize(&map, 5) = 4;
|
|
|
- *putHashMapKeySize(&map, 10) = 3;
|
|
|
- *putHashMapKeySize(&map, 15) = 2;
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 6));
|
|
|
- destroyHashMapSize(&map);
|
|
|
-}
|
|
|
-
|
|
|
-static void testSearchEmpty() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 6));
|
|
|
- destroyHashMapSize(&map);
|
|
|
+ T map;
|
|
|
+ TEST_NULL(map.search(6));
|
|
|
+ map.add(5, 4).add(10, 3).add(15, 2);
|
|
|
+ TEST_NULL(map.search(6));
|
|
|
}
|
|
|
|
|
|
+template<typename T>
|
|
|
static void testAddReplace() {
|
|
|
- HashMapSize map = getTestSizeMap();
|
|
|
- *putHashMapKeySize(&map, 5) = 4;
|
|
|
- *putHashMapKeySize(&map, 5) = 10;
|
|
|
- TEST_NOT_NULL(searchHashMapKeySize(&map, 5));
|
|
|
- size_t* a = searchHashMapKeySize(&map, 5);
|
|
|
+ T map;
|
|
|
+ map.add(5, 4).add(5, 10);
|
|
|
+ TEST_TRUE(map.contains(5));
|
|
|
+ int* a = map.search(5);
|
|
|
if(TEST_NOT_NULL(a)) {
|
|
|
- TEST_SIZE(10, *a);
|
|
|
+ TEST(10, *a);
|
|
|
}
|
|
|
- destroyHashMapSize(&map);
|
|
|
}
|
|
|
|
|
|
+template<typename T>
|
|
|
static void testClear() {
|
|
|
- HashMapSize map = getTestSizeMap();
|
|
|
- *putHashMapKeySize(&map, 5) = 4;
|
|
|
- *putHashMapKeySize(&map, 4) = 10;
|
|
|
- clearHashMapSize(&map);
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 5));
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 4));
|
|
|
- destroyHashMapSize(&map);
|
|
|
-}
|
|
|
-
|
|
|
-static void testClearEmpty() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
- clearHashMapSize(&map);
|
|
|
- destroyHashMapSize(&map);
|
|
|
+ T map;
|
|
|
+ map.clear();
|
|
|
+ map.add(5, 4).add(4, 10);
|
|
|
+ map.clear();
|
|
|
+ TEST_FALSE(map.contains(5));
|
|
|
+ TEST_FALSE(map.contains(4));
|
|
|
}
|
|
|
|
|
|
+template<typename T>
|
|
|
static void testOverflow(bool light) {
|
|
|
- size_t limit = light ? 10'000 : 100'000;
|
|
|
- HashMapSize map = getTestSizeMap();
|
|
|
- for(size_t i = 0; i < limit; i++) {
|
|
|
- *putHashMapKeySize(&map, i) = i;
|
|
|
+ int limit = light ? 10'000 : 100'000;
|
|
|
+ T map;
|
|
|
+ for(int i = 0; i < limit; i++) {
|
|
|
+ map.add(i, i);
|
|
|
}
|
|
|
- for(size_t i = 0; i < limit; i++) {
|
|
|
- TEST_NOT_NULL(searchHashMapKeySize(&map, i));
|
|
|
+ for(int i = 0; i < limit; i++) {
|
|
|
+ TEST_TRUE(map.contains(i));
|
|
|
}
|
|
|
- destroyHashMapSize(&map);
|
|
|
}
|
|
|
|
|
|
-static void testToString() {
|
|
|
- HashMapSize map = getTestSizeMap();
|
|
|
- char buffer[128];
|
|
|
- size_t n = toStringHashMapSize(
|
|
|
- &map, buffer, sizeof(buffer), toStringSize, toStringSize);
|
|
|
- TEST_SIZE(29, n);
|
|
|
- TEST_STRING("[2 = 4, 1 = 3, 3 = 5, 0 = 20]", buffer);
|
|
|
-
|
|
|
- clearHashMapSize(&map);
|
|
|
- *putHashMapKeySize(&map, 1) = 3;
|
|
|
- n = toStringHashMapSize(
|
|
|
- &map, buffer, sizeof(buffer), toStringSize, toStringSize);
|
|
|
- TEST_SIZE(7, n);
|
|
|
- TEST_STRING("[1 = 3]", buffer);
|
|
|
-
|
|
|
- clearHashMapSize(&map);
|
|
|
- n = toStringHashMapSize(
|
|
|
- &map, buffer, sizeof(buffer), toStringSize, toStringSize);
|
|
|
- TEST_SIZE(2, n);
|
|
|
- TEST_STRING("[]", buffer);
|
|
|
-
|
|
|
- destroyHashMapSize(&map);
|
|
|
-}
|
|
|
+static int aInstances = 0;
|
|
|
|
|
|
-static void testEntryForEach() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
- *putHashMapKeySize(&map, 0) = 1;
|
|
|
- *putHashMapKeySize(&map, 5) = 4;
|
|
|
- *putHashMapKeySize(&map, 10) = 3;
|
|
|
- *putHashMapKeySize(&map, 15) = 2;
|
|
|
-
|
|
|
- size_t counter = 0;
|
|
|
- HashMapIteratorSize i;
|
|
|
- initHashMapIteratorSize(&i, &map);
|
|
|
- while(hasNextHashMapNodeSize(&i)) {
|
|
|
- HashMapNodeSize* n = nextHashMapNodeSize(&i);
|
|
|
- counter += *n->key + *n->value;
|
|
|
+struct HashMapTest {
|
|
|
+ int a;
|
|
|
+ int b;
|
|
|
+
|
|
|
+ HashMapTest(int a_, int b_) : a(a_), b(b_) {
|
|
|
}
|
|
|
- TEST_SIZE(40, counter);
|
|
|
|
|
|
- destroyHashMapSize(&map);
|
|
|
-}
|
|
|
+
|
|
|
+ HashMapTest(const HashMapTest&) = delete;
|
|
|
+ HashMapTest(HashMapTest&&) = delete;
|
|
|
+ HashMapTest& operator=(const HashMapTest&) = delete;
|
|
|
+ HashMapTest& operator=(HashMapTest&&) = delete;
|
|
|
|
|
|
-static void testInvalidPut() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
+ bool operator==(const HashMapTest& other) const {
|
|
|
+ return a == other.a && b == other.b;
|
|
|
+ }
|
|
|
|
|
|
- char buffer[128];
|
|
|
- toStringHashMapSize(
|
|
|
- &map, buffer, sizeof(buffer), toStringSize, toStringSize);
|
|
|
- TEST_STRING("[]", buffer);
|
|
|
+ size_t toString(char* s, size_t n) const {
|
|
|
+ size_t total = 0;
|
|
|
+ addString("A(", s, n, total);
|
|
|
+ addString(a, s, n, total);
|
|
|
+ addString(", ", s, n, total);
|
|
|
+ addString(b, s, n, total);
|
|
|
+ addString(")", s, n, total);
|
|
|
+ return total;
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- *putHashMapKeySize(&map, 0) = 3;
|
|
|
- size_t* v = searchHashMapKeySize(&map, 0);
|
|
|
- if(TEST_NOT_NULL(v)) {
|
|
|
- TEST_SIZE(3, *v);
|
|
|
+struct ProbingTest final : public HashMapTest {
|
|
|
+ ProbingTest(int a_, int b_) : HashMapTest(a_, b_) {
|
|
|
+ aInstances++;
|
|
|
+ }
|
|
|
+
|
|
|
+ ProbingTest(const ProbingTest& o) : HashMapTest(o.a, o.b) {
|
|
|
+ aInstances++;
|
|
|
}
|
|
|
- toStringHashMapSize(
|
|
|
- &map, buffer, sizeof(buffer), toStringSize, toStringSize);
|
|
|
- TEST_STRING("[0 = 3]", buffer);
|
|
|
|
|
|
- clearHashMapSize(&map);
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 0));
|
|
|
+ ProbingTest(ProbingTest&& o) : HashMapTest(o.a, o.b) {
|
|
|
+ aInstances++;
|
|
|
+ }
|
|
|
+
|
|
|
+ ~ProbingTest() {
|
|
|
+ aInstances--;
|
|
|
+ }
|
|
|
|
|
|
- destroyHashMapSize(&map);
|
|
|
+ ProbingTest& operator=(ProbingTest o) {
|
|
|
+ a = o.a;
|
|
|
+ b = o.b;
|
|
|
+ return *this;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static void testEmplaceProbing() {
|
|
|
+ {
|
|
|
+ Core::ProbingHashMap<int, ProbingTest> map;
|
|
|
+
|
|
|
+ ProbingTest* ar = nullptr;
|
|
|
+ TEST_TRUE(map.tryEmplace(ar, 0, 3, 4));
|
|
|
+ TEST_TRUE(map.tryEmplace(ar, 3, 4, 5));
|
|
|
+ TEST_TRUE(map.tryEmplace(ar, 20, 5, 6));
|
|
|
+ TEST_FALSE(map.tryEmplace(ar, 3, 6, 7));
|
|
|
+ TEST_FALSE(map.tryEmplace(ar, 20, 7, 8));
|
|
|
+
|
|
|
+ ProbingTest* a = map.search(0);
|
|
|
+ ProbingTest* b = map.search(3);
|
|
|
+ ProbingTest* c = map.search(20);
|
|
|
+
|
|
|
+ if(TEST_NOT_NULL(a) && TEST_NOT_NULL(b) && TEST_NOT_NULL(c)) {
|
|
|
+ TEST(ProbingTest(3, 4), *a);
|
|
|
+ TEST(ProbingTest(4, 5), *b);
|
|
|
+ TEST(ProbingTest(5, 6), *c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ TEST(0, aInstances);
|
|
|
}
|
|
|
|
|
|
-static void testAddCollisions() {
|
|
|
- HashMapSize map = getTestSizeMap();
|
|
|
- for(size_t i = 0; i < 16; i++) {
|
|
|
- *putHashMapKeySize(&map, i * 64) = i;
|
|
|
+template<typename T>
|
|
|
+static void testToString() {
|
|
|
+ if constexpr(Core::IsSame<T, int>) {
|
|
|
+ TEST_STRING(
|
|
|
+ "[1 = 3, 2 = 4, 3 = 5, 2147483647 = 20]", getTestIntMap<T>());
|
|
|
+ } else {
|
|
|
+ TEST_STRING("[0 = 20, 2 = 4, 1 = 3, 3 = 5]", getTestIntMap<T>());
|
|
|
}
|
|
|
- destroyHashMapSize(&map);
|
|
|
+ TEST_STRING("[1 = 3]", T().add(1, 3));
|
|
|
+ TEST_STRING("[]", T());
|
|
|
}
|
|
|
|
|
|
-static void testRemove() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
- *putHashMapKeySize(&map, 1) = 3;
|
|
|
- *putHashMapKeySize(&map, 2) = 4;
|
|
|
- *putHashMapKeySize(&map, 3) = 5;
|
|
|
+template<typename T>
|
|
|
+static void testCopy() {
|
|
|
+ T map = getTestIntMap<T>();
|
|
|
+ T copy = map;
|
|
|
+ T copyA;
|
|
|
+ copyA = map;
|
|
|
+ checkIntMap(map);
|
|
|
+ checkIntMap(copy);
|
|
|
+ checkIntMap(copyA);
|
|
|
+ map.add(1, 20).add(2, 30).add(3, 40);
|
|
|
+ checkIntMap(copy);
|
|
|
+ checkIntMap(copyA);
|
|
|
+}
|
|
|
|
|
|
- TEST_TRUE(removeHashMapKeySize(&map, 2));
|
|
|
- TEST_FALSE(removeHashMapKeySize(&map, 7));
|
|
|
+template<typename T>
|
|
|
+static void testMove() {
|
|
|
+ T map = getTestIntMap<T>();
|
|
|
+ T move(Core::move(map));
|
|
|
+ checkIntMap(move);
|
|
|
+}
|
|
|
|
|
|
- size_t* a = searchHashMapKeySize(&map, 1);
|
|
|
- size_t* b = searchHashMapKeySize(&map, 2);
|
|
|
- size_t* c = searchHashMapKeySize(&map, 3);
|
|
|
+template<typename T>
|
|
|
+static void testMoveAssignment() {
|
|
|
+ T map = getTestIntMap<T>();
|
|
|
+ T move;
|
|
|
+ move = Core::move(map);
|
|
|
+ checkIntMap(move);
|
|
|
+}
|
|
|
|
|
|
- TEST_NULL(b);
|
|
|
- if(TEST_NOT_NULL(a) && TEST_NOT_NULL(c)) {
|
|
|
- TEST_SIZE(3, *a);
|
|
|
- TEST_SIZE(5, *c);
|
|
|
- }
|
|
|
+template<typename T>
|
|
|
+static void testEntryForEach() {
|
|
|
+ T map;
|
|
|
+ map.add(0, 1).add(5, 4).add(10, 3).add(15, 2);
|
|
|
|
|
|
- destroyHashMapSize(&map);
|
|
|
-}
|
|
|
+ int counter = 0;
|
|
|
+ for(auto entry : map) {
|
|
|
+ counter += entry.getKey() + entry.value;
|
|
|
+ }
|
|
|
+ TEST(40, counter);
|
|
|
|
|
|
-static void testHash() {
|
|
|
- const char* s = "wusi";
|
|
|
- TEST_TRUE(hashString(s) != 0);
|
|
|
+ const T& cmap = map;
|
|
|
+ counter = 0;
|
|
|
+ for(auto entry : cmap) {
|
|
|
+ counter += entry.getKey() + entry.value;
|
|
|
+ }
|
|
|
+ TEST(40, counter);
|
|
|
}
|
|
|
|
|
|
-static size_t toStringA(const A* a, char* buffer, size_t n) {
|
|
|
- return toString(buffer, n, "{%zu, %zu}", a->a, a->b);
|
|
|
-}
|
|
|
+template<typename T>
|
|
|
+static void testKeyForEach() {
|
|
|
+ T map;
|
|
|
+ map.add(5, 4).add(10, 3).add(15, 2);
|
|
|
|
|
|
-static void testSearchStruct() {
|
|
|
- HashMapA map;
|
|
|
- initHashMapA(&map);
|
|
|
- clearHashMapA(&map);
|
|
|
- A a = {1, 2};
|
|
|
- A b = {1, 3};
|
|
|
- A c = {0, 0};
|
|
|
- TEST_NULL(searchHashMapKeyA(&map, a));
|
|
|
- TEST_NULL(searchHashMapKeyA(&map, b));
|
|
|
- TEST_NULL(searchHashMapKeyA(&map, c));
|
|
|
- *putHashMapKeyA(&map, a) = 3;
|
|
|
- *putHashMapKeyA(&map, (A){5, 6}) = 5;
|
|
|
-
|
|
|
- char buffer[128];
|
|
|
- size_t n =
|
|
|
- toStringHashMapA(&map, buffer, sizeof(buffer), toStringA, toStringInt);
|
|
|
- TEST_SIZE(24, n);
|
|
|
- TEST_STRING("[{5, 6} = 5, {1, 2} = 3]", buffer);
|
|
|
-
|
|
|
- int* ap = searchHashMapKeyA(&map, a);
|
|
|
- if(TEST_NOT_NULL(ap)) {
|
|
|
- TEST_INT(3, *ap);
|
|
|
+ int counter = 0;
|
|
|
+ for(const int& key : map.getKeys()) {
|
|
|
+ counter += key;
|
|
|
}
|
|
|
- TEST_NULL(searchHashMapKeyA(&map, b));
|
|
|
- TEST_NULL(searchHashMapKeyA(&map, c));
|
|
|
+ TEST(30, counter);
|
|
|
|
|
|
- *putHashMapKeyA(&map, c) = 4;
|
|
|
- int* cp = searchHashMapKeyA(&map, c);
|
|
|
- if(TEST_NOT_NULL(cp)) {
|
|
|
- TEST_INT(4, *cp);
|
|
|
+ const T& cmap = map;
|
|
|
+ counter = 0;
|
|
|
+ for(const int& key : cmap.getKeys()) {
|
|
|
+ counter += key;
|
|
|
}
|
|
|
+ TEST(30, counter);
|
|
|
+}
|
|
|
+
|
|
|
+template<typename T>
|
|
|
+static void testValueForEach() {
|
|
|
+ T map;
|
|
|
+ map.add(5, 4).add(10, 3).add(15, 2);
|
|
|
|
|
|
- for(size_t i = 0; i < 16; i++) {
|
|
|
- *putHashMapKeyA(&map, (A){i * 64, 0}) = (int)i;
|
|
|
+ int counter = 0;
|
|
|
+ for(int& value : map.getValues()) {
|
|
|
+ counter += value;
|
|
|
}
|
|
|
+ TEST(9, counter);
|
|
|
|
|
|
- HashMapIteratorA iter;
|
|
|
- initHashMapIteratorA(&iter, &map);
|
|
|
- size_t sum = 0;
|
|
|
- while(hasNextHashMapNodeA(&iter)) {
|
|
|
- HashMapNodeA* node = nextHashMapNodeA(&iter);
|
|
|
- sum += node->key->b;
|
|
|
+ const T& cmap = map;
|
|
|
+ counter = 0;
|
|
|
+ for(const int& value : cmap.getValues()) {
|
|
|
+ counter += value;
|
|
|
}
|
|
|
- TEST_SIZE(8, sum);
|
|
|
+ TEST(9, counter);
|
|
|
+}
|
|
|
+
|
|
|
+template<typename T>
|
|
|
+static void testType() {
|
|
|
+ Core::ProbingHashMap<T, int> m;
|
|
|
+ m.add(1, 3);
|
|
|
+}
|
|
|
|
|
|
- removeHashMapKeyA(&map, (A){0, 1});
|
|
|
- removeHashMapKeyA(&map, (A){0, 0});
|
|
|
- clearHashMapA(&map);
|
|
|
+template<typename T>
|
|
|
+static void testTypes() {
|
|
|
+ testType<char>();
|
|
|
+ testType<signed char>();
|
|
|
+ testType<signed short>();
|
|
|
+ testType<signed int>();
|
|
|
+ testType<signed long>();
|
|
|
+ testType<signed long long>();
|
|
|
+ testType<unsigned char>();
|
|
|
+ testType<unsigned short>();
|
|
|
+ testType<unsigned int>();
|
|
|
+ testType<unsigned long>();
|
|
|
+ testType<unsigned long long>();
|
|
|
+}
|
|
|
|
|
|
- destroyHashMapA(&map);
|
|
|
+template<typename T>
|
|
|
+static void testInvalid() {
|
|
|
+ T map;
|
|
|
+ int* v;
|
|
|
+ TEST_TRUE(map.tryEmplace(v, 0, 2));
|
|
|
+ if(TEST_NOT_NULL(v)) {
|
|
|
+ TEST(2, *v);
|
|
|
+ }
|
|
|
+ TEST_FALSE(map.tryEmplace(v, 0, 6));
|
|
|
+ if(TEST_NOT_NULL(v)) {
|
|
|
+ TEST(2, *v);
|
|
|
+ }
|
|
|
+ TEST(3, map.put(0, 3));
|
|
|
+ v = map.search(0);
|
|
|
+ if(TEST_NOT_NULL(v)) {
|
|
|
+ TEST(3, *v);
|
|
|
+ }
|
|
|
+ map.clear();
|
|
|
+ TEST_NULL(map.search(0));
|
|
|
}
|
|
|
|
|
|
-static void testSearchSize() {
|
|
|
- HashMapSize map;
|
|
|
- initHashMapSize(&map);
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 0));
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 1));
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 2));
|
|
|
- *putHashMapKeySize(&map, 1) = 3;
|
|
|
-
|
|
|
- size_t* ap = searchHashMapKeySize(&map, 1);
|
|
|
- if(TEST_NOT_NULL(ap)) {
|
|
|
- TEST_SIZE(3, *ap);
|
|
|
+template<typename T>
|
|
|
+static void testInvalidPut() {
|
|
|
+ T map;
|
|
|
+ TEST_STRING("[]", map);
|
|
|
+ TEST(3, map.put(0, 3));
|
|
|
+ TEST_STRING("[0 = 3]", map);
|
|
|
+ int* v = map.search(0);
|
|
|
+ if(TEST_NOT_NULL(v)) {
|
|
|
+ TEST(3, *v);
|
|
|
}
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 0));
|
|
|
- TEST_NULL(searchHashMapKeySize(&map, 2));
|
|
|
+ map.clear();
|
|
|
+ TEST_FALSE(map.contains(0));
|
|
|
+ TEST_STRING("[]", map);
|
|
|
+}
|
|
|
|
|
|
- *putHashMapKeySize(&map, 0) = 4;
|
|
|
- size_t* cp = searchHashMapKeySize(&map, 0);
|
|
|
- if(TEST_NOT_NULL(cp)) {
|
|
|
- TEST_SIZE(4, *cp);
|
|
|
+template<typename T>
|
|
|
+static void testAddCollisions() {
|
|
|
+ T map;
|
|
|
+ for(int i = 0; i < 16; i++) {
|
|
|
+ map.add(i * 64, i);
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- destroyHashMapSize(&map);
|
|
|
+template<typename T>
|
|
|
+static void testMap(bool light) {
|
|
|
+ testAdd<T>();
|
|
|
+ testMultipleAdd<T>();
|
|
|
+ testSearch<T>();
|
|
|
+ testAddReplace<T>();
|
|
|
+ testClear<T>();
|
|
|
+ testOverflow<T>(light);
|
|
|
+ testToString<T>();
|
|
|
+ testCopy<T>();
|
|
|
+ testMove<T>();
|
|
|
+ testMoveAssignment<T>();
|
|
|
+ testEntryForEach<T>();
|
|
|
+ testKeyForEach<T>();
|
|
|
+ testValueForEach<T>();
|
|
|
+ testTypes<T>();
|
|
|
+ testInvalid<T>();
|
|
|
+ testInvalidPut<T>();
|
|
|
+ testAddCollisions<T>();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
void testHashMap(bool light) {
|
|
|
- testAdd();
|
|
|
- testMultipleAdd();
|
|
|
- testSearch();
|
|
|
- testSearchEmpty();
|
|
|
- testAddReplace();
|
|
|
- testClear();
|
|
|
- testClearEmpty();
|
|
|
- testOverflow(light);
|
|
|
- testToString();
|
|
|
- testEntryForEach();
|
|
|
- testInvalidPut();
|
|
|
- testAddCollisions();
|
|
|
- testRemove();
|
|
|
- testHash();
|
|
|
- testSearchStruct();
|
|
|
- testSearchSize();
|
|
|
+ if(!light) {
|
|
|
+
|
|
|
+ testMap<ProbingIntMap>(light);
|
|
|
+
|
|
|
+
|
|
|
+ testEmplaceProbing();
|
|
|
+
|
|
|
+ }
|
|
|
+ ProbingIntMap map;
|
|
|
+ map.add(1, 2);
|
|
|
+ map.add(17, 3);
|
|
|
+ map.add(33, 4);
|
|
|
+ map.add(33, 6);
|
|
|
+ map.add(49, 5);
|
|
|
+ LOG_WARNING("#", map);
|
|
|
+ LOG_WARNING("#", map.keys);
|
|
|
+ LOG_WARNING("#", map.jumps);
|
|
|
}
|