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

// TO DO: create constructor for new head?
#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];
  if (head[0]) {
    head[0] = head[0]->next;
  }
  if (ret) {
    ret->next = 0;
  }
  return ret;
}

#define pull TEMPLATE(type,Pull)
// pull - remove element from end (delete)
type *pull(type **head) {
  type *this = *head;

  if (!*head) return 0;
  if (!(*head)->next) { 
    *head = 0;
  }
  while (this) {
    if (!this->next) return this;
    if (this->next && !this->next->next) {
      type *tmp = this;
      this = this->next;
      tmp->next = 0;
    } else {
      this = this->next;
    }
  }
  return this;
}

#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
/*
  Author: Michael Schmidt (michael@embeddedARM.com)
 */
