//Circular Queue
#include <iostream>
using namespace std;

template <class x> class Queue {
public:
	Queue					(int m);
	~Queue					();
	void	Enqueue			(x e);
	void	Dequeue			(x& e);
	int		QueueIsFull		();
	int		QueueIsEmpty	();
	void	QueueRetreive	(x& e);
private:
	int maxsize;
	x *p;
	int rear;
	int front;
	int n;
};

int main()
{
	Queue<int> q(20);
	int i;
	q.Enqueue(1);
	q.Enqueue(1);
	q.Enqueue(2);
	q.Enqueue(3);
	q.Enqueue(5);
	q.Enqueue(8);

	q.Dequeue(i);
	cout << i << endl;

	q.Dequeue(i);
	cout << i << endl;

	q.Dequeue(i);
	cout << i << endl;

	return 0;
}

template <class x> Queue<x>::Queue(int m) {
	maxsize = m;
	p = new x[maxsize];
	rear = -1;
	front = -1;
	n = 0;
}

template <class x> Queue<x>::~Queue() {
	delete [] p;
	rear = front = -1;
}

template <class x> int Queue<x>::QueueIsFull() {
	if ((rear == maxsize - 1) && (front == -1))
		return 1;
	if ((rear == front) && (n == 1))
		return 1;
	return 0;
}

template <class x> int Queue<x>::QueueIsEmpty() {
	if ((rear == front) && (n == 0))
		return 1;
	return 0;
}

template <class x> void Queue<x>::Enqueue(x e) {
	if(!QueueIsFull()){
		rear = (rear + 1) % maxsize;
		p[rear] = e;
		n = 1;
	}
}

template <class x> void Queue<x>::Dequeue(x& e) {
	if(!QueueIsEmpty()){
		front = (front + 1) % maxsize;
		e = p[front];
		n = 0;
	}
}

template <class x> void Queue<x>::QueueRetreive(x& e){
	if(!QueueIsEmpty()){
		int k = front;
		front = (front + 1) % maxsize;
		e = p[front];
		front = k;
	}
}