Remove array structs (#10)
Reviewed-on: #10
This commit was merged in pull request #10.
This commit is contained in:
@@ -8,65 +8,113 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#define _offset_pointer(PTR, OFFSET) ((void *)((uptr)(PTR) + (OFFSET)))
|
||||
#define _array_header(ARRAY) (ArrayHeader *)(_offset_pointer(ARRAY, (i64)sizeof(ArrayHeader) * -1))
|
||||
|
||||
wapp_persist inline void _array_validate(const GenericArray *array, u64 item_size);
|
||||
wapp_persist inline void _array_validate(const GenericArray array, u64 item_size);
|
||||
|
||||
void *_array_get(GenericArray *array, u64 index, u64 item_size) {
|
||||
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
|
||||
_array_validate(array, item_size);
|
||||
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
||||
u64 _array_count(GenericArray array) {
|
||||
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
||||
|
||||
return _offset_pointer(array->items, array->item_size * index);
|
||||
ArrayHeader *header = _array_header(array);
|
||||
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
|
||||
|
||||
return header->count;
|
||||
}
|
||||
|
||||
void _array_set(GenericArray *array, u64 index, void *value, u64 item_size) {
|
||||
u64 _array_capacity(GenericArray array) {
|
||||
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
||||
|
||||
ArrayHeader *header = _array_header(array);
|
||||
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
|
||||
|
||||
return header->capacity;
|
||||
}
|
||||
|
||||
u64 _array_item_size(GenericArray array) {
|
||||
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
||||
|
||||
ArrayHeader *header = _array_header(array);
|
||||
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
|
||||
|
||||
return header->item_size;
|
||||
}
|
||||
|
||||
void _array_set_count(GenericArray array, u64 count) {
|
||||
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
||||
|
||||
ArrayHeader *header = _array_header(array);
|
||||
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
|
||||
|
||||
header->count = count;
|
||||
}
|
||||
|
||||
void *_array_get(GenericArray array, u64 index, u64 item_size) {
|
||||
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
|
||||
_array_validate(array, item_size);
|
||||
|
||||
ArrayHeader *header = _array_header(array);
|
||||
wapp_runtime_assert(index < header->count, "`index` is out of bounds");
|
||||
|
||||
return _offset_pointer(array, header->item_size * index);
|
||||
}
|
||||
|
||||
void _array_set(GenericArray array, u64 index, void *value, u64 item_size) {
|
||||
void *item = _array_get(array, index, item_size);
|
||||
memcpy(item, value, array->item_size);
|
||||
|
||||
ArrayHeader *header = _array_header(array);
|
||||
memcpy(item, value, header->item_size);
|
||||
}
|
||||
|
||||
void _array_append_capped(GenericArray *array, void *value, u64 item_size) {
|
||||
void _array_append_capped(GenericArray array, void *value, u64 item_size) {
|
||||
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
|
||||
_array_validate(array, item_size);
|
||||
|
||||
if (array->count >= array->capacity) { return; }
|
||||
ArrayHeader *header = _array_header(array);
|
||||
if (header->count >= header->capacity) { return; }
|
||||
|
||||
u64 index = (array->count)++;
|
||||
u64 index = (header->count)++;
|
||||
_array_set(array, index, value, item_size);
|
||||
}
|
||||
|
||||
void _array_extend_capped(GenericArray *dst, const GenericArray *src, u64 item_size) {
|
||||
void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_size) {
|
||||
wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
|
||||
_array_validate(dst, item_size);
|
||||
_array_validate(src, item_size);
|
||||
|
||||
u64 remaining_capacity = dst->capacity - dst->count;
|
||||
ArrayHeader *src_header = _array_header(src);
|
||||
ArrayHeader *dst_header = _array_header(dst);
|
||||
u64 remaining_capacity = dst_header->capacity - dst_header->count;
|
||||
|
||||
u64 copy_count = src->count < remaining_capacity ? src->count : remaining_capacity;
|
||||
void *dst_ptr = _offset_pointer(dst->items, dst->count * dst->item_size);
|
||||
memcpy(dst_ptr, src->items, copy_count * src->item_size);
|
||||
dst->count += copy_count;
|
||||
u64 copy_count = src_header->count < remaining_capacity ? src_header->count : remaining_capacity;
|
||||
void *dst_ptr = _offset_pointer(dst, dst_header->count * dst_header->item_size);
|
||||
memcpy(dst_ptr, src, copy_count * src_header->item_size);
|
||||
dst_header->count += copy_count;
|
||||
}
|
||||
|
||||
void _array_copy_capped(GenericArray *dst, const GenericArray *src, u64 item_size) {
|
||||
void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size) {
|
||||
wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
|
||||
_array_validate(dst, item_size);
|
||||
_array_validate(src, item_size);
|
||||
|
||||
_array_clear(dst, item_size);
|
||||
u64 copy_count = src->count < dst->capacity ? src->count : dst->capacity;
|
||||
memcpy(dst->items, src->items, copy_count * src->item_size);
|
||||
dst->count = copy_count;
|
||||
|
||||
ArrayHeader *src_header = _array_header(src);
|
||||
ArrayHeader *dst_header = _array_header(dst);
|
||||
u64 copy_count = src_header->count < dst_header->capacity ? src_header->count : dst_header->capacity;
|
||||
memcpy((void *)dst, (void *)src, copy_count * src_header->item_size);
|
||||
dst_header->count = copy_count;
|
||||
}
|
||||
|
||||
GenericArray *_array_append_alloc(const Allocator *allocator, GenericArray *array, void *value, u64 item_size) {
|
||||
GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value, u64 item_size) {
|
||||
wapp_runtime_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
||||
_array_validate(array, item_size);
|
||||
|
||||
GenericArray *output = array;
|
||||
GenericArray output = array;
|
||||
|
||||
if (array->count >= array->capacity) {
|
||||
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
||||
output = (GenericArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size, false);
|
||||
ArrayHeader *header = _array_header(array);
|
||||
if (header->count >= header->capacity) {
|
||||
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(header->capacity * 2);
|
||||
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity, header->item_size, false);
|
||||
if (!output) {
|
||||
output = array;
|
||||
goto RETURN_ARRAY_APPEND_ALLOC;
|
||||
@@ -80,17 +128,19 @@ RETURN_ARRAY_APPEND_ALLOC:
|
||||
return output;
|
||||
}
|
||||
|
||||
GenericArray *_array_extend_alloc(const Allocator *allocator, GenericArray *dst, const GenericArray *src, u64 item_size) {
|
||||
GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src, u64 item_size) {
|
||||
wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
|
||||
_array_validate(dst, item_size);
|
||||
_array_validate(src, item_size);
|
||||
|
||||
GenericArray *output = dst;
|
||||
GenericArray output = dst;
|
||||
|
||||
u64 remaining_capacity = dst->capacity - dst->count;
|
||||
if (src->count >= remaining_capacity) {
|
||||
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
||||
output = (GenericArray *)_array_alloc_capacity(allocator, new_capacity, dst->item_size, false);
|
||||
ArrayHeader *src_header = _array_header(src);
|
||||
ArrayHeader *dst_header = _array_header(dst);
|
||||
u64 remaining_capacity = dst_header->capacity - dst_header->count;
|
||||
if (src_header->count >= remaining_capacity) {
|
||||
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst_header->capacity * 2);
|
||||
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity, dst_header->item_size, false);
|
||||
if (!output) {
|
||||
output = dst;
|
||||
goto RETURN_ARRAY_EXTEND_ALLOC;
|
||||
@@ -104,16 +154,19 @@ RETURN_ARRAY_EXTEND_ALLOC:
|
||||
return output;
|
||||
}
|
||||
|
||||
GenericArray *_array_copy_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) {
|
||||
wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
|
||||
_array_validate(dst, item_size);
|
||||
_array_validate(src, item_size);
|
||||
|
||||
GenericArray *output = dst;
|
||||
GenericArray output = dst;
|
||||
|
||||
if (src->count >= dst->capacity) {
|
||||
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
||||
output = (GenericArray *)_array_alloc_capacity(allocator, new_capacity, src->item_size, false);
|
||||
ArrayHeader *src_header = _array_header(src);
|
||||
ArrayHeader *dst_header = _array_header(dst);
|
||||
if (src_header->count >= dst_header->capacity) {
|
||||
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst_header->capacity * 2);
|
||||
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity,
|
||||
src_header->item_size, false);
|
||||
if (!output) {
|
||||
output = dst;
|
||||
goto RETURN_ARRAY_COPY_ALLOC;
|
||||
@@ -126,48 +179,50 @@ RETURN_ARRAY_COPY_ALLOC:
|
||||
return output;
|
||||
}
|
||||
|
||||
void *_array_pop(GenericArray *array, u64 item_size) {
|
||||
void *_array_pop(GenericArray array, u64 item_size) {
|
||||
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
|
||||
_array_validate(array, item_size);
|
||||
|
||||
if (array->count == 0) { return NULL; }
|
||||
ArrayHeader *header = _array_header(array);
|
||||
if (header->count == 0) { return NULL; }
|
||||
|
||||
u64 index = array->count - 1;
|
||||
u64 index = header->count - 1;
|
||||
void *out = _array_get(array, index, item_size);
|
||||
--(array->count);
|
||||
--(header->count);
|
||||
return out;
|
||||
}
|
||||
|
||||
void _array_clear(GenericArray *array, u64 item_size) {
|
||||
void _array_clear(GenericArray array, u64 item_size) {
|
||||
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
|
||||
_array_validate(array, item_size);
|
||||
|
||||
array->count = 0;
|
||||
ArrayHeader *header = _array_header(array);
|
||||
header->count = 0;
|
||||
}
|
||||
|
||||
GenericArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size, b8 fill) {
|
||||
GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size, b8 fill) {
|
||||
wapp_runtime_assert(allocator != NULL, "`allocator` should not be NULL");
|
||||
|
||||
GenericArray *output = NULL;
|
||||
GenericArray output = NULL;
|
||||
|
||||
u64 allocation_size = sizeof(GenericArray) + item_size * capacity;
|
||||
|
||||
output = wapp_mem_allocator_alloc(allocator, allocation_size);
|
||||
if (!output) {
|
||||
u64 allocation_size = sizeof(ArrayHeader) + item_size * capacity;
|
||||
ArrayHeader *header = wapp_mem_allocator_alloc(allocator, allocation_size);
|
||||
if (!header) {
|
||||
goto RETURN_ARRAY_ALLOC;
|
||||
}
|
||||
|
||||
output->magic = WAPP_ARRAY_MAGIC;
|
||||
output->count = fill ? capacity : 0;
|
||||
output->capacity = capacity;
|
||||
output->item_size = item_size;
|
||||
output->items = (void *)(output + 1);
|
||||
output = (u8 *)(header + 1);
|
||||
header->magic = WAPP_ARRAY_MAGIC;
|
||||
header->count = fill ? capacity : 0;
|
||||
header->capacity = capacity;
|
||||
header->item_size = item_size;
|
||||
|
||||
RETURN_ARRAY_ALLOC:
|
||||
return output;
|
||||
}
|
||||
|
||||
wapp_persist inline void _array_validate(const GenericArray *array, u64 item_size) {
|
||||
wapp_runtime_assert(WAPP_ARRAY_MAGIC == array->magic, "`array` is not a valid wapp array");
|
||||
wapp_runtime_assert(item_size == array->item_size, "Invalid item type provided");
|
||||
wapp_persist inline void _array_validate(const GenericArray array, u64 item_size) {
|
||||
ArrayHeader *header = _array_header(array);
|
||||
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
|
||||
wapp_runtime_assert(item_size == header->item_size, "Invalid item type provided");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user