/// Doubly-linked list. #pragma once #include #include #include #define DEF_LIST(type) \ typedef struct type##_node { \ type val; \ struct type##_node* prev; \ struct type##_node* next; \ } type##_node; \ typedef struct type##_list { \ type##_node* head; \ } type##_list; static inline void* alloc(size_t size) { void* ptr = calloc(1, size); assert(ptr); return ptr; } /// Create a new empty list. #define make_list(type) \ (type##_list) { 0 } /// Delete the list. #define del_list(list) \ for (__typeof__(list.head) node = list.head; node;) { \ __typeof__(node) cur = node; \ node = node->next; \ free(cur); \ } \ list.head = 0; /// Prepend a value to the list. #define list_push(list, value) \ { \ __typeof__(list.head) node = alloc(sizeof(*list.head)); \ node->val = value; \ node->next = list.head; \ if (list.head) { \ list.head->prev = node; \ } \ list.head = node; \ } /// Delete the first occurrence of the value from the list. #define list_remove(list, search_value) \ for (__typeof__(list.head) iter = list.head; iter; iter = iter->next) { \ if (iter->val == (search_value)) { \ del_node(list, iter); \ break; \ } \ } /// Delete the node that contains the value at the given address from the /// list. #define list_remove_ptr(list, value_ptr) \ for (__typeof__(list.head) iter = list.head; iter; iter = iter->next) { \ if (&iter->val == value_ptr) { \ del_node(list, iter); \ break; \ } \ } /// Delete the list node. #define del_node(list, node) \ { \ assert(node); \ if (node->prev) { \ node->prev->next = node->next; \ } \ if (node->next) { \ node->next->prev = node->prev; \ } \ if (list.head == node) { \ list.head = 0; \ } \ free(node); \ node = 0; \ } /// Iterate over all the items in the list. /// /// Use 'value' to refer to the address of the current node's value during /// iteration. #define list_foreach(list, body) \ { \ __typeof__(list.head) node = list.head; \ while (node) { \ const __typeof__(node->val)* value = &node->val; \ body; \ node = node->next; \ } \ } /// Iterate over all the items in the list. /// /// Use 'value' to refer to the address of the current node's value during /// iteration. #define list_foreach_mut(list, body) \ { \ __typeof__(list.head) node = list.head; \ while (node) { \ __typeof__(node->val)* value = &node->val; \ body; \ node = node->next; \ } \ }