/* default_types.c
 *
 * Written by Matt Levy.
 * Modified  5 Sep 1999 by Neil Moore <neil@cs.uky.edu>
 *
 * Part of lderes.  See COPYRIGHT for copyright information.
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "default_types.h"

inline Set CreateSet(int maxSize, Element depth)
{
  Set newSet = (Set) malloc (sizeof(Element)*(maxSize+4));
  MAX_SET_SIZE(newSet) = maxSize;
  SET_DEPTH(newSet) = depth;
  SET_SIZE(newSet) = 0;
  SET_STRATUM(newSet) = 0;
  memset((char *) newSet+sizeof(Element), 0, maxSize*sizeof(Element));
  return newSet;
}

inline void resetSet(Set set, int startPlace, int endPlace)
{
  SET_SIZE(set) = 0;
  SET_STRATUM(set) = 0;
  if (startPlace > endPlace)
     return;
  /* memset is faster than loop */
  memset((char *) set+(sizeof(Element)*startPlace), 0,
      (endPlace-startPlace+1)*sizeof(Element));
}

inline void AddElement(Set set, Element newElement)
{
  if (newElement <= MAX_SET_SIZE(set) && !set[newElement]){
     SET_SIZE(set)++;
     set[newElement] = 1;
  }
}

inline void RemoveElement(Set set, Element newElement)
{
  if (newElement <= MAX_SET_SIZE(set) && set[newElement]){
     SET_SIZE(set)--;
     set[newElement] = 0;
  }
}

inline Set CopySet (Set set, Set space)
{
  Set newSet = space;

  memcpy(newSet,set,(set[0]+4)*sizeof(Element));
  return newSet;
}

inline Boolean SubsetEmpty(Set set, int startRange, int endRange)
{
  Element *location = (Element *) memchr (set+startRange, TRUE,
      (endRange-startRange+1)*sizeof(Element));
  return (location == NULL);
}

inline int SubsetSize(Set set, int startRange, int endRange)
{
  int count = 0;
  Element *location = (Element *) memchr (set+startRange, TRUE,
      (endRange-startRange+1)*sizeof(Element));
  while (location != NULL){
     count++;
     location = (Element *) memchr (location+1, TRUE,
	 (endRange-(location-set)+1)*sizeof(Element));
  }
  return count;
}

inline Queue CreateQueue(int size)
{
  Queue newQueue = (Queue) malloc (sizeof(Element)*(size+3));
  
  newQueue[0] = size;
  newQueue[size+1] = 1;
  newQueue[size+2] = 1;
  return newQueue;
}

inline Boolean Enqueue(Queue queue, Element element)
{
  if (QUEUE_FULL(queue))
     return FALSE;
  queue[queue[queue[0] + 2]] = element;
  queue[queue[0]+2] = NEXT_ENTRY(queue);
  return TRUE;
}

inline Element Dequeue(Queue queue)
{
  /* Assumes queue has been checked to be non-empty */
  Element returnValue = queue[queue[queue[0]+1]];
  queue[queue[0]+1] %= queue[0];
  queue[queue[0]+1]++;
  return returnValue;
}

inline void resetQueue(Queue queue)
{
  queue[queue[0]+1] = 1;
  queue[queue[0]+2] = 1;
}

inline Stack CreateStack(int size)
{
  Stack newStack;
  
  newStack = (Stack) malloc(sizeof(int)*(size+2));
  newStack[0] = size;
  newStack[size+1] = 0;
  return newStack;
}

inline Boolean Push(Stack stack, int element)
{
  if (STACK_FULL(stack))
     return FALSE;
  stack[stack[0]+1]++;
  stack[stack[stack[0] + 1]] = element;
  return TRUE;
}

inline int Pop(Stack stack)
{
  /* Assumes stack has been checked to be non-empty */
  int returnValue = stack[stack[stack[0]+1]];
  stack[stack[0]+1]--;
  return returnValue;
}
