aboutsummaryrefslogtreecommitdiff
path: root/src/array.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-10-08 20:37:31 +0100
committerGinger Bill <bill@gingerbill.org>2016-10-08 20:37:31 +0100
commitb705fa7f2257e691f4056a96325d9f01bd031439 (patch)
tree9df673b774e569b7037ae8710efeb24beff4f6dc /src/array.cpp
parenta5c6340316245f4f63e74d307f9d7c8be09360c6 (diff)
Change from gbArray(T) to Array<T>
Diffstat (limited to 'src/array.cpp')
-rw-r--r--src/array.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/array.cpp b/src/array.cpp
new file mode 100644
index 000000000..d8b8e9ef3
--- /dev/null
+++ b/src/array.cpp
@@ -0,0 +1,116 @@
+#define ARRAY_GROW_FORMULA(x) (2*(x) + 8)
+
+template <typename T>
+struct Array {
+ gbAllocator allocator;
+ T *data;
+ isize count;
+ isize capacity;
+
+ T &operator[](isize index) {
+ if (count > 0) {
+ GB_ASSERT_MSG(0 <= index && index < count, "Index out of bounds");
+ }
+ return data[index];
+ }
+
+ T const &operator[](isize index) const {
+ if (count > 0) {
+ GB_ASSERT_MSG(0 <= index && index < count, "Index out of bounds");
+ }
+ return data[index];
+ }
+};
+
+template <typename T> void array_init (Array<T> *array, gbAllocator a, isize init_capacity = 8);
+template <typename T> void array_free (Array<T> *array);
+template <typename T> void array_add (Array<T> *array, T const &t);
+template <typename T> T array_pop (Array<T> *array);
+template <typename T> void array_clear (Array<T> *array);
+template <typename T> void array_reserve (Array<T> *array, isize capacity);
+template <typename T> void array_resize (Array<T> *array, isize count);
+template <typename T> void array_set_capacity(Array<T> *array, isize capacity);
+
+
+template <typename T>
+void array_init(Array<T> *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 <typename T>
+void array_free(Array<T> *array) {
+ gb_free(array->allocator, array->data);
+ array->count = 0;
+ array->capacity = 0;
+}
+
+template <typename T>
+void array__grow(Array<T> *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 <typename T>
+void array_add(Array<T> *array, T const &t) {
+ if (array->capacity < array->count+1) {
+ array__grow(array, 0);
+ }
+ array->data[array->count] = t;
+ array->count++;
+}
+
+template <typename T>
+T array_pop(Array<T> *array) {
+ GB_ASSERT(array->count > 0);
+ array->count--;
+ return array->data[array->count];
+}
+
+template <typename T>
+void array_clear(Array<T> *array) {
+ array->count = 0;
+}
+
+template <typename T>
+void array_reserve(Array<T> *array, isize capacity) {
+ if (array->capacity < capacity) {
+ array_set_capacity(array, capacity);
+ }
+}
+
+template <typename T>
+void array_resize(Array<T> *array, isize count) {
+ if (array->capacity < count) {
+ array__grow(array, count);
+ }
+ array->count = count;
+}
+
+template <typename T>
+void array_set_capacity(Array<T> *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;
+}
+
+
+