//
// stack.h
// General-purpose stack template class
// F.J. Alberti
// 30/04/2001
//

#ifndef SCOL_STACK_H
#define SCOL_STACK_H


#include "base.h"
//#include "except.h"


template <class T> class Stack {
public:
  Stack(uint __capacity);
  ~Stack();
  
  void push(const T& x);
  const T& pop();
  void dropAll();
  const T& top() const;
  uint capacity() const;
  uint size() const;
  bool empty() const;
  bool full() const;

private:
  uint _capacity;  // Stack capacity
  T*   _beg;       // Pointer to stack base
  T*   _top;       // Pointer to stack top
};


template <class T> Stack<T>::Stack(uint __capacity)
  : _capacity(__capacity)
{
  _beg = new T[_capacity];
// if (_beg == 0)
//   throw Exception("Stack: Memory full");
  _top = _beg-1;
}


template <class T> Stack<T>::~Stack()
{
  delete [] _beg;
}


template <class T> void Stack<T>::push(const T& x)
{
// if (_top == _beg+_capacity-1)
//   throw Exception("Stack: overflow"); 
  *++_top = x; 
}


template <class T> const T& Stack<T>::pop()
{
// if (_top < _beg)
//   throw Exception("Stack: underflow");
  return *_top--;
}


template <class T> void Stack<T>::dropAll()
{
  _top = _beg-1;
}


template <class T> const T& Stack<T>::top() const
{
  return *_top;
}


template <class T> uint Stack<T>::capacity() const
{
  return _capacity;
}


template <class T> uint Stack<T>::size() const
{
  return _top-_beg+1;
}


template <class T> bool Stack<T>::empty() const
{
  return _top < _beg;
}


template <class T> bool Stack<T>::full() const
{
  return size() == capacity();
}


#endif // stack.h