// 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) ((TYPE *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(TYPE))) #ifdef WAPP_PLATFORM_CPP #define wapp_i32_array(...) ([&]() { \ wapp_persist i32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \ return I32Array{ \ buf, \ wapp_misc_utils_va_args_count(i32, __VA_ARGS__), \ wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2), \ sizeof(i32) \ }; \ }()) #define wapp_i32_array_with_capacity(CAPACITY) ([&]() { \ wapp_persist i32 buf[CAPACITY] = {}; \ return I32Array{buf, 0, CAPACITY, sizeof(i32)}; \ }()) #define wapp_i32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ *_i32_array_pop(ARRAY_PTR) : \ i32{} \ ) #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) \ (TYPE *)( \ (_stack_array(TYPE, CAPACITY)){ \ .header = { \ .magic = WAPP_ARRAY_MAGIC, \ .count = 0, \ .capacity = CAPACITY, \ .item_size = sizeof(TYPE), \ }, \ .items = {0}, \ }.items \ ) #define wapp_array_count(TYPE, ARRAY_PTR) \ _array_count((u8 *)ARRAY_PTR, sizeof(TYPE)) #define wapp_array_capacity(TYPE, ARRAY_PTR) \ _array_capacity((u8 *)ARRAY_PTR, sizeof(TYPE)) #define wapp_array_item_size(TYPE, ARRAY_PTR) \ _array_item_size((u8 *)ARRAY_PTR, sizeof(TYPE)) #define wapp_array_get(TYPE, ARRAY_PTR, INDEX) \ (*((TYPE *)_array_get((u8 *)ARRAY_PTR, INDEX, sizeof(TYPE)))) #define wapp_array_set(TYPE, ARRAY_PTR, INDEX, VALUE_PTR) \ _array_set((u8 *)ARRAY_PTR, INDEX, (u8 *)VALUE_PTR, sizeof(TYPE)) #define wapp_array_append_capped(TYPE, ARRAY_PTR, VALUE_PTR) \ _array_append_capped((u8 *)ARRAY_PTR, (u8 *)VALUE_PTR, sizeof(TYPE)) #define wapp_array_extend_capped(TYPE, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ _array_extend_capped((u8 *)DST_ARRAY_PTR, (u8 *)SRC_ARRAY_PTR, sizeof(TYPE)) #define wapp_array_copy_capped(TYPE, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ _array_copy_capped((u8 *)DST_ARRAY_PTR, (u8 *)SRC_ARRAY_PTR, sizeof(TYPE)) #define wapp_array_append_alloc(TYPE, ALLOCATOR_PTR, ARRAY_PTR, VALUE_PTR) \ (TYPE *)_array_append_alloc(ALLOCATOR_PTR, (u8 *)ARRAY_PTR, (u8 *)VALUE_PTR, sizeof(TYPE)) #define wapp_array_extend_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ (TYPE *)_array_extend_alloc(ALLOCATOR_PTR, (u8 *)DST_ARRAY_PTR, (u8 *)SRC_ARRAY_PTR, sizeof(TYPE)) #define wapp_array_copy_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ (TYPE *)_array_copy_alloc(ALLOCATOR_PTR, (u8 *)DST_ARRAY_PTR, (u8 *)SRC_ARRAY_PTR, sizeof(TYPE)) #define wapp_array_pop(TYPE, ARRAY_PTR) \ (ARRAY_PTR != NULL && _array_count((u8 *)ARRAY_PTR, sizeof(TYPE)) > 0 ? \ *((TYPE *)_array_pop((u8 *)ARRAY_PTR, sizeof(TYPE))) : \ (TYPE){0} \ ) #define wapp_array_clear(TYPE, ARRAY_PTR) \ _array_clear((u8 *)ARRAY_PTR, sizeof(TYPE)) #endif // !WAPP_PLATFORM_CPP typedef struct header ArrayHeader; struct header { u64 magic; u64 count; u64 capacity; u64 item_size; }; typedef struct array Array; struct array { ArrayHeader header; u8 *items; }; typedef struct GenericArray GenericArray; struct GenericArray { ArrayHeader header; void *items; }; u64 _array_count(u8 *array, u64 item_size); u64 _array_capacity(u8 *array, u64 item_size); u64 _array_item_size(u8 *array, u64 item_size); u8 *_array_get(u8 *array, u64 index, u64 item_size); void _array_set(u8 *array, u64 index, u8 *value, u64 item_size); void _array_append_capped(u8 *array, u8 *value, u64 item_size); void _array_extend_capped(u8 *array, const u8 *other, u64 item_size); void _array_copy_capped(u8 *array, const u8 *other, u64 item_size); u8 *_array_append_alloc(const Allocator *allocator, u8 *array, u8 *value, u64 item_size); u8 *_array_extend_alloc(const Allocator *allocator, u8 *array, const u8 *other, u64 item_size); u8 *_array_copy_alloc(const Allocator *allocator, u8 *array, const u8 *other, u64 item_size); u8 *_array_pop(u8 *array, u64 item_size); void _array_clear(u8 *array, u64 item_size); u8 *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size); #ifdef WAPP_PLATFORM_CPP END_C_LINKAGE #endif // !WAPP_PLATFORM_CPP #endif // !ARRAY_H