#ifndef PK_PKARR_H #define PK_PKARR_H #include #include "pkmem.h" /* deleteme */ 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 */