Bladeren bron

List add at index

Kajetan Johannes Hammerle 2 maanden geleden
bovenliggende
commit
8fc4705303

+ 21 - 0
include/core/ArrayList.hpp

@@ -76,6 +76,27 @@ namespace Core {
             return *this;
         }
 
+        template<typename... Args>
+        T* putAt(size_t t, Args&&... args) {
+            if(length >= N) {
+                return nullptr;
+            } else if(t >= length) {
+                return put(Core::forward<Args>(args)...);
+            }
+            put(Core::move(begin()[length - 1]));
+            for(size_t i = length - 2; i > t; i--) {
+                (*this)[i] = Core::move((*this)[i - 1]);
+            }
+            (*this)[t] = Core::move(T(Core::forward<Args>(args)...));
+            return begin() + t;
+        }
+
+        template<typename... Args>
+        ArrayList& addAt(size_t index, Args&&... args) {
+            putAt(index, Core::forward<Args>(args)...);
+            return *this;
+        }
+
         T& operator[](size_t index) {
             return begin()[index];
         }

+ 2 - 2
include/core/HashMap.hpp

@@ -194,11 +194,11 @@ namespace Core {
             if(length > 0) {
                 for(size_t i = 1; i < length; i++) {
                     if(keys[i] != INVALID) {
-                        map.add(keys[i], values[i]);
+                        map.add(keys[i], Core::move(values[i]));
                     }
                 }
                 if(invalidSet) {
-                    map.add(INVALID, values[length]);
+                    map.add(INVALID, Core::move(values[length]));
                 }
             }
             swap(map);

+ 19 - 0
include/core/List.hpp

@@ -110,6 +110,25 @@ namespace Core {
             return *this;
         }
 
+        template<typename... Args>
+        T& putAt(size_t t, Args&&... args) {
+            if(t >= length) {
+                return put(Core::forward<Args>(args)...);
+            }
+            put(Core::move(data[length - 1]));
+            for(size_t i = length - 2; i > t; i--) {
+                data[i] = Core::move(data[i - 1]);
+            }
+            data[t] = Core::move(T(Core::forward<Args>(args)...));
+            return data[t];
+        }
+
+        template<typename... Args>
+        List& addAt(size_t index, Args&&... args) {
+            putAt(index, Core::forward<Args>(args)...);
+            return *this;
+        }
+
         T& operator[](size_t index) {
             assert(index < length);
             return data[index];

+ 78 - 0
test/modules/ArrayListTests.cpp

@@ -143,6 +143,83 @@ static void testForRange() {
     }
 }
 
+static int arrayListInstances = 0;
+
+struct ArrayListTest final {
+    int value;
+
+    ArrayListTest(int i) : value(i) {
+        arrayListInstances++;
+    }
+
+    ArrayListTest(const ArrayListTest& o) = delete;
+
+    ArrayListTest(ArrayListTest&& o) noexcept : value(o.value) {
+        arrayListInstances++;
+    }
+
+    ~ArrayListTest() {
+        arrayListInstances--;
+    }
+
+    ArrayListTest& operator=(ArrayListTest&& o) noexcept {
+        value = o.value;
+        return *this;
+    }
+
+    ArrayListTest& operator=(const ArrayListTest& o) = delete;
+};
+
+static void testInsert() {
+    Core::ArrayList<ArrayListTest, 5> l;
+    l.addAt(0, 1);
+    TEST(1, l.getLength());
+    TEST(1, l[0].value);
+    TEST(1, arrayListInstances);
+
+    l.addAt(0, 2);
+    TEST(2, l.getLength());
+    TEST(2, l[0].value);
+    TEST(1, l[1].value);
+    TEST(2, arrayListInstances);
+
+    l.addAt(0, 3);
+    TEST(3, l.getLength());
+    TEST(3, l[0].value);
+    TEST(2, l[1].value);
+    TEST(1, l[2].value);
+    TEST(3, arrayListInstances);
+
+    l.addAt(1, 4);
+    TEST(4, l.getLength());
+    TEST(3, l[0].value);
+    TEST(4, l[1].value);
+    TEST(2, l[2].value);
+    TEST(1, l[3].value);
+    TEST(4, arrayListInstances);
+
+    l.addAt(2, 5);
+    TEST(5, l.getLength());
+    TEST(3, l[0].value);
+    TEST(4, l[1].value);
+    TEST(5, l[2].value);
+    TEST(2, l[3].value);
+    TEST(1, l[4].value);
+    TEST(5, arrayListInstances);
+
+    l.addAt(5, 4);
+    TEST(5, l.getLength());
+    TEST(3, l[0].value);
+    TEST(4, l[1].value);
+    TEST(5, l[2].value);
+    TEST(2, l[3].value);
+    TEST(1, l[4].value);
+    TEST(5, arrayListInstances);
+
+    l.clear();
+    TEST(0, arrayListInstances);
+}
+
 void testArrayList(bool light) {
     testAdd();
     testMultipleAdd();
@@ -157,4 +234,5 @@ void testArrayList(bool light) {
     testRemoveBySwap();
     testRemove();
     testForRange();
+    testInsert();
 }

+ 5 - 5
test/modules/HashMapTests.cpp

@@ -91,11 +91,9 @@ struct ProbingTest final {
         aInstances++;
     }
 
-    ProbingTest(const ProbingTest& o) : ProbingTest(o.a, o.b) {
-        aInstances++;
-    }
+    ProbingTest(const ProbingTest& o) = delete;
 
-    ProbingTest(ProbingTest&& o) : ProbingTest(o.a, o.b) {
+    ProbingTest(ProbingTest&& o) noexcept : a(o.a), b(o.b) {
         aInstances++;
     }
 
@@ -103,7 +101,9 @@ struct ProbingTest final {
         aInstances--;
     }
 
-    ProbingTest& operator=(ProbingTest o) {
+    ProbingTest& operator=(const ProbingTest& o) = delete;
+
+    ProbingTest& operator=(ProbingTest&& o) noexcept {
         a = o.a;
         b = o.b;
         return *this;

+ 79 - 0
test/modules/ListTests.cpp

@@ -200,6 +200,84 @@ static void testCopyEmpty() {
     IntList copy = list;
 }
 
+static int listInstances = 0;
+
+struct ListTest final {
+    int value;
+
+    ListTest(int i) : value(i) {
+        listInstances++;
+    }
+
+    ListTest(const ListTest& o) = delete;
+
+    ListTest(ListTest&& o) noexcept : value(o.value) {
+        listInstances++;
+    }
+
+    ~ListTest() {
+        listInstances--;
+    }
+
+    ListTest& operator=(ListTest&& o) noexcept {
+        value = o.value;
+        return *this;
+    }
+
+    ListTest& operator=(const ListTest& o) = delete;
+};
+
+static void testInsert() {
+    Core::List<ListTest> l;
+    l.addAt(0, 1);
+    TEST(1, l.getLength());
+    TEST(1, l[0].value);
+    TEST(1, listInstances);
+
+    l.addAt(0, 2);
+    TEST(2, l.getLength());
+    TEST(2, l[0].value);
+    TEST(1, l[1].value);
+    TEST(2, listInstances);
+
+    l.addAt(0, 3);
+    TEST(3, l.getLength());
+    TEST(3, l[0].value);
+    TEST(2, l[1].value);
+    TEST(1, l[2].value);
+    TEST(3, listInstances);
+
+    l.addAt(1, 4);
+    TEST(4, l.getLength());
+    TEST(3, l[0].value);
+    TEST(4, l[1].value);
+    TEST(2, l[2].value);
+    TEST(1, l[3].value);
+    TEST(4, listInstances);
+
+    l.addAt(2, 5);
+    TEST(5, l.getLength());
+    TEST(3, l[0].value);
+    TEST(4, l[1].value);
+    TEST(5, l[2].value);
+    TEST(2, l[3].value);
+    TEST(1, l[4].value);
+    TEST(5, listInstances);
+
+    l.addAt(5, 4);
+    TEST(6, l.getLength());
+    TEST(3, l[0].value);
+    TEST(4, l[1].value);
+    TEST(5, l[2].value);
+    TEST(2, l[3].value);
+    TEST(1, l[4].value);
+    TEST(4, l[5].value);
+    TEST(6, listInstances);
+
+    l.clear();
+    TEST(0, listInstances);
+}
+
 void testList(bool light) {
     testAdd();
     testMultipleAdd();
@@ -222,4 +300,5 @@ void testList(bool light) {
     testShrinkExact();
     testShrinkResize();
     testCopyEmpty();
+    testInsert();
 }

+ 3 - 0
test/modules/UtilityTests.cpp

@@ -142,6 +142,9 @@ static void outOfMemory(void*) {
 
 [[noreturn]] void testInvalidNew() {
     Core::setOutOfMemoryHandler(outOfMemory, nullptr);
+    volatile char* p2 = new char[0xFF];
+    p2[2] = 3;
+    Core::printMemoryReport();
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wpragmas"
 #pragma GCC diagnostic ignored "-Wunknown-warning-option"