summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice <fabrice@schaub-dev.xyz>2026-03-02 17:00:35 +0100
committerFabrice <fabrice@schaub-dev.xyz>2026-03-02 17:00:35 +0100
commitf8f057a773a6673c99d74e9bfbabf0f1f4c7232a (patch)
tree561e414e0d7b78cb5f363c958666fcfeb7750da4
parent8d0fa5880fa4c991603cfa603d31d3f17e3067e5 (diff)
improving array implementation
-rw-r--r--src/array.cc72
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