dsa-c
 
Loading...
Searching...
No Matches
fstack_template.h
Go to the documentation of this file.
1
5
10
11#ifdef __cplusplus
12#ifdef __GNUC__
13#define restrict __restrict__
14#else
15#define restrict
16#endif
17extern "C" {
18#endif
19
20#include <assert.h>
21#include <stdbool.h>
22#include <stddef.h>
23#include <stdint.h>
24#include <stdio.h>
25#include <stdlib.h>
26
27// macro definitions: {{{
28
33#ifndef PASTE
34#define PASTE(a, b) a##b
35#endif
36
41#ifndef XPASTE
42#define XPASTE(a, b) PASTE(a, b)
43#endif
44
49#ifndef JOIN
50#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
51#endif
52
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)--)
66#endif
67
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)++)
81#endif
82
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]))
96#endif
97
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]))
111#endif
112
120#ifndef NAME
121#define NAME fstack
122#error "Must define NAME."
123#else
124#define FSTACK_NAME NAME
125#endif
126
134#ifndef VALUE_TYPE
135#define VALUE_TYPE int
136#define FUNCTION_DEFINITIONS
137#define TYPE_DEFINITIONS
138#error "Must define VALUE_TYPE."
139#endif
140
145#ifndef FUNCTION_LINKAGE
146#define FUNCTION_LINKAGE
147#endif
148
150#define FSTACK_TYPE struct FSTACK_NAME
151#define FSTACK_IS_EMPTY JOIN(FSTACK_NAME, is_empty)
152#define FSTACK_IS_FULL JOIN(FSTACK_NAME, is_full)
153#define FSTACK_INIT JOIN(FSTACK_NAME, init)
155
156// }}}
157
158// type definitions: {{{
159
164#ifdef TYPE_DEFINITIONS
165
169struct FSTACK_NAME {
170 uint32_t count;
171 uint32_t capacity;
173};
174
175#endif
176
177// }}}
178
179// function declarations: {{{
180
187FUNCTION_LINKAGE FSTACK_TYPE *JOIN(FSTACK_NAME, init)(FSTACK_TYPE *self, const uint32_t capacity);
188
199FUNCTION_LINKAGE FSTACK_TYPE *JOIN(FSTACK_NAME, create)(const uint32_t capacity);
200
208FUNCTION_LINKAGE void JOIN(FSTACK_NAME, destroy)(FSTACK_TYPE *self);
209
217FUNCTION_LINKAGE bool JOIN(FSTACK_NAME, is_empty)(const FSTACK_TYPE *self);
218
226FUNCTION_LINKAGE bool JOIN(FSTACK_NAME, is_full)(const FSTACK_TYPE *self);
227
239FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, at)(const FSTACK_TYPE *self, const uint32_t index);
240
248FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, get_top)(const FSTACK_TYPE *self);
249
257FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, get_bottom)(const FSTACK_TYPE *self);
258
266FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, peek)(const FSTACK_TYPE *self);
267
274FUNCTION_LINKAGE void JOIN(FSTACK_NAME, push)(FSTACK_TYPE *self, const VALUE_TYPE value);
275
283FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, pop)(FSTACK_TYPE *self);
284
290FUNCTION_LINKAGE void JOIN(FSTACK_NAME, clear)(FSTACK_TYPE *self);
291
298FUNCTION_LINKAGE void JOIN(FSTACK_NAME, copy)(FSTACK_TYPE *restrict dest_ptr, const FSTACK_TYPE *restrict src_ptr);
299
300// }}}
301
302// function definitions: {{{
303
308#ifdef FUNCTION_DEFINITIONS
309
310FUNCTION_LINKAGE FSTACK_TYPE *JOIN(FSTACK_NAME, init)(FSTACK_TYPE *self, const uint32_t capacity)
311{
312 assert(self);
313
314 self->count = 0;
315 self->capacity = capacity;
316
317 return self;
318}
319
320FUNCTION_LINKAGE FSTACK_TYPE *JOIN(FSTACK_NAME, create)(const uint32_t capacity)
321{
322 if (capacity == 0 || FSTACK_CALC_SIZEOF_OVERFLOWS(FSTACK_NAME, capacity)) {
323 return NULL;
324 }
325
326 const uint32_t size = FSTACK_CALC_SIZEOF(FSTACK_NAME, capacity);
327
328 FSTACK_TYPE *self = (FSTACK_TYPE *)calloc(1, size);
329
330 if (!self) {
331 return NULL;
332 }
333
334 FSTACK_INIT(self, capacity);
335
336 return self;
337}
338
339FUNCTION_LINKAGE void JOIN(FSTACK_NAME, destroy)(FSTACK_TYPE *self)
340{
341 assert(self != NULL);
342
343 free(self);
344}
345
346FUNCTION_LINKAGE bool JOIN(FSTACK_NAME, is_empty)(const FSTACK_TYPE *self)
347{
348 assert(self != NULL);
349
350 return self->count == 0;
351}
352
353FUNCTION_LINKAGE bool JOIN(FSTACK_NAME, is_full)(const FSTACK_TYPE *self)
354{
355 assert(self != NULL);
356
357 return self->count == self->capacity;
358}
359
360FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, at)(const FSTACK_TYPE *self, const uint32_t index)
361{
362 assert(self != NULL);
363 assert(index < self->count);
364
365 return self->values[self->count - 1 - index];
366}
367
368FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, get_top)(const FSTACK_TYPE *self)
369{
370 assert(self != NULL);
371 assert(FSTACK_IS_EMPTY(self) == false);
372
373 return self->values[self->count - 1];
374}
375
376FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, get_bottom)(const FSTACK_TYPE *self)
377{
378 assert(self != NULL);
379 assert(FSTACK_IS_EMPTY(self) == false);
380
381 return self->values[0];
382}
383
384FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, peek)(const FSTACK_TYPE *self)
385{
386 return JOIN(FSTACK_NAME, get_top)(self);
387}
388
389FUNCTION_LINKAGE void JOIN(FSTACK_NAME, push)(FSTACK_TYPE *self, const VALUE_TYPE value)
390{
391 assert(self != NULL);
392 assert(FSTACK_IS_FULL(self) == false);
393
394 self->values[self->count++] = value;
395}
396
397FUNCTION_LINKAGE VALUE_TYPE JOIN(FSTACK_NAME, pop)(FSTACK_TYPE *self)
398{
399 assert(self != NULL);
400 assert(FSTACK_IS_EMPTY(self) == false);
401
402 return self->values[--self->count];
403}
404
405FUNCTION_LINKAGE void JOIN(FSTACK_NAME, clear)(FSTACK_TYPE *self)
406{
407 assert(self != NULL);
408 self->count = 0;
409}
410
411FUNCTION_LINKAGE void JOIN(FSTACK_NAME, copy)(FSTACK_TYPE *restrict dest_ptr, const FSTACK_TYPE *restrict src_ptr)
412{
413 assert(src_ptr != NULL);
414 assert(dest_ptr != NULL);
415 assert(src_ptr->count <= dest_ptr->capacity);
416 assert(FSTACK_IS_EMPTY(dest_ptr));
417
418 for (uint32_t i = 0; i < src_ptr->count; i++) {
419 dest_ptr->values[i] = src_ptr->values[i];
420 }
421 dest_ptr->count = src_ptr->count;
422}
423
424#endif
425
426// }}}
427
428// macro undefs: {{{
429#undef NAME
430#undef VALUE_TYPE
431#undef FUNCTION_LINKAGE
432#undef FUNCTION_DEFINITIONS
433#undef TYPE_DEFINITIONS
434
435#undef FSTACK_NAME
436#undef FSTACK_TYPE
437#undef FSTACK_IS_EMPTY
438#undef FSTACK_IS_FULL
439#undef FSTACK_INIT
440
441// }}}
442
443#ifdef __cplusplus
444}
445#endif
446
447// vim: ft=c fdm=marker
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:146
#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:135
#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:171
VALUE_TYPE values[]
array of values.
Definition fstack_template.h:172
uint32_t count
number of values.
Definition fstack_template.h:170