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

#ifndef _DEQUE_H
#define _DEQUE_H

#include "DLNode.h"

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

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

//##ModelId=3FBCBCC701E4
template <class T>
class Deque
  {
  public:
    // constructors
	//##ModelId=3FBCBCC701E6
    Deque ();
	//##ModelId=3FBCBCC701F4
    Deque (const Deque<T>&);

    // destructor
	//##ModelId=3FBCBCC701F6
    ~Deque ();

    // assignment operator
	//##ModelId=3FBCBCC701F7
    Deque<T>& operator = (const Deque<T>&);

    // inserting
	//##ModelId=3FBCBCC701F9
    T& prepend (const T& what);
	//##ModelId=3FBCBCC70204
    T& append (const T& what);

    // removing
	//##ModelId=3FBCBCC70206
    T* removeFirst ();
	//##ModelId=3FBCBCC70213
    T* removeLast  ();
	//##ModelId=3FBCBCC70214
    void removeAll ();

    // retrieving
	//##ModelId=3FBCBCC70215
    T* First () const;
	//##ModelId=3FBCBCC70222
    T* Last () const;

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

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

  private:
    // data members
	//##ModelId=3FBCBCC70233
    DLNode<T>* ObjHead;
	//##ModelId=3FBCBCC70243
    DLNode<T>* ObjTail;
    
};	// class Deque

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

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

//##ModelId=3FBCBCC701F4
template <class T>
Deque<T>::Deque (const Deque<T>& d) : ObjHead (NULL), ObjTail (NULL) {
  for (DLNode<T>* n = d.ObjHead; n; n = n->Next)  append (*n->Object);
}

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

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

//##ModelId=3FBCBCC701F9
template <class T>
inline T& Deque<T>::prepend (const T& what) {
  DLNode<T>* n = new DLNode<T> ((T*) &what);
  return *(ObjHead = (ObjHead) ? n->prelink (ObjHead) : (ObjTail = n))->Object;
}

//##ModelId=3FBCBCC70204
template <class T>
inline T& Deque<T>::append (const T& what) {
  DLNode<T>* n = new DLNode<T> ((T*) &what);
  return *(ObjTail = (ObjHead) ? n->postlink (ObjTail) : (ObjHead = n))->Object;
}

//##ModelId=3FBCBCC70206
template <class T>
inline T* Deque<T>::removeFirst () {
  if (!ObjHead)  return NULL;
  DLNode<T>* n = ObjHead;
  if ((ObjHead = ObjHead->Next) == NULL)  ObjTail = NULL;
  T* retVal = n->Object;
  delete n->unlink ();
  return retVal;
}

//##ModelId=3FBCBCC70213
template <class T>
inline T* Deque<T>::removeLast () {
  if (!ObjHead)  return NULL;
  DLNode<T>* n = ObjTail;
  if ((ObjTail = ObjTail->Prev) == NULL)  ObjHead = NULL;
  T* retVal = n->Object;
  delete n->unlink ();
  return retVal;
}

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

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

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

//##ModelId=3FBCBCC70222
template <class T>
inline T* Deque<T>::Last () const {
  return (ObjTail) ? ObjTail->Object : NULL;
}

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

#endif	// !defined _DEQUE_H
