view src/ploki/stack.h @ 8916:0234daffd946

<oerjan> addquote <int-e> I couldn\'t help thinking that maybe if one considers the ramifications in full detail it will turn out that overthinking is often not helpful and therefore, not something to be proud of.
author HackBot
date Sun, 14 Aug 2016 02:31:47 +0000
parents ac0403686959
children
line wrap: on
line source

#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_ */