#ifndef ARBSTACK_H_ASDFASDFASDF
#define ARBSTACK_H_ASDFASDFASDF
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define ROUNDUP(n) ((((n)/64)+1)*64)

#define STACKDECL(stackData,stackDataName) \
\
typedef struct _##stackDataName##Stack stackDataName##Stack;\
\
int stackDataName##StackLen(stackDataName##Stack *s);\
\
int stackDataName##StackMax(stackDataName##Stack *s);\
\
stackDataName##Stack *stackDataName##StackNew();\
\
void stackDataName##StackPush(stackDataName##Stack *self,stackData item);\
\
void stackDataName##StackClear(stackDataName##Stack *self);\
\
void stackDataName##StackGrow(stackDataName##Stack *self,int newMax);\
\
stackData *stackDataName##StackContents(stackDataName##Stack *self);\

#define STACKDEF(stackData,stackDataName) \
struct _##stackDataName##Stack {\
  int max,len;\
  stackData *s;\
};\
\
int stackDataName##StackMax(stackDataName##Stack *s) {assert(s); return s->max;}\
\
int stackDataName##StackLen(stackDataName##Stack *s) {assert(s); return s->len;}\
void stackDataName##StackClear(stackDataName##Stack *self){\
  assert(self);\
  self->len=0;\
}\
\
\
stackDataName##Stack *stackDataName##StackNew() {\
  stackDataName##Stack *self=malloc(sizeof(stackDataName##Stack));\
  assert(self);\
  self->s=NULL;\
  self->max=self->len=0;\
  return self;\
}\
\
void stackDataName##StackGrow(stackDataName##Stack *self,int newMax) {\
  assert(self);\
  if (newMax>=self->max) {\
    self->max=ROUNDUP(newMax);\
    self->s=realloc(self->s,self->max*sizeof(stackData));\
  }\
  assert(self->max>self->len);\
  assert(self->s);\
}\
\
void stackDataName##StackPush(stackDataName##Stack *self,stackData item) {\
  stackDataName##StackGrow(self,self->max); \
  self->s[self->len++]=item;\
}\
\
stackData *stackDataName##StackContents(stackDataName##Stack *self) {assert(self); return self->s;}\

#endif /* arbstack_h */

