// $Source: /usr/local/SimSoft/SoftShop/Basics/Structur/Queue.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: Queue.h,v $
// Revision 1.20  2001/11/29 15:52:23  baum
// -In Kalender.cpp und Kalender.h Handsteuerung eingebaut
//

#ifndef _QUEUE_H
#define _QUEUE_H

#include "SLNode.h"

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

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

//##ModelId=3FBCBCC402DE
template <class T>
class Queue
  {
  public:
    // constructors
	//##ModelId=3FBCBCC402EF
    Queue ();
	//##ModelId=3FBCBCC402F0
    Queue (const Queue<T>&);

    // destructor
	//##ModelId=3FBCBCC402F2
    ~Queue ();

    // assignment operator
	//##ModelId=3FBCBCC402FD
    Queue<T>& operator = (const Queue<T>&);

    // appending
	//##ModelId=3FBCBCC402FF
    T& append (const T& what);

    // removing first object in Queue
	//##ModelId=3FBCBCC40301
    T* remove ();
	//##ModelId=3FBCBCC4030D
    void removeAll ();

    // retrieving
	//##ModelId=3FBCBCC4030E
    T* First () const;

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

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

  private:
    // data members
	//##ModelId=3FBCBCC40320
    SLNode<T>* ObjHead;
	//##ModelId=3FBCBCC4032D
    SLNode<T>* ObjTail;
    
};	// class Queue

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

//##ModelId=3FBCBCC402EF
template<class T>
inline Queue<T>::Queue () : ObjHead (NULL), ObjTail (NULL) { }

//##ModelId=3FBCBCC402F0
template<class T>
Queue<T>::Queue (const Queue<T>& q) : ObjHead (NULL), ObjTail (NULL) {
  for (SLNode<T>* n = q.ObjHead; n; n = n->Next)  append (*n->Object);
}

//##ModelId=3FBCBCC402F2
template<class T>
Queue<T>::~Queue () {
  for (SLNode<T>* n; (n = ObjHead) != NULL; ObjHead = ObjHead->Next, delete n);
}

//##ModelId=3FBCBCC402FD
template<class T>
Queue<T>& Queue<T>::operator = (const Queue<T>& q) {
  SLNode<T>* n;
  for ( ; (n = ObjHead) != NULL; ObjHead = ObjHead->Next, delete n);
  for (n = q.ObjHead; n; n = n->Next)  append (*n->Object);
  return *this;
}

//##ModelId=3FBCBCC402FF
template<class T>
inline T& Queue<T>::append (const T& what) {
  SLNode<T>* n = new SLNode<T> ((T*) &what);
  return *(ObjTail = (ObjHead) ? n->link (ObjTail) : (ObjHead = n))->Object;
}

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

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

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

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

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

#endif	// !defined _QUEUE_H
