/* SPDX-License-Identifier: BSD-3-Clause */ /* * Copyright © 2010, Zed A. Shaw. * Copyright © 2020 rsiddharth */ #ifndef _DArray_h #define _DArray_h #include #include #include 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