// Copyright 2023 alexevier // licensed under the zlib license #ifndef lexlib_linkedListMacro_h #define lexlib_linkedListMacro_h #include #include #include #define LEXLIB_LINKED_LIST_STRUCTS(N,T)\ struct N##Node {\ T data;\ struct N##Node* next;\ };\ \ struct N##LinkedList {\ struct N##Node* head;\ size_t count;\ }; #define LEXLIB_LINKED_LIST_FUNCTIONS(N,T)\ struct N##LinkedList N##LinkedListNew(void);\ void N##LinkedListDelete(struct N##LinkedList* list);\ T N##LinkedListGet(struct N##LinkedList* list, size_t index);\ _Bool N##LinkedListAdd(struct N##LinkedList* list, T data); #define LEXLIB_LINKED_LIST_IMPL(N,T)\ struct N##LinkedList N##LinkedListNew(void){\ return (struct N##LinkedList){\ NULL,\ 0,\ };\ }\ \ void N##LinkedListDelete(struct N##LinkedList* list){\ typeof(list->head) curr = list->head;\ typeof(list->head)* all = calloc(list->count, sizeof(list->head));\ \ for(size_t i = 0; ;i++){\ if(!curr)\ break;\ all[i] = curr;\ curr = curr->next;\ }\ \ for(size_t i = 0; i < list->count; i++){\ free(all[i]);\ }\ \ free(all);\ list->head = NULL;\ list->count = 0;\ }\ \ T N##LinkedListGet(struct N##LinkedList* list, size_t index){\ if(index >= list->count)\ return 0;\ \ typeof(list->head) curr = list->head;\ for(size_t i = 0; i < index; i++)\ curr = curr->next;\ \ return curr->data;\ }\ \ _Bool N##LinkedListAdd(struct N##LinkedList* list, T data){\ if(!list->head){\ list->head = malloc(sizeof(list->head));\ } else {\ typeof(list->head) newMem = realloc(list->head, (list->count+1) * sizeof(list->head));\ if(!newMem)\ return 1;\ list->head = newMem;\ }\ \ if(!list->head)\ return 1;\ \ struct N##Node* node = malloc(sizeof(struct N##Node));\ if(!node)\ return 1;\ \ node->data = data;\ node->next = NULL;\ \ if(list->count == 0){\ list->head = node;\ } else {\ struct N##Node* curr = list->head;\ while(1){\ if(curr->next == NULL){\ curr->next = node;\ break;\ }\ curr = curr->next;\ }\ }\ \ list->count++;\ return 0;\ } #endif