Please send questions to
st10@humboldt.edu .
//---------------------------------------------------------------------
// File: queue.template
// Name: Sharon M. Tuttle
// last modified: 2-1-05
//
// Template class name: queue
//
// Purpose: a collection of items such that entries can be
// inserted at one end (called the rear) and removed at the
// other end (called the front).
//
// Implementation notes:
// * uses a dynamically-allocated array
// * if there is insufficient dynamic memory, then the
// following methods throw bad_alloc: enqueue
//---------------------------------------------------------------------
#include <cassert> // provides assert
//
// note: because this is a template class, it is included
// in the header file (at the bottom), and not compiled
// separately. Thus, the header file is not included here!
//
using namespace std;
/*****************************************************/
/* CONSTRUCTORS and DESTRUCTOR */
/*****************************************************/
// constructor
//
// postcondition: creates an empty queue instance
//
template <typename Item>
queue<Item>::queue()
{
data = new Item[DEFAULT_CAPACITY];
capacity = DEFAULT_CAPACITY;
used = 0;
first = 0;
last = capacity - 1; // first element enqueued should go in 0...
}
// copy constructor (because am using a pointer to
// point to an array, so that array can be replaced with
// a larger one as needed.
//
template <typename Item>
queue<Item>::queue(const queue<Item>& source)
{
data = new Item[source.capacity];
capacity = source.capacity;
used = source.used;
// copy over all array contents (so a "real" copy);
// some may be junk, but with a circular queue,
// "real" data may not start at 0...!
for (int i=0; i<capacity; i++)
{
data[i] = source[i];
}
first = source.first;
last = source.last;
}
// destructor (because am using a pointer to point to
// an array, so that array can be replaced with a
// larger one as needed.
//
template <typename Item>
queue<Item>::~queue()
{
delete [] data;
}
/*************************************************************/
/* ACCESSORS and other constant member functions (observers) */
/*************************************************************/
// is_empty
//
// postcondition: returns true if queue is empty, and
// returns false otherwise
//
template <typename Item>
bool queue<Item>::is_empty( ) const
{
return (used == 0);
}
// get_front
//
// precondition: is_empty() == false
//
// postcondition: returns the value of the front item of the
// queue, BUT the queue is unchanged.
//
template <typename Item>
Item queue<Item>::get_front( ) const
{
assert(is_empty() == false);
return(data[first]);
}
/*****************************************************/
/* MODIFIERS and other modifying member functions */
/*****************************************************/
// enqueue
//
// postcondition: a new copy of entry has been inserted
// at the rear of the queue
//
template <typename Item>
void queue<Item>::enqueue(const Item& entry)
{
Item *larger_data; // IF need to create new, larger array
int old_capacity;
if (used == capacity)
{
old_capacity = capacity;
capacity += queue<Item>::INCR_AMT;
larger_data = new Item[capacity];
// ouch -- this is the tricky part;
// Need to restart circular array so goes from
// 0 to (used-1) in new bigger array, else
// next inserts will nuke first...!
//
for (int i=0, next=first; i < used; i++, next = (next + 1) % old_capacity)
{
larger_data[i] = data[next];
}
// now first and last must be reset, too; first is now
// 0, last is now (used-1)
first = 0;
last = used-1;
// release the memory data currently pointing to
delete [ ] data;
// now make data point to the new, bigger array
data = larger_data;
}
// use modulo arithmetic, so "wrap" index when reach end
// of array
last = (last + 1) % capacity;
data[last] = entry;
used++;
}
// dequeue
//
// precondition: is_empty() == false
//
// postcondition: the front item of the queue has been
// removed, and a reference to it is returned
//
template <typename Item>
Item& queue<Item>::dequeue( )
{
int old_first;
assert(is_empty() == false);
old_first = first;
// use modulo arithmetic, so "wrap" index when reach end
// of array
first = (first + 1) % capacity;
used--;
return data[old_first];
}