// $Source: /usr/local/SimSoft/SoftShop/Basics/Structur/Stack.h,v $
// $Revision: 1.20 $
// $Author: baum $
// $Date: 2001/11/29 15:52:23 $
//
// Login name of the user who locked the revision
// $Locker:  $
// Tag name used to checkout the file
// $Name: Release-20 $
// State assigned to revision
// $State: Exp $
//
//
// $Log: Stack.h,v $
// Revision 1.20  2001/11/29 15:52:23  baum
// -In Kalender.cpp und Kalender.h Handsteuerung eingebaut
//

#ifndef _STACK_H
#define _STACK_H

#include "SLNode.h"

#if defined __GNUG__ || defined __hpux
#  pragma interface
#endif

//==================================================================
//		Klassen-Header
//		fuer class Stack<T>
//==================================================================

//##ModelId=3FBCBCC40232
template <class T>
class Stack
  {
  public:
    // constructors
	//##ModelId=3FBCBCC40243
    Stack ();
	//##ModelId=3FBCBCC40244
    Stack (const Stack<T>&);
    
    // destructor
	//##ModelId=3FBCBCC40246
    ~Stack ();

    // assignment operator
	//##ModelId=3FBCBCC40247
    Stack<T>& operator = (const Stack<T>&);

    // prepending
	//##ModelId=3FBCBCC40252
    T& push (const T&);

    // removing
	//##ModelId=3FBCBCC40254
    T* pop ();
	//##ModelId=3FBCBCC40261
    void removeAll ();

    // retrieving
	//##ModelId=3FBCBCC40262
    T* Top () const;

    // return non-0 if there are no objects on the Stack, 0 otherwise
	//##ModelId=3FBCBCC40264
    bool isEmpty () const;

    // return the number of objects on the Stack
	//##ModelId=3FBCBCC40266
    unsigned Count () const;

  private:
    // data members
	//##ModelId=3FBCBCC40281
    SLNode<T>* ObjHead;

};	// class Stack

//==================================================================
//		Inline-Quellcode
//		fuer class Stack<T>
//==================================================================

//##ModelId=3FBCBCC40243
template <class T>
inline Stack<T>::Stack () : ObjHead (NULL) { }

//##ModelId=3FBCBCC40244
template <class T>
Stack<T>::Stack (const Stack<T>& s) : ObjHead (NULL) {
  if (!s.ObjHead)  return;
  SLNode<T>* n = ObjHead = new SLNode<T>;
  for (SLNode<T>* m = s.ObjHead; m; m = m->Next)
    n = (new SLNode<T> (m->Object))->link (n);
  pop ();
}

//##ModelId=3FBCBCC40246
template <class T>
Stack<T>::~Stack () {
  while (ObjHead) pop ();
}

//##ModelId=3FBCBCC40247
template <class T>
Stack<T>& Stack<T>::operator = (const Stack<T>& s) {
  while (ObjHead)  pop ();
  if (!s.ObjHead)  return *this;
  SLNode<T>* n = ObjHead = new SLNode<T>;
  for (SLNode<T>* m = s.ObjHead; m; m = m->Next)
    n = (new SLNode<T> (m->Object))->link (n);
  pop ();
  return *this;
}

//##ModelId=3FBCBCC40252
template <class T>
inline T& Stack<T>::push (const T& what) {
  SLNode<T>* n = new SLNode<T> ((T*) &what);
  n->Next = ObjHead;
  return *((ObjHead = n)->Object);
}

//##ModelId=3FBCBCC40254
template <class T>
inline T* Stack<T>::pop () {
  if (!ObjHead) return NULL;
  SLNode<T>* n = ObjHead;
  ObjHead = ObjHead->Next;
  T* retVal = n->Object;
  delete n;
  return retVal;
}

//##ModelId=3FBCBCC40261
template <class T>
void Stack<T>::removeAll () {
  for (SLNode<T>* n; (n = ObjHead) != NULL; ObjHead = ObjHead->Next, delete n);
}

//##ModelId=3FBCBCC40262
template <class T>
inline T* Stack<T>::Top () const {
  return (ObjHead) ? ObjHead->Object : NULL;
}

//##ModelId=3FBCBCC40264
template <class T>
inline bool Stack<T>::isEmpty () const {
 return !ObjHead;
}

//##ModelId=3FBCBCC40266
template <class T>
unsigned Stack<T>::Count () const {
  unsigned count = 0;
  for (SLNode<T>* n = ObjHead; n; n = n->Next)  count++;
  return count;
}

#endif	// !defined _STACK_H

