#include <iostream>

class queue
{
    public:
            queue(); // constructor
            ~queue() {delete [] QArray;} // destructor deletes the array
            void Enqueue(int X);
            void Dequeue();
            int GetFront();

            // IsEmpty() tests to see if the size of the queue equals zero
            // and returns either true or false
            int IsEmpty() {return Currentsize == 0;}

            // Is Full() tests to see if the number of element
            // in the queue equals the size of the array QArray
            // and returns either true or false
            int IsFull(){return Currentsize == Maxsize;}

            void MakeEmpty();
 
    private:
            int Maxsize; // the size of the QArray
            int Currentsize; // variable to hold the size of the queue
                             // at any one time
            int Front; // index to indicate the position of the
                       // Front of the queue
            int Back;  // index to indicate the position of the
                       //Back of the queue
            int *QArray; // QArray is a pointer to an integer

            // Increment()
            // function to increment the Front or Back of the queue for a
            // circular queue implementation. This function is private as
            // it is called only by the methods of queue and not by
            // the user. The parameter X is passed by reference as the
            // function Increment() will alter X.

            void Increment(int &X);
};

 

// constructor initialises the private members of queue

queue::queue()
{
    Maxsize = 10;
    Currentsize = 0;
    Front = 0; Back = -1; // the back element is initialised to be off the
                          // end of the queue
    QArray = new int[Maxsize]; // dynamically allocate the array with new
                               // and set its size to Maxsize.
}

// Enqueue() adds elements to the back of the queue

void queue::Enqueue(int X)
{
    if(!IsFull()){
        Increment(Back); // call function Increment to increment
                         // the Back index
        QArray[Back] = X; // place element X at postion Back of the queue
        Currentsize++; // increment the size of the queue by 1.
        }
    else
        cout<<"No room on queue\n";
}

 

// Dequeue() removes and element from the front of the queue

void queue::Dequeue()
{
    if(IsEmpty())
        cout<<"queue empty, nothing to enqueue\n";
    else
    {
        Currentsize--; // decrement the size of the queue by 1
        Increment(Front); // call function Increment to increment
                          // the Front index
    }
}

// GetFront returns the element at the front of the queue

int queue::GetFront()
{
    if(!IsEmpty())
        return QArray[Front];
}

// MakeEmpty() sets the size of the queue to zero and reinitialises
// Front and Back to an emtpy queue

void queue::MakeEmpty()
{
    Currentsize =0;
    Front = 0;
    Back = -1;
}

// Increment() moves the index X to the start of the queue if X is at
// the end of the queue. If X is at the end of the queue it will be at
// position Maxsize-1. So X is first incremented (++X) and then tested to
// see if it is at position Maxsize. If so it is reset to the start of the
// queue i.e., position 0. X is passed by reference to this function as it is
// altered within the function. The function Increment() is called from
// methods Enqueue() and Dequeue() where Back and Front are sent as
// paramenters respectively.

void queue::Increment(int &X)
{
    if(++X == Maxsize)
        X=0;
}