// // File: list.h // // Description: // This file contains codes for a linked list template that // can be used as a stack or a queue. // // History: // Mar 5, 1997 jfink Created file. // Jan 7, 1998 jfink Added Empty method. // #ifndef _LIST_H_ #define _LIST_H_ #include "base.h" template class FListIterator { public: virtual void OnIterate(TElement* pElement, DWORD dw, void* pv) = 0; } ; template class FList : public CBase { protected: TElement *mpHead, *mpTail; DWORD mcElements; public: FList(); virtual ~FList(); DWORD Length(); VOID Enqueue(TElement *pElement); TElement *Dequeue(); VOID Push(TElement *pElement); TElement *Pop(); TElement *Find(const TElement &Element); TElement *Find(TElement *pStart, const TElement &Element); TElement *Remove(const TElement &Element); TElement *Remove(TElement *pELement); void Iterate(FListIterator* pIterator, DWORD dw, void* pv); VOID Empty(); } ; template FList::FList() : CBase() { mpHead = mpTail = NULL; mcElements = 0; } template FList::~FList() { this->Empty(); } template DWORD FList::Length() { return(mcElements); } template VOID FList::Enqueue(TElement *pElement) { this->Lock(); if (NULL == mpHead) mpHead = pElement; else mpTail->mpNext = pElement; mpTail = pElement; pElement->mpNext = NULL; mcElements++; this->Unlock(); } template TElement *FList::Dequeue() { TElement *pTemp; this->Lock(); pTemp = mpHead; if (NULL != mpHead) { mpHead = mpHead->mpNext; pTemp->mpNext = NULL; mcElements--; } else mpTail = NULL; this->Unlock(); return(pTemp); } template VOID FList::Iterate(FListIterator* pIterator, DWORD dw, void* pv) { if (!pIterator) return; this->Lock(); for (TElement* pTemp = mpHead; NULL != pTemp; pTemp = pTemp->mpNext) { pIterator->OnIterate(pTemp, dw, pv); } this->Unlock(); } template VOID FList::Push(TElement *pElement) { if (pElement) { this->Lock(); if (NULL == mpHead) mpTail = pElement; pElement->mpNext = mpHead; mpHead = pElement; mcElements++; this->Unlock(); } } template TElement *FList::Pop() { return(this->Dequeue()); } // // Find the element in the list, starting a pStart, whose contents // match Element. // template TElement *FList::Find(TElement *pStart, const TElement &Element) { TElement *pLoop; this->Lock(); for(pLoop = pStart; NULL != pLoop; pLoop = pLoop->mpNext) { if (pLoop->Find(Element)) break; } this->Unlock(); return(pLoop); } // // Find the element in the list, starting at the head, whose contents // match Element. // template TElement *FList::Find(const TElement &Element) { return(this->Find(mpHead, Element)); } // // Remove the element from the list whose contents match // Element. // template TElement *FList::Remove(const TElement &Element) { TElement *pLoop, *pPrev; this->Lock(); for(pPrev = NULL, pLoop = mpHead; NULL != pLoop; pPrev = pLoop, pLoop = pLoop->mpNext) { if (*pLoop == Element) { // // Remove the node from the list. // if (pLoop == mpHead) mpHead = pLoop->mpNext; else pPrev->mpNext = pLoop->mpNext; if (pLoop == mpTail) mpTail = pPrev; pLoop->mpNext = NULL; mcElements--; break; } } this->Unlock(); return(pLoop); } // // Remove the element from the list whose pointer matches // pElement. // template TElement *FList::Remove(TElement * pElement) { TElement *pLoop, *pPrev; this->Lock(); for(pPrev = NULL, pLoop = mpHead; NULL != pLoop; pPrev = pLoop, pLoop = pLoop->mpNext) { if (pLoop == pElement) { // // Remove the node from the list. // if (pLoop == mpHead) mpHead = pLoop->mpNext; else pPrev->mpNext = pLoop->mpNext; if (pLoop == mpTail) mpTail = pPrev; pLoop->mpNext = NULL; mcElements--; break; } } this->Unlock(); return(pLoop); } template VOID FList::Empty() { TElement *pElement; this->Lock(); while(pElement = this->Pop()) { delete pElement; } this->Unlock(); } #endif