summaryrefslogtreecommitdiffstats
path: root/src/darray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/darray.h')
-rw-r--r--src/darray.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/darray.h b/src/darray.h
new file mode 100644
index 0000000..7e5ae5d
--- /dev/null
+++ b/src/darray.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright © 2010, Zed A. Shaw.
+ * Copyright © 2020 rsiddharth <s@ricketyspace.net>
+ */
+
+#ifndef _DArray_h
+#define _DArray_h
+#include <stdlib.h>
+#include <assert.h>
+#include <dbg.h>
+
+typedef struct DArray {
+ int end;
+ int max;
+ size_t element_size;
+ size_t expand_rate;
+ void **contents;
+} DArray;
+
+typedef int (*DArray_compare) (const void *a, const void *b);
+
+DArray *DArray_create(size_t element_size, size_t initial_max);
+
+void DArray_destroy(DArray *array);
+
+void DArray_clear(DArray *array);
+
+int DArray_expand(DArray *array);
+
+int DArray_contract(DArray *array);
+
+int DArray_push(DArray *array, void *el);
+
+void *DArray_pop(DArray *array);
+
+int DArray_sort_add(DArray *array, void *el, DArray_compare cmp);
+
+int DArray_find(DArray *array, void *el, DArray_compare cmp);
+
+void DArray_clear_destroy(DArray *array);
+
+/**
+ * Creates a new DArray using `DArray_create` and copies the
+ * `contents` from array to the newly created DArray.
+ *
+ * Returns newly created DArray.
+ */
+DArray *DArray_shallow_copy(DArray *array);
+
+#define DArray_last(A) ((A)->contents[(A)->end - 1])
+#define DArray_first(A) ((A)->contents[0])
+#define DArray_end(A) ((A)->end)
+#define DArray_count(A) DArray_end(A)
+#define DArray_max(A) ((A)->max)
+
+#define DEFAULT_EXPAND_RATE 300
+
+static inline int DArray_set(DArray *array, int i, void *el)
+{
+ check(array != NULL, "array cannot be NULL");
+ check(i >= 0, "i cannot be lesser than 0");
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+ check(i < array->max, "darray attempt to set past max");
+#pragma GCC diagnostic pop
+
+ if (i > array->end)
+ array->end = i;
+
+ array->contents[i] = el;
+ return i;
+ error:
+ return -1;
+}
+
+static inline void *DArray_get(DArray *array, int i)
+{
+ check(array != NULL, "array cannot be NULL");
+ check(i >= 0, "i cannot be lesser than 0");
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+ check(i < array->max, "darray attempt to get past max");
+#pragma GCC diagnostic pop
+
+ return array->contents[i];
+ error:
+ return NULL;
+}
+
+static inline void *DArray_remove(DArray *array, int i)
+{
+ check(array != NULL, "array cannot be NULL");
+ check(i >= 0, "i cannot be lesser than 0");
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+ check(i < array->max, "darray attempt to get past max");
+#pragma GCC diagnostic pop
+
+ void *el = array->contents[i];
+
+ array->contents[i] = NULL;
+
+ return el;
+ error:
+ return NULL;
+}
+
+static inline void *DArray_new(DArray *array)
+{
+ check(array != NULL, "array cannot be NULL");
+ check(array->element_size > 0,
+ "Can't use DArray_new on 0 size darrays.");
+
+ return calloc(1, array->element_size);
+
+ error:
+ return NULL;
+}
+
+#define DArray_free(E) free((E))
+
+#endif