#ifndef _STACK_H_
#define _STACK_H_

template <class T> class Stack {
public:
  Stack(int);
  ~Stack();
  
  void push(T);
  T pop(void);
  int size(void);
  
  class BadMemory {};
  class UnderFlow {};
  class OverFlow {};

private:
  int maxsize;
  int top;
  T *st;
};

template <class T> 
Stack<T>::Stack(int ss)
  : top(-1), maxsize(ss)
{
  st = new T[ss];
  if(st == NULL)
    throw BadMemory();
}

template <class T>
Stack<T>::~Stack()
{
  if(st == NULL)
    throw BadMemory();
  delete[] st;
}

template <class T> 
void Stack<T>::push(T i)
{
  if(size() == maxsize)
    throw OverFlow();
    
  st[++top] = i;
}

template <class T> 
T Stack<T>::pop(void)
{
  if(size() == 0)
    throw UnderFlow();
  return(st[top--]);
}

template <class T> 
int Stack<T>::size(void)
{
  return(top + 1);
}

#endif

