From 74bf6a57c3c852d8b5237f2b5920556c63da1d79 Mon Sep 17 00:00:00 2001 From: Jonathan Bradley Date: Thu, 5 Dec 2024 15:05:04 -0500 Subject: pkarr: first-pass --- pkarr.h | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 pkarr.h (limited to 'pkarr.h') diff --git a/pkarr.h b/pkarr.h new file mode 100644 index 0000000..7da67fd --- /dev/null +++ b/pkarr.h @@ -0,0 +1,129 @@ +#ifndef PK_PKARR_H +#define PK_PKARR_H + +#include +#include "pkmem.h" /* delete me */ + +struct pk_arr { + uint32_t next; + uint32_t reserved; + uint32_t stride; + uint32_t alignment; + struct pk_membucket *bkt; + void *data; +}; + +void pk_arr_clear(struct pk_arr *arr); +void pk_arr_reset(struct pk_arr *arr); +void pk_arr_reserve(struct pk_arr *arr, uint32_t count); +void pk_arr_resize(struct pk_arr *arr, uint32_t count); +void pk_arr_move_to_back(struct pk_arr *arr, uint32_t index); +void pk_arr_append(struct pk_arr *arr, void *data); +void pk_arr_remove_at(struct pk_arr *arr, uint32_t index); + +#endif /* PK_PKARR_H */ +#ifdef PK_IMPL_ARR + +#ifndef PK_ARR_GROW_RATIO +#define PK_ARR_GROW_RATIO 1.5 +#endif +#ifndef PK_ARR_INITIAL_COUNT +#define PK_ARR_INITIAL_COUNT 16 +#endif + +void +pk_arr_clear(struct pk_arr *arr) +{ + arr->next = 0; +} + +void +pk_arr_reset(struct pk_arr *arr) +{ + arr->next = 0; + arr->reserved = 0; + if (arr->data != NULL) pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt); + arr->data = NULL; +} + +void +pk_arr_reserve(struct pk_arr *arr, uint32_t count) +{ + if (arr->reserved >= count) return; + void *new_data = pk_new(arr->stride * count, arr->alignment, arr->bkt); + if (arr->data != NULL) { + memcpy(new_data, arr->data, arr->stride * arr->reserved); + pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt); + } + arr->reserved = count; + arr->data = new_data; +} + +void +pk_arr_resize(struct pk_arr *arr, uint32_t count) +{ + pk_arr_reserve(arr, count); + arr->next = count; +} + +void +pk_arr_move_to_back(struct pk_arr *arr, uint32_t index) +{ + if (arr->reserved == 0) return; + if (arr->next <= 1) return; + char *new_data = (char *)pk_new(arr->stride * arr->reserved, arr->alignment, arr->bkt); + if (index > 0) { + memcpy(new_data, arr->data, arr->stride * index); + } + memcpy( + new_data + (arr->stride * (arr->next - 1)), + ((char *)arr->data) + (arr->stride * index), + arr->stride); + memcpy( + new_data + (arr->stride * index), + ((char *)arr->data) + (arr->stride * (index + 1)), + arr->stride * (arr->next - index - 1)); + pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt); + arr->data = (void *)new_data; +} + +void +pk_arr_append(struct pk_arr *arr, void *data) +{ + if (arr->reserved == arr->next) { + uint32_t new_count = arr->reserved == 0 ? PK_ARR_INITIAL_COUNT : arr->reserved * PK_ARR_GROW_RATIO; + void *new_data = pk_new(arr->stride * new_count, arr->alignment, arr->bkt); + if (arr->data != NULL) { + memcpy(new_data, arr->data, arr->stride * arr->reserved); + pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt); + } + arr->data = new_data; + arr->reserved = new_count; + } + memcpy(((char *)arr->data) + (arr->stride * arr->next), data, arr->stride); + arr->next += 1; + return; +} + +void +pk_arr_remove_at(struct pk_arr *arr, uint32_t index) +{ + if (arr->reserved == 0) return; + if (index == arr->next - 1) { + arr->next -=1; + return; + } + char *new_data = (char *)pk_new(arr->stride * arr->reserved, arr->alignment, arr->bkt); + if (index > 0) { + memcpy(new_data, arr->data, arr->stride * index); + } + memcpy( + new_data + (arr->stride * index), + ((char *)arr->data) + (arr->stride * (index + 1)), + arr->stride * (arr->next - index - 1)); + pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt); + arr->data = (void *)new_data; + arr->next -= 1; +} + +#endif /* PK_IMPL_ARR */ -- cgit v1.2.3