3012 lines
92 KiB
C
3012 lines
92 KiB
C
/**
|
|
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN
|
|
*/
|
|
|
|
#include "./array.h"
|
|
#include "../../common/assert/assert.h"
|
|
#include "../../common/aliases/aliases.h"
|
|
#include "../mem_allocator/mem_allocator.h"
|
|
#include "../../common/misc/misc_utils.h"
|
|
#include "../../common/aliases/aliases.h"
|
|
#include "../../common/platform/platform.h"
|
|
#include <stddef.h>
|
|
|
|
Str8 *wapp_str8_array_get(const Str8Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (Str8 *)ptr;
|
|
}
|
|
|
|
void wapp_str8_array_set(Str8Array *array, u64 index, Str8 *item) {
|
|
Str8 *ptr = wapp_str8_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_str8_array_append_capped(Str8Array *array, Str8 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_str8_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_str8_array_extend_capped(Str8Array *array, const Str8Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
Str8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_str8_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_str8_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_str8_array_clear(Str8Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_str8_array_copy_capped(const Str8Array *src, Str8Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_str8_array_clear(dst);
|
|
|
|
Str8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_str8_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_str8_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
Str8Array *wapp_str8_array_append_alloc(const Allocator *allocator, Str8Array *array, Str8 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
Str8Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (Str8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_STR8_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_str8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_str8_array_append_capped(output, item);
|
|
|
|
RETURN_STR8_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
Str8Array *wapp_str8_array_extend_alloc(const Allocator *allocator, Str8Array *array, const Str8Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
Str8Array *output = array;
|
|
|
|
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 = (Str8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_STR8_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_str8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_str8_array_extend_capped(output, other);
|
|
|
|
RETURN_STR8_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
Str8Array *wapp_str8_array_copy_alloc(const Allocator *allocator, const Str8Array *src, Str8Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
Str8Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (Str8Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_STR8_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_str8_array_clear(output);
|
|
wapp_str8_array_copy_capped(src, output);
|
|
|
|
RETURN_STR8_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
Str8 *_str8_array_pop(Str8Array *array) {
|
|
u64 index = array->count - 1;
|
|
Str8 *out = wapp_str8_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
void * *wapp_void_ptr_array_get(const VoidPArray *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (void * *)ptr;
|
|
}
|
|
|
|
void wapp_void_ptr_array_set(VoidPArray *array, u64 index, void * *item) {
|
|
void * *ptr = wapp_void_ptr_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_void_ptr_array_append_capped(VoidPArray *array, void * *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_void_ptr_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_void_ptr_array_extend_capped(VoidPArray *array, const VoidPArray *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
void * *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_void_ptr_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_void_ptr_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_void_ptr_array_clear(VoidPArray *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_void_ptr_array_copy_capped(const VoidPArray *src, VoidPArray *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_void_ptr_array_clear(dst);
|
|
|
|
void * *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_void_ptr_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_void_ptr_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
VoidPArray *wapp_void_ptr_array_append_alloc(const Allocator *allocator, VoidPArray *array, void * *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
VoidPArray *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (VoidPArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_VOID_PTR_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_void_ptr_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_void_ptr_array_append_capped(output, item);
|
|
|
|
RETURN_VOID_PTR_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
VoidPArray *wapp_void_ptr_array_extend_alloc(const Allocator *allocator, VoidPArray *array, const VoidPArray *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
VoidPArray *output = array;
|
|
|
|
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 = (VoidPArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_VOID_PTR_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_void_ptr_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_void_ptr_array_extend_capped(output, other);
|
|
|
|
RETURN_VOID_PTR_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
VoidPArray *wapp_void_ptr_array_copy_alloc(const Allocator *allocator, const VoidPArray *src, VoidPArray *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
VoidPArray *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (VoidPArray *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_VOID_PTR_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_void_ptr_array_clear(output);
|
|
wapp_void_ptr_array_copy_capped(src, output);
|
|
|
|
RETURN_VOID_PTR_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
void * *_void_ptr_array_pop(VoidPArray *array) {
|
|
u64 index = array->count - 1;
|
|
void * *out = wapp_void_ptr_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
b32 *wapp_b32_array_get(const B32Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (b32 *)ptr;
|
|
}
|
|
|
|
void wapp_b32_array_set(B32Array *array, u64 index, b32 *item) {
|
|
b32 *ptr = wapp_b32_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_b32_array_append_capped(B32Array *array, b32 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_b32_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_b32_array_extend_capped(B32Array *array, const B32Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
b32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_b32_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_b32_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_b32_array_clear(B32Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_b32_array_copy_capped(const B32Array *src, B32Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_b32_array_clear(dst);
|
|
|
|
b32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_b32_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_b32_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
B32Array *wapp_b32_array_append_alloc(const Allocator *allocator, B32Array *array, b32 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
B32Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (B32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_B32_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_b32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_b32_array_append_capped(output, item);
|
|
|
|
RETURN_B32_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
B32Array *wapp_b32_array_extend_alloc(const Allocator *allocator, B32Array *array, const B32Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
B32Array *output = array;
|
|
|
|
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 = (B32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_B32_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_b32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_b32_array_extend_capped(output, other);
|
|
|
|
RETURN_B32_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
B32Array *wapp_b32_array_copy_alloc(const Allocator *allocator, const B32Array *src, B32Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
B32Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (B32Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_B32_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_b32_array_clear(output);
|
|
wapp_b32_array_copy_capped(src, output);
|
|
|
|
RETURN_B32_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
b32 *_b32_array_pop(B32Array *array) {
|
|
u64 index = array->count - 1;
|
|
b32 *out = wapp_b32_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
char *wapp_char_array_get(const CharArray *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (char *)ptr;
|
|
}
|
|
|
|
void wapp_char_array_set(CharArray *array, u64 index, char *item) {
|
|
char *ptr = wapp_char_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_char_array_append_capped(CharArray *array, char *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_char_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_char_array_extend_capped(CharArray *array, const CharArray *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
char *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_char_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_char_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_char_array_clear(CharArray *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_char_array_copy_capped(const CharArray *src, CharArray *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_char_array_clear(dst);
|
|
|
|
char *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_char_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_char_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
CharArray *wapp_char_array_append_alloc(const Allocator *allocator, CharArray *array, char *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
CharArray *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (CharArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_CHAR_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_char_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_char_array_append_capped(output, item);
|
|
|
|
RETURN_CHAR_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
CharArray *wapp_char_array_extend_alloc(const Allocator *allocator, CharArray *array, const CharArray *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
CharArray *output = array;
|
|
|
|
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 = (CharArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_CHAR_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_char_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_char_array_extend_capped(output, other);
|
|
|
|
RETURN_CHAR_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
CharArray *wapp_char_array_copy_alloc(const Allocator *allocator, const CharArray *src, CharArray *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
CharArray *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (CharArray *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_CHAR_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_char_array_clear(output);
|
|
wapp_char_array_copy_capped(src, output);
|
|
|
|
RETURN_CHAR_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
char *_char_array_pop(CharArray *array) {
|
|
u64 index = array->count - 1;
|
|
char *out = wapp_char_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
c8 *wapp_c8_array_get(const C8Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (c8 *)ptr;
|
|
}
|
|
|
|
void wapp_c8_array_set(C8Array *array, u64 index, c8 *item) {
|
|
c8 *ptr = wapp_c8_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_c8_array_append_capped(C8Array *array, c8 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_c8_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_c8_array_extend_capped(C8Array *array, const C8Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
c8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_c8_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_c8_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_c8_array_clear(C8Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_c8_array_copy_capped(const C8Array *src, C8Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_c8_array_clear(dst);
|
|
|
|
c8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_c8_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_c8_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
C8Array *wapp_c8_array_append_alloc(const Allocator *allocator, C8Array *array, c8 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
C8Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (C8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_C8_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_c8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_c8_array_append_capped(output, item);
|
|
|
|
RETURN_C8_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
C8Array *wapp_c8_array_extend_alloc(const Allocator *allocator, C8Array *array, const C8Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
C8Array *output = array;
|
|
|
|
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 = (C8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_C8_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_c8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_c8_array_extend_capped(output, other);
|
|
|
|
RETURN_C8_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
C8Array *wapp_c8_array_copy_alloc(const Allocator *allocator, const C8Array *src, C8Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
C8Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (C8Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_C8_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_c8_array_clear(output);
|
|
wapp_c8_array_copy_capped(src, output);
|
|
|
|
RETURN_C8_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
c8 *_c8_array_pop(C8Array *array) {
|
|
u64 index = array->count - 1;
|
|
c8 *out = wapp_c8_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
c16 *wapp_c16_array_get(const C16Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (c16 *)ptr;
|
|
}
|
|
|
|
void wapp_c16_array_set(C16Array *array, u64 index, c16 *item) {
|
|
c16 *ptr = wapp_c16_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_c16_array_append_capped(C16Array *array, c16 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_c16_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_c16_array_extend_capped(C16Array *array, const C16Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
c16 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_c16_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_c16_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_c16_array_clear(C16Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_c16_array_copy_capped(const C16Array *src, C16Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_c16_array_clear(dst);
|
|
|
|
c16 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_c16_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_c16_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
C16Array *wapp_c16_array_append_alloc(const Allocator *allocator, C16Array *array, c16 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
C16Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (C16Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_C16_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_c16_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_c16_array_append_capped(output, item);
|
|
|
|
RETURN_C16_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
C16Array *wapp_c16_array_extend_alloc(const Allocator *allocator, C16Array *array, const C16Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
C16Array *output = array;
|
|
|
|
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 = (C16Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_C16_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_c16_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_c16_array_extend_capped(output, other);
|
|
|
|
RETURN_C16_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
C16Array *wapp_c16_array_copy_alloc(const Allocator *allocator, const C16Array *src, C16Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
C16Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (C16Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_C16_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_c16_array_clear(output);
|
|
wapp_c16_array_copy_capped(src, output);
|
|
|
|
RETURN_C16_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
c16 *_c16_array_pop(C16Array *array) {
|
|
u64 index = array->count - 1;
|
|
c16 *out = wapp_c16_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
c32 *wapp_c32_array_get(const C32Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (c32 *)ptr;
|
|
}
|
|
|
|
void wapp_c32_array_set(C32Array *array, u64 index, c32 *item) {
|
|
c32 *ptr = wapp_c32_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_c32_array_append_capped(C32Array *array, c32 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_c32_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_c32_array_extend_capped(C32Array *array, const C32Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
c32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_c32_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_c32_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_c32_array_clear(C32Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_c32_array_copy_capped(const C32Array *src, C32Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_c32_array_clear(dst);
|
|
|
|
c32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_c32_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_c32_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
C32Array *wapp_c32_array_append_alloc(const Allocator *allocator, C32Array *array, c32 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
C32Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (C32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_C32_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_c32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_c32_array_append_capped(output, item);
|
|
|
|
RETURN_C32_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
C32Array *wapp_c32_array_extend_alloc(const Allocator *allocator, C32Array *array, const C32Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
C32Array *output = array;
|
|
|
|
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 = (C32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_C32_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_c32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_c32_array_extend_capped(output, other);
|
|
|
|
RETURN_C32_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
C32Array *wapp_c32_array_copy_alloc(const Allocator *allocator, const C32Array *src, C32Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
C32Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (C32Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_C32_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_c32_array_clear(output);
|
|
wapp_c32_array_copy_capped(src, output);
|
|
|
|
RETURN_C32_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
c32 *_c32_array_pop(C32Array *array) {
|
|
u64 index = array->count - 1;
|
|
c32 *out = wapp_c32_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
i8 *wapp_i8_array_get(const I8Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (i8 *)ptr;
|
|
}
|
|
|
|
void wapp_i8_array_set(I8Array *array, u64 index, i8 *item) {
|
|
i8 *ptr = wapp_i8_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_i8_array_append_capped(I8Array *array, i8 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_i8_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_i8_array_extend_capped(I8Array *array, const I8Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
i8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i8_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i8_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_i8_array_clear(I8Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_i8_array_copy_capped(const I8Array *src, I8Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_i8_array_clear(dst);
|
|
|
|
i8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i8_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i8_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
I8Array *wapp_i8_array_append_alloc(const Allocator *allocator, I8Array *array, i8 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
I8Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (I8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I8_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_i8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i8_array_append_capped(output, item);
|
|
|
|
RETURN_I8_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I8Array *wapp_i8_array_extend_alloc(const Allocator *allocator, I8Array *array, const I8Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
I8Array *output = array;
|
|
|
|
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 = (I8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I8_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_i8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i8_array_extend_capped(output, other);
|
|
|
|
RETURN_I8_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I8Array *wapp_i8_array_copy_alloc(const Allocator *allocator, const I8Array *src, I8Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
I8Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (I8Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_I8_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_i8_array_clear(output);
|
|
wapp_i8_array_copy_capped(src, output);
|
|
|
|
RETURN_I8_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
i8 *_i8_array_pop(I8Array *array) {
|
|
u64 index = array->count - 1;
|
|
i8 *out = wapp_i8_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
i16 *wapp_i16_array_get(const I16Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (i16 *)ptr;
|
|
}
|
|
|
|
void wapp_i16_array_set(I16Array *array, u64 index, i16 *item) {
|
|
i16 *ptr = wapp_i16_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_i16_array_append_capped(I16Array *array, i16 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_i16_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_i16_array_extend_capped(I16Array *array, const I16Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
i16 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i16_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i16_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_i16_array_clear(I16Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_i16_array_copy_capped(const I16Array *src, I16Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_i16_array_clear(dst);
|
|
|
|
i16 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i16_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i16_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
I16Array *wapp_i16_array_append_alloc(const Allocator *allocator, I16Array *array, i16 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
I16Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (I16Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I16_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_i16_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i16_array_append_capped(output, item);
|
|
|
|
RETURN_I16_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I16Array *wapp_i16_array_extend_alloc(const Allocator *allocator, I16Array *array, const I16Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
I16Array *output = array;
|
|
|
|
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 = (I16Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I16_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_i16_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i16_array_extend_capped(output, other);
|
|
|
|
RETURN_I16_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I16Array *wapp_i16_array_copy_alloc(const Allocator *allocator, const I16Array *src, I16Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
I16Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (I16Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_I16_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_i16_array_clear(output);
|
|
wapp_i16_array_copy_capped(src, output);
|
|
|
|
RETURN_I16_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
i16 *_i16_array_pop(I16Array *array) {
|
|
u64 index = array->count - 1;
|
|
i16 *out = wapp_i16_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
i32 *wapp_i32_array_get(const I32Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (i32 *)ptr;
|
|
}
|
|
|
|
void wapp_i32_array_set(I32Array *array, u64 index, i32 *item) {
|
|
i32 *ptr = wapp_i32_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_i32_array_append_capped(I32Array *array, i32 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_i32_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_i32_array_extend_capped(I32Array *array, const I32Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
i32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i32_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i32_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_i32_array_clear(I32Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_i32_array_copy_capped(const I32Array *src, I32Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_i32_array_clear(dst);
|
|
|
|
i32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i32_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i32_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
I32Array *wapp_i32_array_append_alloc(const Allocator *allocator, I32Array *array, i32 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
I32Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (I32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I32_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_i32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i32_array_append_capped(output, item);
|
|
|
|
RETURN_I32_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I32Array *wapp_i32_array_extend_alloc(const Allocator *allocator, I32Array *array, const I32Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
I32Array *output = array;
|
|
|
|
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 = (I32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I32_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_i32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i32_array_extend_capped(output, other);
|
|
|
|
RETURN_I32_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I32Array *wapp_i32_array_copy_alloc(const Allocator *allocator, const I32Array *src, I32Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
I32Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (I32Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_I32_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_i32_array_clear(output);
|
|
wapp_i32_array_copy_capped(src, output);
|
|
|
|
RETURN_I32_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
i32 *_i32_array_pop(I32Array *array) {
|
|
u64 index = array->count - 1;
|
|
i32 *out = wapp_i32_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
i64 *wapp_i64_array_get(const I64Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (i64 *)ptr;
|
|
}
|
|
|
|
void wapp_i64_array_set(I64Array *array, u64 index, i64 *item) {
|
|
i64 *ptr = wapp_i64_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_i64_array_append_capped(I64Array *array, i64 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_i64_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_i64_array_extend_capped(I64Array *array, const I64Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
i64 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i64_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i64_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_i64_array_clear(I64Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_i64_array_copy_capped(const I64Array *src, I64Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_i64_array_clear(dst);
|
|
|
|
i64 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_i64_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_i64_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
I64Array *wapp_i64_array_append_alloc(const Allocator *allocator, I64Array *array, i64 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
I64Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (I64Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I64_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_i64_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i64_array_append_capped(output, item);
|
|
|
|
RETURN_I64_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I64Array *wapp_i64_array_extend_alloc(const Allocator *allocator, I64Array *array, const I64Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
I64Array *output = array;
|
|
|
|
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 = (I64Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_I64_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_i64_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_i64_array_extend_capped(output, other);
|
|
|
|
RETURN_I64_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
I64Array *wapp_i64_array_copy_alloc(const Allocator *allocator, const I64Array *src, I64Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
I64Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (I64Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_I64_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_i64_array_clear(output);
|
|
wapp_i64_array_copy_capped(src, output);
|
|
|
|
RETURN_I64_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
i64 *_i64_array_pop(I64Array *array) {
|
|
u64 index = array->count - 1;
|
|
i64 *out = wapp_i64_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
u8 *wapp_u8_array_get(const U8Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (u8 *)ptr;
|
|
}
|
|
|
|
void wapp_u8_array_set(U8Array *array, u64 index, u8 *item) {
|
|
u8 *ptr = wapp_u8_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_u8_array_append_capped(U8Array *array, u8 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_u8_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_u8_array_extend_capped(U8Array *array, const U8Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
u8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u8_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u8_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_u8_array_clear(U8Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_u8_array_copy_capped(const U8Array *src, U8Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_u8_array_clear(dst);
|
|
|
|
u8 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u8_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u8_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
U8Array *wapp_u8_array_append_alloc(const Allocator *allocator, U8Array *array, u8 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
U8Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (U8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U8_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_u8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u8_array_append_capped(output, item);
|
|
|
|
RETURN_U8_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U8Array *wapp_u8_array_extend_alloc(const Allocator *allocator, U8Array *array, const U8Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
U8Array *output = array;
|
|
|
|
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 = (U8Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U8_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_u8_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u8_array_extend_capped(output, other);
|
|
|
|
RETURN_U8_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U8Array *wapp_u8_array_copy_alloc(const Allocator *allocator, const U8Array *src, U8Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
U8Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (U8Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_U8_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_u8_array_clear(output);
|
|
wapp_u8_array_copy_capped(src, output);
|
|
|
|
RETURN_U8_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
u8 *_u8_array_pop(U8Array *array) {
|
|
u64 index = array->count - 1;
|
|
u8 *out = wapp_u8_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
u16 *wapp_u16_array_get(const U16Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (u16 *)ptr;
|
|
}
|
|
|
|
void wapp_u16_array_set(U16Array *array, u64 index, u16 *item) {
|
|
u16 *ptr = wapp_u16_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_u16_array_append_capped(U16Array *array, u16 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_u16_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_u16_array_extend_capped(U16Array *array, const U16Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
u16 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u16_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u16_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_u16_array_clear(U16Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_u16_array_copy_capped(const U16Array *src, U16Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_u16_array_clear(dst);
|
|
|
|
u16 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u16_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u16_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
U16Array *wapp_u16_array_append_alloc(const Allocator *allocator, U16Array *array, u16 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
U16Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (U16Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U16_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_u16_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u16_array_append_capped(output, item);
|
|
|
|
RETURN_U16_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U16Array *wapp_u16_array_extend_alloc(const Allocator *allocator, U16Array *array, const U16Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
U16Array *output = array;
|
|
|
|
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 = (U16Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U16_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_u16_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u16_array_extend_capped(output, other);
|
|
|
|
RETURN_U16_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U16Array *wapp_u16_array_copy_alloc(const Allocator *allocator, const U16Array *src, U16Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
U16Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (U16Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_U16_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_u16_array_clear(output);
|
|
wapp_u16_array_copy_capped(src, output);
|
|
|
|
RETURN_U16_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
u16 *_u16_array_pop(U16Array *array) {
|
|
u64 index = array->count - 1;
|
|
u16 *out = wapp_u16_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
u32 *wapp_u32_array_get(const U32Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (u32 *)ptr;
|
|
}
|
|
|
|
void wapp_u32_array_set(U32Array *array, u64 index, u32 *item) {
|
|
u32 *ptr = wapp_u32_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_u32_array_append_capped(U32Array *array, u32 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_u32_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_u32_array_extend_capped(U32Array *array, const U32Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
u32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u32_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u32_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_u32_array_clear(U32Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_u32_array_copy_capped(const U32Array *src, U32Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_u32_array_clear(dst);
|
|
|
|
u32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u32_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u32_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
U32Array *wapp_u32_array_append_alloc(const Allocator *allocator, U32Array *array, u32 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
U32Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (U32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U32_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_u32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u32_array_append_capped(output, item);
|
|
|
|
RETURN_U32_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U32Array *wapp_u32_array_extend_alloc(const Allocator *allocator, U32Array *array, const U32Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
U32Array *output = array;
|
|
|
|
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 = (U32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U32_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_u32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u32_array_extend_capped(output, other);
|
|
|
|
RETURN_U32_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U32Array *wapp_u32_array_copy_alloc(const Allocator *allocator, const U32Array *src, U32Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
U32Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (U32Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_U32_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_u32_array_clear(output);
|
|
wapp_u32_array_copy_capped(src, output);
|
|
|
|
RETURN_U32_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
u32 *_u32_array_pop(U32Array *array) {
|
|
u64 index = array->count - 1;
|
|
u32 *out = wapp_u32_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
u64 *wapp_u64_array_get(const U64Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (u64 *)ptr;
|
|
}
|
|
|
|
void wapp_u64_array_set(U64Array *array, u64 index, u64 *item) {
|
|
u64 *ptr = wapp_u64_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_u64_array_append_capped(U64Array *array, u64 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_u64_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_u64_array_extend_capped(U64Array *array, const U64Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
u64 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u64_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u64_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_u64_array_clear(U64Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_u64_array_copy_capped(const U64Array *src, U64Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_u64_array_clear(dst);
|
|
|
|
u64 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_u64_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_u64_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
U64Array *wapp_u64_array_append_alloc(const Allocator *allocator, U64Array *array, u64 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
U64Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (U64Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U64_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_u64_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u64_array_append_capped(output, item);
|
|
|
|
RETURN_U64_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U64Array *wapp_u64_array_extend_alloc(const Allocator *allocator, U64Array *array, const U64Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
U64Array *output = array;
|
|
|
|
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 = (U64Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_U64_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_u64_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_u64_array_extend_capped(output, other);
|
|
|
|
RETURN_U64_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
U64Array *wapp_u64_array_copy_alloc(const Allocator *allocator, const U64Array *src, U64Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
U64Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (U64Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_U64_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_u64_array_clear(output);
|
|
wapp_u64_array_copy_capped(src, output);
|
|
|
|
RETURN_U64_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
u64 *_u64_array_pop(U64Array *array) {
|
|
u64 index = array->count - 1;
|
|
u64 *out = wapp_u64_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
f32 *wapp_f32_array_get(const F32Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (f32 *)ptr;
|
|
}
|
|
|
|
void wapp_f32_array_set(F32Array *array, u64 index, f32 *item) {
|
|
f32 *ptr = wapp_f32_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_f32_array_append_capped(F32Array *array, f32 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_f32_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_f32_array_extend_capped(F32Array *array, const F32Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
f32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_f32_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_f32_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_f32_array_clear(F32Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_f32_array_copy_capped(const F32Array *src, F32Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_f32_array_clear(dst);
|
|
|
|
f32 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_f32_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_f32_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
F32Array *wapp_f32_array_append_alloc(const Allocator *allocator, F32Array *array, f32 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
F32Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (F32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_F32_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_f32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_f32_array_append_capped(output, item);
|
|
|
|
RETURN_F32_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
F32Array *wapp_f32_array_extend_alloc(const Allocator *allocator, F32Array *array, const F32Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
F32Array *output = array;
|
|
|
|
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 = (F32Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_F32_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_f32_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_f32_array_extend_capped(output, other);
|
|
|
|
RETURN_F32_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
F32Array *wapp_f32_array_copy_alloc(const Allocator *allocator, const F32Array *src, F32Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
F32Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (F32Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_F32_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_f32_array_clear(output);
|
|
wapp_f32_array_copy_capped(src, output);
|
|
|
|
RETURN_F32_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
f32 *_f32_array_pop(F32Array *array) {
|
|
u64 index = array->count - 1;
|
|
f32 *out = wapp_f32_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
f64 *wapp_f64_array_get(const F64Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (f64 *)ptr;
|
|
}
|
|
|
|
void wapp_f64_array_set(F64Array *array, u64 index, f64 *item) {
|
|
f64 *ptr = wapp_f64_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_f64_array_append_capped(F64Array *array, f64 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_f64_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_f64_array_extend_capped(F64Array *array, const F64Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
f64 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_f64_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_f64_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_f64_array_clear(F64Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_f64_array_copy_capped(const F64Array *src, F64Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_f64_array_clear(dst);
|
|
|
|
f64 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_f64_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_f64_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
F64Array *wapp_f64_array_append_alloc(const Allocator *allocator, F64Array *array, f64 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
F64Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (F64Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_F64_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_f64_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_f64_array_append_capped(output, item);
|
|
|
|
RETURN_F64_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
F64Array *wapp_f64_array_extend_alloc(const Allocator *allocator, F64Array *array, const F64Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
F64Array *output = array;
|
|
|
|
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 = (F64Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_F64_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_f64_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_f64_array_extend_capped(output, other);
|
|
|
|
RETURN_F64_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
F64Array *wapp_f64_array_copy_alloc(const Allocator *allocator, const F64Array *src, F64Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
F64Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (F64Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_F64_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_f64_array_clear(output);
|
|
wapp_f64_array_copy_capped(src, output);
|
|
|
|
RETURN_F64_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
f64 *_f64_array_pop(F64Array *array) {
|
|
u64 index = array->count - 1;
|
|
f64 *out = wapp_f64_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
f128 *wapp_f128_array_get(const F128Array *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (f128 *)ptr;
|
|
}
|
|
|
|
void wapp_f128_array_set(F128Array *array, u64 index, f128 *item) {
|
|
f128 *ptr = wapp_f128_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_f128_array_append_capped(F128Array *array, f128 *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_f128_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_f128_array_extend_capped(F128Array *array, const F128Array *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
f128 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_f128_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_f128_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_f128_array_clear(F128Array *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_f128_array_copy_capped(const F128Array *src, F128Array *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_f128_array_clear(dst);
|
|
|
|
f128 *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_f128_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_f128_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
F128Array *wapp_f128_array_append_alloc(const Allocator *allocator, F128Array *array, f128 *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
F128Array *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (F128Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_F128_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_f128_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_f128_array_append_capped(output, item);
|
|
|
|
RETURN_F128_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
F128Array *wapp_f128_array_extend_alloc(const Allocator *allocator, F128Array *array, const F128Array *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
F128Array *output = array;
|
|
|
|
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 = (F128Array *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_F128_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_f128_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_f128_array_extend_capped(output, other);
|
|
|
|
RETURN_F128_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
F128Array *wapp_f128_array_copy_alloc(const Allocator *allocator, const F128Array *src, F128Array *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
F128Array *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (F128Array *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_F128_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_f128_array_clear(output);
|
|
wapp_f128_array_copy_capped(src, output);
|
|
|
|
RETURN_F128_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
f128 *_f128_array_pop(F128Array *array) {
|
|
u64 index = array->count - 1;
|
|
f128 *out = wapp_f128_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
iptr *wapp_iptr_array_get(const IptrArray *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (iptr *)ptr;
|
|
}
|
|
|
|
void wapp_iptr_array_set(IptrArray *array, u64 index, iptr *item) {
|
|
iptr *ptr = wapp_iptr_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_iptr_array_append_capped(IptrArray *array, iptr *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_iptr_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_iptr_array_extend_capped(IptrArray *array, const IptrArray *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
iptr *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_iptr_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_iptr_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_iptr_array_clear(IptrArray *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_iptr_array_copy_capped(const IptrArray *src, IptrArray *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_iptr_array_clear(dst);
|
|
|
|
iptr *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_iptr_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_iptr_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
IptrArray *wapp_iptr_array_append_alloc(const Allocator *allocator, IptrArray *array, iptr *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
IptrArray *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (IptrArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_IPTR_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_iptr_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_iptr_array_append_capped(output, item);
|
|
|
|
RETURN_IPTR_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
IptrArray *wapp_iptr_array_extend_alloc(const Allocator *allocator, IptrArray *array, const IptrArray *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
IptrArray *output = array;
|
|
|
|
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 = (IptrArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_IPTR_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_iptr_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_iptr_array_extend_capped(output, other);
|
|
|
|
RETURN_IPTR_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
IptrArray *wapp_iptr_array_copy_alloc(const Allocator *allocator, const IptrArray *src, IptrArray *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
IptrArray *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (IptrArray *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_IPTR_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_iptr_array_clear(output);
|
|
wapp_iptr_array_copy_capped(src, output);
|
|
|
|
RETURN_IPTR_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
iptr *_iptr_array_pop(IptrArray *array) {
|
|
u64 index = array->count - 1;
|
|
iptr *out = wapp_iptr_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
uptr *wapp_uptr_array_get(const UptrArray *array, u64 index) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
|
|
|
|
u8 *ptr = (u8 *)(array->items) + (array->item_size * index);
|
|
return (uptr *)ptr;
|
|
}
|
|
|
|
void wapp_uptr_array_set(UptrArray *array, u64 index, uptr *item) {
|
|
uptr *ptr = wapp_uptr_array_get(array, index);
|
|
|
|
memcpy((void *)ptr, (void *)item, array->item_size);
|
|
}
|
|
|
|
void wapp_uptr_array_append_capped(UptrArray *array, uptr *item) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
wapp_runtime_assert(array->count < array->capacity, "`array` is full");
|
|
|
|
u64 index = (array->count)++;
|
|
wapp_uptr_array_set(array, index, item);
|
|
}
|
|
|
|
void wapp_uptr_array_extend_capped(UptrArray *array, const UptrArray *other) {
|
|
wapp_debug_assert(array != NULL && other != NULL, "`array` and `other` should not be NULL");
|
|
|
|
u64 remaining_capacity = array->capacity - array->count;
|
|
wapp_runtime_assert(other->count < remaining_capacity, "`array` does not have enough capacity");
|
|
|
|
uptr *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 items_to_add = other->count;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_uptr_array_get(other, item_index);
|
|
++item_index;
|
|
running = item_index < items_to_add;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_uptr_array_append_capped(array, item);
|
|
}
|
|
}
|
|
|
|
void wapp_uptr_array_clear(UptrArray *array) {
|
|
wapp_debug_assert(array != NULL, "`array` should not be NULL");
|
|
array->count = 0;
|
|
}
|
|
|
|
void wapp_uptr_array_copy_capped(const UptrArray *src, UptrArray *dst) {
|
|
wapp_debug_assert(src != NULL && dst != NULL, "`src` and `dst` should not be NULL");
|
|
|
|
wapp_uptr_array_clear(dst);
|
|
|
|
uptr *item;
|
|
|
|
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
|
|
// MSVC Spectre mitigation warnings
|
|
u64 to_copy = src->count < dst->capacity ? src->count : dst->capacity;
|
|
u64 item_index = 0;
|
|
b32 running = true;
|
|
while (running) {
|
|
item = wapp_uptr_array_get(src, item_index);
|
|
++item_index;
|
|
running = item_index < to_copy;
|
|
|
|
if (!item) {
|
|
continue;
|
|
}
|
|
|
|
wapp_uptr_array_append_capped(dst, item);
|
|
}
|
|
}
|
|
|
|
UptrArray *wapp_uptr_array_append_alloc(const Allocator *allocator, UptrArray *array, uptr *item) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
|
|
|
|
UptrArray *output = array;
|
|
|
|
if (array->count >= array->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2);
|
|
output = (UptrArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_UPTR_ARRAY_APPEND_ALLOC;
|
|
}
|
|
wapp_uptr_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_uptr_array_append_capped(output, item);
|
|
|
|
RETURN_UPTR_ARRAY_APPEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
UptrArray *wapp_uptr_array_extend_alloc(const Allocator *allocator, UptrArray *array, const UptrArray *other) {
|
|
wapp_debug_assert(allocator != NULL && array != NULL && other != NULL, "`allocator`, `array` and `other` should not be NULL");
|
|
|
|
UptrArray *output = array;
|
|
|
|
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 = (UptrArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size);
|
|
if (!output) {
|
|
output = array;
|
|
goto RETURN_UPTR_ARRAY_EXTEND_ALLOC;
|
|
}
|
|
wapp_uptr_array_copy_capped(array, output);
|
|
}
|
|
|
|
wapp_uptr_array_extend_capped(output, other);
|
|
|
|
RETURN_UPTR_ARRAY_EXTEND_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
UptrArray *wapp_uptr_array_copy_alloc(const Allocator *allocator, const UptrArray *src, UptrArray *dst) {
|
|
wapp_debug_assert(allocator != NULL && src != NULL && dst != NULL, "`allocator`, `src` and `dst` should not be NULL");
|
|
|
|
UptrArray *output = dst;
|
|
|
|
if (src->count >= dst->capacity) {
|
|
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2);
|
|
output = (UptrArray *)_array_alloc_capacity(allocator, new_capacity, src->item_size);
|
|
if (!output) {
|
|
output = dst;
|
|
goto RETURN_UPTR_ARRAY_COPY_ALLOC;
|
|
}
|
|
}
|
|
|
|
wapp_uptr_array_clear(output);
|
|
wapp_uptr_array_copy_capped(src, output);
|
|
|
|
RETURN_UPTR_ARRAY_COPY_ALLOC:
|
|
return output;
|
|
}
|
|
|
|
uptr *_uptr_array_pop(UptrArray *array) {
|
|
u64 index = array->count - 1;
|
|
uptr *out = wapp_uptr_array_get(array, index);
|
|
--(array->count);
|
|
return out;
|
|
}
|
|
|
|
VoidPArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size) {
|
|
wapp_debug_assert(allocator != NULL, "`array` should not be NULL");
|
|
|
|
u64 allocation_size = sizeof(VoidPArray) + item_size * capacity;
|
|
VoidPArray *array = wapp_mem_allocator_alloc(allocator, allocation_size);
|
|
if (!array) {
|
|
goto RETURN_GENERIC_ARRAY_ALLOC;
|
|
}
|
|
|
|
array->items = (void * *)((u8 *)array + sizeof(VoidPArray));
|
|
array->count = 0;
|
|
array->capacity = capacity;
|
|
array->item_size = item_size;
|
|
|
|
RETURN_GENERIC_ARRAY_ALLOC:
|
|
return array;
|
|
}
|
|
|