1.1 --- a/src/linked_list.c Sun Feb 07 21:29:51 2021 +0100 1.2 +++ b/src/linked_list.c Mon Feb 08 00:14:07 2021 +0100 1.3 @@ -51,7 +51,7 @@ 1.4 } 1.5 } 1.6 1.7 -int cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *newnode) { 1.8 +int cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { 1.9 // TODO: how do we report error messages? 1.10 if (loc_next < 0 || (begin == NULL && end == NULL)) { 1.11 return 1; 1.12 @@ -62,15 +62,15 @@ 1.13 if (begin == NULL) { 1.14 return 1; 1.15 } else { 1.16 - *begin = newnode; 1.17 + *begin = new_node; 1.18 return 0; 1.19 } 1.20 } 1.21 1.22 void **next = CX_LL_PTR(last, loc_next); 1.23 - *next = newnode; 1.24 + *next = new_node; 1.25 if (loc_prev >= 0) { 1.26 - void **prev = CX_LL_PTR(newnode, loc_prev); 1.27 + void **prev = CX_LL_PTR(new_node, loc_prev); 1.28 *prev = last; 1.29 } 1.30 1.31 @@ -88,19 +88,21 @@ 1.32 typedef struct { 1.33 void *begin; 1.34 void *end; 1.35 + ptrdiff_t loc_prev; 1.36 + ptrdiff_t loc_next; 1.37 } cx_linked_list; 1.38 1.39 int cx_ll_add(cx_list *list, void *elem) { 1.40 - cx_linked_list *listdata = list->listdata; 1.41 + cx_linked_list *listdata = (cx_linked_list *) list->listdata; 1.42 CxAllocator allocator = list->allocator; 1.43 1.44 struct cx_linked_list_node *node = cxMalloc(allocator, 1.45 - sizeof(struct cx_linked_list_node) + list->itemsize); 1.46 + sizeof(struct cx_linked_list_node) + list->itemsize); 1.47 if (node == NULL) 1.48 return 1; 1.49 1.50 node->next = NULL; 1.51 - memcpy(&node->payload, elem, list->itemsize); 1.52 + memcpy(node->payload, elem, list->itemsize); 1.53 1.54 int ret = cx_linked_list_add( 1.55 &listdata->begin, 1.56 @@ -118,27 +120,27 @@ 1.57 } 1.58 1.59 int cx_ll_insert(cx_list *list, size_t index, void *elem) { 1.60 - cx_linked_list *listdata = list->listdata; 1.61 + cx_linked_list *listdata = (cx_linked_list *) list->listdata; 1.62 // TODO: implement using low level API 1.63 return 1; 1.64 } 1.65 1.66 void *cx_ll_remove(cx_list *list, size_t index) { 1.67 - cx_linked_list *listdata = list->listdata; 1.68 + cx_linked_list *listdata = (cx_linked_list *) list->listdata; 1.69 // TODO: implement using low level API 1.70 return NULL; 1.71 } 1.72 1.73 size_t cx_ll_find(cx_list *list, void *elem) { 1.74 - cx_linked_list *listdata = list->listdata; 1.75 + cx_linked_list *listdata = (cx_linked_list *) list->listdata; 1.76 // TODO: implement using low level API 1.77 return 0; 1.78 } 1.79 1.80 void *cx_ll_last(cx_list *list) { 1.81 - cx_linked_list *ll = list->listdata; 1.82 + cx_linked_list *listdata = (cx_linked_list *) list->listdata; 1.83 struct cx_linked_list_node *last = cx_linked_list_last( 1.84 - NULL, &ll->end, offsetof(struct cx_linked_list_node, next)); 1.85 + NULL, &listdata->end, offsetof(struct cx_linked_list_node, next)); 1.86 return &last->payload; 1.87 } 1.88 1.89 @@ -150,20 +152,50 @@ 1.90 cx_ll_last 1.91 }; 1.92 1.93 -CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t itemsize) { 1.94 - CxList list = cxMalloc(allocator, sizeof(list)); 1.95 +CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) { 1.96 + CxLinkedListDesc desc; 1.97 + desc.item_size = item_size; 1.98 + desc.begin = desc.end = NULL; 1.99 + desc.loc_prev = offsetof(struct cx_linked_list_node, prev); 1.100 + desc.loc_next = offsetof(struct cx_linked_list_node, next); 1.101 + 1.102 + return cxLinkedListWrap(allocator, comparator, desc); 1.103 +} 1.104 + 1.105 +CxList cxLinkedListWrap(CxAllocator allocator, CxListComparator comparator, CxLinkedListDesc desc) { 1.106 + CxList list = cxMalloc(allocator, sizeof(list) + sizeof(cx_linked_list)); 1.107 if (list == NULL) 1.108 return NULL; 1.109 1.110 list->cl = &cx_linked_list_class; 1.111 list->data.allocator = allocator; 1.112 list->data.cmpfunc = comparator; 1.113 - list->data.size = 0; 1.114 - list->data.itemsize = itemsize; 1.115 + list->data.itemsize = desc.item_size; 1.116 list->data.capacity = SIZE_MAX; 1.117 - list->data.listdata = cxCalloc(allocator, 1, sizeof(cx_linked_list)); 1.118 - if (list->data.listdata == NULL) { 1.119 - cxFree(allocator, list); 1.120 - return NULL; 1.121 + 1.122 + cx_linked_list *ll = (cx_linked_list *) list->data.listdata; 1.123 + ll->begin = desc.begin ? *desc.begin : NULL; 1.124 + ll->end = desc.end ? *desc.end : NULL; 1.125 + ll->loc_prev = desc.loc_prev; 1.126 + ll->loc_next = desc.loc_next; 1.127 + cxLinkedListRecalculateSize(list); 1.128 + 1.129 + return list; 1.130 +} 1.131 + 1.132 +size_t cxLinkedListRecalculateSize(CxList list) { 1.133 + cx_linked_list *ll = (cx_linked_list *) list->data.listdata; 1.134 + 1.135 + if (ll->begin == NULL) { 1.136 + list->data.size = 0; 1.137 + return 0; 1.138 + } else { 1.139 + void *cur = ll->begin; 1.140 + size_t size; 1.141 + do { 1.142 + size++; 1.143 + } while ((cur = *CX_LL_PTR(cur, ll->loc_next)) != NULL); 1.144 + list->data.size = size; 1.145 + return size; 1.146 } 1.147 -} 1.148 \ No newline at end of file 1.149 +}