#include<iostream>

using namespace std;
#define MAX 5
class Full{  };
class Empty {
      string origin;
      public:
         Empty(string s): origin(s) { } 
         string getString(){
           return origin;
         }          
};

template <class atype>
class Queue{
    private:  
      atype q[MAX];
      int front;
      int rear;      
    public:
      Queue():front(-1), rear(-1){ }
      void insert()
      {
         atype input;  
         if(rear == MAX-1)
            throw Full();      
         if(front == -1)
            front = 0;
         cout<<"Enter value : ";
         cin>>input;
         q[++rear] = input;      
      }
      void del(){
         if(front == -1 || front>rear ) 
            throw Empty("del()");
         cout<<"delete element : "<<q[front]<<endl;
         front++;            
      }
      void display(){
         int i;  
         if(front == -1 || front>rear)
            throw Empty("display");
         cout<<"queue is below: "<<endl; 
         for(i=front; i<=rear; i++)
            cout<<q[i]<<" ";     
         cout<<endl;            
      }       
};

main(){
     try{  
       Queue<char> q1;
       q1.insert();
       q1.insert();
       //q1.insert();
       //q1.insert();
       //q1.insert();
       q1.display();
       q1.del();
       q1.del();
       q1.del();
     }
     catch(Full){
        cout<<"Exception: Queue is full"<<endl;                   
     }
     catch(Empty e){
        cout<<"Exception: Queue is Empty"<<endl;
        cout<<"Function : "<<e.getString()<<endl;
     }
     
     
     /*
     cout<<"after deleting one value"<<endl;
     q1.del();
     q1.display();
     cout<<"after deleting another value"<<endl;
     q1.del();
     q1.display();       
     cout<<"after deleting third value"<<endl;
     q1.del();
     q1.display();*/
     system("pause");  
}
