summaryrefslogtreecommitdiff
path: root/pkarr.h
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2024-12-05 15:05:04 -0500
committerJonathan Bradley <jcb@pikum.xyz>2024-12-05 15:06:10 -0500
commit74bf6a57c3c852d8b5237f2b5920556c63da1d79 (patch)
tree0379d5f64a6e09127cc137941d6452f2fbb0f98e /pkarr.h
parent42d967bb6a674fe025a2ad8455bc49a8b93b9d20 (diff)
pkarr: first-pass
Diffstat (limited to 'pkarr.h')
-rw-r--r--pkarr.h129
1 files changed, 129 insertions, 0 deletions
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 <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 */