adds cxLinkedListWrap and cxLinkedListRecalculateSize

Mon, 08 Feb 2021 00:14:07 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 08 Feb 2021 00:14:07 +0100
changeset 406
9cbea761fbf7
parent 405
44efaa54d63d
child 407
b447539ec255

adds cxLinkedListWrap and cxLinkedListRecalculateSize

src/cx/linked_list.h file | annotate | diff | comparison | revisions
src/cx/list.h file | annotate | diff | comparison | revisions
src/linked_list.c file | annotate | diff | comparison | revisions
--- a/src/cx/linked_list.h	Sun Feb 07 21:29:51 2021 +0100
+++ b/src/cx/linked_list.h	Mon Feb 08 00:14:07 2021 +0100
@@ -34,10 +34,22 @@
 
 void *cx_linked_list_last(void **begin, void **end, ptrdiff_t loc_next);
 
-int cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *newnode);
-
-CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t itemsize);
+int cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node);
 
 extern cx_list_class cx_linked_list_class;
 
+typedef struct {
+    void **begin;
+    void **end;
+    ptrdiff_t loc_prev;
+    ptrdiff_t loc_next;
+    size_t item_size;
+} CxLinkedListDesc;
+
+CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size);
+
+CxList cxLinkedListWrap(CxAllocator allocator, CxListComparator comparator, CxLinkedListDesc desc);
+
+size_t cxLinkedListRecalculateSize(CxList list);
+
 #endif /* UCX_LINKED_LIST_H */
--- a/src/cx/list.h	Sun Feb 07 21:29:51 2021 +0100
+++ b/src/cx/list.h	Mon Feb 08 00:14:07 2021 +0100
@@ -40,7 +40,7 @@
     size_t itemsize;
     size_t size;
     size_t capacity;
-    void *listdata;
+    char listdata[];
 } cx_list;
 
 typedef struct {
--- a/src/linked_list.c	Sun Feb 07 21:29:51 2021 +0100
+++ b/src/linked_list.c	Mon Feb 08 00:14:07 2021 +0100
@@ -51,7 +51,7 @@
     }
 }
 
-int cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *newnode) {
+int cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) {
     // TODO: how do we report error messages?
     if (loc_next < 0 || (begin == NULL && end == NULL)) {
         return 1;
@@ -62,15 +62,15 @@
         if (begin == NULL) {
             return 1;
         } else {
-            *begin = newnode;
+            *begin = new_node;
             return 0;
         }
     }
 
     void **next = CX_LL_PTR(last, loc_next);
-    *next = newnode;
+    *next = new_node;
     if (loc_prev >= 0) {
-        void **prev = CX_LL_PTR(newnode, loc_prev);
+        void **prev = CX_LL_PTR(new_node, loc_prev);
         *prev = last;
     }
 
@@ -88,19 +88,21 @@
 typedef struct {
     void *begin;
     void *end;
+    ptrdiff_t loc_prev;
+    ptrdiff_t loc_next;
 } cx_linked_list;
 
 int cx_ll_add(cx_list *list, void *elem) {
-    cx_linked_list *listdata = list->listdata;
+    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
     CxAllocator allocator = list->allocator;
 
     struct cx_linked_list_node *node = cxMalloc(allocator,
-            sizeof(struct cx_linked_list_node) + list->itemsize);
+                                                sizeof(struct cx_linked_list_node) + list->itemsize);
     if (node == NULL)
         return 1;
 
     node->next = NULL;
-    memcpy(&node->payload, elem, list->itemsize);
+    memcpy(node->payload, elem, list->itemsize);
 
     int ret = cx_linked_list_add(
             &listdata->begin,
@@ -118,27 +120,27 @@
 }
 
 int cx_ll_insert(cx_list *list, size_t index, void *elem) {
-    cx_linked_list *listdata = list->listdata;
+    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
     // TODO: implement using low level API
     return 1;
 }
 
 void *cx_ll_remove(cx_list *list, size_t index) {
-    cx_linked_list *listdata = list->listdata;
+    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
     // TODO: implement using low level API
     return NULL;
 }
 
 size_t cx_ll_find(cx_list *list, void *elem) {
-    cx_linked_list *listdata = list->listdata;
+    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
     // TODO: implement using low level API
     return 0;
 }
 
 void *cx_ll_last(cx_list *list) {
-    cx_linked_list *ll = list->listdata;
+    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
     struct cx_linked_list_node *last = cx_linked_list_last(
-            NULL, &ll->end, offsetof(struct cx_linked_list_node, next));
+            NULL, &listdata->end, offsetof(struct cx_linked_list_node, next));
     return &last->payload;
 }
 
@@ -150,20 +152,50 @@
         cx_ll_last
 };
 
-CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t itemsize) {
-    CxList list = cxMalloc(allocator, sizeof(list));
+CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) {
+    CxLinkedListDesc desc;
+    desc.item_size = item_size;
+    desc.begin = desc.end = NULL;
+    desc.loc_prev = offsetof(struct cx_linked_list_node, prev);
+    desc.loc_next = offsetof(struct cx_linked_list_node, next);
+
+    return cxLinkedListWrap(allocator, comparator, desc);
+}
+
+CxList cxLinkedListWrap(CxAllocator allocator, CxListComparator comparator, CxLinkedListDesc desc) {
+    CxList list = cxMalloc(allocator, sizeof(list) + sizeof(cx_linked_list));
     if (list == NULL)
         return NULL;
 
     list->cl = &cx_linked_list_class;
     list->data.allocator = allocator;
     list->data.cmpfunc = comparator;
-    list->data.size = 0;
-    list->data.itemsize = itemsize;
+    list->data.itemsize = desc.item_size;
     list->data.capacity = SIZE_MAX;
-    list->data.listdata = cxCalloc(allocator, 1, sizeof(cx_linked_list));
-    if (list->data.listdata == NULL) {
-        cxFree(allocator, list);
-        return NULL;
+
+    cx_linked_list *ll = (cx_linked_list *) list->data.listdata;
+    ll->begin = desc.begin ? *desc.begin : NULL;
+    ll->end = desc.end ? *desc.end : NULL;
+    ll->loc_prev = desc.loc_prev;
+    ll->loc_next = desc.loc_next;
+    cxLinkedListRecalculateSize(list);
+
+    return list;
+}
+
+size_t cxLinkedListRecalculateSize(CxList list) {
+    cx_linked_list *ll = (cx_linked_list *) list->data.listdata;
+
+    if (ll->begin == NULL) {
+        list->data.size = 0;
+        return 0;
+    } else {
+        void *cur = ll->begin;
+        size_t size;
+        do {
+            size++;
+        } while ((cur = *CX_LL_PTR(cur, ll->loc_next)) != NULL);
+        list->data.size = size;
+        return size;
     }
-}
\ No newline at end of file
+}

mercurial