#include "resarr.h" #include #include #include size_t get_res_count(size_t count) { size_t ec = 1; while (ec < count) ec *= 2; return ec; } stype_resarr resarr_create(size_t elemsize) { return (stype_resarr) { .elemsize = elemsize, .elemcount = 0, .allocsize = 0, .array = NULL }; } int resarr_reserve(stype_resarr *arr, size_t elemcount) { if (arr == NULL) return -1; size_t ec = get_res_count(elemcount); if (ec * arr->elemsize < arr->allocsize) return -1; arr->array = realloc(arr->array, (ec * arr->elemsize)); if (arr->array == NULL) return -1; arr->allocsize = ec * arr->elemsize; return 0; } int resarr_reserve_exact(stype_resarr *arr, size_t elemcount) { if (arr == NULL) return -1; if (elemcount * arr->elemsize < arr->allocsize) return -1; arr->array = realloc(arr->array, (elemcount * arr->elemsize)); if (arr->array == NULL) return -1; arr->allocsize = elemcount * arr->elemsize; return 0; } int resarr_truncate(stype_resarr *arr) { if (arr == NULL) return -1; void *narray = malloc(arr->elemcount * arr->elemsize); if (narray == NULL) return -1; memcpy(narray, arr->array, arr->elemcount * arr->elemsize); free(arr->array); arr->array = narray; arr->allocsize = arr->elemcount * arr->elemsize; return 0; } int resarr_push(stype_resarr *arr, void *elem) { if (arr == NULL) return -1; if (arr->elemsize * arr->elemcount == arr->allocsize) { arr->array = realloc(arr->array, (arr->allocsize * 2)); if (arr->array == NULL) return -1; arr->allocsize *= 2; } memcpy( ((uintptr_t *)arr->array + (arr->elemsize * arr->elemcount)), (uintptr_t *)elem, arr->elemsize ); return 0; } int resarr_pop(stype_resarr *arr) { if (arr == NULL) return -1; if (arr->array == NULL) return -1; memset( ((uintptr_t *)arr->array + (arr->elemsize * arr->elemcount)), 0, arr->elemsize ); return 0; } size_t resarr_size(stype_resarr arr) { return arr.elemcount; } int resarr_insert(stype_resarr *arr, void *elem, size_t before, size_t count) { if (arr == NULL) return -1; if (before > arr->elemcount) return -1; size_t esize = arr->elemsize; size_t newcount = arr->elemcount + count; size_t alloc = get_res_count(newcount) * esize; void *narray = malloc(alloc); if (narray == NULL) return -1; memcpy( narray, arr->array, before * esize ); memcpy( ((uint8_t *)narray + (before * esize)), elem, count * esize ); memcpy( ((uint8_t *)narray + (before * esize) + (count * esize)), ((uint8_t *)arr->array + (before * esize)), (arr->elemcount - before) * esize ); free(arr->array); arr->array = narray; arr->elemcount = newcount; arr->allocsize = alloc; return 0; } int resarr_insert_single(stype_resarr *arr, void *elem, size_t before) { return resarr_insert(arr, elem, before, 1); } int resarr_delete(stype_resarr *arr, size_t start, size_t end) { if (arr == NULL) return -1; if ((start > end) || (start > arr->elemcount) || (end > arr->elemcount)) return -1; size_t rmcount = end - start; memset(((uint8_t *)arr->array + (start * arr->elemsize)), 0, rmcount * arr->elemsize); if (end != arr->elemcount) { memmove( ((uint8_t *)arr->array + (start * arr->elemsize)), ((uint8_t *)arr->array + (end * arr->elemsize)), (arr->elemcount - end) * arr->elemsize ); } arr->elemcount -= rmcount; return 0; } int resarr_swap(stype_resarr *first, stype_resarr *second) { if (first == NULL || second == NULL) return -1; if (first->elemsize != second->elemsize) return -1; size_t size = first->elemsize; size_t largest = 0; if (first->elemcount > second->elemcount) { largest = first->elemcount; resarr_reserve(second, first->elemcount); } else { largest = second->elemcount; resarr_reserve(first, second->elemcount); } // There has got to be a better way to do this... stype_resarr uwu = resarr_create(size); resarr_reserve_exact(&uwu, largest); uwu.elemcount = first->elemcount; memcpy( (uintptr_t *)uwu.array, (uintptr_t *)first->array, size ); first->elemcount = second->elemcount; memcpy( (uintptr_t *)first->array, (uintptr_t *)second->array, size ); second->elemcount = uwu.elemcount; memcpy( (uintptr_t *)second->array, (uintptr_t *)uwu.array, size ); resarr_destroy(&uwu); return 0; } int resarr_swap_quick(stype_resarr *first, stype_resarr *second) { if (first == NULL || second == NULL) return -1; if (first->elemsize != second->elemsize) return -1; size_t size = first->elemcount; size_t alloc = first->allocsize; void *array = first->array; first->elemcount = second->elemcount; first->allocsize = second->allocsize; first->array = second->array; second->elemcount = size; second->allocsize = alloc; second->array = array; return 0; } int resarr_clear(stype_resarr *arr) { if (arr == NULL) return -1; memset( ((uintptr_t *)arr->array), 0, arr->elemsize * arr->elemcount ); arr->elemcount = 0; return 0; } int resarr_destroy(stype_resarr *arr) { if (arr == NULL) return -1; free(arr->array); arr->elemcount = 0; arr->elemsize = 0; arr->allocsize = 0; return 0; }