summaryrefslogtreecommitdiffstats
path: root/src/alloc.h
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-11-23 13:31:33 -0500
committerTavian Barnes <tavianator@tavianator.com>2023-11-23 13:56:03 -0500
commit9032d107ab759450c21fea8f82865ff48c743132 (patch)
tree527e752b4f7b119a6368415158935ea1517bd550 /src/alloc.h
parent5c91f597459de2c5973c9210a3854a19bbc67577 (diff)
downloadbfs-9032d107ab759450c21fea8f82865ff48c743132.tar.xz
alloc: New helpers for growing dynamic arrays
Diffstat (limited to 'src/alloc.h')
-rw-r--r--src/alloc.h36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/alloc.h b/src/alloc.h
index a6dee99..7132470 100644
--- a/src/alloc.h
+++ b/src/alloc.h
@@ -9,6 +9,7 @@
#define BFS_ALLOC_H
#include "config.h"
+#include <errno.h>
#include <stdlib.h>
/** Check if a size is properly aligned. */
@@ -180,6 +181,41 @@ void *xrealloc(void *ptr, size_t align, size_t old_size, size_t new_size);
(type *)xrealloc((ptr), alignof(type), sizeof_flex(type, member, old_count), sizeof_flex(type, member, new_count))
/**
+ * Reserve space for one more element in a dynamic array.
+ *
+ * @param ptr
+ * The pointer to reallocate.
+ * @param align
+ * The required alignment.
+ * @param count
+ * The current size of the array.
+ * @return
+ * The reallocated memory, on both success *and* failure. On success,
+ * errno will be set to zero, and the returned pointer will have room
+ * for (count + 1) elements. On failure, errno will be non-zero, and
+ * ptr will returned unchanged.
+ */
+void *reserve(void *ptr, size_t align, size_t size, size_t count);
+
+/**
+ * Convenience macro to grow a dynamic array.
+ *
+ * @param type
+ * The array element type.
+ * @param type **ptr
+ * A pointer to the array.
+ * @param size_t *count
+ * A pointer to the array's size.
+ * @return
+ * On success, a pointer to the newly reserved array element, i.e.
+ * `*ptr + *count++`. On failure, NULL is returned, and both *ptr and
+ * *count remain unchanged.
+ */
+#define RESERVE(type, ptr, count) \
+ ((*ptr) = reserve((*ptr), alignof(type), sizeof(type), (*count)), \
+ errno ? NULL : (*ptr) + (*count)++)
+
+/**
* An arena allocator for fixed-size types.
*
* Arena allocators are intentionally not thread safe.