Loading...
Searching...
No Matches
Go to the documentation of this file.
5#define LL_FREE kest_free
9#define LL_MALLOC kest_alloc
12#define DECLARE_LINKED_LIST(X) struct X##_ll; \
13typedef struct X##_ll { \
15 struct X##_ll *next; \
18X##_ll *X##_ll_new(X x); \
19void X##_ll_free(X##_ll *list); \
20X##_ll *X##_ll_tail(X##_ll *list); \
21X##_ll *X##_ll_append(X##_ll *list, X x); \
22int X##_ll_safe_append(X##_ll **list_ptr, X x); \
23X##_ll *X##_ll_append_return_tail(X##_ll **list, X x); \
24X##_ll *X##_ll_remove_next(X##_ll *list); \
25void X##_ll_destroy(X##_ll *list, void (*destructor)(X x)); \
26void X##_ll_map(X##_ll *list, X (*fmap)(X x)); \
27X##_ll *X##_ll_cmp_search(X##_ll *list, int (*cmp_function)(X, X), X x); \
28X##_ll *X##_ll_destructor_free_and_remove_matching(X##_ll *list, int (*cmp_function)(X, X), X x, void (*destructor)(X));
30#define IMPLEMENT_LINKED_LIST(X) \
31X##_ll *X##_ll_new(X x) \
33 X##_ll *result = (X##_ll*)LL_MALLOC(sizeof(X##_ll)); \
39 result->next = NULL; \
44X##_ll *X##_ll_tail(X##_ll *list) \
49 X##_ll *current = list; \
51 while (current->next != NULL) \
52 current = current->next; \
57void X##_ll_free(X##_ll *list) \
61 X##_ll *current = list; \
62 X##_ll *next = NULL; \
63 while (current != NULL) { \
64 next = current->next; \
70void X##_ll_destroy(X##_ll *list, void (*destructor)(X x)) \
75 X##_ll *current = list; \
76 X##_ll *next = NULL; \
78 while (current != NULL) { \
79 next = current->next; \
80 destructor(current->data); \
86X##_ll *X##_ll_append(X##_ll *list, X x) \
88 X##_ll *next = X##_ll_new(x); \
89 if (list == NULL) return next; \
91 X##_ll *current = list; \
93 while (current->next != NULL) \
94 current = current->next; \
96 current->next = next; \
101int X##_ll_safe_append(X##_ll **list_ptr, X x) \
103 if (!list_ptr) return 0; \
104 X##_ll *next = X##_ll_new(x); \
105 if (!next) return 0; \
106 X##_ll *list = *list_ptr; \
113 X##_ll *current = list; \
115 while (current->next != NULL) \
116 current = current->next; \
118 current->next = next; \
123X##_ll *X##_ll_append_return_tail(X##_ll **list, X x) \
128 X##_ll *next = X##_ll_new(x); \
129 if (*list == NULL) { \
134 X##_ll *current = *list; \
136 while (current->next != NULL) \
137 current = current->next; \
139 current->next = next; \
144X##_ll *X##_ll_remove_next(X##_ll *list) \
149 X##_ll *next = list->next; \
154 list->next = list->next->next; \
159void X##_ll_map(X##_ll *list, X (*fmap)(X x)) \
164 list->data = fmap(list->data); \
165 X##_ll_map(list->next, fmap); \
168X##_ll *X##_ll_cmp_search(X##_ll *list, int (*cmp_function)(X, X), X x) \
173 X##_ll *current = list; \
176 if (cmp_function(current->data, x) == 0) \
179 current = current->next; \
185X##_ll *X##_ll_destructor_free_and_remove_matching(X##_ll *list, int (*cmp_function)(X, X), X x, void (*destructor)(X)) \
190 X##_ll *current = list; \
191 X##_ll *prev = NULL; \
192 X##_ll *next = NULL; \
195 next = current->next; \
196 if (cmp_function(current->data, x) == 0) { \
197 if (current == list) \
199 destructor(current->data); \
212#define DECLARE_LINKED_PTR_LIST(X) struct X##_pll; \
213typedef struct X##_pll { \
215 struct X##_pll *next; \
218X##_pll *X##_pll_new(X *value); \
219X##_pll *X##_pll_anew(X *value, void* (*allocator)(size_t size)); \
220void X##_pll_free(X##_pll *list); \
221X##_pll *X##_pll_tail(X##_pll *list); \
222X##_pll *X##_pll_append(X##_pll *list, X *value); \
223X##_pll *X##_pll_aappend(X##_pll *list, X *value, void* (*allocator)(size_t size)); \
224int X##_pll_safe_append(X##_pll **list_ptr, X *value); \
225int X##_pll_safe_aappend(X##_pll **list_ptr, X *value, void* (*allocator)(size_t size)); \
226X##_pll *X##_pll_append_return_tail(X##_pll **list, X *x); \
227X##_pll *X##_pll_aappend_return_tail(X##_pll **list, X *x, void* (*allocator)(size_t size)); \
228X##_pll *X##_pll_remove_next(X##_pll *list); \
229void X##_pll_free(X##_pll *list); \
230void X##_pll_destroy(X##_pll *list, void (*destructor)(X *x)); \
231X##_pll *X##_pll_cmp_search(X##_pll *list, int (*cmp_function)(const X*, const X*), const X *x); \
232X##_pll *X##_pll_destructor_free_and_remove_matching(X##_pll *list, int (*cmp_function)(X*, X*), X *x, void (*destructor)(X*));
234#define IMPLEMENT_LINKED_PTR_LIST(X) \
236X##_pll *X##_pll_new(X *value) \
238 X##_pll *result = (X##_pll*)LL_MALLOC(sizeof(X##_pll)); \
240 if (result == NULL) \
243 result->data = value; \
244 result->next = NULL; \
249X##_pll *X##_pll_anew(X *value, void* (*allocator)(size_t size)) \
251 X##_pll *result = (X##_pll*)allocator(sizeof(X##_pll)); \
253 if (result == NULL) \
256 result->data = value; \
257 result->next = NULL; \
262X##_pll *X##_pll_tail(X##_pll *list) \
267 X##_pll *current = list; \
269 while (current->next != NULL) \
270 current = current->next; \
275X##_pll *X##_pll_append(X##_pll *list, X *x) \
277 X##_pll *next = X##_pll_new(x); \
278 if (list == NULL) return next; \
280 X##_pll *current = list; \
282 while (current->next != NULL) \
283 current = current->next; \
285 current->next = next; \
290X##_pll *X##_pll_aappend(X##_pll *list, X *x, void* (*allocator)(size_t size)) \
292 X##_pll *next = X##_pll_anew(x, allocator); \
293 if (list == NULL) return next; \
295 X##_pll *current = list; \
297 while (current->next != NULL) \
298 current = current->next; \
300 current->next = next; \
305int X##_pll_safe_append(X##_pll **list_ptr, X *x) \
307 if (!list_ptr) return ERR_NULL_PTR; \
308 X##_pll *next = X##_pll_new(x); \
309 if (!next) return ERR_ALLOC_FAIL; \
310 X##_pll *list = *list_ptr; \
317 X##_pll *current = list; \
319 while (current->next != NULL) \
320 current = current->next; \
322 current->next = next; \
327int X##_pll_safe_aappend(X##_pll **list_ptr, X *x, void* (*allocator)(size_t size)) \
329 if (!list_ptr) return ERR_NULL_PTR; \
330 X##_pll *next = X##_pll_anew(x, allocator); \
331 if (!next) return ERR_ALLOC_FAIL; \
332 X##_pll *list = *list_ptr; \
339 X##_pll *current = list; \
341 while (current->next != NULL) \
342 current = current->next; \
344 current->next = next; \
349X##_pll *X##_pll_append_return_tail(X##_pll **list, X *x) \
354 X##_pll *next = X##_pll_new(x); \
355 if (*list == NULL) { \
360 X##_pll *current = *list; \
362 while (current->next != NULL) \
363 current = current->next; \
365 current->next = next; \
370X##_pll *X##_pll_aappend_return_tail(X##_pll **list, X *x, void* (*allocator)(size_t size)) \
375 X##_pll *next = X##_pll_anew(x, allocator); \
376 if (*list == NULL) { \
381 X##_pll *current = *list; \
383 while (current->next != NULL) \
384 current = current->next; \
386 current->next = next; \
392void X##_pll_free(X##_pll *list) \
396 X##_pll *current = list; \
397 X##_pll *next = NULL; \
398 while (current != NULL) { \
399 next = current->next; \
400 LL_FREE(current->data); \
406void X##_pll_destroy(X##_pll *list, void (*destructor)(X *x)) \
411 X##_pll *current = list; \
412 X##_pll *next = NULL; \
413 while (current != NULL) { \
414 next = current->next; \
415 destructor(current->data); \
421X##_pll *X##_pll_remove_next(X##_pll *list) \
426 X##_pll *next = list->next; \
431 list->next = next->next; \
436void X##_pll_map(X##_pll *list, X *(*fmap)(X *x)) \
441 list->data = fmap(list->data); \
442 X##_pll_map(list->next, fmap); \
445X##_pll *X##_pll_cmp_search(X##_pll *list, int (*cmp_function)(const X*, const X*), const X *x) \
450 X##_pll *current = list; \
453 if (cmp_function(current->data, x) == 0) \
456 current = current->next; \
463X##_pll *X##_pll_destructor_free_and_remove_matching(X##_pll *list, int (*cmp_function)(X*, X*), X *x, void (*destructor)(X*)) \
468 X##_pll *current = list; \
469 X##_pll *next = NULL; \
470 X##_pll *prev = NULL; \
473 next = current->next; \
474 if (cmp_function(current->data, x) == 0) { \
475 if (current == list) \
477 destructor(current->data); \