170 |
170 |
171 static int cx_ll_add(cx_list_s *list, void *elem) { |
171 static int cx_ll_add(cx_list_s *list, void *elem) { |
172 return cx_ll_insert(list, list->size, elem); |
172 return cx_ll_insert(list, list->size, elem); |
173 } |
173 } |
174 |
174 |
|
175 static int cx_pll_insert(cx_list_s *list, size_t index, void *elem) { |
|
176 return cx_ll_insert(list, index, &elem); |
|
177 } |
|
178 |
|
179 static int cx_pll_add(cx_list_s *list, void *elem) { |
|
180 return cx_ll_insert(list, list->size, &elem); |
|
181 } |
|
182 |
175 static int cx_ll_remove(cx_list_s *list, size_t index) { |
183 static int cx_ll_remove(cx_list_s *list, size_t index) { |
176 cx_linked_list *ll = (cx_linked_list *) list; |
184 cx_linked_list *ll = (cx_linked_list *) list; |
177 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
185 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
178 |
186 |
179 // out-of-bounds check |
187 // out-of-bounds check |
203 } |
211 } |
204 |
212 |
205 static void *cx_ll_at(cx_list_s *list, size_t index) { |
213 static void *cx_ll_at(cx_list_s *list, size_t index) { |
206 cx_linked_list *ll = (cx_linked_list *) list; |
214 cx_linked_list *ll = (cx_linked_list *) list; |
207 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
215 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
208 return node == NULL ? NULL : &node->payload; |
216 return node == NULL ? NULL : node->payload; |
|
217 } |
|
218 |
|
219 static void *cx_pll_at(cx_list_s *list, size_t index) { |
|
220 cx_linked_list *ll = (cx_linked_list *) list; |
|
221 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
|
222 return node == NULL ? NULL : *(void**)node->payload; |
209 } |
223 } |
210 |
224 |
211 static size_t cx_ll_find(cx_list_s *list, void *elem) { |
225 static size_t cx_ll_find(cx_list_s *list, void *elem) { |
212 CxListComparator cmp = list->cmpfunc; |
226 CxListComparator cmp = list->cmpfunc; |
213 cx_linked_list *ll = (cx_linked_list *) list; |
227 cx_linked_list *ll = (cx_linked_list *) list; |
222 node = node->next; |
236 node = node->next; |
223 } |
237 } |
224 return index; |
238 return index; |
225 } |
239 } |
226 |
240 |
|
241 static size_t cx_pll_find(cx_list_s *list, void *elem) { |
|
242 CxListComparator cmp = list->cmpfunc; |
|
243 cx_linked_list *ll = (cx_linked_list *) list; |
|
244 |
|
245 size_t index; |
|
246 cx_linked_list_node *node = ll->begin; |
|
247 for (index = 0; index < list->size; index++) { |
|
248 void *current = *(void**)node->payload; |
|
249 if (cmp(current, elem) == 0) { |
|
250 return index; |
|
251 } |
|
252 node = node->next; |
|
253 } |
|
254 return index; |
|
255 } |
|
256 |
227 static void *cx_ll_last(cx_list_s *list) { |
257 static void *cx_ll_last(cx_list_s *list) { |
228 cx_linked_list *ll = (cx_linked_list *) list; |
258 cx_linked_list *ll = (cx_linked_list *) list; |
229 cx_linked_list_node *last = ll->end; |
259 cx_linked_list_node *last = ll->end; |
230 return last == NULL ? NULL : &last->payload; |
260 return last == NULL ? NULL : last->payload; |
|
261 } |
|
262 |
|
263 static void *cx_pll_last(cx_list_s *list) { |
|
264 cx_linked_list *ll = (cx_linked_list *) list; |
|
265 cx_linked_list_node *last = ll->end; |
|
266 return last == NULL ? NULL : *(void**)last->payload; |
231 } |
267 } |
232 |
268 |
233 static cx_list_class cx_linked_list_class = { |
269 static cx_list_class cx_linked_list_class = { |
234 cx_ll_add, |
270 cx_ll_add, |
235 cx_ll_insert, |
271 cx_ll_insert, |
237 cx_ll_at, |
273 cx_ll_at, |
238 cx_ll_find, |
274 cx_ll_find, |
239 cx_ll_last |
275 cx_ll_last |
240 }; |
276 }; |
241 |
277 |
|
278 static cx_list_class cx_pointer_linked_list_class = { |
|
279 cx_pll_add, |
|
280 cx_pll_insert, |
|
281 cx_ll_remove, |
|
282 cx_pll_at, |
|
283 cx_pll_find, |
|
284 cx_pll_last |
|
285 }; |
|
286 |
242 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) { |
287 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) { |
243 cx_linked_list *list = cxMalloc(allocator, sizeof(cx_linked_list)); |
288 cx_linked_list *list = cxMalloc(allocator, sizeof(cx_linked_list)); |
244 if (list == NULL) |
289 if (list == NULL) |
245 return NULL; |
290 return NULL; |
246 |
291 |
247 list->base.cl = &cx_linked_list_class; |
292 list->base.cl = &cx_linked_list_class; |
248 list->base.allocator = allocator; |
293 list->base.allocator = allocator; |
249 list->base.cmpfunc = comparator; |
294 list->base.cmpfunc = comparator; |
250 list->base.itemsize = item_size; |
295 list->base.itemsize = item_size; |
|
296 list->base.capacity = SIZE_MAX; |
|
297 list->base.size = 0; |
|
298 |
|
299 list->begin = NULL; |
|
300 list->end = NULL; |
|
301 |
|
302 return (CxList) list; |
|
303 } |
|
304 |
|
305 CxList cxPointerLinkedListCreate(CxAllocator allocator, CxListComparator comparator) { |
|
306 cx_linked_list *list = cxMalloc(allocator, sizeof(cx_linked_list)); |
|
307 if (list == NULL) |
|
308 return NULL; |
|
309 |
|
310 list->base.cl = &cx_pointer_linked_list_class; |
|
311 list->base.allocator = allocator; |
|
312 list->base.cmpfunc = comparator; |
|
313 list->base.itemsize = sizeof(void*); |
251 list->base.capacity = SIZE_MAX; |
314 list->base.capacity = SIZE_MAX; |
252 list->base.size = 0; |
315 list->base.size = 0; |
253 |
316 |
254 list->begin = NULL; |
317 list->begin = NULL; |
255 list->end = NULL; |
318 list->end = NULL; |