diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2024-12-05 15:05:04 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2024-12-05 15:06:10 -0500 |
| commit | 74bf6a57c3c852d8b5237f2b5920556c63da1d79 (patch) | |
| tree | 0379d5f64a6e09127cc137941d6452f2fbb0f98e /pkarr.h | |
| parent | 42d967bb6a674fe025a2ad8455bc49a8b93b9d20 (diff) | |
pkarr: first-pass
Diffstat (limited to 'pkarr.h')
| -rw-r--r-- | pkarr.h | 129 |
1 files changed, 129 insertions, 0 deletions
@@ -0,0 +1,129 @@ +#ifndef PK_PKARR_H +#define PK_PKARR_H + +#include <stdint.h> +#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 */ |
