4223
|
1 #ifndef STACK_H_
|
|
2 #define STACK_H_
|
|
3
|
|
4 #include "config.h"
|
|
5 #include "xmalloc.h"
|
|
6
|
|
7 #include <stddef.h>
|
|
8
|
|
9 #define stack(T) struct T##STACK
|
|
10 #define stack_func(T, f) T##STACK##f
|
|
11
|
|
12 #define stack_declare(T, X) \
|
|
13 \
|
|
14 stack(T) { \
|
|
15 T *arr; \
|
|
16 size_t size, length; \
|
|
17 }; \
|
|
18 \
|
|
19 X void stack_func(T, init)(stack(T) *); \
|
|
20 X void stack_func(T, end)(stack(T) *); \
|
|
21 X void stack_func(T, clear)(stack(T) *, size_t); \
|
|
22 \
|
|
23 X void stack_func(T, push)(stack(T) *, const T *); \
|
|
24 X void stack_func(T, pushnull)(stack(T) *); \
|
|
25 X int stack_func(T, pop)(stack(T) *, T *); \
|
|
26 /* X int stack_func(T, peek)(const stack(T) *, T *); */ \
|
|
27 ATTR_PURE \
|
|
28 X T *stack_func(T, at)(const stack(T) *, size_t); \
|
|
29 ATTR_PURE \
|
|
30 X size_t stack_func(T, size)(const stack(T) *); \
|
|
31 /* end of declaration */
|
|
32
|
|
33 #define stack_define(T, X, prepare, clean, copy) \
|
|
34 X void stack_func(T, init)(stack(T) *s) { \
|
|
35 s->arr = xmalloc(s->size = 7, sizeof *s->arr); \
|
|
36 s->length = 0; \
|
|
37 } \
|
|
38 \
|
|
39 X void stack_func(T, end)(stack(T) *s) { \
|
|
40 while (s->length) { \
|
|
41 --s->length; \
|
|
42 (clean)(&s->arr[s->length]); \
|
|
43 } \
|
|
44 xfree(s->arr); \
|
|
45 s->arr = 0; \
|
|
46 } \
|
|
47 \
|
|
48 X void stack_func(T, clear)(stack(T) *s, size_t n) { \
|
|
49 while (n && s->length) { \
|
|
50 --n; \
|
|
51 --s->length; \
|
|
52 (clean)(&s->arr[s->length]); \
|
|
53 } \
|
|
54 } \
|
|
55 \
|
|
56 X void stack_func(T, push)(stack(T) *s, const T *x) { \
|
|
57 if (s->length >= s->size) { \
|
|
58 s->arr = xrealloc(s->arr, s->size *= 2); \
|
|
59 } \
|
|
60 (prepare)(&s->arr[s->length]); \
|
|
61 (copy)(&s->arr[s->length], x); \
|
|
62 ++s->length; \
|
|
63 } \
|
|
64 \
|
|
65 X void stack_func(T, pushnull)(stack(T) *s) { \
|
|
66 if (s->length >= s->size) { \
|
|
67 s->arr = xrealloc(s->arr, s->size *= 2); \
|
|
68 } \
|
|
69 (prepare)(&s->arr[s->length]); \
|
|
70 ++s->length; \
|
|
71 } \
|
|
72 \
|
|
73 X int stack_func(T, pop)(stack(T) *s, T *x) { \
|
|
74 if (s->length) { \
|
|
75 --s->length; \
|
|
76 (copy)(x, &s->arr[s->length]); \
|
|
77 (clean)(&s->arr[s->length]); \
|
|
78 return 0; \
|
|
79 } \
|
|
80 return 1; \
|
|
81 } \
|
|
82 \
|
|
83 /* X int stack_func(T, peek)(const stack(T) *s, T *x) { \
|
|
84 if (s->length) { \
|
|
85 (copy)(x, &s->arr[s->length - 1]); \
|
|
86 return 0; \
|
|
87 } \
|
|
88 return 1; \
|
|
89 } */ \
|
|
90 \
|
|
91 X size_t stack_func(T, size)(const stack(T) *s) { \
|
|
92 return s->length; \
|
|
93 } \
|
|
94 \
|
|
95 X T *stack_func(T, at)(const stack(T) *s, size_t n) { \
|
|
96 if (n < s->length) { \
|
|
97 return &s->arr[s->length - n - 1u]; \
|
|
98 } \
|
|
99 return NULL; \
|
|
100 } \
|
|
101 /* end of definition */
|
|
102
|
|
103 #endif /* STACK_H_ */
|