185 lines
9.4 KiB
C
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
|