#ifndef ARRAY_CC #define ARRAY_CC #include "memory.cc" #define ARRAY_INIT 4 #define ARRAY_GROWTH 2 template struct Array { usize capacity, size; u8* data; const Allocator* allocator; }; #define array_init(T, allocator) \ Array { 0, 0, nullptr, allocator } template static inline usize array_nbytes(usize size) { return size * sizeof(T); } template static inline usize array_next_capacity(const Array* array) { assert(array != nullptr); return array->capacity == 0 ? ARRAY_INIT : array->capacity * ARRAY_GROWTH; } template bool array_resize(Array* array, usize new_capacity) { assert(array != nullptr); assert(array->size < new_capacity); u8* new_data = allocate(array->allocator, array_nbytes(new_capacity), alignof(T)); if(new_data == nullptr) return false; memcpy(new_data, array->data, array_nbytes(new_capacity)); deallocate(array->allocator, array->data); array->data = new_data; array->capacity = new_capacity; return true; } template static inline bool array_grow_if_needed(Array* 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 static inline T* array_at(const Array* array, usize index) { assert(array != NULL); assert(index < array->capacity); return array->data + index; } template bool array_push(Array* 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 void array_deinit(Array* array) { assert(array != nullptr); if (unlikely(array->data == nullptr)) return; deallocate(array->allocator, array->data); memset(array, 0, sizeof(*array)); } #endif