16#define restrict __restrict__
34#define PASTE(a, b) a##b
42#define XPASTE(a, b) PASTE(a, b)
50#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
63#ifndef FSTACK_FOR_EACH
64#define FSTACK_FOR_EACH(self, index, value) \
65 for ((index) = (self)->count; (index) > 0 && ((value) = (self)->values[(index) - 1], true); (index)--)
78#ifndef FSTACK_FOR_EACH_REVERSE
79#define FSTACK_FOR_EACH_REVERSE(self, index, value) \
80 for ((index) = 0; (index) < (self)->count && ((value) = (self)->values[(index)], true); (index)++)
93#ifndef FSTACK_CALC_SIZEOF
94#define FSTACK_CALC_SIZEOF(fstack_name, capacity) \
95 (uint32_t)(offsetof(struct fstack_name, values) + capacity * sizeof(((struct fstack_name *)0)->values[0]))
108#ifndef FSTACK_CALC_SIZEOF_OVERFLOWS
109#define FSTACK_CALC_SIZEOF_OVERFLOWS(fstack_name, capacity) \
110 (capacity > (UINT32_MAX - offsetof(struct fstack_name, values)) / sizeof(((struct fstack_name *)0)->values[0]))
121#error "Must define NAME."
122#define FUNCTION_DEFINITIONS
123#define TYPE_DEFINITIONS
125#define FSTACK_NAME NAME
136#define VALUE_TYPE int
137#error "Must define VALUE_TYPE."
144#ifndef FUNCTION_LINKAGE
145#define FUNCTION_LINKAGE
149#define FSTACK_TYPE struct FSTACK_NAME
150#define FSTACK_IS_EMPTY JOIN(FSTACK_NAME, is_empty)
151#define FSTACK_IS_FULL JOIN(FSTACK_NAME, is_full)
152#define FSTACK_INIT JOIN(FSTACK_NAME, init)
165#ifdef TYPE_DEFINITIONS
188FUNCTION_LINKAGE FSTACK_TYPE *
JOIN(FSTACK_NAME, init)(FSTACK_TYPE *self,
const uint32_t capacity);
203 create_custom)(
const uint32_t capacity,
void *context_ptr,
204 void *(*allocate)(
void *context_ptr,
size_t alignment,
size_t size));
226 void (*deallocate)(
void *context_ptr,
void *mem));
325FUNCTION_LINKAGE void JOIN(FSTACK_NAME, copy)(FSTACK_TYPE *restrict dest_ptr,
const FSTACK_TYPE *restrict src_ptr);
335#ifdef FUNCTION_DEFINITIONS
347 self->capacity = capacity;
353 create_custom)(
const uint32_t capacity,
void *context_ptr,
354 void *(*allocate)(
void *context_ptr,
size_t alignment,
size_t size))
362 FSTACK_TYPE *self = (FSTACK_TYPE *)allocate(context_ptr,
alignof(FSTACK_TYPE), size);
368 memset(self, 0, size);
369 FSTACK_INIT(self, capacity);
375static inline void *
JOIN(internal,
JOIN(FSTACK_NAME, allocate))(
void *context_ptr,
size_t alignment,
size_t size)
385 return JOIN(FSTACK_NAME, create_custom)(capacity, NULL,
JOIN(internal,
JOIN(FSTACK_NAME, allocate)));
389 void (*deallocate)(
void *context_ptr,
void *mem))
391 assert(self != NULL);
393 deallocate(context_ptr, self);
397static inline void JOIN(internal,
JOIN(FSTACK_NAME, deallocate))(
void *context_ptr,
void *mem)
406 assert(self != NULL);
408 JOIN(FSTACK_NAME, destroy_custom)(self, NULL,
JOIN(internal,
JOIN(FSTACK_NAME, deallocate)));
413 assert(self != NULL);
415 return self->count == 0;
420 assert(self != NULL);
422 return self->count == self->capacity;
427 assert(self != NULL);
428 assert(index < self->count);
430 return self->values[self->count - 1 - index];
435 assert(self != NULL);
436 assert(FSTACK_IS_EMPTY(self) ==
false);
438 return self->values[self->count - 1];
443 assert(self != NULL);
444 assert(FSTACK_IS_EMPTY(self) ==
false);
446 return self->values[0];
451 return JOIN(FSTACK_NAME, get_top)(self);
456 assert(self != NULL);
457 assert(FSTACK_IS_FULL(self) ==
false);
459 self->values[self->count++] = value;
464 assert(self != NULL);
465 assert(FSTACK_IS_EMPTY(self) ==
false);
467 return self->values[--self->count];
472 assert(self != NULL);
476FUNCTION_LINKAGE void JOIN(FSTACK_NAME, copy)(FSTACK_TYPE *restrict dest_ptr,
const FSTACK_TYPE *restrict src_ptr)
478 assert(src_ptr != NULL);
479 assert(dest_ptr != NULL);
480 assert(src_ptr->count <= dest_ptr->capacity);
481 assert(FSTACK_IS_EMPTY(dest_ptr));
483 for (uint32_t i = 0; i < src_ptr->count; i++) {
484 dest_ptr->values[i] = src_ptr->values[i];
486 dest_ptr->count = src_ptr->count;
496#undef FUNCTION_LINKAGE
497#undef FUNCTION_DEFINITIONS
498#undef TYPE_DEFINITIONS
502#undef FSTACK_IS_EMPTY
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:145
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition fstack_template.h:50
#define VALUE_TYPE
Stack value type. This must be manually defined before including this header file.
Definition fstack_template.h:136
#define FSTACK_CALC_SIZEOF(fstack_name, capacity)
Calculate the size of the stack struct. No overflow checks.
Definition fstack_template.h:94
#define FSTACK_CALC_SIZEOF_OVERFLOWS(fstack_name, capacity)
Check for a given capacity, if the equivalent size of the stack struct overflows.
Definition fstack_template.h:109
uint32_t capacity
maximum number of values allocated for.
Definition fstack_template.h:172
VALUE_TYPE values[]
array of values.
Definition fstack_template.h:173
uint32_t count
number of values.
Definition fstack_template.h:171