# HG changeset patch # User Mike Becker # Date 1632673884 -7200 # Node ID 0fe204d50f54fa5692c1f8cd3811a9db8648905d # Parent 38ee262e8b946bad0357bc3be5f061029f57f3de change inheritance model for lists diff -r 38ee262e8b94 -r 0fe204d50f54 src/cx/list.h --- 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; diff -r 38ee262e8b94 -r 0fe204d50f54 src/linked_list.c --- 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; } } diff -r 38ee262e8b94 -r 0fe204d50f54 src/list.c --- 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); } diff -r 38ee262e8b94 -r 0fe204d50f54 test/test_list.c --- 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)