diff options
Diffstat (limited to 'src/darray.h')
-rw-r--r-- | src/darray.h | 126 |
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 |