Source: CList.cc
//////////////////////////////////////////////////////////////////////
//
//  LISTENKLASSE "CList" - Implementierung
//
//  Datei:      CList.cc
//  Autor:	Torben Nehmer <Torben.Nehmer@gmx.net>
//  
//////////////////////////////////////////////////////////////////////
#include <stdio.h>
//////////////////////////////////////////////////////////////////////
// Konstruktion / Destruktion
//
template <class T>
CList<T>::CList()
{
  // Standardkonstruktor initialisiert m_pFirst auf leere Liste
    m_pFirst = NULL;
}
template <class T>
CList<T>::~CList()
{
  // Destruktor entfernd noch vorhandende Speicherobjekte. Es werden
  // jedoch NICHT die gespeicherten Objekte geloescht.
    if (!IsEmpty())
    {
        CElement * pTemp = m_pFirst;
        CElement * pDel;
        while (pTemp)
        {
            pDel = pTemp;
            pTemp = pTemp->GetNext();
            delete pDel;
        }
    }
}
//////////////////////////////////////////////////////////////////////
//  Zugriffs - Funktionen
//
template <class T>
void CList<T>::AddData(T pData)
{
  // Fuegt einen neuen Listeneintrag am Ende der Liste ein.
    if (IsEmpty())
        m_pFirst = new CElement(NULL, pData);
    else
    {
        CElement * pLast = m_pFirst;
        while (pLast->GetNext())
            pLast = pLast->GetNext();
        pLast->SetNext(new CElement(NULL, pData));
    }
}
template <class T>
int CList<T>::GetData (int iPos, T & pResult) const
{
  // Liefert den Datensatz an der Stelle iPos zurueck, wobei die
  // Indizierung mit 1 beginnt.
  // Der gespeicherte Zeiger wird in pResult zurueckgeliefert.
  // Die Funktion selbst liefert TRUE (nonzero), falls der Aufruf
  // erfolgreich war.
    CElement * pElement = GetElement (iPos);
    if (pElement)
      {
	pResult = pElement->GetData();
	return 1;
      }
    else
      return 0;
}
template <class T>
int CList<T>::RemoveData (int iPos, T & pResult)
{
  // Liefert den Datensatz an der Stelle iPos zurueck, wobei die
  // Indizierung mit 1 beginnt. Der betroffene Eintrag wird aus
  // der Liste entfernt.
  // Der gespeicherte Zeiger wird in pResult zurueckgeliefert.
  // Die Funktion selbst liefert TRUE (nonzero), falls der Aufruf
  // erfolgreich war.
    CElement * pDel = GetElement (iPos);
    if (!pDel)
        return 0;
    if (iPos == 1)
        m_pFirst = pDel->GetNext();
    else
    {
        CElement * pPrev = GetElement (iPos - 1);
        pPrev->SetNext(pDel->GetNext());
    }
    pResult = pDel->GetData();
    delete pDel;
    return 1;
}
//////////////////////////////////////////////////////////////////////
//  Statusabfrage - Funktionen
//
template <class T>
inline int CList<T>::IsEmpty () const
{
  // Liefert TRUE (nonzero), wenn KEINE Elemente in der Liste 
  // vorhanden sind.
    return (!m_pFirst) ? 1 : 0;
}
//////////////////////////////////////////////////////////////////////
//  Private Hilfsfunktionen
//
template <class T>
CList<T>::CElement * CList<T>::GetElement(int iPos) const
{
  // Private Hilfsfunktion, die versucht, den Listeneintrag an der 
  // Stelle iPos zurueckzuliefern. Existiert ein solches Element,
  // wird der CElement Pointer darauf zurueckgegeben, ansonsten der
  // NULL Pointer.
    if (!m_pFirst || iPos < 1)
        return NULL;
    CElement * pTemp = m_pFirst;
    
    for (int i = 1; i < iPos; i++)
    {
        if (!pTemp->GetNext())
            return NULL;
        pTemp = pTemp->GetNext();
    }
    return pTemp;    
}
//////////////////////////////////////////////////////////////////////
//  Debug Funktionen
//
#ifdef _DEBUG
#include <iostream.h>
template <class T>
void CList<T>::Dump() const
{
  // DEBUG Funktion, mit deren Hilfe sich der Inhalt des Objektes 
  // MIT Speicheradressen nach COUT ausgegeben werden kann. Die 
  // gespeicherten Objekte muessen deshalb ueber einen definierten
  // Stream Output Operator verfuegen.
    CElement * pTemp;
    cout << "*** DEBUG - Ausgabe Objekt CList in " << this << endl;
    if (!IsEmpty())
    {
        pTemp = m_pFirst;
        int i = 1;
        while (pTemp)
        {
            cout << "  Element " << i++ << " at " << pTemp << " contains " 
                << *((T) pTemp->GetData()) << endl;
            pTemp = pTemp->GetNext();
        }
        cout << "*** DEBUG Ausgabe abgeschlossen\n";
    }
    else
        cout << "Keine Elemente vorhanden!\n*** DEBUG Ausgabe abgeschlossen!\n";
}
#endif _DEBUG
//////////////////////////////////////////////////////////////////////
//  Implementierung Hilfsklasse CList::CElement
//  und deren Zugriffsfunktionen
//
template <class T>
CList<T>::CElement::CElement ( CElement * pNext, T pData)
  : m_pNext(pNext), m_pData(pData)
{
}
template <class T>
CList<T>::CElement * CList<T>::CElement::GetNext () const
{
  return m_pNext;
}
template <class T>
void CList<T>::CElement::SetNext ( CElement * pNext )
{
  m_pNext = pNext;
}
template <class T>
T CList<T>::CElement::GetData() const
{
  return m_pData;
}
template <class T>
void CList<T>::CElement::SetData (T data)
{
  m_pData = data;
}