71 lines
2.2 KiB
C
71 lines
2.2 KiB
C
#pragma once
|
|
#include "../std.h"
|
|
|
|
// minimal max_len after initial (0)
|
|
#define __List_min_size 16
|
|
|
|
#define List_declare(T)\
|
|
typedef struct List_##T {\
|
|
T* data;\
|
|
u32 len;\
|
|
u32 max_len;\
|
|
} List_##T;\
|
|
\
|
|
static inline List_##T List_##T##_construct(T* data_ptr, u32 len, u32 max_len) {\
|
|
return (List_##T){ .data = data_ptr, .len = len, .max_len = max_len };\
|
|
}\
|
|
\
|
|
List_##T List_##T##_alloc(u32 initial_len);\
|
|
\
|
|
T* List_##T##_expand(List_##T* ptr, u32 count);\
|
|
void List_##T##_push(List_##T* ptr, T value);\
|
|
void List_##T##_pushMany(List_##T* ptr, T* values, u32 count);\
|
|
bool List_##T##_tryRemoveAt(List_##T* ptr, u32 i);\
|
|
|
|
|
|
#define List_define(T)\
|
|
List_##T List_##T##_alloc(u32 initial_len){\
|
|
if(initial_len == 0)\
|
|
return List_##T##_construct((T*)NULL, 0, 0);\
|
|
u32 max_len = ALIGN_TO(initial_len, sizeof(void*)/sizeof(T));\
|
|
/* branchless version of max(max_len, __List_min_size) */\
|
|
max_len += (max_len < __List_min_size) * (__List_min_size - max_len);\
|
|
return List_##T##_construct((T*)malloc(initial_len * sizeof(T)), 0, max_len);\
|
|
}\
|
|
\
|
|
T* List_##T##_expand(List_##T* ptr, u32 count){\
|
|
u32 occupied_len = ptr->len;\
|
|
u32 expanded_max_len = ptr->max_len;\
|
|
ptr->len += count;\
|
|
while(ptr->len > ptr->max_len){\
|
|
expanded_max_len *= 2;\
|
|
}\
|
|
ptr->data = (T*)realloc(ptr->data, expanded_max_len * sizeof(T));\
|
|
return ptr->data + occupied_len;\
|
|
}\
|
|
\
|
|
void List_##T##_push(List_##T* ptr, T value){\
|
|
T* empty_cell_ptr = List_##T##_expand(ptr, 1);\
|
|
*empty_cell_ptr = value;\
|
|
}\
|
|
\
|
|
void List_##T##_pushMany(List_##T* ptr, T* values, u32 count){\
|
|
T* empty_cell_ptr = List_##T##_expand(ptr, count);\
|
|
memcpy(empty_cell_ptr, values, count * sizeof(T));\
|
|
}\
|
|
\
|
|
bool List_##T##_tryRemoveAt(List_##T* ptr, u32 i){\
|
|
if(ptr->len == 0 || i >= ptr->len)\
|
|
return false;\
|
|
\
|
|
ptr->len--;\
|
|
for(; i < ptr->len; i++){\
|
|
ptr->data[i] = ptr->data[i + 1];\
|
|
}\
|
|
return true;\
|
|
}\
|
|
|
|
|
|
List_declare(u32);
|
|
List_declare(u8);
|