/** * @file linked_list.h * @author Piotr Krygier (everyonecancode@gmail.com) * @brief * @version 0.1 * @date 2024-05-01 * * @copyright Copyright (c) 2024 * */ #ifndef LINKED_LIST_H #define LINKED_LIST_H #include "utilities/commons.h" /** * @brief Define a linked list structure * * @param name Name of the linked list structure * @param type Type of the data stored in the linked list * @return struct name { type data; struct name *next; } * @note This macro defines a linked list structure with a given name and data type */ #define RSE_LINKED_LIST_DEFINE(name, type) \ struct name { \ type data; \ struct name *next; \ } #define RSE_LINKED_LIST_PUSH_FRONT(list, value) \ __typeof__(list) new_node = NULL; \ rse_malloc(new_node, sizeof(*(list))); \ new_node->data = value; \ new_node->next = list; \ list = new_node #define RSE_LINKED_LIST_PUSH_BACK(list, value) \ __typeof__((list)) new_node = NULL; \ rse_malloc(new_node, sizeof(*(list))); \ new_node->data = value; \ new_node->next = NULL; \ if (list == NULL) { \ list = new_node; \ } else { \ __typeof__(list) current = list; \ while (current->next != NULL) { \ current = current->next; \ } \ current->next = new_node; \ } #define RSE_LINKED_LIST_POP_FRONT(list) \ if (list != NULL) { \ __typeof__(list) temp = list; \ list = list->next; \ rse_free(temp); \ } #define RSE_LINKED_LIST_POP_BACK(list) \ if (list != NULL) { \ if (list->next == NULL) { \ rse_free(list); \ list = NULL; \ } else { \ __typeof__(list) *current = list; \ while (current->next->next != NULL) { \ current = current->next; \ } \ rse_free(current->next); \ current->next = NULL; \ } \ } #define RSE_LINKED_LIST_FRONT(list) \ list->data #define RSE_LINKED_LIST_BACK(list) \ if (list != NULL) { \ __typeof__(list) *current = list; \ while (current->next != NULL) { \ current = current->next; \ } \ current->data; \ } #define RSE_LINKED_LIST_IS_EMPTY(list) \ (list == NULL) #define RSE_LINKED_LIST_SIZE(list) \ ({ \ int size = 0; \ __typeof__(list) current = list; \ while (current != NULL) { \ size++; \ current = current->next; \ } \ size; \ }) #define RSE_LINKED_LIST_CLEAR(list) \ while (list != NULL) { \ __typeof__(list) temp = list; \ list = list->next; \ rse_free(temp); \ } #define RSE_LINKED_LIST_FOREACH(list, i) \ for (__typeof__(list) i = list; i != NULL; i = i->next) #define RSE_LINKED_LIST_FOREACH_REVERSE(list, i) \ for (__typeof__(list) i = list; i != NULL; i = i->next) #define RSE_LINKED_LIST_TO_ARRAY(list, array) \ ({ \ int size = RSE_LINKED_LIST_SIZE(list); \ rse_malloc(array, size * sizeof(*(list))); \ int i = 0; \ RSE_LINKED_LIST_FOREACH(list, current) { \ array[i++] = current->data; \ } \ size; \ }) #endif // LINKED_LIST_H