Przeglądaj źródła

LinkedList and tests

Kajetan Johannes Hammerle 11 miesięcy temu
rodzic
commit
947f5183d9
5 zmienionych plików z 388 dodań i 3 usunięć
  1. 3 2
      CMakeLists.txt
  2. 34 0
      include/core/LinkedList.h
  3. 94 0
      src/LinkedList.c
  4. 1 1
      test/Main.c
  5. 256 0
      test/modules/LinkedListTests.c

+ 3 - 2
CMakeLists.txt

@@ -8,6 +8,7 @@ set(SRC
     "src/Box.c"
     "src/Buffer.c"
     "src/Frustum.c"
+    "src/LinkedList.c"
     "src/List.c"
     "src/Logger.c"
     "src/Matrix.c"
@@ -27,6 +28,7 @@ set(SRC_TESTS
     "test/modules/BoxTests.c"
     "test/modules/BufferTests.c"
     "test/modules/FrustumTests.c"
+    "test/modules/LinkedListTests.c"
     "test/modules/ListTests.c"
     "test/modules/MatrixTests.c"
     "test/modules/PlaneTests.c"
@@ -38,7 +40,6 @@ set(SRC_TESTS
     "test/modules/ViewTests.c"
     #"test/modules/ComponentsTests.cpp"
     #"test/modules/HashMapTests.cpp"
-    #"test/modules/LinkedListTests.cpp"
     #"test/modules/RingBufferTests.cpp"
 )
 
@@ -100,6 +101,7 @@ target_sources(core PUBLIC
         ./include/core/Buffer.h
         ./include/core/Check.h
         ./include/core/Frustum.h
+        ./include/core/LinkedList.h
         ./include/core/List.h
         ./include/core/Logger.h
         ./include/core/Matrix.h
@@ -113,7 +115,6 @@ target_sources(core PUBLIC
         ./include/core/View.h
 #        ./include/core/Components.hpp
 #        ./include/core/HashMap.hpp
-#        ./include/core/LinkedList.hpp
 #        ./include/core/ProbingHashMap.hpp
 #        ./include/core/RingBuffer.hpp
 )

+ 34 - 0
include/core/LinkedList.h

@@ -0,0 +1,34 @@
+#ifndef CORE_LINKED_LIST_H
+#define CORE_LINKED_LIST_H
+
+#include "core/Types.h"
+
+struct CoreLinkedListNode {
+    struct CoreLinkedListNode* next;
+    struct CoreLinkedListNode* previous;
+};
+typedef struct CoreLinkedListNode CoreLinkedListNode;
+
+typedef struct {
+    CoreLinkedListNode* first;
+    CoreLinkedListNode* last;
+    size_t length;
+} CoreLinkedList;
+
+#define CORE_LINKED_LIST ((CoreLinkedList){nullptr, nullptr, 0})
+void coreDestroyLinkedList(CoreLinkedList* l);
+CoreLinkedListNode* coreLinkedListAddPointer(CoreLinkedList* l,
+                                             const void* data, size_t n);
+#define coreLinkedListAdd(l, type, ...)                                        \
+    coreLinkedListAddPointer(l, &(type){__VA_ARGS__}, sizeof(type))
+#define coreLinkedListGetPointer(node, type) ((type*)(node + 1))
+#define coreLinkedListGet(node, type) (*coreLinkedListGetPointer(node, type))
+void coreClearLinkedList(CoreLinkedList* l);
+void coreLinkedListRemove(CoreLinkedList* l, CoreLinkedListNode* n);
+void coreLinkedListRemoveFirst(CoreLinkedList* l);
+void coreLinkedListRemoveLast(CoreLinkedList* l);
+size_t coreToStringLinkedList(CoreLinkedList* l, char* buffer, size_t n,
+                              CoreToString c);
+void coreSwapLinkedList(CoreLinkedList* a, CoreLinkedList* b);
+
+#endif

+ 94 - 0
src/LinkedList.c

@@ -0,0 +1,94 @@
+#include "core/LinkedList.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "core/Utility.h"
+
+void coreDestroyLinkedList(CoreLinkedList* l) {
+    coreClearLinkedList(l);
+}
+
+CoreLinkedListNode* coreLinkedListAddPointer(CoreLinkedList* l,
+                                             const void* data, size_t n) {
+    CoreLinkedListNode* node = coreAllocate(sizeof(CoreLinkedListNode) + n);
+    node->next = nullptr;
+    node->previous = nullptr;
+    memcpy(coreLinkedListGetPointer(node, void), data, n);
+    l->length++;
+    if(l->first == nullptr) {
+        l->first = node;
+        l->last = node;
+        return node;
+    }
+    l->last->next = node;
+    node->previous = l->last;
+    l->last = node;
+    return node;
+}
+
+void coreClearLinkedList(CoreLinkedList* l) {
+    CoreLinkedListNode* n = l->first;
+    while(n != nullptr) {
+        CoreLinkedListNode* next = n->next;
+        coreFree(n);
+        n = next;
+    }
+    l->length = 0;
+    l->first = nullptr;
+    l->last = nullptr;
+}
+
+void coreLinkedListRemove(CoreLinkedList* l, CoreLinkedListNode* n) {
+    if(n == l->first) {
+        if(l->first->next != nullptr) {
+            l->first->next->previous = nullptr;
+        }
+        l->first = l->first->next;
+    }
+    if(n == l->last) {
+        if(l->last->previous != nullptr) {
+            l->last->previous->next = nullptr;
+        }
+        l->last = l->last->previous;
+    }
+    if(n->previous != nullptr) {
+        n->previous->next = n->next;
+    }
+    if(n->next != nullptr) {
+        n->next->previous = n->previous;
+    }
+    l->length--;
+    coreFree(n);
+}
+
+void coreLinkedListRemoveFirst(CoreLinkedList* l) {
+    coreLinkedListRemove(l, l->first);
+}
+
+void coreLinkedListRemoveLast(CoreLinkedList* l) {
+    coreLinkedListRemove(l, l->last);
+}
+
+size_t coreToStringLinkedList(CoreLinkedList* l, char* buffer, size_t n,
+                              CoreToString c) {
+    size_t w = 0;
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, "["));
+    CoreLinkedListNode* current = l->first;
+    while(current != nullptr) {
+        coreStringAdd(&w, &buffer, &n,
+                      c(coreLinkedListGetPointer(current, void), buffer, n));
+        current = current->next;
+        if(current != nullptr) {
+            coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, ", "));
+        }
+    }
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, "]"));
+    return w;
+}
+
+void coreSwapLinkedList(CoreLinkedList* a, CoreLinkedList* b) {
+    CoreLinkedList tmp = *a;
+    *a = *b;
+    *b = tmp;
+}

+ 1 - 1
test/Main.c

@@ -33,12 +33,12 @@ int main(int argAmount, const char** args) {
 
     // coreTestComponents();
     // coreTestHashMap(light);
-    // coreTestLinkedList(light);
     // coreTestRingBuffer();
     coreTestBitArray();
     coreTestBox();
     coreTestBuffer(light);
     coreTestFrustum();
+    coreTestLinkedList(light);
     coreTestList(light);
     coreTestMatrix();
     coreTestPlane();

+ 256 - 0
test/modules/LinkedListTests.c

@@ -0,0 +1,256 @@
+#include "../Tests.h"
+#include "core/LinkedList.h"
+#include "core/Utility.h"
+
+static void testAdd() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 5);
+    CoreLinkedListNode* current = list.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(5, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(1, list.length);
+    coreDestroyLinkedList(&list);
+}
+
+static void testMultipleAdd() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 4);
+    coreLinkedListAdd(&list, size_t, 3);
+    coreLinkedListAdd(&list, size_t, 2);
+    CoreLinkedListNode* current = list.first;
+    CORE_TEST_SIZE(4, coreLinkedListGet(current, size_t));
+    current = current->next;
+    CORE_TEST_SIZE(3, coreLinkedListGet(current, size_t));
+    current = current->next;
+    CORE_TEST_SIZE(2, coreLinkedListGet(current, size_t));
+    CORE_TEST_SIZE(3, list.length);
+    coreDestroyLinkedList(&list);
+}
+
+static void testClear() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 5);
+    coreLinkedListAdd(&list, size_t, 4);
+    coreClearLinkedList(&list);
+    CORE_TEST_SIZE(0, list.length);
+    CORE_TEST_NULL(list.first);
+    CORE_TEST_NULL(list.last);
+    coreDestroyLinkedList(&list);
+}
+
+static void testBigAdd(bool light) {
+    size_t limit = light ? 10000 : 100000;
+    CoreLinkedList list = CORE_LINKED_LIST;
+    for(size_t i = 0; i < limit; i++) {
+        coreLinkedListAdd(&list, size_t, i);
+    }
+    CoreLinkedListNode* current = list.first;
+    for(size_t i = 0; i < list.length; i++) {
+        CORE_TEST_SIZE(i, coreLinkedListGet(current, size_t));
+        current = current->next;
+    }
+    CORE_TEST_SIZE(limit, list.length);
+    coreDestroyLinkedList(&list);
+}
+
+static void testToString1() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 1);
+    coreLinkedListAdd(&list, size_t, 243);
+    coreLinkedListAdd(&list, size_t, 423);
+    char buffer[128];
+    size_t n =
+        coreToStringLinkedList(&list, buffer, sizeof(buffer), coreToStringSize);
+    CORE_TEST_SIZE(13, n);
+    CORE_TEST_STRING("[1, 243, 423]", buffer);
+    coreDestroyLinkedList(&list);
+}
+
+static void testToString2() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 1);
+    char buffer[128];
+    size_t n =
+        coreToStringLinkedList(&list, buffer, sizeof(buffer), coreToStringSize);
+    CORE_TEST_SIZE(3, n);
+    CORE_TEST_STRING("[1]", buffer);
+    coreDestroyLinkedList(&list);
+}
+
+static void testToString3() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    char buffer[128];
+    size_t n =
+        coreToStringLinkedList(&list, buffer, sizeof(buffer), coreToStringSize);
+    CORE_TEST_SIZE(2, n);
+    CORE_TEST_STRING("[]", buffer);
+    coreDestroyLinkedList(&list);
+}
+
+static void testRemove() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    CoreLinkedListNode* a = coreLinkedListAdd(&list, size_t, 4u);
+    CoreLinkedListNode* b = coreLinkedListAdd(&list, size_t, 3u);
+    CoreLinkedListNode* c = coreLinkedListAdd(&list, size_t, 2u);
+    CoreLinkedListNode* d = coreLinkedListAdd(&list, size_t, 1u);
+    CORE_TEST_NOT_NULL(a);
+    CORE_TEST_NOT_NULL(b);
+    CORE_TEST_NOT_NULL(c);
+    CORE_TEST_NOT_NULL(d);
+
+    coreLinkedListRemove(&list, b);
+    CoreLinkedListNode* current = list.first;
+    CORE_TEST_SIZE(4, coreLinkedListGet(current, size_t));
+    current = current->next;
+    CORE_TEST_SIZE(2, coreLinkedListGet(current, size_t));
+    current = current->next;
+    CORE_TEST_SIZE(1, coreLinkedListGet(current, size_t));
+    CORE_TEST_SIZE(3, list.length);
+
+    coreLinkedListRemove(&list, a);
+    current = list.first;
+    CORE_TEST_SIZE(2, coreLinkedListGet(current, size_t));
+    current = current->next;
+    CORE_TEST_SIZE(1, coreLinkedListGet(current, size_t));
+    CORE_TEST_SIZE(2, list.length);
+
+    coreLinkedListRemove(&list, d);
+    current = list.first;
+    CORE_TEST_SIZE(2, coreLinkedListGet(current, size_t));
+    CORE_TEST_SIZE(1, list.length);
+
+    coreLinkedListRemove(&list, c);
+    CORE_TEST_NULL(list.first);
+    CORE_TEST_NULL(list.last);
+    CORE_TEST_SIZE(0, list.length);
+
+    coreDestroyLinkedList(&list);
+}
+
+static void testRemoveFirst() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 4u);
+    coreLinkedListAdd(&list, size_t, 3u);
+    coreLinkedListAdd(&list, size_t, 2u);
+    coreLinkedListAdd(&list, size_t, 1u);
+
+    coreLinkedListRemoveFirst(&list);
+    CoreLinkedListNode* current = list.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(3, coreLinkedListGet(current, size_t));
+        current = current->next;
+    }
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(2, coreLinkedListGet(current, size_t));
+        current = current->next;
+    }
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(1, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(3, list.length);
+
+    coreLinkedListRemoveFirst(&list);
+    current = list.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(2, coreLinkedListGet(current, size_t));
+        current = current->next;
+    }
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(1, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(2, list.length);
+
+    coreLinkedListRemoveFirst(&list);
+    current = list.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(1, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(1, list.length);
+
+    coreLinkedListRemoveFirst(&list);
+    CORE_TEST_NULL(list.first);
+    CORE_TEST_NULL(list.last);
+    CORE_TEST_SIZE(0, list.length);
+
+    coreDestroyLinkedList(&list);
+}
+
+static void testRemoveLast() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 4u);
+    coreLinkedListAdd(&list, size_t, 3u);
+    coreLinkedListAdd(&list, size_t, 2u);
+    coreLinkedListAdd(&list, size_t, 1u);
+
+    coreLinkedListRemoveLast(&list);
+    CoreLinkedListNode* current = list.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(4, coreLinkedListGet(current, size_t));
+        current = current->next;
+    }
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(3, coreLinkedListGet(current, size_t));
+        current = current->next;
+    }
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(2, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(3, list.length);
+
+    coreLinkedListRemoveLast(&list);
+    current = list.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(4, coreLinkedListGet(current, size_t));
+        current = current->next;
+    }
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(3, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(2, list.length);
+
+    coreLinkedListRemoveLast(&list);
+    current = list.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(4, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(1, list.length);
+
+    coreLinkedListRemoveLast(&list);
+    CORE_TEST_NULL(list.first);
+    CORE_TEST_NULL(list.last);
+    CORE_TEST_SIZE(0, list.length);
+
+    coreDestroyLinkedList(&list);
+}
+
+static void testSwap() {
+    CoreLinkedList list = CORE_LINKED_LIST;
+    coreLinkedListAdd(&list, size_t, 5);
+    CoreLinkedList swap = CORE_LINKED_LIST;
+    coreSwapLinkedList(&list, &swap);
+
+    CoreLinkedListNode* current = swap.first;
+    if(CORE_TEST_NOT_NULL(current)) {
+        CORE_TEST_SIZE(5, coreLinkedListGet(current, size_t));
+    }
+    CORE_TEST_SIZE(0, list.length);
+    CORE_TEST_SIZE(1, swap.length);
+
+    coreDestroyLinkedList(&swap);
+    coreDestroyLinkedList(&list);
+}
+
+void coreTestLinkedList(bool light) {
+    testAdd();
+    testMultipleAdd();
+    testClear();
+    testBigAdd(light);
+    testToString1();
+    testToString2();
+    testToString3();
+    testRemove();
+    testRemoveFirst();
+    testRemoveLast();
+    testSwap();
+}