diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2023-11-23 13:31:33 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-11-23 13:56:03 -0500 |
commit | 9032d107ab759450c21fea8f82865ff48c743132 (patch) | |
tree | 527e752b4f7b119a6368415158935ea1517bd550 /src/alloc.h | |
parent | 5c91f597459de2c5973c9210a3854a19bbc67577 (diff) | |
download | bfs-9032d107ab759450c21fea8f82865ff48c743132.tar.xz |
alloc: New helpers for growing dynamic arrays
Diffstat (limited to 'src/alloc.h')
-rw-r--r-- | src/alloc.h | 36 |
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. |