From 7792f009b8d8fbc4949b8110ebbcffc943878cae Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Wed, 23 Nov 2016 14:41:20 +0000 Subject: Numpty forgot to add .c files --- src/array.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 src/array.c (limited to 'src/array.c') diff --git a/src/array.c b/src/array.c new file mode 100644 index 000000000..7e185e872 --- /dev/null +++ b/src/array.c @@ -0,0 +1,235 @@ +#define ARRAY_GROW_FORMULA(x) (2*(x) + 8) +GB_STATIC_ASSERT(ARRAY_GROW_FORMULA(0) > 0); + +#define Array(Type_) struct { \ + gbAllocator allocator; \ + Type_ * e; \ + isize count; \ + isize capacity; \ +} + +typedef Array(void) ArrayVoid; + +#define array_init_reserve(x_, allocator_, init_capacity_) do { \ + GB_ASSERT((x_) != NULL); \ + void **e = cast(void **)&((x_)->e); \ + (x_)->allocator = (allocator_); \ + (x_)->count = 0; \ + (x_)->capacity = (init_capacity_); \ + *e = gb_alloc((allocator_), gb_size_of(*(x_)->e)*(init_capacity_)); \ +} while (0) + +#define array_init_count(x_, allocator_, init_count_) do { \ + GB_ASSERT((x_) != NULL); \ + void **e = cast(void **)&((x_)->e); \ + (x_)->allocator = (allocator_); \ + (x_)->count = (init_count_); \ + (x_)->capacity = (init_count_); \ + *e = gb_alloc((allocator_), gb_size_of(*(x_)->e)*(init_count_)); \ +} while (0) + +#define array_init(x_, allocator_) do { array_init_reserve(x_, allocator_, ARRAY_GROW_FORMULA(0)); } while (0) +#define array_free(x_) do { gb_free((x_)->allocator, (x_)->e); } while (0) +#define array_set_capacity(x_, capacity_) do { array__set_capacity((x_), (capacity_), gb_size_of(*(x_)->e)); } while (0) + +#define array_grow(x_, min_capacity_) do { \ + isize new_capacity = ARRAY_GROW_FORMULA((x_)->capacity); \ + if (new_capacity < (min_capacity_)) { \ + new_capacity = (min_capacity_); \ + } \ + array_set_capacity(x_, new_capacity); \ +} while (0) + +#define array_add(x_, item_) do { \ + if ((x_)->capacity < (x_)->count+1) { \ + array_grow(x_, 0); \ + } \ + (x_)->e[(x_)->count++] = item_; \ +} while (0) + +#define array_pop(x_) do { GB_ASSERT((x_)->count > 0); (x_)->count--; } while (0) +#define array_clear(x_) do { (x_)->count = 0; } while (0) + +#define array_resize(x_, new_count_) do { \ + if ((x_)->capacity < (new_count_)) { \ + array_grow((x_), (new_count_)); \ + } \ + (x_)->count = (new_count_); \ +} while (0) + +#define array_reserve(x_, new_capacity_) do { \ + if ((x_)->capacity < (new_capacity_)) { \ + array_set_capacity((x_), (new_capacity_)); \ + } \ +} while (0) + + + + +void array__set_capacity(void *ptr, isize capacity, isize element_size) { + GB_ASSERT(ptr != NULL); + ArrayVoid *x = cast(ArrayVoid *)ptr; + + GB_ASSERT(element_size > 0); + + if (capacity == x->capacity) { + return; + } + + if (capacity < x->count) { + if (x->capacity < capacity) { + isize new_capacity = ARRAY_GROW_FORMULA(x->capacity); + if (new_capacity < capacity) { + new_capacity = capacity; + } + array__set_capacity(ptr, new_capacity, element_size); + } + x->count = capacity; + } + + { + // TODO(bill): Resize rather than copy and delete + void *new_data = gb_alloc(x->allocator, element_size*capacity); + gb_memmove(new_data, x->e, element_size*x->count); + gb_free(x->allocator, x->e); + x->capacity = capacity; + x->e = new_data; + } +} + + +#if 0 +template +struct Array { + gbAllocator allocator; + T * data; + isize count; + isize capacity; + + T &operator[](isize index) { + GB_ASSERT_MSG(0 <= index && index < count, "Index out of bounds"); + return data[index]; + } + + T const &operator[](isize index) const { + GB_ASSERT_MSG(0 <= index && index < count, "Index out of bounds"); + return data[index]; + } +}; + +template void array_init (Array *array, gbAllocator a, isize init_capacity = ARRAY_GROW_FORMULA(0)); +template void array_init_count (Array *array, gbAllocator a, isize count); +template Array array_make (T *data, isize count, isize capacity); +template void array_free (Array *array); +template void array_add (Array *array, T const &t); +template T array_pop (Array *array); +template void array_clear (Array *array); +template void array_reserve (Array *array, isize capacity); +template void array_resize (Array *array, isize count); +template void array_set_capacity(Array *array, isize capacity); + + +template +void array_init(Array *array, gbAllocator a, isize init_capacity) { + array->allocator = a; + array->data = gb_alloc_array(a, T, init_capacity); + array->count = 0; + array->capacity = init_capacity; +} + +template +void array_init_count(Array *array, gbAllocator a, isize count) { + array->allocator = a; + array->data = gb_alloc_array(a, T, count); + array->count = count; + array->capacity = count; +} + + +template +Array array_make(T *data, isize count, isize capacity) { + Array a = {0}; + a.data = data; + a.count = count; + a.capacity = capacity; + return a; +} + + +template +void array_free(Array *array) { + if (array->allocator.proc != NULL) { + gb_free(array->allocator, array->data); + } + array->count = 0; + array->capacity = 0; +} + +template +void array__grow(Array *array, isize min_capacity) { + isize new_capacity = ARRAY_GROW_FORMULA(array->capacity); + if (new_capacity < min_capacity) { + new_capacity = min_capacity; + } + array_set_capacity(array, new_capacity); +} + +template +void array_add(Array *array, T const &t) { + if (array->capacity < array->count+1) { + array__grow(array, 0); + } + array->data[array->count] = t; + array->count++; +} + +template +T array_pop(Array *array) { + GB_ASSERT(array->count > 0); + array->count--; + return array->data[array->count]; +} + +template +void array_clear(Array *array) { + array->count = 0; +} + +template +void array_reserve(Array *array, isize capacity) { + if (array->capacity < capacity) { + array_set_capacity(array, capacity); + } +} + +template +void array_resize(Array *array, isize count) { + if (array->capacity < count) { + array__grow(array, count); + } + array->count = count; +} + +template +void array_set_capacity(Array *array, isize capacity) { + if (capacity == array->capacity) { + return; + } + + if (capacity < array->count) { + array_resize(array, capacity); + } + + T *new_data = NULL; + if (capacity > 0) { + new_data = gb_alloc_array(array->allocator, T, capacity); + gb_memmove(new_data, array->data, gb_size_of(T) * array->capacity); + } + gb_free(array->allocator, array->data); + array->data = new_data; + array->capacity = capacity; +} + + + +#endif -- cgit v1.2.3