/** * 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 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; }