93#define DefList(type) \
96 struct Node##type* rest; \
98typedef struct Node##type* List##type; \
99void List##type##_deinit(List##type list); \
100type List##type##_car(struct Node##type node); \
101struct Node##type* List##type##_cdr(struct Node##type node); \
102List##type List##type##_cons(type a, List##type list); \
103List##type List##type##_rev(List##type list, List##type a); \
104List##type List##type##_reverse(List##type list); \
105size_t List##type##_length(List##type list); \
106type List##type##_at(List##type list, size_t index); \
107List##type List##type##_drop(List##type list, size_t n); \
108List##type List##type##_drop(List##type list, size_t n);
110#define ImplList(type) \
111void List##type##_deinit(List##type list) { \
112 if (list != NULL) { \
113 List##type##_deinit(list->rest); \
118type List##type##_car(struct Node##type node) { \
119 List##type##_deinit(node.rest); \
123struct Node##type* List##type##_cdr(struct Node##type node) { \
127List##type List##type##_cons(type a, List##type list) { \
128 struct Node##type* node = (struct Node##type*)calloc(1, sizeof(struct Node##type)); \
130 *node = (struct Node##type){ .head = a, .rest = list }; \
131 return (List##type)node; \
134List##type List##type##_rev(List##type list, List##type a) { \
135 if (list != NULL) { \
136 List##type out = List##type##_rev(list->rest, List##type##_cons(list->head, a)); \
142List##type List##type##_reverse(List##type list) { \
143 return List##type##_rev(list, NULL); \
146size_t List##type##_length(List##type list) { \
147 if (list != NULL) return List##type##_length(list->rest) + 1; \
151type List##type##_at(List##type list, size_t index) { \
152 if (list != NULL) return index == 1 ? list->head : List##type##_at(list->rest, index - 1); \
157List##type List##type##_take(List##type list, size_t n) { \
158 if (list != NULL) { \
160 return List##type##_cons(list->head, List##type##_take(list->rest, n - 1)); \
162 List##type##_deinit(list->rest); \
166 log(FATAL, "Took too many elements from List\n"); \
171List##type List##type##_drop(List##type list, size_t n) { \
172 if (list != NULL) { \
174 List##type kod = list; \
175 list = list-> rest; \
177 return List##type##_take(list, n - 1); \
181 log(FATAL, "Took too many elements from List\n"); \
struct NodeOpaque * ListOpaque
This is the actual type of the List.
Definition list.h:30
void * Opaque
An opaque type.
Definition list.h:21
size_t ListOpaque_length(ListOpaque list)
Returns the length of the List.
ListOpaque ListOpaque_cons(Opaque fst, ListOpaque list)
Prepend an element to the List.
ListOpaque ListOpaque_rev(ListOpaque list, ListOpaque acc)
Helper function for ListOpaque_reverse.
Opaque ListOpaque_at(ListOpaque list, size_t index)
The indexing function for a List.
Opaque ListOpaque_car(struct NodeOpaque node)
Returns the element at the head of the List.
struct NodeOpaque * ListOpaque_cdr(struct NodeOpaque node)
Returns the rest of the List, ignoring the first element.
ListOpaque ListOpaque_reverse(ListOpaque list)
Reverses a List.
void ListOpaque_deinit(ListOpaque list)
Deinitialize the List.
This is the data at each node on a List.
Definition list.h:24
struct NodeOpaque * rest
the rest of the List
Definition list.h:26
Opaque head
the data at each index of the List
Definition list.h:25