diff --git a/src/containers/array/array.c b/src/containers/array/array.c new file mode 100644 index 0000000..c2c1f9e --- /dev/null +++ b/src/containers/array/array.c @@ -0,0 +1,154 @@ +#include "array.h" +#include "../../common/aliases/aliases.h" +#include "../../common/misc/misc_utils.h" +#include "../../core/mem/allocator/mem_allocator.h" +#include + +i32 *wapp_i32_array_get(const I32Array *array, u64 index) { + if (!array || index >= array->count) { + return NULL; + } + + return &(array->items[index]); +} + +void wapp_i32_array_set(I32Array *array, u64 index, i32 item) { + if (!array || index >= array->count) { + return; + } + + array->items[index] = item; +} + +void wapp_i32_array_append_capped(I32Array *array, i32 item) { + if (!array || array->count >= array->capacity) { + return; + } + + array->items[(array->count)++] = item; +} + +void wapp_i32_array_extend_capped(I32Array *array, const I32Array *other) { + if (!array || !other) { + return; + } + + u64 remaining_capacity = array->capacity - array->count; + if (other->count >= remaining_capacity) { + return; + } + + i32 *item; + u64 items_to_add = other->count; + for (u64 i = 0; i < items_to_add; ++i) { + item = wapp_i32_array_get(other, i); + if (!item) { + continue; + } + + wapp_i32_array_append_capped(array, *item); + } +} + +void wapp_i32_array_clear(I32Array *array) { + if (!array) { + return; + } + + array->count = 0; +} + +i32 wapp_i32_array_pop(I32Array *array) { + if (!array || array->count == 0) { + return (i32){0}; + } + + return array->items[--(array->count)]; +} + +void wapp_i32_array_copy(const I32Array *src, I32Array *dst) { + if (!src || !dst) { + return; + } + + wapp_i32_array_clear(dst); + + i32 *item; + u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity; + for (u64 i = 0; i < to_copy; ++i) { + item = wapp_i32_array_get(src, i); + if (!item) { + continue; + } + + wapp_i32_array_append_capped(dst, *item); + } +} + +I32Array *wapp_i32_array_alloc_capacity(const Allocator *allocator, u64 capacity) { + u64 allocation_size = sizeof(I32Array) + sizeof(i32) * capacity; + I32Array *array = NULL; + + if (!allocator) { + goto RETURN_INT_ARRAY_ALLOC; + } + + array = wapp_mem_allocator_alloc(allocator, allocation_size); + if (!array) { + goto RETURN_INT_ARRAY_ALLOC; + } + + array->items = (i32 *)((u8 *)array + sizeof(I32Array)); + array->count = 0; + array->capacity = capacity; + +RETURN_INT_ARRAY_ALLOC: + return array; +} + +I32Array *wapp_i32_array_append_alloc(const Allocator *allocator, I32Array *array, i32 item) { + I32Array *output = array; + + if (!allocator || !array) { + goto RETURN_INT_ARRAY_APPEND_ALLOC; + } + + if (array->count >= array->capacity) { + u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2); + output = wapp_i32_array_alloc_capacity(allocator, new_capacity); + if (!output) { + output = array; + goto RETURN_INT_ARRAY_APPEND_ALLOC; + } + wapp_i32_array_copy(array, output); + } + + wapp_i32_array_append_capped(output, item); + +RETURN_INT_ARRAY_APPEND_ALLOC: + return output; +} + +I32Array *wapp_i32_array_extend_alloc(const Allocator *allocator, I32Array *array, const I32Array *other) { + I32Array *output = array; + + if (!allocator || !array || !other) { + goto RETURN_INT_ARRAY_EXTEND_ALLOC; + } + + u64 remaining_capacity = array->capacity - array->count; + if (other->count >= remaining_capacity) { + u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2); + output = wapp_i32_array_alloc_capacity(allocator, new_capacity); + if (!output) { + output = array; + goto RETURN_INT_ARRAY_EXTEND_ALLOC; + } + wapp_i32_array_copy(array, output); + } + + wapp_i32_array_extend_capped(output, other); + +RETURN_INT_ARRAY_EXTEND_ALLOC: + return output; +} diff --git a/src/containers/array/array.h b/src/containers/array/array.h index e98e4d7..3748324 100644 --- a/src/containers/array/array.h +++ b/src/containers/array/array.h @@ -2,49 +2,39 @@ #define ARRAY_H #include "../../common/aliases/aliases.h" +#include "../../common/misc/misc_utils.h" #include "../../common/platform/platform.h" +#include "../../core/mem/allocator/mem_allocator.h" #ifdef WAPP_PLATFORM_CPP BEGIN_C_LINKAGE #endif // !WAPP_PLATFORM_CPP -typedef struct int_array IntArray; -struct int_array { - int *items; +typedef struct i32_array I32Array; +struct i32_array { + i32 *items; u64 count; u64 capacity; }; -#define U64_RSHIFT_OR_1(X) (((u64)X) | (((u64)X) >> 1)) -#define U64_RSHIFT_OR_2(X) (((u64)X) | (((u64)X) >> 2)) -#define U64_RSHIFT_OR_4(X) (((u64)X) | (((u64)X) >> 4)) -#define U64_RSHIFT_OR_8(X) (((u64)X) | (((u64)X) >> 8)) -#define U64_RSHIFT_OR_16(X) (((u64)X) | (((u64)X) >> 16)) -#define U64_RSHIFT_OR_32(X) (((u64)X) | (((u64)X) >> 32)) -#define U64_ROUND_UP_POW2(X) ( \ - ( \ - U64_RSHIFT_OR_32( \ - U64_RSHIFT_OR_16( \ - U64_RSHIFT_OR_8( \ - U64_RSHIFT_OR_4( \ - U64_RSHIFT_OR_2( \ - U64_RSHIFT_OR_1(X - 1) \ - ) \ - ) \ - ) \ - ) \ - ) \ - ) + 1 \ -) - -#define INT_ARRAY_COUNT_ARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) - -#define wapp_int_array(...) ((IntArray){ \ - .items = (int[U64_ROUND_UP_POW2(INT_ARRAY_COUNT_ARGS(__VA_ARGS__) * 2)]){__VA_ARGS__}, \ - .count = INT_ARRAY_COUNT_ARGS(__VA_ARGS__), \ - .capacity = U64_ROUND_UP_POW2(INT_ARRAY_COUNT_ARGS(__VA_ARGS__) * 2) \ +#define wapp_i32_array(...) ((I32Array){ \ + .items = (i32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \ + .count = wapp_misc_utils_va_args_count(i32, __VA_ARGS__), \ + .capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2) \ }) -#define wapp_int_array_with_capacity(CAPACITY) ((IntArray){.items = (int[CAPACITY]){0}, .count = 0, .capacity = CAPACITY}) +#define wapp_i32_array_with_capacity(CAPACITY) ((I32Array){.items = (i32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY}) + +i32 *wapp_i32_array_get(const I32Array *array, u64 index); +void wapp_i32_array_set(I32Array *array, u64 index, i32 item); +void wapp_i32_array_append_capped(I32Array *array, i32 item); +void wapp_i32_array_extend_capped(I32Array *array, const I32Array *other); +void wapp_i32_array_clear(I32Array *array); +i32 wapp_i32_array_pop(I32Array *array); +void wapp_i32_array_copy(const I32Array *src, I32Array *dst); + +I32Array *wapp_i32_array_alloc_capacity(const Allocator *allocator, u64 capacity); +I32Array *wapp_i32_array_append_alloc(const Allocator *allocator, I32Array *array, i32 item); +I32Array *wapp_i32_array_extend_alloc(const Allocator *allocator, I32Array *array, const I32Array *other); #ifdef WAPP_PLATFORM_CPP END_C_LINKAGE