1.1 --- a/src/linked_list.c Thu May 23 19:29:14 2024 +0200 1.2 +++ b/src/linked_list.c Thu May 23 20:29:28 2024 +0200 1.3 @@ -501,10 +501,10 @@ 1.4 cx_linked_list const *list, 1.5 size_t index 1.6 ) { 1.7 - if (index >= list->base.size) { 1.8 + if (index >= list->base.base.size) { 1.9 return NULL; 1.10 - } else if (index > list->base.size / 2) { 1.11 - return cx_linked_list_at(list->end, list->base.size - 1, CX_LL_LOC_PREV, index); 1.12 + } else if (index > list->base.base.size / 2) { 1.13 + return cx_linked_list_at(list->end, list->base.base.size - 1, CX_LL_LOC_PREV, index); 1.14 } else { 1.15 return cx_linked_list_at(list->begin, 0, CX_LL_LOC_NEXT, index); 1.16 } 1.17 @@ -517,15 +517,15 @@ 1.18 ) { 1.19 1.20 // create the new new_node 1.21 - cx_linked_list_node *new_node = cxMalloc(list->allocator, 1.22 - sizeof(cx_linked_list_node) + list->item_size); 1.23 + cx_linked_list_node *new_node = cxMalloc(list->base.allocator, 1.24 + sizeof(cx_linked_list_node) + list->base.item_size); 1.25 1.26 // sortir if failed 1.27 if (new_node == NULL) return 1; 1.28 1.29 // initialize new new_node 1.30 new_node->prev = new_node->next = NULL; 1.31 - memcpy(new_node->payload, elem, list->item_size); 1.32 + memcpy(new_node->payload, elem, list->base.item_size); 1.33 1.34 // insert 1.35 cx_linked_list *ll = (cx_linked_list *) list; 1.36 @@ -536,7 +536,7 @@ 1.37 ); 1.38 1.39 // increase the size and return 1.40 - list->size++; 1.41 + list->base.size++; 1.42 return 0; 1.43 } 1.44 1.45 @@ -547,7 +547,7 @@ 1.46 size_t n 1.47 ) { 1.48 // out-of bounds and corner case check 1.49 - if (index > list->size || n == 0) return 0; 1.50 + if (index > list->base.size || n == 0) return 0; 1.51 1.52 // find position efficiently 1.53 cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1); 1.54 @@ -566,7 +566,7 @@ 1.55 // we can add the remaining nodes and immedately advance to the inserted node 1.56 char const *source = array; 1.57 for (size_t i = 1; i < n; i++) { 1.58 - source += list->item_size; 1.59 + source += list->base.item_size; 1.60 if (0 != cx_ll_insert_at(list, node, source)) { 1.61 return i; 1.62 } 1.63 @@ -601,27 +601,27 @@ 1.64 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 1.65 1.66 // adjust size 1.67 - list->size--; 1.68 + list->base.size--; 1.69 1.70 // free and return 1.71 - cxFree(list->allocator, node); 1.72 + cxFree(list->base.allocator, node); 1.73 1.74 return 0; 1.75 } 1.76 1.77 static void cx_ll_clear(struct cx_list_s *list) { 1.78 - if (list->size == 0) return; 1.79 + if (list->base.size == 0) return; 1.80 1.81 cx_linked_list *ll = (cx_linked_list *) list; 1.82 cx_linked_list_node *node = ll->begin; 1.83 while (node != NULL) { 1.84 cx_invoke_destructor(list, node->payload); 1.85 cx_linked_list_node *next = node->next; 1.86 - cxFree(list->allocator, node); 1.87 + cxFree(list->base.allocator, node); 1.88 node = next; 1.89 } 1.90 ll->begin = ll->end = NULL; 1.91 - list->size = 0; 1.92 + list->base.size = 0; 1.93 } 1.94 1.95 #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE 1.96 @@ -634,12 +634,12 @@ 1.97 size_t i, 1.98 size_t j 1.99 ) { 1.100 - if (i >= list->size || j >= list->size) return 1; 1.101 + if (i >= list->base.size || j >= list->base.size) return 1; 1.102 if (i == j) return 0; 1.103 1.104 // perform an optimized search that finds both elements in one run 1.105 cx_linked_list *ll = (cx_linked_list *) list; 1.106 - size_t mid = list->size / 2; 1.107 + size_t mid = list->base.size / 2; 1.108 size_t left, right; 1.109 if (i < j) { 1.110 left = i; 1.111 @@ -671,7 +671,7 @@ 1.112 // chose the closest to begin / end 1.113 size_t closest; 1.114 size_t other; 1.115 - size_t diff2boundary = list->size - right - 1; 1.116 + size_t diff2boundary = list->base.size - right - 1; 1.117 if (left <= diff2boundary) { 1.118 closest = left; 1.119 other = right; 1.120 @@ -707,7 +707,7 @@ 1.121 } 1.122 } 1.123 1.124 - if (list->item_size > CX_LINKED_LIST_SWAP_SBO_SIZE) { 1.125 + if (list->base.item_size > CX_LINKED_LIST_SWAP_SBO_SIZE) { 1.126 cx_linked_list_node *prev = nleft->prev; 1.127 cx_linked_list_node *next = nright->next; 1.128 cx_linked_list_node *midstart = nleft->next; 1.129 @@ -739,9 +739,9 @@ 1.130 } else { 1.131 // swap payloads to avoid relinking 1.132 char buf[CX_LINKED_LIST_SWAP_SBO_SIZE]; 1.133 - memcpy(buf, nleft->payload, list->item_size); 1.134 - memcpy(nleft->payload, nright->payload, list->item_size); 1.135 - memcpy(nright->payload, buf, list->item_size); 1.136 + memcpy(buf, nleft->payload, list->base.item_size); 1.137 + memcpy(nleft->payload, nright->payload, list->base.item_size); 1.138 + memcpy(nright->payload, buf, list->base.item_size); 1.139 } 1.140 1.141 return 0; 1.142 @@ -768,21 +768,21 @@ 1.143 (void **) &node, 1.144 ll->begin, 1.145 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, 1.146 - list->cmpfunc, elem 1.147 + list->base.cmpfunc, elem 1.148 ); 1.149 if (node != NULL) { 1.150 cx_invoke_destructor(list, node->payload); 1.151 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 1.152 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 1.153 - list->size--; 1.154 - cxFree(list->allocator, node); 1.155 + list->base.size--; 1.156 + cxFree(list->base.allocator, node); 1.157 } 1.158 return index; 1.159 } else { 1.160 return cx_linked_list_find( 1.161 ((cx_linked_list *) list)->begin, 1.162 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, 1.163 - list->cmpfunc, elem 1.164 + list->base.cmpfunc, elem 1.165 ); 1.166 } 1.167 } 1.168 @@ -791,7 +791,7 @@ 1.169 cx_linked_list *ll = (cx_linked_list *) list; 1.170 cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end, 1.171 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA, 1.172 - list->cmpfunc); 1.173 + list->base.cmpfunc); 1.174 } 1.175 1.176 static void cx_ll_reverse(struct cx_list_s *list) { 1.177 @@ -807,7 +807,7 @@ 1.178 cx_linked_list *right = (cx_linked_list *) other; 1.179 return cx_linked_list_compare(left->begin, right->begin, 1.180 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, 1.181 - list->cmpfunc); 1.182 + list->base.cmpfunc); 1.183 } 1.184 1.185 static bool cx_ll_iter_valid(void const *it) { 1.186 @@ -817,8 +817,8 @@ 1.187 1.188 static void cx_ll_iter_next(void *it) { 1.189 struct cx_iterator_s *iter = it; 1.190 - if (iter->remove) { 1.191 - iter->remove = false; 1.192 + if (iter->base.remove) { 1.193 + iter->base.remove = false; 1.194 struct cx_list_s *list = iter->src_handle.m; 1.195 cx_linked_list *ll = iter->src_handle.m; 1.196 cx_linked_list_node *node = iter->elem_handle; 1.197 @@ -826,8 +826,8 @@ 1.198 cx_invoke_destructor(list, node->payload); 1.199 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 1.200 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 1.201 - list->size--; 1.202 - cxFree(list->allocator, node); 1.203 + list->base.size--; 1.204 + cxFree(list->base.allocator, node); 1.205 } else { 1.206 iter->index++; 1.207 cx_linked_list_node *node = iter->elem_handle; 1.208 @@ -837,8 +837,8 @@ 1.209 1.210 static void cx_ll_iter_prev(void *it) { 1.211 struct cx_iterator_s *iter = it; 1.212 - if (iter->remove) { 1.213 - iter->remove = false; 1.214 + if (iter->base.remove) { 1.215 + iter->base.remove = false; 1.216 struct cx_list_s *list = iter->src_handle.m; 1.217 cx_linked_list *ll = iter->src_handle.m; 1.218 cx_linked_list_node *node = iter->elem_handle; 1.219 @@ -847,8 +847,8 @@ 1.220 cx_invoke_destructor(list, node->payload); 1.221 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 1.222 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 1.223 - list->size--; 1.224 - cxFree(list->allocator, node); 1.225 + list->base.size--; 1.226 + cxFree(list->base.allocator, node); 1.227 } else { 1.228 iter->index--; 1.229 cx_linked_list_node *node = iter->elem_handle; 1.230 @@ -871,13 +871,13 @@ 1.231 iter.index = index; 1.232 iter.src_handle.c = list; 1.233 iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index); 1.234 - iter.elem_size = list->item_size; 1.235 - iter.elem_count = list->size; 1.236 - iter.valid = cx_ll_iter_valid; 1.237 - iter.current = cx_ll_iter_current; 1.238 - iter.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; 1.239 - iter.mutating = false; 1.240 - iter.remove = false; 1.241 + iter.elem_size = list->base.item_size; 1.242 + iter.elem_count = list->base.size; 1.243 + iter.base.valid = cx_ll_iter_valid; 1.244 + iter.base.current = cx_ll_iter_current; 1.245 + iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; 1.246 + iter.base.mutating = false; 1.247 + iter.base.remove = false; 1.248 return iter; 1.249 } 1.250 1.251 @@ -895,8 +895,8 @@ 1.252 iter->index += prepend * (0 == result); 1.253 return result; 1.254 } else { 1.255 - int result = cx_ll_insert_element(list, list->size, elem); 1.256 - iter->index = list->size; 1.257 + int result = cx_ll_insert_element(list, list->base.size, elem); 1.258 + iter->index = list->base.size; 1.259 return result; 1.260 } 1.261 } 1.262 @@ -908,11 +908,11 @@ 1.263 while (node) { 1.264 cx_invoke_destructor(list, node->payload); 1.265 void *next = node->next; 1.266 - cxFree(list->allocator, node); 1.267 + cxFree(list->base.allocator, node); 1.268 node = next; 1.269 } 1.270 1.271 - cxFree(list->allocator, list); 1.272 + cxFree(list->base.allocator, list); 1.273 } 1.274 1.275 static cx_list_class cx_linked_list_class = { 1.276 @@ -944,13 +944,13 @@ 1.277 if (list == NULL) return NULL; 1.278 1.279 list->base.cl = &cx_linked_list_class; 1.280 - list->base.allocator = allocator; 1.281 + list->base.base.allocator = allocator; 1.282 1.283 if (item_size > 0) { 1.284 - list->base.item_size = item_size; 1.285 - list->base.cmpfunc = comparator; 1.286 + list->base.base.item_size = item_size; 1.287 + list->base.base.cmpfunc = comparator; 1.288 } else { 1.289 - list->base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator; 1.290 + list->base.base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator; 1.291 cxListStorePointers((CxList *) list); 1.292 } 1.293