diff options
| author | Fabrice <fabrice@schaub-dev.xyz> | 2026-03-02 17:00:35 +0100 |
|---|---|---|
| committer | Fabrice <fabrice@schaub-dev.xyz> | 2026-03-02 17:00:35 +0100 |
| commit | f8f057a773a6673c99d74e9bfbabf0f1f4c7232a (patch) | |
| tree | 561e414e0d7b78cb5f363c958666fcfeb7750da4 | |
| parent | 8d0fa5880fa4c991603cfa603d31d3f17e3067e5 (diff) | |
improving array implementation
| -rw-r--r-- | src/array.cc | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/src/array.cc b/src/array.cc index 06b79c2..fa2cb61 100644 --- a/src/array.cc +++ b/src/array.cc @@ -8,21 +8,83 @@ template <typename T> struct Array { - Slice<T> buffer; + usize capacity, size; + u8* data; const Allocator* allocator; }; #define array_init(T, allocator) \ - Array<T> { Slice<T>{}, allocator } + Array<T> { 0, 0, nullptr, allocator } + +template<typename T> +static inline usize array_nbytes(usize size) { + return size * sizeof(T); +} + +template<typename T> +static inline usize array_next_capacity(const Array<T>* array) { + assert(array != nullptr); + return array->capacity == 0 ? ARRAY_INIT : array->capacity * ARRAY_GROWTH; +} + +template<typename T> +bool array_resize(Array<T>* array, usize new_capacity) { + assert(array != nullptr); + assert(array->size < new_capacity); + + u8* new_data = allocate(array->allocator, array_nbytes<T>(new_capacity), alignof(T)); + if(new_data == nullptr) return false; + + memcpy(new_data, array->data, array_nbytes<T>(new_capacity)); + deallocate(array->allocator, array->data); + + array->data = new_data; + array->capacity = new_capacity; + return true; +} + +template<typename T> +static inline bool array_grow_if_needed(Array<T>* array) { + assert(array != nullptr); + assert(array->size <= array->capacity); + + if(array->size < array->capacity) return true; + + usize new_capacity = array_next_capacity(array); + return array_resize(array, new_capacity); +} + +template<typename T> +static inline T* array_at(const Array<T>* array, usize index) { + assert(array != NULL); + assert(index < array->capacity); + + return array->data + index; +} + +template<typename T> +bool array_push(Array<T>* array, T* item) { + assert(array != nullptr); + assert(item != nullptr); + + bool ret = array_grow_if_needed(array); + if(!ret) return false; + + T* loc = array_at(array, array->size); + memcpy(loc, item, sizeof(T)); + array->size += 1; + + return true; +} template <typename T> void array_deinit(Array<T>* array) { assert(array != nullptr); - if (unlikely(array->allocator == nullptr)) return; + if (unlikely(array->data == nullptr)) return; - slice_deallocate(array->allocator, &array->buffer); - array->allocator = nullptr; + deallocate(array->allocator, array->data); + memset(array, 0, sizeof(*array)); } #endif |
