/* * CList.cpp * $Id: CList.cpp,v 1.5 2001/11/15 16:54:51 guenth Exp $ * * Copyright (C) 1999-2001 Michael Meissner * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * As a special exception to the GPL, the QGLViewer authors (Markus * Janich, Michael Meissner, Richard Guenther, Alexander Buck and Thomas * Woerner) give permission to link this program with Qt (non-)commercial * edition, and distribute the resulting executable, without including * the source code for the Qt (non-)commercial edition in the source * distribution. * */ /** documentation stuff @author Michael Meissner @version 0.0 //see cvs docu */ // Own //////// #include "CList.h" // System /////////// //Constructors //////////////// template CList::CList() /******************************/ { init(); } //Constructors //////////////// template CList::CList(const CList &list) { // Initialize init(); // Copy all entries CListContainer *pIterator; if (pIterator = list.getFirst()) { do { insertAsLast(pIterator->getObject()); } while (pIterator = pIterator->getNext()); } } //Destructors //////////////// template CList::~CList() /*******************************/ { //cerr << "CList::~CList: Number of objects is " << getNumObjects() << endl; if (getNumObjects() != 0) clear(); } //////////////////////// // // // Functions of CList // // // //////////////////////// // Function : insertAsFirst // Parameters : ObjectType* pObj // Purpose : Inserts new object at the beginning of the list. // Comments : template int CList::insertAsFirst(ObjectType* pObj) /*********************************************************/ { CListContainer* pTmp; if (!pObj) { #ifdef DEBUGCLIST cout << "No object ( CList::Append)" << endl; #endif return 1; } pTmp = new CListContainer(pObj); // Create new list element if (pTmp == NULL) { cout << "Memory error: Could not allocate memory in heap !" << endl; return 0; } if (getFirst()) { getFirst()->setPrev(pTmp); pTmp->setNext(getFirst()); setFirst(pTmp); #ifdef DEBUGCLIST cout << "Hallo drinnen (if)" << endl; #endif } else { setFirst(pTmp); setLast(pTmp); #ifdef DEBUGCLIST cout << "Hallo drinnen (else)" << endl; #endif } increaseNumObjects(); #ifdef DEBUGCLIST cout << "Hallo fertig" << endl; #endif return 1; } // Function : insertAsLast // Parameters : ObjectType* pObj // Purpose : Appends the object 'pObj' to the end of the list. // Comments : template int CList::insertAsLast(ObjectType* pObj) /********************************************************/ { CListContainer *pTemp; if (!pObj) { #ifdef DEBUGCLIST cout << "No object ( CList::Append)" << endl; #endif return 1; } pTemp = new CListContainer(pObj); // Create new list element if (pTemp == NULL) { cout << "Memory error: Could not allocate memory in heap !" << endl; return 0; } if (getLast()) { getLast()->setNext(pTemp); pTemp->setPrev(getLast()); setLast(pTemp); } else { setFirst(pTemp); setLast(pTemp); } increaseNumObjects(); return 1; } // Function : insertAfter // Parameters : CListContainer *pThere, ObjectType* pObject // Purpose : insert an object after the given container // Comments : template int CList::insertAfter(CListContainer *pThere, ObjectType *pObject) /**************************************************************************/ { #ifdef DEBUGCLIST cout << "CList::insertAfter" << endl; #endif CListContainer *pContainer; if (pThere == getLast()) insertAsLast(pObject); else { pContainer = new CListContainer(pObject); pContainer->setPrev(pThere); pContainer->setNext(pThere->getNext()); pThere->getNext()->setPrev(pContainer); pThere->setNext(pContainer); } increaseNumObjects(); return 1; } // Function : find // Parameters : ObjectType* // Purpose : finds the object in the linekd list // Comments : template CListContainer* CList::find(ObjectType *pObj) const /*************************************************************************/ { #ifdef DEBUGCLIST cout << "CList: find" << endl; #endif CListContainer* pTmp; pTmp = getLast(); while (pTmp) if (pTmp->getObject() == pObj) return pTmp; else pTmp = pTmp->getPrev(); return NULL; } // Function : remove // Parameters : CListContainer *pRemove // Purpose : removes the given element from list // Comments : template int CList::remove(CListContainer *pRemove) /**********************************************************/ { #ifdef DEBUGCLIST cout << "CList: You remove a CListContainer !" << endl; #endif if (pRemove == NULL) { cerr << "# Error, null pointer isn't a container !!! (CList)" << endl; return -1; } CListContainer *pFirst = getFirst(); CListContainer *pLast = getLast(); // update pointers to head and last ///////////////////////////////////// if (pRemove == pFirst) setFirst(pRemove->getNext()); if (pRemove == pLast) setLast(pRemove->getPrev()); // update linked list /////////////////////// // is it a container, not at the end nor at the beginning ? if (pRemove != pFirst && pRemove != pLast) { #ifdef DEBUGCLIST cout << "CList: Remove something not at the border !" << endl; #endif pRemove->getPrev()->setNext(pRemove->getNext()); pRemove->getNext()->setPrev(pRemove->getPrev()); delete pRemove; decreaseNumObjects(); return 1; } // is it the first container but NOT the only one ? if (pRemove == pFirst && pRemove != pLast) { #ifdef DEBUGCLIST cout << "CList: Remove head, is not the only object !" << endl; #endif pRemove->getNext()->setPrev(NULL); delete pRemove; decreaseNumObjects(); return 1; } // is it the last container but NOT the only one and not the first ? if (pRemove == pLast && pRemove != pFirst) { #ifdef DEBUGCLIST cout << "CList: Remove last, is not the only object !" << endl; #endif pRemove->getPrev()->setNext(NULL); delete pRemove; decreaseNumObjects(); return 1; } // is the only object in list #ifdef DEBUGCLIST cout << "CList: element which is head and last !" << endl; #endif delete pRemove; decreaseNumObjects(); return 1; } // Function : remove // Parameters : ObjectType* // Purpose : removes pObj and container from list // Comments : template int CList::remove(ObjectType *pObj) /***************************************************/ { CListContainer* pTmp; pTmp = find(pObj); if (pTmp == NULL) { #ifdef DEBUGCLIST cout << "Object is NOT in list !" << endl; #endif return -1; } return remove(pTmp); } // Function : getFullDuplicate // Parameters : // Purpose : Returns a copy of the list. But this method NOT only copies the // the pointer of the objects as the '=' operator does. No, this // method makes a real memcpy of the list. // Comments : template CList* CList::getFullDuplicate() const /*************************************************/ { CList* pTmpList = new CList; CListContainer *pContainer = getFirst(); while (pContainer) { pTmpList->insertAsLast(new ObjectType(*(pContainer->getObject()))); pContainer = pContainer->getNext(); } return pTmpList; } // Function : clear // Parameters : int nFlag // Purpose : Removes all containers from the list if 'nFlag' = 0 (default). // If 'nFlag' = 1 then also the objects are deleted from the heap. // Comments : template void CList::clear(int nFlag) /*************************************************/ { #ifdef DEBUGCLIST cout << "CList: clear" << endl; #endif switch (nFlag) { case 0: { // remove only the containers CListContainer* pLast; while (pLast = getLast()) remove(pLast); break; } case 1: { // remove containers and delete objects CListContainer* pLast; while (pLast = getLast()) { delete pLast->getObject(); remove(pLast); } break; } default: cerr << "WARNING!! CList::clear(int): Wrong parameter value!" << endl; break; } } // Function : operator[] // Parameters : unsigned int i // Purpose : returns pointer to the object in i-th element in list // Comments : template ObjectType& CList::operator[](int index) const /*****************************************************************/ { CListContainer* pTemp; if (index < 0 || index >= getNumObjects()) throw("CList: Index out of range"); pTemp = getFirst(); for (int j=0; jgetNext(); return *pTemp->m_pObject; } // Function : operator() // Parameters : unsigned int i // Purpose : returns pointer to the i-th element of list // Comments : template CListContainer *CList::operator()(int index) const /*********************************************************************/ { CListContainer* pTemp; if (index < 0 || index >= getNumObjects()) { cerr << "CList: Index out of range (" << index << " )" << endl; return NULL; } pTemp = getFirst(); for (int j=0; jgetNext(); return pTemp; } // Function : operator+ // Parameters : const CList &cSource // Purpose : // Comments : template const CList &CList::operator+(const CList &cSource) /*********************************************************************/ { int i; CListContainer* pTemp; pTemp = cSource.getFirst(); insertAsLast(pTemp->getObject()); for (i=0; igetNext(); insertAsLast(pTemp->getObject()); } return *this; } // Function : operator= // Parameters : const CList &cSource // Purpose : // Comments : template CList &CList::operator=(const CList &cSource) /*********************************************************************/ { // Don't copy a list to itself if (&cSource == this) return *this; // Destruct destination clear(); // Copy all entries CListContainer *pIterator; if (pIterator = cSource.getFirst()) { do { insertAsLast(pIterator->getObject()); } while (pIterator = pIterator->getNext()); } return *this; }