// 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 WP_PLATFORM_CPP BEGIN_C_LINKAGE #endif // !WP_PLATFORM_CPP #define WP_DBL_LIST_MAGIC wpU64Const(0x57415f444c5354) #define WP_DBL_NODE_MAGIC wpU64Const(0x57415f444e44) typedef struct WpDblNode WpDblNode; typedef struct WpDblNodeHeader { u64 magic; u64 item_size; WpDblNode *prev; WpDblNode *next; } WpDblNodeHeader; struct WpDblNode { WpDblNodeHeader header; void *item; }; typedef struct WpDblList { u64 magic; u64 node_count; u64 item_size; WpDblNode *first; WpDblNode *last; } WpDblList; // NOTE (Abdelrahman): WpDblList typedefs for readability typedef WpDblList WpVoidPtrList; typedef WpDblList WpC8List; typedef WpDblList WpC16List; typedef WpDblList WpC32List; typedef WpDblList WpU8List; typedef WpDblList WpU16List; typedef WpDblList WpU32List; typedef WpDblList WpU64List; typedef WpDblList WpB8List; typedef WpDblList WpI8List; typedef WpDblList WpI16List; typedef WpDblList WpI32List; typedef WpDblList WpI64List; typedef WpDblList WpF32List; typedef WpDblList WpF64List; typedef WpDblList WpF128List; typedef WpDblList WpUptrList; typedef WpDblList WpIptrList; typedef WpDblList WpStr8List; // NOTE (Abdelrahman): WpDblNode typedefs for readability typedef WpDblNode WpVoidPtrNode; typedef WpDblNode WpC8Node; typedef WpDblNode WpC16Node; typedef WpDblNode WpC32Node; typedef WpDblNode WpU8Node; typedef WpDblNode WpU16Node; typedef WpDblNode WpU32Node; typedef WpDblNode WpU64Node; typedef WpDblNode WpB8Node; typedef WpDblNode WpI8Node; typedef WpDblNode WpI16Node; typedef WpDblNode WpI32Node; typedef WpDblNode WpI64Node; typedef WpDblNode WpF32Node; typedef WpDblNode WpF64Node; typedef WpDblNode WpF128Node; typedef WpDblNode WpUptrNode; typedef WpDblNode WpIptrNode; typedef WpDblNode WpStr8Node; #ifdef WP_PLATFORM_CPP #define wpDblList(TYPE) \ WpDblList{WP_DBL_LIST_MAGIC, 0, sizeof(TYPE), nullptr, nullptr} #define dblListNode(TYPE, ITEM_PTR) ([&]() { \ wp_persist WpDblNode node = { \ WpDblNodeHeader{WP_DBL_NODE_MAGIC, sizeof(TYPE), nullptr, nullptr}, \ ITEM_PTR, \ }; \ \ return &node; \ }()) #else #define wpDblList(TYPE) ( \ (WpDblList){.magic = WP_DBL_LIST_MAGIC, .item_size = sizeof(TYPE)} \ ) #define dblListNode(TYPE, ITEM_PTR) ( \ &((WpDblNode){.header = {.magic = WP_DBL_NODE_MAGIC, .item_size = sizeof(TYPE)}, \ .item = ITEM_PTR}) \ ) #endif // !WP_PLATFORM_CPP #define wpDblListAlloc(TYPE, ALLOCATOR) \ (dblListAlloc(ALLOCATOR, sizeof(TYPE))) #define wpDblListGet(TYPE, LIST_PTR, ITEM_INDEX) \ ((TYPE *)(dblListGet(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item)) #define wpDblListGetNode(TYPE, LIST_PTR, ITEM_INDEX) \ (dblListGet(LIST_PTR, ITEM_INDEX, sizeof(TYPE))) #define wpDblListGetNodeItem(TYPE, NODE_PTR) \ ((TYPE *)( \ (NODE_PTR == NULL) ? \ NULL : \ (NODE_PTR)->item \ )) #define wpDblListPushFront(TYPE, LIST_PTR, ITEM_PTR) \ (dblListPushFront(LIST_PTR, dblListNode(TYPE, ITEM_PTR), sizeof(TYPE))) #define wpDblListPushBack(TYPE, LIST_PTR, ITEM_PTR) \ (dblListPushBack(LIST_PTR, dblListNode(TYPE, ITEM_PTR), sizeof(TYPE))) #define wpDblListInsert(TYPE, LIST_PTR, ITEM_PTR, ITEM_INDEX) \ (dblListInsert(LIST_PTR, dblListNode(TYPE, ITEM_PTR), \ ITEM_INDEX, sizeof(TYPE))) #define wpDblListPushFrontAlloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \ (dblListPushFront(LIST_PTR, dblListNodeAlloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \ sizeof(TYPE))) #define wpDblListPushBackAlloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \ (dblListPushBack(LIST_PTR, dblListNodeAlloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \ sizeof(TYPE))) #define wpDblListInsertAlloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR, ITEM_INDEX) \ (dblListInsert(LIST_PTR, dblListNodeAlloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \ ITEM_INDEX, sizeof(TYPE))) #define wpDblListPopFront(TYPE, LIST_PTR) \ ((TYPE *)( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ dblListPopFront(LIST_PTR, sizeof(TYPE))->item \ )) #define wpDblListPopBack(TYPE, LIST_PTR) \ ((TYPE *)( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ dblListPopBack(LIST_PTR, sizeof(TYPE))->item \ )) #define wpDblListRemove(TYPE, LIST_PTR, ITEM_INDEX) \ ((TYPE *)( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \ NULL : \ dblListRemove(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item \ )) #define wpDblListPopFrontNode(TYPE, LIST_PTR) \ ( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ dblListPopFront(LIST_PTR, sizeof(TYPE)) \ ) #define wpDblListPopBackNode(TYPE, LIST_PTR) \ ( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \ NULL : \ dblListPopBack(LIST_PTR, sizeof(TYPE)) \ ) #define wpDblListRemoveNode(TYPE, LIST_PTR, ITEM_INDEX) \ ( \ (LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \ NULL : \ dblListRemove(LIST_PTR, ITEM_INDEX, sizeof(TYPE)) \ ) #define wpDblListEmpty(TYPE, LIST_PTR) \ (dblListEmpty(LIST_PTR, sizeof(TYPE))) WpDblList *dblListAlloc(const WpAllocator *allocator, u64 item_size); WpDblNode *dblListNodeAlloc(const WpAllocator *allocator, void *item, u64 item_size); WpDblNode *dblListGet(const WpDblList *list, u64 index, u64 item_size); void dblListPushFront(WpDblList *list, WpDblNode *node, u64 item_size); void dblListPushBack(WpDblList *list, WpDblNode *node, u64 item_size); void dblListInsert(WpDblList *list, WpDblNode *node, u64 index, u64 item_size); WpDblNode *dblListPopFront(WpDblList *list, u64 item_size); WpDblNode *dblListPopBack(WpDblList *list, u64 item_size); WpDblNode *dblListRemove(WpDblList *list, u64 index, u64 item_size); void dblListEmpty(WpDblList *list, u64 item_size); #ifdef WP_PLATFORM_CPP END_C_LINKAGE #endif // !WP_PLATFORM_CPP #endif // !DBL_LIST_H