// File: bstrq.C
//
// Implementation of class BStringQ which was derived from GenQ

#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include "bstrq.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
//
BStringQ::BStringQ()
: GenQ(cmp, prt)        // member initializer
{
#ifndef NDEBUG
   cerr << "BStringQ constructor, this = " << this << endl ;
#endif
   // Do nothing
}


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

   // Do nothing, GenQ destructor automatically called
}


// Add a string to the end of the queue
//
void BStringQ::enqueue(const BString& bs) {

   BString *newstr = new BString(bs) ;
   CrashOnNULL(newstr, "Out of memory in BStringQ::enqueue()") ;

   GenQ::enqueue(newstr) ;
}


// Return and delete from front of queue
//
BString BStringQ::dequeue() {
   BString bs, *bsptr ;

   bsptr = (BString *) GenQ::dequeue() ;

   bs = *bsptr ;    // inefficient, but avoids memory leaks
   delete bsptr ;
   return bs ;
}


// Return string at the front of the queue
//
BString BStringQ::peek() {
   BString bs, *bsptr ;

   bsptr = (BString *) GenQ::peek() ;
   return *bsptr ;
}


// Remove items with key equal to given string
//
void BStringQ::remove(const BString& bs) {

   GenQ::remove((void *) &bs) ;
}


// Compare two strings
//
int BStringQ::cmp(void *vptr1, void *vptr2) {
   BString *ptr1, *ptr2 ;

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

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

   if (*ptr1 < *ptr2) return -1 ; // uses overloaded BString comps.
   if (*ptr1 == *ptr2) return 0 ;
   return 1 ;
}


// print out a string
//
void BStringQ::prt(void *vptr) {
   BString *ptr ;

   if (vptr == NULL) return ;

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