// #define type <type of array>
// #define type_null <value to return for empty array>
#define TOKENIZE(a,b) a##_##b
#define TEMPLATE(a,b) TOKENIZE(a,b)
#define type_null TEMPLATE(type,_null)

// TO DO: add macro to compute element starting at end of array
// IDEA: realloc that can take a pointer anywhere in the malloced buffer

#define push TEMPLATE(type,Push)
// push - add element to beginning (prepend)
void push(type **head,type *value) {
  int i;

  value->next = head[0];
  head[0] = value;
}

#define pop TEMPLATE(type,Pop)
// pop - remove element from beginning (delete)
type *pop(type **head) {
  type *ret = head[0];
  head[0] = head[0]->next;
  return ret;
}

#define pull TEMPLATE(type,Pull)
// pull - remove element from end (delete)
type *pull(type *head) {
  while (head) {
    if (!head->next) return head;
    head = head->next;
  }
  return head;
}

#define queue TEMPLATE(type,Queue)
// queue - add element to end (append)
void queue(type **head,type *value) {
  type *next = head[0];
  while (next) {
    if (!next->next) {
      next->next = value;
      return;
    }
    next = next->next;
  }
  head[0] = value;
}

#define delete TEMPLATE(type,Delete)
// delete - remove element from list
void delete(type **head,type *value) {
  type *cur = head[0], *ret;

  if (cur == value) {
    head[0] = cur->next;
    // freeType(cur);
  }
  while (cur->next != value) {
    cur = cur->next;
  }
  cur->next = value->next;
  // freeType(cur);
}

#undef F0
#undef F1
#undef push
#undef pop
#undef pull
#undef queue
#undef type
