Header-only library for lists.
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_