diff src/ploki/stack.h @ 4223:ac0403686959

<oerjan> rm -rf src/ploki; mv ploki src
author HackBot
date Fri, 20 Dec 2013 22:18:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ploki/stack.h	Fri Dec 20 22:18:50 2013 +0000
@@ -0,0 +1,103 @@
+#ifndef STACK_H_
+#define STACK_H_
+
+#include "config.h"
+#include "xmalloc.h"
+
+#include <stddef.h>
+
+#define stack(T) struct T##STACK
+#define stack_func(T, f) T##STACK##f
+
+#define stack_declare(T, X) \
+ \
+stack(T) { \
+	T *arr; \
+	size_t size, length; \
+}; \
+ \
+X void stack_func(T, init)(stack(T) *); \
+X void stack_func(T, end)(stack(T) *); \
+X void stack_func(T, clear)(stack(T) *, size_t); \
+ \
+X void stack_func(T, push)(stack(T) *, const T *); \
+X void stack_func(T, pushnull)(stack(T) *); \
+X int stack_func(T, pop)(stack(T) *, T *); \
+/* X int stack_func(T, peek)(const stack(T) *, T *); */ \
+ATTR_PURE \
+X T *stack_func(T, at)(const stack(T) *, size_t); \
+ATTR_PURE \
+X size_t stack_func(T, size)(const stack(T) *); \
+/* end of declaration */
+
+#define stack_define(T, X, prepare, clean, copy) \
+X void stack_func(T, init)(stack(T) *s) { \
+	s->arr = xmalloc(s->size = 7, sizeof *s->arr); \
+	s->length = 0; \
+} \
+ \
+X void stack_func(T, end)(stack(T) *s) { \
+	while (s->length) { \
+		--s->length; \
+		(clean)(&s->arr[s->length]); \
+	} \
+	xfree(s->arr); \
+	s->arr = 0; \
+} \
+ \
+X void stack_func(T, clear)(stack(T) *s, size_t n) { \
+	while (n && s->length) { \
+		--n; \
+		--s->length; \
+		(clean)(&s->arr[s->length]); \
+	} \
+} \
+ \
+X void stack_func(T, push)(stack(T) *s, const T *x) { \
+	if (s->length >= s->size) { \
+		s->arr = xrealloc(s->arr, s->size *= 2); \
+	} \
+	(prepare)(&s->arr[s->length]); \
+	(copy)(&s->arr[s->length], x); \
+	++s->length; \
+} \
+ \
+X void stack_func(T, pushnull)(stack(T) *s) { \
+	if (s->length >= s->size) { \
+		s->arr = xrealloc(s->arr, s->size *= 2); \
+	} \
+	(prepare)(&s->arr[s->length]); \
+	++s->length; \
+} \
+ \
+X int stack_func(T, pop)(stack(T) *s, T *x) { \
+	if (s->length) { \
+		--s->length; \
+		(copy)(x, &s->arr[s->length]); \
+		(clean)(&s->arr[s->length]); \
+		return 0; \
+	} \
+	return 1; \
+} \
+ \
+/* X int stack_func(T, peek)(const stack(T) *s, T *x) { \
+	if (s->length) { \
+		(copy)(x, &s->arr[s->length - 1]); \
+		return 0; \
+	} \
+	return 1; \
+} */ \
+ \
+X size_t stack_func(T, size)(const stack(T) *s) { \
+	return s->length; \
+} \
+ \
+X T *stack_func(T, at)(const stack(T) *s, size_t n) { \
+	if (n < s->length) { \
+		return &s->arr[s->length - n - 1u]; \
+	} \
+	return NULL; \
+} \
+/* end of definition */
+
+#endif /* STACK_H_ */