#include <_vector.h>
#include <_llist.h>
#include <iostream>
#include <cstdlib>
using namespace std;
 
template <class T>
class baseStack {
public:
  virtual void  clear  () = 0;
  /* Modifica: la pila receptora que pasa a estar vacía. */
  virtual bool  empty  () const = 0;
  /* Produce:  cierto si la pila receptora es vacía.   */
  virtual T      top    () const = 0;
  /* Produce:  el elemento del tope de la pila.
     Error:    si la pila está vacía.                */
  virtual void  push    (const T & value) = 0;
  /* Necesita: un valor de tipo T.
     Modifica: la pila receptora añadiendo el valor
         indicado al tope de la pila.    */
  virtual void  pop    () = 0;
  /* Modifica: la pila receptora suprimiendo el elemento
               situado en el tope de la pila.
     Error:    si la pila está vacía.                    */
};
 
 
//---------------------------------------------------------------------------
//                                                 
//         Definicion de la clase VStack
//                  Pilas basadas en vectores             
//                                               
//---------------------------------------------------------------------------
 
//
// Clase VStack
//  Implementacion de pilas utilizando vectores 
//
 
template <class T>
class VStack : public baseStack<T> {
public:
  // constructores
  explicit VStack  (int size=0);
  VStack          (const VStack<T> & rhs);
  
  // operaciones para pilas
  virtual void   clear  ();
  /* Coste t.: O(1)    */
  virtual bool   empty  () const;
  /* Coste t.: O(1)    */
  virtual T  top    () const;
  /* Coste t.: O(1)    */
  virtual void  push  (const T & value);
  /* Coste t.: O(1), O(n) si se redimensiona.  */
  virtual void  pop    ();
  /* Coste t.: O(1)    */
   
  // asignacion
  VStack<T> & operator =  (const VStack<T> & rhs);
  
  //operaciones adicionales
  int size () const;
  // Produce:  el numero de elementos de la lista. 
  // Coste t.: O(1)
    
protected:
  // area de datos
  sVector<T>  data;
  int  theTop;      // posicion del tope de la pila
  
  //operaciones privadas para el control de errores
  void assertIsEmpty() const;   
};
template <class T>
VStack<T>::VStack
  (int size) : data(size), theTop(-1)
{
  // crea e inicializa una pila
}
 
template <class T>
VStack<T>::VStack (const VStack<T> & rhs)
  : data(rhs.data), theTop(rhs.theTop)
{ 
  // constructor de copia
}
 
template <class T>
void VStack<T>::clear ()
{
  // borra los elementos de una pila
  theTop = -1;
}
 
template <class T>
bool VStack<T>::empty () const
{
  // retorna cierto si la pila no tiene elementos
  return theTop == -1;
}
 
template <class T>
T VStack<T>::top () const
{
  // retorna el elemento del tope de la pila
  assertIsEmpty();
  return data[theTop];
}
 
template <class T>
void VStack<T>::push (const T & value)
{
  // inserta un elemento en la pila
  // si la pila está llena, aumentarla
  if (theTop == data.size()-1)
    data.resize(data.size()*2+1);
  
  data[++theTop] = value;
}
 
template <class T>
void VStack<T>::pop ()
{
  // borra el elemento del tope de la pila
  assertIsEmpty();
  theTop--;
}
 
template <class T>
VStack<T> & VStack<T>::operator = (const VStack<T> & rhs)
{
  // asignacion 
  if( this != &rhs )
  {
    data = rhs.data;
    theTop = rhs.theTop;
  }  
  return *this;
}
 
template <class T>
int VStack<T>::size () const
{
   return theTop+1;
}
 
template <class T>
void VStack<T>::assertIsEmpty( ) const
{
  if ( empty() )
     throw runtime_error("VStack UnderFlow"); 
}    
int main() {
VStack<int> v1;
system("PAUSE");
return 0;
}