// vim:fileencoding=utf-8:foldmethod=marker #ifndef DBL_LIST_H #define DBL_LIST_H #include "../mem/allocator/mem_allocator.h" #include "../../common/aliases/aliases.h" #include "../../common/platform/platform.h" #ifdef WAPP_PLATFORM_CPP BEGIN_C_LINKAGE #endif // !WAPP_PLATFORM_CPP #define WAPP_DBL_LIST_MAGIC (u64)0x57415f444c5354 #define WAPP_DBL_NODE_MAGIC (u64)0x57415f444e44 typedef struct GenericNode GenericNode; typedef struct { u64 magic; u64 item_size; GenericNode *prev; GenericNode *next; } NodeHeader; struct GenericNode { NodeHeader header; void *item; }; typedef struct { u64 magic; u64 node_count; u64 item_size; GenericNode *first; GenericNode *last; } GenericList; // NOTE (Abdelrahman): GenericList typedefs for readability typedef GenericList VoidPtrList; typedef GenericList C8List; typedef GenericList C16List; typedef GenericList C32List; typedef GenericList U8List; typedef GenericList U16List; typedef GenericList U32List; typedef GenericList U64List; typedef GenericList B8List; typedef GenericList I8List; typedef GenericList I16List; typedef GenericList I32List; typedef GenericList I64List; typedef GenericList F32List; typedef GenericList F64List; typedef GenericList F128List; typedef GenericList UptrList; typedef GenericList IptrList; typedef GenericList Str8List; // NOTE (Abdelrahman): GenericNode typedefs for readability typedef GenericNode VoidPtrNode; typedef GenericNode C8Node; typedef GenericNode C16Node; typedef GenericNode C32Node; typedef GenericNode U8Node; typedef GenericNode U16Node; typedef GenericNode U32Node; typedef GenericNode U64Node; typedef GenericNode B8Node; typedef GenericNode I8Node; typedef GenericNode I16Node; typedef GenericNode I32Node; typedef GenericNode I64Node; typedef GenericNode F32Node; typedef GenericNode F64Node; typedef GenericNode F128Node; typedef GenericNode UptrNode; typedef GenericNode IptrNode; typedef GenericNode Str8Node; #ifdef WAPP_PLATFORM_CPP #define wapp_dbl_list(TYPE) \ GenericList{WAPP_DBL_LIST_MAGIC, 0, sizeof(TYPE), nullptr, nullptr} #define _dbl_list_node(TYPE, ITEM_PTR) ([&]() { \ wapp_persist GenericNode node = { \ NodeHeader{WAPP_DBL_NODE_MAGIC, sizeof(TYPE), nullptr, nullptr}, \ ITEM_PTR, \ }; \ \ return &node; \ }()) #else #define wapp_dbl_list(TYPE) ( \ (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(TYPE)} \ ) #define _dbl_list_node(TYPE, ITEM_PTR) ( \ &((GenericNode){.header = {.magic = WAPP_DBL_NODE_MAGIC, .item_size = sizeof(TYPE)}, \ .item = ITEM_PTR}) \ ) #endif // !WAPP_PLATFORM_CPP #define wapp_dbl_list_alloc(TYPE, ALLOCATOR) \ (_dbl_list_alloc(ALLOCATOR, sizeof(TYPE))) #define wapp_dbl_list_get(TYPE, LIST_PTR, ITEM_INDEX) \ ((TYPE *)(_dbl_list_get(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item)) #define wapp_dbl_list_get_node(TYPE, LIST_PTR, ITEM_INDEX) \ (_dbl_list_get(LIST_PTR, ITEM_INDEX, sizeof(TYPE))) #define wapp_dbl_list_get_node_item(TYPE, NODE_PTR) \ ((TYPE *)( \ (NODE_PTR == NULL) ? \ NULL : \ (NODE_PTR)->item \ )) #define wapp_dbl_list_push_front(TYPE, LIST_PTR, ITEM_PTR) \ (_dbl_list_push_front(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), sizeof(TYPE))) #define wapp_dbl_list_push_back(TYPE, LIST_PTR, ITEM_PTR) \ (_dbl_list_push_back(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), sizeof(TYPE))) #define wapp_dbl_list_insert(TYPE, LIST_PTR, ITEM_PTR, ITEM_INDEX) \ (_dbl_list_insert(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), \ ITEM_INDEX, sizeof(TYPE))) #define wapp_dbl_list_push_front_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \ (_dbl_list_push_front(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \ sizeof(TYPE))) #define wapp_dbl_list_push_back_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \ (_dbl_list_push_back(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \ sizeof(TYPE))) #define wapp_dbl_list_insert_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR, ITEM_INDEX) \ (_dbl_list_insert(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \ ITEM_INDEX, sizeof(TYPE))) #define wapp_dbl_list_pop_front(TYPE, LIST_PTR) \ ((TYPE *)( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ _dbl_list_pop_front(LIST_PTR, sizeof(TYPE))->item \ )) #define wapp_dbl_list_pop_back(TYPE, LIST_PTR) \ ((TYPE *)( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ _dbl_list_pop_back(LIST_PTR, sizeof(TYPE))->item \ )) #define wapp_dbl_list_remove(TYPE, LIST_PTR, ITEM_INDEX) \ ((TYPE *)( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \ NULL : \ _dbl_list_remove(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item \ )) #define wapp_dbl_list_pop_front_node(TYPE, LIST_PTR) \ ( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ _dbl_list_pop_front(LIST_PTR, sizeof(TYPE)) \ ) #define wapp_dbl_list_pop_back_node(TYPE, LIST_PTR) \ ( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ _dbl_list_pop_back(LIST_PTR, sizeof(TYPE)) \ ) #define wapp_dbl_list_remove_node(TYPE, LIST_PTR, ITEM_INDEX) \ ( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \ NULL : \ _dbl_list_remove(LIST_PTR, ITEM_INDEX, sizeof(TYPE)) \ ) #define wapp_dbl_list_empty(TYPE, LIST_PTR) \ (_dbl_list_empty(LIST_PTR, sizeof(TYPE))) GenericList *_dbl_list_alloc(const Allocator *allocator, u64 item_size); GenericNode *_dbl_list_node_alloc(const Allocator *allocator, void *item, u64 item_size); GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size); void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size); void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size); void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size); GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size); GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size); GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size); void _dbl_list_empty(GenericList *list, u64 item_size); #ifdef WAPP_PLATFORM_CPP END_C_LINKAGE #endif // !WAPP_PLATFORM_CPP #endif // !DBL_LIST_H