// File: intq.C
//
// Implementation of class IntQ which was derived from GenQ

#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include "intq.h"

// "Local" functions
//
static void CrashOnNULL(void *ptr, char *mesg) ;

static void CrashOnNULL(void *ptr, char *mesg) {
   if (ptr == NULL) {
      cerr << "CrashOnNULL: " << mesg << endl ;
      exit(1) ;
   }
}


// Default constructor
//
IntQ::IntQ()
: GenQ(cmp, prt)        // member initializer
{
#ifndef NDEBUG
   cerr << "IntQ constructor, this = " << this << endl ;
#endif
   // Do nothing
}


// Destructor
//
IntQ::~IntQ() {
#ifndef NDEBUG
   cerr << "IntQ destructor, this = " << this << endl ;
#endif

   // Do nothing, GenQ destructor automatically called
}


// Add an int to the end of the queue
//
void IntQ::enqueue(int n) {

   int *ptr = new int(n) ;
   CrashOnNULL(ptr, "Out of memory in IntQ::enqueue()") ;

   GenQ::enqueue(ptr) ;
}


// Return and delete from front of queue
//
int IntQ::dequeue() {
   int result, *ptr ;

   ptr = (int *) GenQ::dequeue() ;
   result = *ptr ;
   delete ptr ;
   return result ;
}


// Return int at the front of the queue
//
int IntQ::peek() {
   int *ptr ;

   ptr = (int *) GenQ::peek() ;
   return *ptr ;
}


// Remove items with key equal to given int
//
void IntQ::remove(int n) {

   GenQ::remove(&n) ;
}


// Compare two integers
//
int IntQ::cmp(void *vptr1, void *vptr2) {
   int *ptr1, *ptr2 ;

   ptr1 = (int *) vptr1 ;
   ptr2 = (int *) vptr2 ;

   if (ptr1 == NULL && ptr2 == NULL) return 0 ;
   if (ptr1 == NULL) return -1 ;
   if (ptr2 == NULL) return  1 ;

   if (*ptr1 < *ptr2) return -1 ;
   if (*ptr1 == *ptr2) return 0 ;
   return 1 ;
}

// print out an integer
//
void IntQ::prt(void *vptr) {
   int *ptr ;

   if (vptr == NULL) return ;

   ptr = (int *) vptr ;
   cout << *ptr << " " ;
}
