/*
 $Id: stack.c,v 1.1 1996/10/10 10:01:26 roitzsch Exp $
 (C)opyright 1996 by Konrad-Zuse-Center, Berlin
 All rights reserved.
 Part of the Kaskade distribution
*/

#include "stack.h"


template<class T> 
Stack<T>:: Stack(int l1, int top1, int h1) 
			   : Vector<T>(l1,top1)  { top=top1; h=h1; }

template<class T>  
Stack<T>:: Stack(int l1, int top1) 
			   : Vector<T>(l1,top1)  { top=top1; h=l1-1; }

template<class T> 
Stack<T>:: Stack(int top1) : Vector<T>(1,top1)   { top=top1; h=0;}

template<class T> 
Stack<T>:: Stack()         : Vector<T>(DefaultSize) { top=DefaultSize; h=0;}



template<class T> void Stack<T>:: push(const T a)
{
    if (h==top) extend();
    v[++h] = a;
}

template<class T> T Stack<T>:: pop()
{
    if (h < l)
    {
	cout << "\n*** pop tried from empty stack \n"; 
        cout.flush(); abort();  return v[l];	// dummy to avoid compiler warnings
    }
    else return v[h--];
}

template<class T> T Stack<T>:: Top() const
{
    if (h < l)
    {
	cout << "\n*** Class Stack (Top): empty stack \n"; 
        cout.flush(); abort();   return v[l];	// dummy to avoid compiler warnings
    }
    else return v[h];
}

template<class T>  T Stack<T>:: Prev() const
{
    if (h <= l)
    {
	cout << "\n*** Class Stack (Prev): only one element on stack \n"; 
        cout.flush(); abort();   return v[l];	// dummy to avoid compiler warnings
    }
    else return v[h-1];
}

template<class T> void Stack<T>:: extend()
{
    int stackSize = top-l+1;
    stackSize = int(1.5*stackSize);
    if (stackSize <= 2) stackSize = 4;
    
    top = l+stackSize-1;
    T* vnew = new T[stackSize];
    if (!vnew) 
    {
	cout << "\n*** stack extension failure: l=" <<l<< " top=" <<top<< "\n";
	cout.flush(); abort();
    }
    vnew -= l;

    for (int i=l; i<=h; ++i) vnew[i] = v[i];
    v = v+l;
    delete [] v;
    v = vnew;

    if (AnnounceExtensionFlag) cout << "\n* Stack extended to " << top << "\n";
}
//-------------------------------------------------------------------------

template<class T> void Stack<T>:: resize(int newl, int newTop)
{
    v += l; delete[] v;
    allocate (newl, newTop);
    top = newTop;
    h = newl-1;
}

template<class T> void Stack<T>:: resize(int newTop) { resize (1,newTop); }

template<class T> void Stack<T>:: resize(int newl, int newTop, int newh)
{
    resize(newl, newTop);
    h = newh;
}
//-------------------------------------------------------------------------

template<class T> Stack<T>:: Stack(Stack<T>& /*vec*/)
{
    notImplemented("Stack:: copy constructor! Check function arguments");
}
