/*
 $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; this->h=h1; }

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

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

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



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

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

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

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

template<class T> void Stack<T>:: extend()
{
    int stackSize = top - this->l + 1;
    stackSize = int(1.5*stackSize);
    if (stackSize <= 2) stackSize = 4;

    top = this->l+stackSize-1;
    T* vnew = new T[stackSize];
    if (!vnew)
    {
	cout << "\n*** stack extension failure: l=" <<this->l<< " top=" <<top<< "\n";
	cout.flush(); abort();
    }
    vnew -= this->l;

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

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

template<class T> void Stack<T>:: resize(int newl, int newTop)
{
    this->v += this->l; delete[] this->v;
    this->allocate (newl, newTop);
    top = newTop;
    this->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);
    this->h = newh;
}
//-------------------------------------------------------------------------

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


syntax highlighted by Code2HTML, v. 0.9.1