1 #include <kiba/containers/array.h>
5 static inline void *_array_pointer_at_offset(
void *arr, usize offset) {
7 return (u8 *) (arr) + (offset * header->element_size);
10 void *_array_create(usize initial_capacity, usize element_size, usize element_alignment,
allocator *alloc) {
12 KB_ASSERT(initial_capacity != 0,
"initial capacity must not be 0");
15 KB_MAX(element_alignment, 8));
18 res->capacity = initial_capacity;
19 res->element_size = element_size;
26 void array_destroy(
void *arr_ptr) {
36 b8 array_reserve(
void *arr_ptr, usize new_capacity) {
39 if (new_capacity > header->capacity) {
45 new_arr->capacity = new_capacity;
52 b8 array_resize(
void *arr_ptr, usize new_size) {
55 if (new_size > header->capacity) {
56 if (!array_reserve(arr, new_size)) {
59 header = _array_get_header(*arr);
61 if (new_size > header->size) {
62 memory_zero((u8 *) *arr + header->size * header->element_size,
63 (new_size - header->size) * header->element_size);
65 header->size = new_size;
69 void *array_clone(
const void *arr,
allocator *alloc) {
71 void *new_arr = _array_create(array_size(arr), array_element_size(arr), 1, alloc);
73 memory_copy(new_arr, arr, array_size(arr) * array_element_size(arr));
78 b8 array_push_checked(
void *arr_ptr,
void *element) {
83 KB_ASSERT(header->size <= header->capacity,
84 "array capacity must not have been exceeded beforehand size: {usize} vs capacity: {usize}",
87 if (header->size == header->capacity) {
88 if (!array_reserve(arr, header->capacity * 2)) {
91 header = _array_get_header(*arr);
93 memory_copy(_array_pointer_at_offset(*arr, header->size++), element, header->element_size);
97 b8 array_pop_checked(
void *arr_ptr,
void *element) {
101 if (header->size == 0) {
106 memory_copy(element, _array_pointer_at_offset(*arr, header->size), header->element_size);
111 b8 array_insert(
void *arr_ptr, usize index,
void *element) {
112 void **arr = arr_ptr;
114 KB_ASSERT(element !=
KB_NULL,
"pointer to read data from must not be nullptr");
116 if (index > header->size) {
117 KB_WARN(
"index out of range: index {usize} requested but array size only {usize}", index, header->size);
120 if (!array_push_checked(arr, element)) {
124 usize move_count = header->size - index;
125 for (usize i = 0; i < move_count; ++i) {
126 memory_copy(_array_pointer_at_offset(*arr, header->size - 1 - i),
127 _array_pointer_at_offset(*arr, header->size - 2 - i),
128 header->element_size);
130 memory_copy(_array_pointer_at_offset(*arr, index), element, header->element_size);
134 b8 array_remove(
void *arr_ptr, usize index,
void *element) {
135 void **arr = arr_ptr;
138 if (index >= header->size) {
139 KB_WARN(
"index out of range in array: index {usize} requested but array size only {usize}",
144 usize move_count = header->size - index;
146 memory_copy(element, _array_pointer_at_offset(*arr, index), header->element_size);
148 if (move_count > 0) {
150 _array_pointer_at_offset(*arr, index + 1),
151 move_count * header->element_size);
void * allocator_allocate_aligned(allocator *alloc, usize size, usize alignment)
Allocate aligned memory.
void * allocator_reallocate(allocator *alloc, void *original, usize new_size)
Reallocate memory to unaligned block.
void allocator_free(allocator *alloc, void *mem)
Give back memory to the allocator.
void * memory_copy(void *dst, const void *src, usize size)
Copy memory.
void * memory_zero(void *mem, usize size)
Zero out memory.
Lightweight layer between platform and other engine components to enable tracing/monitoring.
#define KB_MAX(x, y)
Ternary to get the maximum of two numbers.
#define KB_NULL
Value of an invalid ptr (nullptr).
#define KB_ASSERT(expr,...)
Perform runtime assertion and log failures.
#define KB_WARN(...)
Log entry with warn log level.
Central allocator structure.