Files
wizapp-stdlib/src/base/array/array.h
2026-01-02 16:50:52 +00:00

196 lines
11 KiB
C

// vim:fileencoding=utf-8:foldmethod=marker
#ifndef ARRAY_H
#define ARRAY_H
#include "../mem/allocator/mem_allocator.h"
#include "../../common/misc/misc_utils.h"
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define WAPP_ARRAY_MAGIC (u64)0x57415f415252
#define _calc_array_count(TYPE, ...) wapp_misc_utils_va_args_count(TYPE, __VA_ARGS__)
#define _calc_array_capacity(TYPE, ...) wapp_misc_utils_u64_round_up_pow2(_calc_array_count(TYPE, __VA_ARGS__) * 2)
#define wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, FILL) \
((TYPE *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(TYPE), FILL))
typedef struct Str8 Str8;
// NOTE (Abdelrahman): Typedefs to distinguish arrays from regular pointers
typedef void *GenericArray;
typedef void **VoidPtrArray;
typedef c8 *C8Array;
typedef c16 *C16Array;
typedef c32 *C32Array;
typedef u8 *U8Array;
typedef u16 *U16Array;
typedef u32 *U32Array;
typedef u64 *U64Array;
typedef b8 *B8Array;
typedef i8 *I8Array;
typedef i16 *I16Array;
typedef i32 *I32Array;
typedef i64 *I64Array;
typedef f32 *F32Array;
typedef f64 *F64Array;
typedef f128 *F128Array;
typedef uptr *UptrArray;
typedef iptr *IptrArray;
typedef Str8 *Str8Array;
#ifdef WAPP_PLATFORM_CPP
#define wapp_array(TYPE, ...) ([&]() { \
u64 capacity = _calc_array_capacity(TYPE, __VA_ARGS__); \
\
TYPE items[_calc_array_capacity(TYPE, __VA_ARGS__)] = {__VA_ARGS__}; \
\
wapp_persist u8 array[ \
sizeof(ArrayHeader) + _calc_array_capacity(TYPE, __VA_ARGS__) * sizeof(TYPE) \
] = {0}; \
ArrayHeader *header = (ArrayHeader *)array; \
header->magic = WAPP_ARRAY_MAGIC; \
header->count = _calc_array_count(TYPE, __VA_ARGS__); \
header->capacity = _calc_array_capacity(TYPE, __VA_ARGS__); \
header->item_size = sizeof(TYPE); \
\
u8 *buf = (u8 *)(header + 1); \
memcpy(buf, items, capacity * sizeof(TYPE)); \
return (TYPE *)buf; \
}())
#define wapp_array_with_capacity(TYPE, CAPACITY, FILL) ([&]() { \
wapp_persist u8 array[ \
sizeof(ArrayHeader) + CAPACITY * sizeof(TYPE) \
] = {0}; \
ArrayHeader *header = (ArrayHeader *)array; \
header->magic = WAPP_ARRAY_MAGIC; \
header->count = FILL ? CAPACITY : 0; \
header->capacity = CAPACITY; \
header->item_size = sizeof(TYPE); \
\
return (TYPE *)(header + 1); \
}())
#define wapp_array_pop(TYPE, ARRAY) ([&]() { \
if (ARRAY == NULL || _array_count((GenericArray)ARRAY) == 0) { \
TYPE result{}; \
return result; \
} \
\
return *((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))); \
}())
#else
#define _stack_array(TYPE, SIZE) struct { ArrayHeader header; TYPE items[SIZE]; }
#define wapp_array(TYPE, ...) \
(TYPE *)( \
(_stack_array(TYPE, _calc_array_capacity(TYPE, __VA_ARGS__))){ \
.header = { \
.magic = WAPP_ARRAY_MAGIC, \
.count = _calc_array_count(TYPE, __VA_ARGS__), \
.capacity = _calc_array_capacity(TYPE, __VA_ARGS__), \
.item_size = sizeof(TYPE), \
}, \
.items = {__VA_ARGS__}, \
}.items \
)
#define wapp_array_with_capacity(TYPE, CAPACITY, FILL) \
(TYPE *)( \
(_stack_array(TYPE, CAPACITY)){ \
.header = { \
.magic = WAPP_ARRAY_MAGIC, \
.count = FILL ? CAPACITY : 0, \
.capacity = CAPACITY, \
.item_size = sizeof(TYPE), \
}, \
.items = {0}, \
}.items \
)
#define wapp_array_pop(TYPE, ARRAY) \
(ARRAY == NULL || _array_count((GenericArray)ARRAY) == 0 ? \
(TYPE){0} : \
*((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))) \
)
#endif // !WAPP_PLATFORM_CPP
#define wapp_array_count(ARRAY) \
_array_count((GenericArray)ARRAY)
#define wapp_array_capacity(ARRAY) \
_array_capacity((GenericArray)ARRAY)
#define wapp_array_item_size(ARRAY) \
_array_item_size((GenericArray)ARRAY)
#define wapp_array_set_count(ARRAY, COUNT) \
_array_set_count((GenericArray)ARRAY, COUNT)
#define wapp_array_get(TYPE, ARRAY, INDEX) \
((TYPE *)_array_get((GenericArray)ARRAY, \
INDEX, \
sizeof(TYPE)))
#define wapp_array_set(TYPE, ARRAY, INDEX, VALUE_PTR) \
_array_set((GenericArray)ARRAY, \
INDEX, \
(u8 *)VALUE_PTR, \
sizeof(TYPE))
#define wapp_array_append_capped(TYPE, ARRAY, VALUE_PTR) \
_array_append_capped((GenericArray)ARRAY, \
(u8 *)VALUE_PTR, \
sizeof(TYPE))
#define wapp_array_extend_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
_array_extend_capped((GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
#define wapp_array_copy_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
_array_copy_capped((GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
#define wapp_array_append_alloc(TYPE, ALLOCATOR_PTR, ARRAY, VALUE_PTR) \
(TYPE *)_array_append_alloc(ALLOCATOR_PTR, \
(GenericArray)ARRAY, \
(u8 *)VALUE_PTR, \
sizeof(TYPE))
#define wapp_array_extend_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY) \
(TYPE *)_array_extend_alloc(ALLOCATOR_PTR, \
(GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
#define wapp_array_copy_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY) \
(TYPE *)_array_copy_alloc(ALLOCATOR_PTR, \
(GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
sizeof(TYPE))
#define wapp_array_clear(TYPE, ARRAY) \
_array_clear((GenericArray)ARRAY, \
sizeof(TYPE))
typedef struct header ArrayHeader;
struct header {
u64 magic;
u64 count;
u64 capacity;
u64 item_size;
};
u64 _array_count(GenericArray array);
u64 _array_capacity(GenericArray array);
u64 _array_item_size(GenericArray array);
void _array_set_count(GenericArray array, u64 count);
void *_array_get(GenericArray array, u64 index, u64 item_size);
void _array_set(GenericArray array, u64 index, void *value, u64 item_size);
void _array_append_capped(GenericArray array, void *value, u64 item_size);
void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_size);
void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size);
GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value, u64 item_size);
GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src, u64 item_size);
GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src, u64 item_size);
void *_array_pop(GenericArray array, u64 item_size);
void _array_clear(GenericArray array, u64 item_size);
GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size, b8 fill);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !ARRAY_H