change inheritance model for lists

Sun, 26 Sep 2021 18:31:24 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 26 Sep 2021 18:31:24 +0200
changeset 435
0fe204d50f54
parent 434
38ee262e8b94
child 436
ca9ce2297c29

change inheritance model for lists

src/cx/list.h file | annotate | diff | comparison | revisions
src/linked_list.c file | annotate | diff | comparison | revisions
src/list.c file | annotate | diff | comparison | revisions
test/test_list.c file | annotate | diff | comparison | revisions
--- a/src/cx/list.h	Sun Sep 26 18:01:51 2021 +0200
+++ b/src/cx/list.h	Sun Sep 26 18:31:24 2021 +0200
@@ -38,31 +38,28 @@
 
 typedef int(*CxListComparator)(void const *left, void const *right);
 
+typedef struct cx_list_s cx_list_s;
+
 typedef struct {
+    int (*add)(cx_list_s *list, void *elem);
+
+    int (*insert)(cx_list_s *list, size_t index, void *elem);
+
+    void *(*remove)(cx_list_s *list, size_t index);
+
+    size_t (*find)(cx_list_s *list, void *elem);
+
+    void *(*last)(cx_list_s *list);
+} cx_list_class;
+
+struct cx_list_s {
+    cx_list_class *cl;
     CxAllocator allocator;
     CxListComparator cmpfunc;
     size_t itemsize;
     size_t size;
     size_t capacity;
-    char listdata[];
-} cx_list;
-
-typedef struct {
-    int (*add)(cx_list *list, void *elem);
-
-    int (*insert)(cx_list *list, size_t index, void *elem);
-
-    void *(*remove)(cx_list *list, size_t index);
-
-    size_t (*find)(cx_list *list, void *elem);
-
-    void *(*last)(cx_list *list);
-} cx_list_class;
-
-typedef struct {
-    cx_list_class *cl;
-    cx_list data;
-} cx_list_s;
+};
 
 typedef cx_list_s *CxList;
 
--- a/src/linked_list.c	Sun Sep 26 18:01:51 2021 +0200
+++ b/src/linked_list.c	Sun Sep 26 18:31:24 2021 +0200
@@ -90,27 +90,27 @@
 };
 
 typedef struct {
+    cx_list_s base;
     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 = (cx_linked_list *) list->listdata;
-    CxAllocator allocator = list->allocator;
+int cx_ll_add(cx_list_s *list, void *elem) {
+    cx_linked_list *linkedlist = (cx_linked_list *) list;
 
-    struct cx_linked_list_node *node = cxMalloc(allocator,
+    struct cx_linked_list_node *node = cxMalloc(list->allocator,
                                                 sizeof(struct cx_linked_list_node) + list->itemsize);
     if (node == NULL)
         return 1;
 
-    node->next = NULL;
+    node->next = node->prev = NULL;
     memcpy(node->payload, elem, list->itemsize);
 
     int ret = cx_linked_list_add(
-            &listdata->begin,
-            &listdata->end,
+            &linkedlist->begin,
+            &linkedlist->end,
             offsetof(struct cx_linked_list_node, prev),
             offsetof(struct cx_linked_list_node, next),
             node
@@ -123,28 +123,28 @@
     }
 }
 
-int cx_ll_insert(cx_list *list, size_t index, void *elem) {
-    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
+int cx_ll_insert(cx_list_s *list, size_t index, void *elem) {
+    cx_linked_list *linkedList = (cx_linked_list *) list;
     // TODO: implement using low level API
     return 1;
 }
 
-void *cx_ll_remove(cx_list *list, size_t index) {
-    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
+void *cx_ll_remove(cx_list_s *list, size_t index) {
+    cx_linked_list *linkedList = (cx_linked_list *) list;
     // TODO: implement using low level API
     return NULL;
 }
 
-size_t cx_ll_find(cx_list *list, void *elem) {
-    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
+size_t cx_ll_find(cx_list_s *list, void *elem) {
+    cx_linked_list *linkedList = (cx_linked_list *) list;
     // TODO: implement using low level API
     return 0;
 }
 
-void *cx_ll_last(cx_list *list) {
-    cx_linked_list *listdata = (cx_linked_list *) list->listdata;
+void *cx_ll_last(cx_list_s *list) {
+    cx_linked_list *linkedList = (cx_linked_list *) list;
     struct cx_linked_list_node *last = cx_linked_list_last(
-            NULL, &listdata->end, offsetof(struct cx_linked_list_node, next));
+            NULL, &linkedList->end, offsetof(struct cx_linked_list_node, next));
     return &last->payload;
 }
 
@@ -157,47 +157,47 @@
 };
 
 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) {
-    CxList list = cxMalloc(allocator, sizeof(cx_list_s) + sizeof(cx_linked_list));
+    cx_linked_list* list = cxMalloc(allocator, 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.itemsize = item_size;
-    list->data.capacity = SIZE_MAX;
+    list->base.cl = &cx_linked_list_class;
+    list->base.allocator = allocator;
+    list->base.cmpfunc = comparator;
+    list->base.itemsize = item_size;
+    list->base.capacity = SIZE_MAX;
 
-    cx_linked_list *ll = (cx_linked_list *) list->data.listdata;
-    ll->begin = NULL;
-    ll->loc_prev = offsetof(struct cx_linked_list_node, prev);
-    ll->loc_next = offsetof(struct cx_linked_list_node, next);
-    cxLinkedListRecalculateSize(list);
+    list->begin = NULL;
+    list->loc_prev = offsetof(struct cx_linked_list_node, prev);
+    list->loc_next = offsetof(struct cx_linked_list_node, next);
 
-    return list;
+    CxList result = (CxList) list;
+    cxLinkedListRecalculateSize(result);
+    return result;
 }
 
 void cxLinkedListDestroy(CxList list) {
     // TODO: free contents
-    cxFree(list->data.allocator, list);
+    cxFree(list->allocator, list);
 }
 
 size_t cxLinkedListRecalculateSize(CxList list) {
-    cx_linked_list *ll = (cx_linked_list *) list->data.listdata;
+    cx_linked_list *ll = (cx_linked_list *) list;
 
     if (ll->begin == NULL) {
-        list->data.size = 0;
+        ll->base.size = 0;
         ll->end = NULL;
         return 0;
     } else {
         void *cur = ll->begin;
         void *last;
-        size_t size;
+        size_t size = 0;
         do {
             last = cur;
             size++;
         } while ((cur = *CX_LL_PTR(cur, ll->loc_next)) != NULL);
         ll->end = last;
-        list->data.size = size;
+        ll->base.size = size;
         return size;
     }
 }
--- a/src/list.c	Sun Sep 26 18:01:51 2021 +0200
+++ b/src/list.c	Sun Sep 26 18:31:24 2021 +0200
@@ -29,21 +29,21 @@
 #include "cx/list.h"
 
 int cxListAdd(CxList list, void *elem) {
-    return list->cl->add(&list->data, elem);
+    return list->cl->add(list, elem);
 }
 
 int cxListInsert(CxList list, size_t index, void *elem) {
-    return list->cl->insert(&list->data, index, elem);
+    return list->cl->insert(list, index, elem);
 }
 
 void *cxListRemove(CxList list, size_t index) {
-    return list->cl->remove(&list->data, index);
+    return list->cl->remove(list, index);
 }
 
 size_t cxListFind(CxList list, void *elem) {
-    return list->cl->find(&list->data, elem);
+    return list->cl->find(list, elem);
 }
 
 void *cxListLast(CxList list) {
-    return list->cl->last(&list->data);
+    return list->cl->last(list);
 }
--- a/test/test_list.c	Sun Sep 26 18:01:51 2021 +0200
+++ b/test/test_list.c	Sun Sep 26 18:31:24 2021 +0200
@@ -40,20 +40,22 @@
 
     CxList list = cxLinkedListCreate(cxTestingAllocator, (CxListComparator) cmp_int, sizeof(int));
 
-    CU_ASSERT_EQUAL(list->data.size, 0)
-    CU_ASSERT_EQUAL(list->data.capacity, (size_t) -1)
-    CU_ASSERT_PTR_EQUAL(list->data.allocator, cxTestingAllocator)
-    CU_ASSERT_EQUAL(list->data.itemsize, sizeof(int))
-    CU_ASSERT_PTR_EQUAL(list->data.cmpfunc, cmp_int)
+    CU_ASSERT_EQUAL(list->size, 0)
+    CU_ASSERT_EQUAL(list->capacity, (size_t) -1)
+    CU_ASSERT_PTR_EQUAL(list->allocator, cxTestingAllocator)
+    CU_ASSERT_EQUAL(list->itemsize, sizeof(int))
+    CU_ASSERT_PTR_EQUAL(list->cmpfunc, cmp_int)
 
-    struct node {
+    // assume this structure for a linked list
+    struct ll_check {
+        cx_list_s base;
         void *begin;
         void *end;
         ptrdiff_t ploc;
         ptrdiff_t nloc;
     };
 
-    struct node *actual = (struct node *) list->data.listdata;
+    struct ll_check *actual = (struct ll_check *) list;
     CU_ASSERT_PTR_NULL(actual->begin)
     CU_ASSERT_PTR_NULL(actual->end)
     CU_ASSERT_EQUAL(0, actual->ploc)

mercurial