Kaynağa Gözat

Makro Queue

Kajetan Johannes Hammerle 7 ay önce
ebeveyn
işleme
b34f5b8080
7 değiştirilmiş dosya ile 154 ekleme ve 158 silme
  1. 0 1
      CMakeLists.txt
  2. 77 17
      include/core/Queue.h
  3. 1 6
      include/core/ToString.h
  4. 0 48
      src/Queue.c
  5. 9 6
      src/ReadLine.c
  6. 0 16
      src/ToString.c
  7. 67 64
      test/modules/QueueTests.c

+ 0 - 1
CMakeLists.txt

@@ -13,7 +13,6 @@ set(SRC
     "src/Matrix.c"
     "src/Plane.c"
     "src/Quaternion.c"
-    "src/Queue.c"
     "src/Random.c"
     "src/ReadLine.c"
     "src/SpinLock.c"

+ 77 - 17
include/core/Queue.h

@@ -1,25 +1,85 @@
 #ifndef CORE_QUEUE_H
 #define CORE_QUEUE_H
 
+#include <assert.h>
+
+#include "core/ToString.h"
 #include "core/Types.h"
+#include "core/Utility.h"
 
-struct QueueT {
-    size_t writeIndex;
-    size_t readIndex;
-    size_t length;
-    size_t capacity;
-    size_t dataSize;
-    void* data;
-};
-typedef struct QueueT Queue;
+#define QUEUE(T, N)                                                            \
+    typedef struct {                                                           \
+        size_t writeIndex;                                                     \
+        size_t readIndex;                                                      \
+        size_t length;                                                         \
+        size_t capacity;                                                       \
+        T* data;                                                               \
+    } Queue##N;                                                                \
+                                                                               \
+    void initQueue##N(Queue##N* r, size_t capacity);                           \
+    void destroyQueue##N(Queue##N* r);                                         \
+    void pushQueueData##N(Queue##N* r, T data);                                \
+    T* getQueueIndex##N(const Queue##N* r, size_t index);                      \
+    void clearQueue##N(Queue##N* r);                                           \
+    void popQueueData##N(Queue##N* r);                                         \
+    typedef size_t (*ToString##N)(const T*, char* buffer, size_t n);           \
+    size_t toStringQueue##N(const Queue##N* r, char* buffer, size_t n,         \
+                            ToString##N c);
 
-void initQueue(Queue* r, size_t capacity, size_t dataSize);
-void destroyQueue(Queue* r);
-void pushQueueData(Queue* r, const void* data);
-#define pushQueueType(l, type, ...) pushQueueData(l, &(type){__VA_ARGS__})
-void* getQueueIndex(const Queue* r, size_t index);
-#define getTypedQueueIndex(r, index, type) (*(type*)getQueueIndex(r, index))
-void clearQueue(Queue* r);
-void popQueueData(Queue* r);
+#define QUEUE_SOURCE(T, N)                                                     \
+    void initQueue##N(Queue##N* r, size_t capacity) {                          \
+        *r = ((Queue##N){0, 0, 0, capacity, nullptr});                         \
+    }                                                                          \
+                                                                               \
+    void destroyQueue##N(Queue##N* r) {                                        \
+        coreFree(r->data);                                                     \
+        *r = (Queue##N){0};                                                    \
+    }                                                                          \
+                                                                               \
+    void pushQueueData##N(Queue##N* r, T data) {                               \
+        if(r->length >= r->capacity) {                                         \
+            return;                                                            \
+        } else if(r->data == nullptr) {                                        \
+            r->data = coreAllocate(r->capacity * sizeof(T));                   \
+        }                                                                      \
+        r->data[r->writeIndex] = data;                                         \
+        r->writeIndex = (r->writeIndex + 1) % r->capacity;                     \
+        r->length++;                                                           \
+    }                                                                          \
+                                                                               \
+    T* getQueueIndex##N(const Queue##N* r, size_t index) {                     \
+        return r->data + ((index + r->readIndex) % r->capacity);               \
+    }                                                                          \
+                                                                               \
+    void clearQueue##N(Queue##N* r) {                                          \
+        r->writeIndex = 0;                                                     \
+        r->readIndex = 0;                                                      \
+        r->length = 0;                                                         \
+    }                                                                          \
+                                                                               \
+    void popQueueData##N(Queue##N* r) {                                        \
+        assert(r->length > 0);                                                 \
+        r->length--;                                                           \
+        r->readIndex = (r->readIndex + 1) % r->capacity;                       \
+    }                                                                          \
+                                                                               \
+    size_t toStringQueue##N(const Queue##N* r, char* buffer, size_t n,         \
+                            ToString##N c) {                                   \
+        size_t w = 0;                                                          \
+        stringAdd(&w, &buffer, &n, coreToString(buffer, n, "["));              \
+        size_t end = r->length;                                                \
+        if(end > 0) {                                                          \
+            end--;                                                             \
+            for(size_t i = 0; i < end; i++) {                                  \
+                stringAdd(&w, &buffer, &n,                                     \
+                          c(getQueueIndex##N(r, i), buffer, n));               \
+                stringAdd(&w, &buffer, &n, coreToString(buffer, n, ", "));     \
+            }                                                                  \
+            stringAdd(&w, &buffer, &n,                                         \
+                      c(getQueueIndex##N(r, end), buffer, n));                 \
+        }                                                                      \
+        stringAdd(&w, &buffer, &n, coreToString(buffer, n, "]"));              \
+        return w;                                                              \
+    }
 
 #endif

+ 1 - 6
include/core/ToString.h

@@ -10,10 +10,6 @@ size_t toStringSize(const void* p, char* buffer, size_t n);
 size_t toStringInt(const void* p, char* buffer, size_t n);
 void stringAdd(size_t* w, char** buffer, size_t* n, size_t shift);
 
-struct QueueT;
-size_t toStringQueue(const struct QueueT* r, char* buffer, size_t n,
-                     ToString c);
-
 #define STRUCT_TO_STRING(type)                                                 \
     struct type##T;                                                            \
     size_t toString##type(const struct type##T* a, char* buffer, size_t n);
@@ -35,7 +31,6 @@ STRUCT_TO_STRING(Plane)
         STRUCT_PAIR(BitArray),                                                 \
         STRUCT_PAIR(Box),                                                      \
         STRUCT_PAIR(Matrix),                                                   \
-        STRUCT_PAIR(Plane),                                                    \
-        STRUCT_PAIR(Queue))(t, __VA_ARGS__)
+        STRUCT_PAIR(Plane))(t, __VA_ARGS__)
 
 #endif

+ 0 - 48
src/Queue.c

@@ -1,48 +0,0 @@
-#include "core/Queue.h"
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "core/ToString.h"
-#include "core/Utility.h"
-
-void initQueue(Queue* r, size_t capacity, size_t dataSize) {
-    *r = ((Queue){0, 0, 0, capacity, dataSize, nullptr});
-}
-
-void destroyQueue(Queue* r) {
-    coreFree(r->data);
-    *r = (Queue){0};
-}
-
-static void* getPointer(const Queue* r, size_t index) {
-    return (char*)r->data + r->dataSize * index;
-}
-
-void pushQueueData(Queue* r, const void* data) {
-    if(r->length >= r->capacity) {
-        return;
-    } else if(r->data == nullptr) {
-        r->data = coreAllocate(r->capacity * r->dataSize);
-    }
-    memcpy(getPointer(r, r->writeIndex), data, r->dataSize);
-    r->writeIndex = (r->writeIndex + 1) % r->capacity;
-    r->length++;
-}
-
-void* getQueueIndex(const Queue* r, size_t index) {
-    return getPointer(r, (index + r->readIndex) % r->capacity);
-}
-
-void clearQueue(Queue* r) {
-    r->writeIndex = 0;
-    r->readIndex = 0;
-    r->length = 0;
-}
-
-void popQueueData(Queue* r) {
-    assert(r->length > 0);
-    r->length--;
-    r->readIndex = (r->readIndex + 1) % r->capacity;
-}

+ 9 - 6
src/ReadLine.c

@@ -23,11 +23,14 @@ typedef struct ConsoleLine {
     int length;
 } ConsoleLine;
 
+QUEUE(ConsoleLine, CL)
+QUEUE_SOURCE(ConsoleLine, CL)
+
 static atomic_bool running = true;
 static thrd_t readThread = {0};
 
 static struct termios original;
-static Queue buffer = {0};
+static QueueCL buffer = {0};
 static ConsoleLine currentBuffer = {0};
 static int move = 0;
 static int cursorMove = 0;
@@ -115,7 +118,7 @@ static void unlock() {
 static void addLine() {
     addToHistory();
     lock();
-    pushQueueData(&buffer, &currentBuffer);
+    pushQueueDataCL(&buffer, currentBuffer);
     unlock();
     clear();
 }
@@ -259,7 +262,7 @@ bool startReadLine(void) {
         LOG_WARNING("cannot set terminal attributes");
     }
 
-    initQueue(&buffer, 10, sizeof(ConsoleLine));
+    initQueueCL(&buffer, 10);
     atomic_store(&running, true);
     if(MUTEX_INIT_FAIL || mtx_init(&bufferMutex, mtx_plain) != thrd_success) {
         LOG_ERROR("cannot init buffer mutex");
@@ -279,9 +282,9 @@ bool readLine(char* buffer_, size_t n) {
         return false;
     }
     lock();
-    ConsoleLine* line = getQueueIndex(&buffer, 0);
+    ConsoleLine* line = getQueueIndexCL(&buffer, 0);
     snprintf(buffer_, n, "%s", line->data);
-    popQueueData(&buffer);
+    popQueueDataCL(&buffer);
     unlock();
     return true;
 }
@@ -290,6 +293,6 @@ void stopReadLine() {
     atomic_store(&running, false);
     thrd_join(readThread, nullptr);
     restoreAttributes();
-    destroyQueue(&buffer);
+    destroyQueueCL(&buffer);
     mtx_destroy(&bufferMutex);
 }

+ 0 - 16
src/ToString.c

@@ -81,19 +81,3 @@ size_t toStringPlane(const Plane* p, char* buffer, size_t n) {
                         (double)p->abc.data[0], (double)p->abc.data[1],
                         (double)p->abc.data[2], (double)p->d);
 }
-
-size_t toStringQueue(const Queue* r, char* buffer, size_t n, ToString c) {
-    size_t w = 0;
-    stringAdd(&w, &buffer, &n, coreToString(buffer, n, "["));
-    size_t end = r->length;
-    if(end > 0) {
-        end--;
-        for(size_t i = 0; i < end; i++) {
-            stringAdd(&w, &buffer, &n, c(getQueueIndex(r, i), buffer, n));
-            stringAdd(&w, &buffer, &n, coreToString(buffer, n, ", "));
-        }
-        stringAdd(&w, &buffer, &n, c(getQueueIndex(r, end), buffer, n));
-    }
-    stringAdd(&w, &buffer, &n, coreToString(buffer, n, "]"));
-    return w;
-}

+ 67 - 64
test/modules/QueueTests.c

@@ -3,119 +3,122 @@
 #include "core/ToString.h"
 #include "core/Utility.h"
 
+QUEUE(size_t, Size)
+QUEUE_SOURCE(size_t, Size)
+
 static void testReadAndWrite() {
-    Queue r;
-    initQueue(&r, 5, sizeof(size_t));
+    QueueSize r;
+    initQueueSize(&r, 5);
     TEST_SIZE(0, r.length);
-    pushQueueType(&r, size_t, 4);
+    pushQueueDataSize(&r, 4);
     TEST_SIZE(1, r.length);
-    TEST_SIZE(4, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
+    TEST_SIZE(4, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
     TEST_SIZE(0, r.length);
-    destroyQueue(&r);
+    destroyQueueSize(&r);
 }
 
 static void testOverflow() {
-    Queue r;
-    initQueue(&r, 3, sizeof(size_t));
-    pushQueueType(&r, size_t, 1);
-    pushQueueType(&r, size_t, 2);
-    pushQueueType(&r, size_t, 3);
-    pushQueueType(&r, size_t, 4);
-    pushQueueType(&r, size_t, 5);
+    QueueSize r;
+    initQueueSize(&r, 3);
+    pushQueueDataSize(&r, 1);
+    pushQueueDataSize(&r, 2);
+    pushQueueDataSize(&r, 3);
+    pushQueueDataSize(&r, 4);
+    pushQueueDataSize(&r, 5);
     TEST_SIZE(3, r.length);
-    TEST_SIZE(1, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
+    TEST_SIZE(1, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
     TEST_SIZE(2, r.length);
-    TEST_SIZE(2, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
+    TEST_SIZE(2, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
     TEST_SIZE(1, r.length);
-    TEST_SIZE(3, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
+    TEST_SIZE(3, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
     TEST_SIZE(0, r.length);
-    destroyQueue(&r);
+    destroyQueueSize(&r);
 }
 
 static void testRefill() {
-    Queue r;
-    initQueue(&r, 3, sizeof(size_t));
-    pushQueueType(&r, size_t, 1);
-    pushQueueType(&r, size_t, 2);
-    pushQueueType(&r, size_t, 3);
-    pushQueueType(&r, size_t, 4);
+    QueueSize r;
+    initQueueSize(&r, 3);
+    pushQueueDataSize(&r, 1);
+    pushQueueDataSize(&r, 2);
+    pushQueueDataSize(&r, 3);
+    pushQueueDataSize(&r, 4);
     TEST_SIZE(3, r.length);
-    TEST_SIZE(1, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
-    TEST_SIZE(2, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
-    TEST_SIZE(3, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
+    TEST_SIZE(1, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
+    TEST_SIZE(2, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
+    TEST_SIZE(3, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
     TEST_SIZE(0, r.length);
-    pushQueueType(&r, size_t, 5);
-    pushQueueType(&r, size_t, 6);
+    pushQueueDataSize(&r, 5);
+    pushQueueDataSize(&r, 6);
     TEST_SIZE(2, r.length);
-    TEST_SIZE(5, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
-    TEST_SIZE(6, getTypedQueueIndex(&r, 0, size_t));
-    popQueueData(&r);
+    TEST_SIZE(5, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
+    TEST_SIZE(6, *getQueueIndexSize(&r, 0));
+    popQueueDataSize(&r);
     TEST_SIZE(0, r.length);
-    destroyQueue(&r);
+    destroyQueueSize(&r);
 }
 
 static void testClear() {
-    Queue r;
-    initQueue(&r, 3, sizeof(size_t));
-    pushQueueType(&r, size_t, 1);
-    pushQueueType(&r, size_t, 2);
+    QueueSize r;
+    initQueueSize(&r, 3);
+    pushQueueDataSize(&r, 1);
+    pushQueueDataSize(&r, 2);
     TEST_SIZE(2, r.length);
-    clearQueue(&r);
+    clearQueueSize(&r);
     TEST_SIZE(0, r.length);
-    destroyQueue(&r);
+    destroyQueueSize(&r);
 }
 
 static void testOverall() {
-    Queue r;
-    initQueue(&r, 3, sizeof(size_t));
-    pushQueueType(&r, size_t, 1);
-    pushQueueType(&r, size_t, 2);
-    pushQueueType(&r, size_t, 3);
+    QueueSize r;
+    initQueueSize(&r, 3);
+    pushQueueDataSize(&r, 1);
+    pushQueueDataSize(&r, 2);
+    pushQueueDataSize(&r, 3);
 
     char buffer[128];
-    toString(&r, buffer, sizeof(buffer), toStringSize);
+    toStringQueueSize(&r, buffer, sizeof(buffer), (ToStringSize)toStringSize);
     TEST_STRING("[1, 2, 3]", buffer);
     TEST_SIZE(3, r.length);
 
-    popQueueData(&r);
-    toString(&r, buffer, sizeof(buffer), toStringSize);
+    popQueueDataSize(&r);
+    toStringQueueSize(&r, buffer, sizeof(buffer), (ToStringSize)toStringSize);
     TEST_STRING("[2, 3]", buffer);
     TEST_SIZE(2, r.length);
 
-    pushQueueType(&r, size_t, 4);
-    toString(&r, buffer, sizeof(buffer), toStringSize);
+    pushQueueDataSize(&r, 4);
+    toStringQueueSize(&r, buffer, sizeof(buffer), (ToStringSize)toStringSize);
     TEST_STRING("[2, 3, 4]", buffer);
     TEST_SIZE(3, r.length);
 
-    popQueueData(&r);
-    toString(&r, buffer, sizeof(buffer), toStringSize);
+    popQueueDataSize(&r);
+    toStringQueueSize(&r, buffer, sizeof(buffer), (ToStringSize)toStringSize);
     TEST_STRING("[3, 4]", buffer);
     TEST_SIZE(2, r.length);
 
-    pushQueueType(&r, size_t, 5);
-    toString(&r, buffer, sizeof(buffer), toStringSize);
+    pushQueueDataSize(&r, 5);
+    toStringQueueSize(&r, buffer, sizeof(buffer), (ToStringSize)toStringSize);
     TEST_STRING("[3, 4, 5]", buffer);
     TEST_SIZE(3, r.length);
 
-    popQueueData(&r);
-    toString(&r, buffer, sizeof(buffer), toStringSize);
+    popQueueDataSize(&r);
+    toStringQueueSize(&r, buffer, sizeof(buffer), (ToStringSize)toStringSize);
     TEST_STRING("[4, 5]", buffer);
     TEST_SIZE(2, r.length);
 
-    clearQueue(&r);
-    toString(&r, buffer, sizeof(buffer), toStringSize);
+    clearQueueSize(&r);
+    toStringQueueSize(&r, buffer, sizeof(buffer), (ToStringSize)toStringSize);
     TEST_STRING("[]", buffer);
     TEST_SIZE(0, r.length);
 
-    destroyQueue(&r);
+    destroyQueueSize(&r);
 }
 
 void testQueue() {