#pragma once

//===========================================================================//
// File:	 GStack.h														 //
// Project:  gosGml				                                         //
// Contents:																 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 4/10/00   DP     Created													 //
//---------------------------------------------------------------------------//
// Copyright (C) 2000 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//


template<class T> class GStack
{
	public:
		GStack();
		~GStack();
		void Push(T* Obj);
		T* Pop();
		void Clear();

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//Only call anything below here if you care about every clock cycle. There is a complete interface above.                //
		//The interface below is possibly faster, it gives you more control but it takes more work, and you can cause it to fail.//
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



		T* FPop(); //fast but dangerous pop. will crash if stack is empty!
		bool IsEmpty();//true if stack is empty. If you find yourself using this perhaps the above interface is better for you?

	private:
		struct StackNode
		{
			T* Data;
			StackNode* Next;
		};
		StackNode* Top;

		GStack(GStack const &);//don't call this
		GStack& operator= (GStack const &); //don't call the assignment operator
};



template<class T> GStack<T>::GStack():
	Top(NULL)
{
}

template<class T> GStack<T>::~GStack()
{
	Clear();
}

template<class T> void GStack<T>::Clear()
{
	while(Top)
	{
		StackNode* Victim=Top;
		Top=Top->Next;
		delete Victim->Data;
		delete Victim;
	}
}

template<class T> void GStack<T>::Push(T* Obj)
{
	StackNode* Temp=new StackNode;
	Temp->Data=Obj;
	Temp->Next=Top;
	Top=Temp;
}

template<class T> T* GStack<T>::Pop()
{
	if(!Top) return 0;
	StackNode* TopOfStack=Top;
	Top=Top->Next;
	T* Data = TopOfStack->Data;
	delete TopOfStack;
	return Data;
}

template<class T> T* GStack<T>::FPop()
{
	StackNode* TopOfStack=Top;
	Top=Top->Next;
	T* Data = TopOfStack->Data;
	delete TopOfStack;
	return Data;
}

template<class T> bool GStack<T>::IsEmpty()
{
	return (bool)!Top;
}

