Header-only library for lists.
at main 72 lines 2.1 kB view raw
1#ifndef LIST_H_ 2#define LIST_H_ 3/* ----- List definition ----- */ 4#ifndef LIST_IMPLEMENTATION 5#define DefList(type) \ 6struct Node##type { \ 7 type head; \ 8 struct Node##type* rest; \ 9}; \ 10typedef struct Node##type* List##type; \ 11void List##type##_deinit(List##type list); \ 12type List##type##_car(struct Node##type node); \ 13struct Node##type* List##type##_cdr(struct Node##type node); \ 14List##type List##type##_cons(type a, List##type list); \ 15List##type List##type##_rev(List##type list, List##type a); \ 16List##type List##type##_reverse(List##type list); \ 17size_t List##type##_length(List##type list); \ 18type List##type##_at(List##type list, size_t index); 19#else 20#define DefList(type) \ 21struct Node##type { \ 22 type head; \ 23 struct Node##type* rest; \ 24}; \ 25typedef struct Node##type* List##type; \ 26 \ 27void List##type##_deinit(List##type list) { \ 28 if (list != NULL) { \ 29 List##type##_deinit(list->rest); \ 30 assert(list->rest == NULL); \ 31 free(list); \ 32 list = NULL; \ 33 } \ 34} \ 35 \ 36type List##type##_car(struct Node##type node) { \ 37 List##type##_deinit(node.rest); \ 38 return node.head; \ 39} \ 40 \ 41struct Node##type* List##type##_cdr(struct Node##type node) { \ 42 return node.rest; \ 43} \ 44 \ 45List##type List##type##_cons(type a, List##type list) { \ 46 struct Node##type* node = (struct Node##type*)calloc(sizeof(struct Node##type), 1); \ 47 exists(node); \ 48 *node = (struct Node##type){ .head = a, .rest = list }; \ 49 return (List##type)node; \ 50} \ 51 \ 52List##type List##type##_rev(List##type list, List##type a) { \ 53 if (list != NULL) return List##type##_rev(list->rest, List##type##_cons(list->head, a)); \ 54 else return a; \ 55} \ 56 \ 57List##type List##type##_reverse(List##type list) { \ 58 return List##type##_rev(list, NULL); \ 59} \ 60 \ 61size_t List##type##_length(List##type list) { \ 62 if (list != NULL) return List##type##_length(list->rest) + 1; \ 63 else return 0; \ 64} \ 65 \ 66type List##type##_at(List##type list, size_t index) { \ 67 if (list != NULL) return index == 1 ? list->head : List##type##_at(list->rest, index - 1); \ 68 else exists(NULL); \ 69 return (type){0}; \ 70} 71#endif 72#endif // LIST_H_