diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/zix/allocator.h | 152 | ||||
-rw-r--r-- | include/zix/btree.h | 5 | ||||
-rw-r--r-- | include/zix/hash.h | 8 | ||||
-rw-r--r-- | include/zix/ring.h | 3 | ||||
-rw-r--r-- | include/zix/tree.h | 12 |
5 files changed, 170 insertions, 10 deletions
diff --git a/include/zix/allocator.h b/include/zix/allocator.h new file mode 100644 index 0000000..73e2207 --- /dev/null +++ b/include/zix/allocator.h @@ -0,0 +1,152 @@ +/* + Copyright 2021 David Robillard <d@drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef ZIX_ALLOCATOR_H +#define ZIX_ALLOCATOR_H + +#include "zix/attributes.h" + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @addtogroup zix + @{ + @name Allocator + @{ +*/ + +/// Opaque user data for allocation functions +typedef void ZixAllocatorHandle; + +/** + General malloc-like memory allocation function. + + This works like the standard C malloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED ( + *ZixMallocFunc)(ZixAllocatorHandle* ZIX_NULLABLE handle, size_t size); + +/** + General calloc-like memory allocation function. + + This works like the standard C calloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixCallocFunc)(ZixAllocatorHandle* ZIX_NULLABLE + handle, + size_t nmemb, + size_t size); + +/** + General realloc-like memory reallocation function. + + This works like the standard C remalloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixReallocFunc)(ZixAllocatorHandle* ZIX_NULLABLE + handle, + void* ZIX_NULLABLE ptr, + size_t size); + +/** + General free-like memory deallocation function. + + This works like the standard C remalloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void (*ZixFreeFunc)(ZixAllocatorHandle* ZIX_NULLABLE handle, + void* ZIX_NULLABLE ptr); + +/** + A memory allocator. + + This object-like structure provides an interface like the standard C + functions malloc(), calloc(), realloc(), and free(). It allows the user to + pass a custom allocator to be used by data structures. +*/ +typedef struct { + ZixAllocatorHandle* ZIX_NULLABLE handle; + ZixMallocFunc ZIX_NONNULL malloc; + ZixCallocFunc ZIX_NONNULL calloc; + ZixReallocFunc ZIX_NONNULL realloc; + ZixFreeFunc ZIX_NONNULL free; +} ZixAllocator; + +/// Return the default allocator which simply uses the system allocator +ZIX_CONST_API +const ZixAllocator* ZIX_NONNULL +zix_default_allocator(void); + +/// Convenience wrapper that defers to malloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_malloc(const ZixAllocator* const ZIX_NULLABLE allocator, const size_t size) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + return actual->malloc(actual->handle, size); +} + +/// Convenience wrapper that defers to calloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_calloc(const ZixAllocator* const ZIX_NULLABLE allocator, + const size_t nmemb, + const size_t size) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + return actual->calloc(actual->handle, nmemb, size); +} + +/// Convenience wrapper that defers to realloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_realloc(const ZixAllocator* const ZIX_NULLABLE allocator, + void* const ZIX_NULLABLE ptr, + const size_t size) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + return actual->realloc(actual->handle, ptr, size); +} + +/// Convenience wrapper that defers to free() if allocator is null +static inline void +zix_free(const ZixAllocator* const ZIX_NULLABLE allocator, + void* const ZIX_NULLABLE ptr) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + actual->free(actual->handle, ptr); +} + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ZIX_ALLOCATOR_H */ diff --git a/include/zix/btree.h b/include/zix/btree.h index 3979084..9c67dda 100644 --- a/include/zix/btree.h +++ b/include/zix/btree.h @@ -17,6 +17,7 @@ #ifndef ZIX_BTREE_H #define ZIX_BTREE_H +#include "zix/allocator.h" #include "zix/attributes.h" #include "zix/common.h" @@ -88,7 +89,9 @@ static const ZixBTreeIter zix_btree_end_iter = { */ ZIX_API ZixBTree* ZIX_ALLOCATED -zix_btree_new(ZixComparator ZIX_NONNULL cmp, const void* ZIX_NULLABLE cmp_data); +zix_btree_new(const ZixAllocator* ZIX_NULLABLE allocator, + ZixComparator ZIX_NONNULL cmp, + const void* ZIX_NULLABLE cmp_data); /** Free `t` and all the nodes it contains. diff --git a/include/zix/hash.h b/include/zix/hash.h index 8be8941..cc56d0e 100644 --- a/include/zix/hash.h +++ b/include/zix/hash.h @@ -17,6 +17,7 @@ #ifndef ZIX_HASH_H #define ZIX_HASH_H +#include "zix/allocator.h" #include "zix/attributes.h" #include "zix/common.h" @@ -133,9 +134,10 @@ typedef struct { */ ZIX_API ZixHash* ZIX_ALLOCATED -zix_hash_new(ZixKeyFunc ZIX_NONNULL key_func, - ZixHashFunc ZIX_NONNULL hash_func, - ZixKeyEqualFunc ZIX_NONNULL equal_func); +zix_hash_new(const ZixAllocator* ZIX_NULLABLE allocator, + ZixKeyFunc ZIX_NONNULL key_func, + ZixHashFunc ZIX_NONNULL hash_func, + ZixKeyEqualFunc ZIX_NONNULL equal_func); /// Free `hash` ZIX_API diff --git a/include/zix/ring.h b/include/zix/ring.h index b323e70..af98ecf 100644 --- a/include/zix/ring.h +++ b/include/zix/ring.h @@ -17,6 +17,7 @@ #ifndef ZIX_RING_H #define ZIX_RING_H +#include "zix/allocator.h" #include "zix/attributes.h" #include <stdint.h> @@ -48,7 +49,7 @@ typedef struct ZixRingImpl ZixRing; */ ZIX_MALLOC_API ZixRing* ZIX_ALLOCATED -zix_ring_new(uint32_t size); +zix_ring_new(const ZixAllocator* ZIX_NULLABLE allocator, uint32_t size); /// Destroy a ring ZIX_API diff --git a/include/zix/tree.h b/include/zix/tree.h index 2ce7490..c3b9262 100644 --- a/include/zix/tree.h +++ b/include/zix/tree.h @@ -17,6 +17,7 @@ #ifndef ZIX_TREE_H #define ZIX_TREE_H +#include "zix/allocator.h" #include "zix/attributes.h" #include "zix/common.h" @@ -43,11 +44,12 @@ typedef struct ZixTreeNodeImpl ZixTreeIter; /// Create a new (empty) tree ZIX_API ZixTree* ZIX_ALLOCATED -zix_tree_new(bool allow_duplicates, - ZixComparator ZIX_NONNULL cmp, - void* ZIX_NULLABLE cmp_data, - ZixDestroyFunc ZIX_NULLABLE destroy, - const void* ZIX_NULLABLE destroy_user_data); +zix_tree_new(const ZixAllocator* ZIX_NULLABLE allocator, + bool allow_duplicates, + ZixComparator ZIX_NONNULL cmp, + void* ZIX_NULLABLE cmp_data, + ZixDestroyFunc ZIX_NULLABLE destroy, + const void* ZIX_NULLABLE destroy_user_data); /// Free `t` ZIX_API |