Update dbl list API
This commit is contained in:
@@ -25,15 +25,16 @@ DBL_LIST_ALLOC_RETURN:
|
||||
return list;
|
||||
}
|
||||
|
||||
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, u64 item_size) {
|
||||
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, void *item, u64 item_size) {
|
||||
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
|
||||
|
||||
GenericNode *node = wapp_mem_allocator_alloc(allocator, sizeof(GenericNode));
|
||||
if (!node) { goto DBL_LIST_NODE_ALLOC_RETURN; }
|
||||
|
||||
memset((void *)node, 0, sizeof(GenericNode));
|
||||
node->magic = WAPP_DBL_NODE_MAGIC;
|
||||
node->item_size = item_size;
|
||||
node->item = item;
|
||||
node->header.magic = WAPP_DBL_NODE_MAGIC;
|
||||
node->header.item_size = item_size;
|
||||
|
||||
DBL_LIST_NODE_ALLOC_RETURN:
|
||||
return node;
|
||||
@@ -47,7 +48,7 @@ GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size) {
|
||||
GenericNode *output = NULL;
|
||||
GenericNode *current = list->first;
|
||||
for (u64 i = 1; i <= index; ++i) {
|
||||
current = current->next;
|
||||
current = current->header.next;
|
||||
}
|
||||
|
||||
output = current;
|
||||
@@ -71,11 +72,11 @@ void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size) {
|
||||
|
||||
GenericNode *first = list->first;
|
||||
if (first) {
|
||||
first->prev = node_list.last;
|
||||
first->header.prev = node_list.last;
|
||||
}
|
||||
|
||||
list->first = node_list.first;
|
||||
node_list.last->next = first;
|
||||
node_list.last->header.next = first;
|
||||
}
|
||||
|
||||
void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size) {
|
||||
@@ -94,11 +95,11 @@ void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size) {
|
||||
|
||||
GenericNode *last = list->last;
|
||||
if (last) {
|
||||
last->next = node_list.first;
|
||||
last->header.next = node_list.first;
|
||||
}
|
||||
|
||||
list->last = node_list.last;
|
||||
node_list.first->prev = last;
|
||||
node_list.first->header.prev = last;
|
||||
}
|
||||
|
||||
void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size) {
|
||||
@@ -123,72 +124,78 @@ void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_
|
||||
|
||||
list->node_count += node_list.node_count;
|
||||
|
||||
GenericNode *prev = dst_node->prev;
|
||||
GenericNode *prev = dst_node->header.prev;
|
||||
|
||||
dst_node->prev = node_list.last;
|
||||
prev->next = node_list.first;
|
||||
dst_node->header.prev = node_list.last;
|
||||
prev->header.next = node_list.first;
|
||||
|
||||
node_list.first->prev = prev;
|
||||
node_list.last->next = dst_node;
|
||||
node_list.first->header.prev = prev;
|
||||
node_list.last->header.next = dst_node;
|
||||
}
|
||||
|
||||
GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size) {
|
||||
void *_dbl_list_pop_front(GenericList *list, u64 item_size) {
|
||||
wapp_debug_assert(list != NULL, "`list` should not be NULL");
|
||||
_dbl_list_validate(list, item_size);
|
||||
|
||||
GenericNode *output = NULL;
|
||||
void *output = NULL;
|
||||
|
||||
if (list->node_count == 0) {
|
||||
goto RETURN_LIST_POP_FRONT;
|
||||
}
|
||||
|
||||
output = list->first;
|
||||
GenericNode *node = list->first;
|
||||
|
||||
if (list->node_count == 1) {
|
||||
*list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size};
|
||||
goto RETURN_LIST_POP_FRONT;
|
||||
goto LIST_POP_FRONT_RETRIEVE_NODE_ITEM;
|
||||
}
|
||||
|
||||
--(list->node_count);
|
||||
list->first = output->next;
|
||||
list->first = node->header.next;
|
||||
|
||||
output->prev = output->next = NULL;
|
||||
node->header.prev = node->header.next = NULL;
|
||||
|
||||
LIST_POP_FRONT_RETRIEVE_NODE_ITEM:
|
||||
output = node->item;
|
||||
|
||||
RETURN_LIST_POP_FRONT:
|
||||
return output;
|
||||
}
|
||||
|
||||
GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size) {
|
||||
void *_dbl_list_pop_back(GenericList *list, u64 item_size) {
|
||||
wapp_debug_assert(list != NULL, "`list` should not be NULL");
|
||||
_dbl_list_validate(list, item_size);
|
||||
|
||||
GenericNode *output = NULL;
|
||||
void *output = NULL;
|
||||
|
||||
if (list->node_count == 0) {
|
||||
goto RETURN_LIST_POP_BACK;
|
||||
}
|
||||
|
||||
output = list->last;
|
||||
GenericNode *node = list->last;
|
||||
|
||||
if (list->node_count == 1) {
|
||||
*list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size};
|
||||
goto RETURN_LIST_POP_BACK;
|
||||
goto LIST_POP_BACK_RETRIEVE_NODE_ITEM;
|
||||
}
|
||||
|
||||
--(list->node_count);
|
||||
list->last = output->prev;
|
||||
list->last = node->header.prev;
|
||||
|
||||
output->prev = output->next = NULL;
|
||||
node->header.prev = node->header.next = NULL;
|
||||
|
||||
LIST_POP_BACK_RETRIEVE_NODE_ITEM:
|
||||
output = node->item;
|
||||
|
||||
RETURN_LIST_POP_BACK:
|
||||
return output;
|
||||
}
|
||||
|
||||
GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size) {
|
||||
void *_dbl_list_remove(GenericList *list, u64 index, u64 item_size) {
|
||||
wapp_debug_assert(list != NULL, "`list` should not be NULL");
|
||||
_dbl_list_validate(list, item_size);
|
||||
|
||||
GenericNode *output = NULL;
|
||||
void *output = NULL;
|
||||
|
||||
if (index == 0) {
|
||||
output = _dbl_list_pop_front(list, item_size);
|
||||
@@ -198,17 +205,19 @@ GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size) {
|
||||
goto RETURN_LIST_REMOVE;
|
||||
}
|
||||
|
||||
output = _dbl_list_get(list, index, item_size);
|
||||
if (!output) {
|
||||
GenericNode *node = _dbl_list_get(list, index, item_size);
|
||||
if (!node) {
|
||||
goto RETURN_LIST_REMOVE;
|
||||
}
|
||||
|
||||
output->prev->next = output->next;
|
||||
output->next->prev = output->prev;
|
||||
node->header.prev->header.next = node->header.next;
|
||||
node->header.next->header.prev = node->header.prev;
|
||||
|
||||
--(list->node_count);
|
||||
|
||||
output->prev = output->next = NULL;
|
||||
node->header.prev = node->header.next = NULL;
|
||||
|
||||
output = node->item;
|
||||
|
||||
RETURN_LIST_REMOVE:
|
||||
return output;
|
||||
@@ -233,13 +242,13 @@ wapp_intern GenericList _node_to_list(GenericNode *node, u64 item_size) {
|
||||
.item_size = item_size,
|
||||
};
|
||||
|
||||
while (output.first->prev != NULL) {
|
||||
output.first = output.first->prev;
|
||||
while (output.first->header.prev != NULL) {
|
||||
output.first = output.first->header.prev;
|
||||
++(output.node_count);
|
||||
}
|
||||
|
||||
while (output.last->next != NULL) {
|
||||
output.last = output.last->next;
|
||||
while (output.last->header.next != NULL) {
|
||||
output.last = output.last->header.next;
|
||||
++(output.node_count);
|
||||
}
|
||||
|
||||
@@ -252,7 +261,7 @@ wapp_intern inline void _dbl_list_validate(const GenericList *list, u64 item_siz
|
||||
}
|
||||
|
||||
wapp_intern inline void _dbl_list_node_validate(const GenericList *list, const GenericNode *node, u64 item_size) {
|
||||
wapp_runtime_assert(node->magic == WAPP_DBL_NODE_MAGIC, "`node` isn't a valid wapp node type");
|
||||
wapp_runtime_assert(list->item_size == node->item_size, "Mismatched `list` and `node` types");
|
||||
wapp_runtime_assert(node->item_size == item_size, "Invalid item provided");
|
||||
wapp_runtime_assert(node->header.magic == WAPP_DBL_NODE_MAGIC, "`node` isn't a valid wapp node type");
|
||||
wapp_runtime_assert(list->item_size == node->header.item_size, "Mismatched `list` and `node` types");
|
||||
wapp_runtime_assert(node->header.item_size == item_size, "Invalid item provided");
|
||||
}
|
||||
|
||||
@@ -14,96 +14,110 @@ BEGIN_C_LINKAGE
|
||||
#define WAPP_DBL_LIST_MAGIC (u64)0x57415f444c5354
|
||||
#define WAPP_DBL_NODE_MAGIC (u64)0x57415f444e44
|
||||
|
||||
#define WAPP_DEF_DBL_LIST_TYPE(T, NODE_NAME, LIST_NAME) \
|
||||
typedef struct NODE_NAME NODE_NAME; \
|
||||
struct NODE_NAME { \
|
||||
u64 magic; \
|
||||
T *item; \
|
||||
NODE_NAME *prev; \
|
||||
NODE_NAME *next; \
|
||||
u64 item_size; \
|
||||
}; \
|
||||
\
|
||||
typedef struct { \
|
||||
u64 magic; \
|
||||
NODE_NAME *first; \
|
||||
NODE_NAME *last; \
|
||||
u64 node_count; \
|
||||
u64 item_size; \
|
||||
} LIST_NAME
|
||||
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): 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;
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
#define wapp_dbl_list(ELEM_TYPE, LIST_TYPE) \
|
||||
LIST_TYPE{WAPP_DBL_LIST_MAGIC, nullptr, nullptr, 0, sizeof(ELEM_TYPE)}
|
||||
#define wapp_dbl_list_node(ELEM_TYPE, NODE_TYPE, ELEM_PTR) \
|
||||
NODE_TYPE{WAPP_DBL_NODE_MAGIC, ELEM_PTR, nullptr, nullptr, sizeof(ELEM_TYPE)}
|
||||
#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(ELEM_TYPE, LIST_TYPE) ( \
|
||||
(LIST_TYPE){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(ELEM_TYPE)} \
|
||||
#define wapp_dbl_list(TYPE) ( \
|
||||
(GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(TYPE)} \
|
||||
)
|
||||
#define wapp_dbl_list_node(ELEM_TYPE, NODE_TYPE, ELEM_PTR) ( \
|
||||
(NODE_TYPE){.magic = WAPP_DBL_NODE_MAGIC, .item = ELEM_PTR, .item_size = sizeof(ELEM_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(ELEM_TYPE, LIST_TYPE, ALLOCATOR) \
|
||||
((LIST_TYPE *)_dbl_list_alloc(ALLOCATOR, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_node_alloc(ELEM_TYPE, NODE_TYPE, ALLOCATOR) \
|
||||
((NODE_TYPE *)_dbl_list_node_alloc(ALLOCATOR, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_get(ELEM_TYPE, NODE_TYPE, LIST_PTR, ELEM_INDEX) \
|
||||
((NODE_TYPE *)_dbl_list_get((GenericList *)LIST_PTR, ELEM_INDEX, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_push_front(ELEM_TYPE, LIST_PTR, NODE_PTR) \
|
||||
(_dbl_list_push_front((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_push_back(ELEM_TYPE, LIST_PTR, NODE_PTR) \
|
||||
(_dbl_list_push_back((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_insert(ELEM_TYPE, LIST_PTR, NODE_PTR, ELEM_INDEX) \
|
||||
(_dbl_list_insert((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, \
|
||||
ELEM_INDEX, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_pop_front(ELEM_TYPE, NODE_TYPE, LIST_PTR) \
|
||||
((NODE_TYPE *)_dbl_list_pop_front((GenericList *)LIST_PTR, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_pop_back(ELEM_TYPE, NODE_TYPE, LIST_PTR) \
|
||||
((NODE_TYPE *)_dbl_list_pop_back((GenericList *)LIST_PTR, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_remove(ELEM_TYPE, NODE_TYPE, LIST_PTR, ELEM_INDEX) \
|
||||
((NODE_TYPE *)_dbl_list_remove((GenericList *)LIST_PTR, ELEM_INDEX, sizeof(ELEM_TYPE)))
|
||||
#define wapp_dbl_list_empty(ELEM_TYPE, LIST_PTR) \
|
||||
(_dbl_list_empty((GenericList *)LIST_PTR, sizeof(ELEM_TYPE)))
|
||||
|
||||
WAPP_DEF_DBL_LIST_TYPE(void, GenericNode, GenericList);
|
||||
#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_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 *)_dbl_list_pop_front(LIST_PTR, sizeof(TYPE)))
|
||||
#define wapp_dbl_list_pop_back(TYPE, LIST_PTR) \
|
||||
((TYPE *)_dbl_list_pop_back(LIST_PTR, sizeof(TYPE)))
|
||||
#define wapp_dbl_list_remove(TYPE, LIST_PTR, ITEM_INDEX) \
|
||||
((TYPE *)_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, 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_pop_front(GenericList *list, u64 item_size);
|
||||
void *_dbl_list_pop_back(GenericList *list, u64 item_size);
|
||||
void *_dbl_list_remove(GenericList *list, u64 index, u64 item_size);
|
||||
void _dbl_list_empty(GenericList *list, u64 item_size);
|
||||
|
||||
// Base list types
|
||||
typedef struct Str8 Str8;
|
||||
|
||||
WAPP_DEF_DBL_LIST_TYPE(void *, VoidPtrNode, VoidPtrList);
|
||||
WAPP_DEF_DBL_LIST_TYPE(c8 , C8Node , C8List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(c16 , C16Node , C16List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(c32 , C32Node , C32List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(u8 , U8Node , U8List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(u16 , U16Node , U16List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(u32 , U32Node , U32List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(u64 , U64Node , U64List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(b8 , B8Node , B8List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(i8 , I8Node , I8List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(i16 , I16Node , I16List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(i32 , I32Node , I32List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(i64 , I64Node , I64List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(f32 , F32Node , F32List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(f64 , F64Node , F64List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(f128 , F128Node , F128List);
|
||||
WAPP_DEF_DBL_LIST_TYPE(uptr , UptrNode , UptrList);
|
||||
WAPP_DEF_DBL_LIST_TYPE(iptr , IptrNode , IptrList);
|
||||
WAPP_DEF_DBL_LIST_TYPE(Str8 , Str8Node , Str8List);
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
END_C_LINKAGE
|
||||
#endif // !WAPP_PLATFORM_CPP
|
||||
|
||||
@@ -333,14 +333,12 @@ i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
|
||||
Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
|
||||
wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
|
||||
|
||||
Str8List *output = wapp_dbl_list_alloc(Str8, Str8List, allocator);
|
||||
Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
|
||||
|
||||
if (delimiter->size > str->size) {
|
||||
Str8 *full = wapp_str8_alloc_str8(allocator, str);
|
||||
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
|
||||
if (node) {
|
||||
node->item = full;
|
||||
wapp_dbl_list_push_back(Str8, output, node);
|
||||
Str8 *full = wapp_str8_alloc_str8(allocator, str);
|
||||
if (full) {
|
||||
wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
|
||||
}
|
||||
|
||||
goto RETURN_STR8_SPLIT;
|
||||
@@ -358,10 +356,8 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
|
||||
}
|
||||
|
||||
before_str = wapp_str8_alloc_substr(allocator, str, start, start + end);
|
||||
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
|
||||
if (node && before_str) {
|
||||
node->item = before_str;
|
||||
wapp_dbl_list_push_back(Str8, output, node);
|
||||
if (before_str) {
|
||||
wapp_dbl_list_push_back_alloc(Str8, allocator, output, before_str);
|
||||
}
|
||||
|
||||
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
|
||||
@@ -372,11 +368,9 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
|
||||
}
|
||||
|
||||
// Ensure the last part of the string after the delimiter is added to the list
|
||||
rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
|
||||
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
|
||||
if (node && rest) {
|
||||
node->item = rest;
|
||||
wapp_dbl_list_push_back(Str8, output, node);
|
||||
rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
|
||||
if (rest) {
|
||||
wapp_dbl_list_push_back_alloc(Str8, allocator, output, rest);
|
||||
}
|
||||
|
||||
RETURN_STR8_SPLIT:
|
||||
@@ -386,14 +380,12 @@ RETURN_STR8_SPLIT:
|
||||
Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
|
||||
wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
|
||||
|
||||
Str8List *output = wapp_dbl_list_alloc(Str8, Str8List, allocator);
|
||||
Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
|
||||
|
||||
if (delimiter->size > str->size) {
|
||||
Str8 *full = wapp_str8_alloc_str8(allocator, str);
|
||||
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
|
||||
if (node && full) {
|
||||
node->item = full;
|
||||
wapp_dbl_list_push_back(Str8, output, node);
|
||||
Str8 *full = wapp_str8_alloc_str8(allocator, str);
|
||||
if (full) {
|
||||
wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
|
||||
}
|
||||
|
||||
goto RETURN_STR8_SPLIT;
|
||||
@@ -410,10 +402,8 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
|
||||
}
|
||||
|
||||
after_str = wapp_str8_alloc_substr(allocator, rest, end + delimiter->size, str->size);
|
||||
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
|
||||
if (node) {
|
||||
node->item = after_str;
|
||||
wapp_dbl_list_push_front(Str8, output, node);
|
||||
if (after_str) {
|
||||
wapp_dbl_list_push_front_alloc(Str8, allocator, output, after_str);
|
||||
}
|
||||
|
||||
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
|
||||
@@ -422,11 +412,9 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
|
||||
++splits;
|
||||
}
|
||||
|
||||
rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
|
||||
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator);
|
||||
if (node && rest) {
|
||||
node->item = rest;
|
||||
wapp_dbl_list_push_front(Str8, output, node);
|
||||
rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
|
||||
if (rest) {
|
||||
wapp_dbl_list_push_front_alloc(Str8, allocator, output, rest);
|
||||
}
|
||||
|
||||
RETURN_STR8_SPLIT:
|
||||
@@ -441,16 +429,16 @@ Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *d
|
||||
|
||||
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
||||
// MSVC Spectre mitigation warnings
|
||||
Str8Node *node;
|
||||
Str8 *node;
|
||||
u64 node_index = 0;
|
||||
b8 running = node_index < list->node_count;
|
||||
while (running) {
|
||||
node = wapp_dbl_list_get(Str8, Str8Node, list, node_index);
|
||||
node = wapp_dbl_list_get(Str8, list, node_index);
|
||||
if (!node) {
|
||||
break;
|
||||
}
|
||||
|
||||
wapp_str8_concat_capped(output, node->item);
|
||||
wapp_str8_concat_capped(output, node);
|
||||
|
||||
// NOTE (Abdelrahman): Comparison extracted to variable to silence
|
||||
// MSVC Spectre mitigation warnings
|
||||
@@ -473,17 +461,17 @@ u64 wapp_str8_list_total_size(const Str8List *list) {
|
||||
|
||||
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
||||
// MSVC Spectre mitigation warnings
|
||||
Str8Node* node;
|
||||
Str8 *node;
|
||||
u64 node_index = 0;
|
||||
u64 output = 0;
|
||||
b8 running = node_index < list->node_count;
|
||||
while (running) {
|
||||
node = wapp_dbl_list_get(Str8, Str8Node, list, node_index);
|
||||
node = wapp_dbl_list_get(Str8, list, node_index);
|
||||
if (!node) {
|
||||
break;
|
||||
}
|
||||
|
||||
output += node->item->size;
|
||||
output += node->size;
|
||||
++node_index;
|
||||
running = node_index < list->node_count;
|
||||
}
|
||||
|
||||
@@ -125,27 +125,6 @@ u64 wapp_str8_list_total_size(const Str8List *list);
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
END_C_LINKAGE
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_lvalue(T&&) {
|
||||
return std::is_lvalue_reference<T>{};
|
||||
}
|
||||
|
||||
#define wapp_str8_node_from_cstr(STRING) wapp_dbl_list_node(Str8, Str8Node, [&]() { \
|
||||
wapp_persist Str8 str = wapp_str8_lit(STRING); \
|
||||
return &str; \
|
||||
}())
|
||||
#define wapp_str8_node_from_str8(STRING) wapp_dbl_list_node(Str8, Str8Node, [&]() { \
|
||||
if (is_lvalue(STRING)) { return &STRING; } \
|
||||
\
|
||||
wapp_persist Str8 str = STRING; \
|
||||
return &str; \
|
||||
}())
|
||||
#else
|
||||
#define wapp_str8_node_from_cstr(STRING) wapp_dbl_list_node(Str8, Str8Node, &wapp_str8_lit(STRING))
|
||||
#define wapp_str8_node_from_str8(STRING) wapp_dbl_list_node(Str8, Str8Node, &(STRING))
|
||||
#endif // !WAPP_PLATFORM_CPP
|
||||
|
||||
#endif // !STR8_H
|
||||
|
||||
@@ -29,23 +29,23 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
|
||||
}
|
||||
|
||||
// Handle first node
|
||||
const Str8Node *first_node = wapp_dbl_list_get(Str8, Str8Node, parts, 0);
|
||||
wapp_str8_copy_str8_capped(dst, first_node->item);
|
||||
Str8 *first_node = wapp_dbl_list_get(Str8, parts, 0);
|
||||
wapp_str8_copy_str8_capped(dst, first_node);
|
||||
|
||||
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
||||
// MSVC Spectre mitigation warnings
|
||||
const Str8Node *node = first_node;
|
||||
u64 node_index = 1;
|
||||
b8 running = node_index < parts->node_count;
|
||||
while (running && node->next) {
|
||||
node = node->next;
|
||||
if (node->item->size == 0) {
|
||||
continue;
|
||||
Str8 *node = first_node;
|
||||
u64 node_index = 1;
|
||||
b8 running = node_index < parts->node_count;
|
||||
while (running) {
|
||||
node = wapp_dbl_list_get(Str8, parts, node_index);
|
||||
if (node->size == 0) {
|
||||
goto CPATH_JOIN_LOOP_END;
|
||||
}
|
||||
|
||||
if (dst->size > 0) {
|
||||
char dst_last = wapp_str8_get(dst, dst->size - 1);
|
||||
char node_start = wapp_str8_get(node->item, 0);
|
||||
char node_start = wapp_str8_get(node, 0);
|
||||
b8 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP;
|
||||
|
||||
if (add_path_sep) {
|
||||
@@ -53,8 +53,9 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
|
||||
}
|
||||
}
|
||||
|
||||
wapp_str8_concat_capped(dst, node->item);
|
||||
wapp_str8_concat_capped(dst, node);
|
||||
|
||||
CPATH_JOIN_LOOP_END:
|
||||
++node_index;
|
||||
running = node_index < parts->node_count;
|
||||
}
|
||||
@@ -106,7 +107,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
|
||||
wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
|
||||
} else {
|
||||
for (u64 i = 0; i < levels; ++i) {
|
||||
wapp_dbl_list_pop_back(Str8, Str8Node, parts);
|
||||
wapp_dbl_list_pop_back(Str8, parts);
|
||||
}
|
||||
|
||||
u64 alignment = sizeof(void *) * 2;
|
||||
|
||||
Reference in New Issue
Block a user