# HG changeset patch # User Mike Becker # Date 1612739647 -3600 # Node ID 9cbea761fbf71ac21da5440decfe20e9f137f883 # Parent 44efaa54d63dab0a50d54485d9e012f95340d59d adds cxLinkedListWrap and cxLinkedListRecalculateSize diff -r 44efaa54d63d -r 9cbea761fbf7 src/cx/linked_list.h --- 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 */ diff -r 44efaa54d63d -r 9cbea761fbf7 src/cx/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 { diff -r 44efaa54d63d -r 9cbea761fbf7 src/linked_list.c --- 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 +}