2022-02-08 21:53:13 +00:00
|
|
|
#ifndef APFL_ALLOC_H
|
|
|
|
|
#define APFL_ALLOC_H
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
|
|
#define ALLOCATOR_CALL(a, oldptr, oldsize, newsize) \
|
|
|
|
|
((a).alloc((a).opaque, (oldptr), (oldsize), (newsize)))
|
|
|
|
|
|
|
|
|
|
#define ALLOC_BYTES(a, n) (((n) == 0) ? NULL : ALLOCATOR_CALL(a, NULL, 0, (n)))
|
|
|
|
|
#define REALLOC_BYTES(a, ptr, old, new) ALLOCATOR_CALL(a, ptr, old, new)
|
|
|
|
|
#define FREE_BYTES(a, ptr, n) ALLOCATOR_CALL(a, ptr, n, 0)
|
|
|
|
|
|
|
|
|
|
#define REALLOC_LIST(a, ptr, old, new) REALLOC_BYTES(a, ptr, sizeof(*ptr) * (old), sizeof(*ptr) * (new))
|
|
|
|
|
#define ALLOC_LIST(a, T, len) (T *)ALLOC_BYTES(a, sizeof(T) * (len))
|
|
|
|
|
#define FREE_LIST(a, ptr, len) FREE_BYTES(a, ptr, sizeof(*ptr) * (len))
|
|
|
|
|
|
|
|
|
|
#define ALLOC_OBJ(a, T) ALLOC_LIST(a, T, 1)
|
|
|
|
|
#define FREE_OBJ(a, ptr) FREE_LIST(a, ptr, 1)
|
|
|
|
|
|
2022-04-22 19:43:19 +00:00
|
|
|
#define DEINIT_CAP_LIST(allocator, items, len, cap, item_deinit) \
|
|
|
|
|
do { \
|
|
|
|
|
if ((items) == NULL) { \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
for (size_t i = 0; i < (len); i++) { \
|
|
|
|
|
item_deinit(allocator, &((items)[i])); \
|
|
|
|
|
} \
|
|
|
|
|
FREE_LIST(allocator, items, cap); \
|
|
|
|
|
len = 0; \
|
|
|
|
|
cap = 0; \
|
|
|
|
|
(items) = NULL; \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
#define DEINIT_LIST(allocator, items, len, item_deinit) \
|
|
|
|
|
do { \
|
|
|
|
|
if ((items) == NULL) { \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
for (size_t i = 0; i < (len); i++) { \
|
|
|
|
|
item_deinit(allocator, &((items)[i])); \
|
|
|
|
|
} \
|
|
|
|
|
FREE_LIST(allocator, items, len); \
|
|
|
|
|
len = 0; \
|
|
|
|
|
(items) = NULL; \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
#define DEINIT_LIST_WITH_ARGS(allocator, items, len, item_deinit, ...) \
|
|
|
|
|
do { \
|
|
|
|
|
if ((items) == NULL) { \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
for (size_t i = 0; i < (len); i++) { \
|
|
|
|
|
item_deinit(__VA_ARGS__, &((items)[i])); \
|
|
|
|
|
} \
|
|
|
|
|
FREE_LIST(allocator, items, len); \
|
|
|
|
|
len = 0; \
|
|
|
|
|
(items) = NULL; \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
#define DEINIT_CAP_LIST_WITH_ARGS(allocator, items, len, cap, item_deinit, ...) \
|
|
|
|
|
do { \
|
|
|
|
|
if ((items) == NULL) { \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
for (size_t i = 0; i < (len); i++) { \
|
|
|
|
|
item_deinit(__VA_ARGS__, &((items)[i])); \
|
|
|
|
|
} \
|
|
|
|
|
FREE_LIST(allocator, items, cap); \
|
|
|
|
|
len = 0; \
|
|
|
|
|
cap = 0; \
|
|
|
|
|
(items) = NULL; \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
#define MOVEPTR(out, in) \
|
|
|
|
|
do { \
|
|
|
|
|
out = in; \
|
|
|
|
|
in = NULL; \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
// DESTROY destroys a dynamically allocated value.
|
|
|
|
|
// It will first deinit the value using deiniter,
|
|
|
|
|
// free the memory and then set the variable to NULL.
|
|
|
|
|
// It is always allowed to destroy an already destroyed
|
|
|
|
|
// or deinited value.
|
|
|
|
|
#define DESTROY(allocator, var, deiniter) \
|
|
|
|
|
do { \
|
|
|
|
|
if ((var) == NULL) { \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
deiniter(allocator, var); \
|
|
|
|
|
FREE_OBJ(allocator, var); \
|
|
|
|
|
(var) = NULL; \
|
|
|
|
|
} while(0)
|
2022-02-08 21:53:13 +00:00
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|