Files
wizapp-stdlib/src/base/dbl_list/dbl_list.h
T
2026-09-13 02:31:46 +01:00

185 lines
9.4 KiB
C

// 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