| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 | 
							- #include "../Tests.hpp"
 
- #include "core/ProbingHashMap.hpp"
 
- #include "core/Random.hpp"
 
- #include "core/Test.hpp"
 
- template struct Core::ProbingHashMap<int, int>;
 
- using ProbingIntMap = Core::ProbingHashMap<int, int>;
 
- // template struct Core::HashMap<int, int>;
 
- // using IntMap = Core::HashMap<int, int>;
 
- // static void testHash() {
 
- //     const char* s = "wusi";
 
- //     TEST_TRUE(hashString(s) != 0);
 
- // }
 
- template<typename T>
 
- static T getTestIntMap() {
 
-     T map;
 
-     map.add(1, 3).add(2, 4).add(3, 5).add(0, 20);
 
-     return map;
 
- }
 
- 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(3, *a);
 
-         TEST(4, *b);
 
-         TEST(5, *c);
 
-         TEST(20, *d);
 
-     }
 
- }
 
- template<typename T>
 
- static void testAdd() {
 
-     T map;
 
-     map.add(5, 4);
 
-     int* value = map.search(5);
 
-     if(TEST_NOT_NULL(value)) {
 
-         TEST(4, *value);
 
-     }
 
- }
 
- template<typename T>
 
- static void testMultipleAdd() {
 
-     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() {
 
-     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() {
 
-     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(10, *a);
 
-     }
 
- }
 
- template<typename T>
 
- static void testClear() {
 
-     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) {
 
-     int limit = light ? 10'000 : 100'000;
 
-     T map;
 
-     for(int i = 0; i < limit; i++) {
 
-         map.add(i, i);
 
-     }
 
-     for(int i = 0; i < limit; i++) {
 
-         TEST_TRUE(map.contains(i));
 
-     }
 
- }
 
- static int aInstances = 0;
 
- struct HashMapTest {
 
-     int a;
 
-     int b;
 
-     HashMapTest(int a_, int b_) : a(a_), b(b_) {
 
-     }
 
-     // none of these should be needed for the hashmap
 
-     HashMapTest(const HashMapTest&) = delete;
 
-     HashMapTest(HashMapTest&&) = delete;
 
-     HashMapTest& operator=(const HashMapTest&) = delete;
 
-     HashMapTest& operator=(HashMapTest&&) = delete;
 
-     bool operator==(const HashMapTest& other) const {
 
-         return a == other.a && b == other.b;
 
-     }
 
-     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;
 
-     }
 
- };
 
- struct ProbingTest final : public HashMapTest {
 
-     ProbingTest(int a_, int b_) : HashMapTest(a_, b_) {
 
-         aInstances++;
 
-     }
 
-     ProbingTest(const ProbingTest& o) : HashMapTest(o.a, o.b) {
 
-         aInstances++;
 
-     }
 
-     ProbingTest(ProbingTest&& o) : HashMapTest(o.a, o.b) {
 
-         aInstances++;
 
-     }
 
-     ~ProbingTest() {
 
-         aInstances--;
 
-     }
 
-     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);
 
- }
 
- 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>());
 
-     }
 
-     TEST_STRING("[1 = 3]", T().add(1, 3));
 
-     TEST_STRING("[]", T());
 
- }
 
- 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);
 
- }
 
- template<typename T>
 
- static void testMove() {
 
-     T map = getTestIntMap<T>();
 
-     T move(Core::move(map));
 
-     checkIntMap(move);
 
- }
 
- template<typename T>
 
- static void testMoveAssignment() {
 
-     T map = getTestIntMap<T>();
 
-     T move;
 
-     move = Core::move(map);
 
-     checkIntMap(move);
 
- }
 
- template<typename T>
 
- static void testEntryForEach() {
 
-     T map;
 
-     map.add(0, 1).add(5, 4).add(10, 3).add(15, 2);
 
-     int counter = 0;
 
-     for(auto entry : map) {
 
-         counter += entry.getKey() + entry.value;
 
-     }
 
-     TEST(40, counter);
 
-     const T& cmap = map;
 
-     counter = 0;
 
-     for(auto entry : cmap) {
 
-         counter += entry.getKey() + entry.value;
 
-     }
 
-     TEST(40, counter);
 
- }
 
- template<typename T>
 
- static void testKeyForEach() {
 
-     T map;
 
-     map.add(5, 4).add(10, 3).add(15, 2);
 
-     int counter = 0;
 
-     for(const int& key : map.getKeys()) {
 
-         counter += key;
 
-     }
 
-     TEST(30, counter);
 
-     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);
 
-     int counter = 0;
 
-     for(int& value : map.getValues()) {
 
-         counter += value;
 
-     }
 
-     TEST(9, counter);
 
-     const T& cmap = map;
 
-     counter = 0;
 
-     for(const int& value : cmap.getValues()) {
 
-         counter += value;
 
-     }
 
-     TEST(9, counter);
 
- }
 
- template<typename T>
 
- static void testType() {
 
-     Core::ProbingHashMap<T, int> m;
 
-     m.add(1, 3);
 
- }
 
- 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>();
 
- }
 
- 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));
 
- }
 
- 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);
 
-     }
 
-     map.clear();
 
-     TEST_FALSE(map.contains(0));
 
-     TEST_STRING("[]", map);
 
- }
 
- template<typename T>
 
- static void testAddCollisions() {
 
-     T map;
 
-     for(int i = 0; i < 16; i++) {
 
-         map.add(i * 64, i);
 
-     }
 
- }
 
- template<typename T>
 
- static void testRemove() {
 
-     T map;
 
-     map.add(1, 3).add(2, 4).add(3, 5);
 
-     TEST_TRUE(map.remove(2));
 
-     TEST_FALSE(map.remove(7));
 
-     int* a = map.search(1);
 
-     int* b = map.search(2);
 
-     int* c = map.search(3);
 
-     TEST_NULL(b);
 
-     if(TEST_NOT_NULL(a) && TEST_NOT_NULL(c)) {
 
-         TEST(3, *a);
 
-         TEST(5, *c);
 
-     }
 
- }
 
- template<typename T>
 
- static void testRemoveLong() {
 
-     T map;
 
-     Core::Random r(5);
 
-     constexpr size_t LIMIT = 75;
 
-     Core::Array<i32, LIMIT> a;
 
-     for(int i = 0; i < 10'000; i++) {
 
-         i32 r1 = r.nextI32(0, LIMIT);
 
-         if(r.nextBool()) {
 
-             i32 r2 = r.nextI32(0, LIMIT);
 
-             map.add(r1, 2);
 
-             map.add(r2, 2);
 
-             a[static_cast<size_t>(r1)] = 1;
 
-             a[static_cast<size_t>(r2)] = 1;
 
-         } else {
 
-             map.remove(r1);
 
-             a[static_cast<size_t>(r1)] = 0;
 
-         }
 
-         Core::Array<i32, LIMIT> copy = a;
 
-         for(int key : map.getKeys()) {
 
-             TEST_TRUE(copy[static_cast<size_t>(key)]);
 
-             copy[static_cast<size_t>(key)] = 0;
 
-         }
 
-         for(int key : copy) {
 
-             TEST(0, key);
 
-         }
 
-     }
 
- }
 
- 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>();
 
-     testRemove<T>();
 
-     testRemoveLong<T>();
 
- }
 
- // static void testEmplace() {
 
- //     Core::ProbingHashMap<int, HashMapTest> map;
 
- //
 
- //     HashMapTest* 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));
 
- //
 
- //     HashMapTest* a = map.search(0);
 
- //     HashMapTest* b = map.search(3);
 
- //     HashMapTest* c = map.search(20);
 
- //
 
- //     if(TEST_NOT_NULL(a) && TEST_NOT_NULL(b) && TEST_NOT_NULL(c)) {
 
- //         TEST(HashMapTest(3, 4), *a);
 
- //         TEST(HashMapTest(4, 5), *b);
 
- //         TEST(HashMapTest(5, 6), *c);
 
- //     }
 
- // }
 
- void testHashMap(bool light) {
 
-     // testHash();
 
-     testMap<ProbingIntMap>(light);
 
-     // testMap<IntMap>(light);
 
-     // testEmplace();
 
-     testEmplaceProbing();
 
- }
 
 
  |