#ifndef __LIST_H_INCLUDED__ #define __LIST_H_INCLUDED__ //+--------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation, 1999. // // File: list.h // // Contents: Quick 'n dirty basic templated list class. // // History: 04-26-1999 Alan Shi (AlanShi) Created. // //---------------------------------------------------------------------------- // // ListNode // typedef void * LISTNODE; template class ListNode { public: ListNode(Type item); virtual ~ListNode(); void SetNext(ListNode *pNode); void SetPrev(ListNode *pNode); Type GetItem(); ListNode *GetNext(); ListNode *GetPrev(); private: DWORD _dwSig; Type _type; ListNode *_pNext; ListNode *_pPrev; }; // // List // template class List { public: List(); ~List(); LISTNODE AddHead(const Type &item); LISTNODE AddTail(const Type &item); LISTNODE GetHeadPosition(); LISTNODE GetTailPosition(); void RemoveAt(LISTNODE pNode); void RemoveAll(); LISTNODE Find(const Type &item); int GetCount(); Type GetNext(LISTNODE &pNode); Type GetAt(LISTNODE pNode); LISTNODE AddSorted(const Type &item, LPVOID pfn); public: DWORD _dwSig; private: ListNode *_pHead; ListNode *_pTail; int _iCount; }; // // ListNode Implementation // template ListNode::ListNode(Type item) : _pNext(NULL) , _pPrev(NULL) , _type(item) { _dwSig = 'EDON'; } template ListNode::~ListNode() { } template void ListNode::SetNext(ListNode *pNode) { _pNext = pNode; } template void ListNode::SetPrev(ListNode *pNode) { _pPrev = pNode; } template Type ListNode::GetItem() { return _type; } template ListNode *ListNode::GetNext() { return _pNext; } template ListNode *ListNode::GetPrev() { return _pPrev; } // // List Implementation // template List::List() : _pHead(NULL) , _pTail(NULL) , _iCount(0) { _dwSig = 'TSIL'; } template List::~List() { RemoveAll(); } template LISTNODE List::AddHead(const Type &item) { ListNode *pNode = NULL; pNode = new ListNode(item); if (pNode) { _iCount++; pNode->SetNext(_pHead); pNode->SetPrev(NULL); if (_pHead == NULL) { _pTail = pNode; } else { _pHead->SetPrev(pNode); } _pHead = pNode; } return (LISTNODE)pNode; } template LISTNODE List::AddSorted(const Type &item, LPVOID pfn) { ListNode *pNode = NULL; LISTNODE pCurrNode = NULL; LISTNODE pPrevNode = NULL; int i; Type curItem; LONG (*pFN) (const Type item1, const Type item2); pFN = (LONG (*) (const Type item1, const Type item2))pfn; if(_pHead == NULL) { return AddHead(item); } else { pCurrNode = GetHeadPosition(); curItem = ((ListNode *) pCurrNode)->GetItem(); for (i = 0; i < _iCount; i++) { if (pFN(item, curItem) < 1) { pNode = new(ListNode(item)); pNode->SetPrev((ListNode *)pPrevNode); pNode->SetNext((ListNode *)pCurrNode); if(pPrevNode) { ((ListNode *)pPrevNode)->SetNext(pNode); } else { _pHead = pNode; } _iCount++; break; } pPrevNode = pCurrNode; curItem = GetNext(pCurrNode); if(i+1 == _iCount) return AddTail(item); } } return (LISTNODE)pNode; } template LISTNODE List::AddTail(const Type &item) { ListNode *pNode = NULL; pNode = new ListNode(item); if (pNode) { _iCount++; if (_pTail) { pNode->SetPrev(_pTail); _pTail->SetNext(pNode); _pTail = pNode; } else { _pHead = _pTail = pNode; } } return (LISTNODE)pNode; } template int List::GetCount() { return _iCount; } template LISTNODE List::GetHeadPosition() { return (LISTNODE)_pHead; } template LISTNODE List::GetTailPosition() { return (LISTNODE)_pTail; } template Type List::GetNext(LISTNODE &pNode) { Type item; ListNode *pListNode = (ListNode *)pNode; // Faults if you pass NULL item = pListNode->GetItem(); pNode = (LISTNODE)(pListNode->GetNext()); return item; } template void List::RemoveAll() { int i; LISTNODE listNode = NULL; ListNode *pDelNode = NULL; listNode = GetHeadPosition(); for (i = 0; i < _iCount; i++) { pDelNode = (ListNode *)listNode; GetNext(listNode); delete pDelNode; } _iCount = 0; _pHead = NULL; _pTail = NULL; } template void List::RemoveAt(LISTNODE pNode) { ListNode *pListNode = (ListNode *)pNode; ListNode *pPrevNode = NULL; ListNode *pNextNode = NULL; if (pNode) { pPrevNode = pListNode->GetPrev(); pNextNode = pListNode->GetNext(); if (pPrevNode) { pPrevNode->SetNext(pNextNode); if (pNextNode) { pNextNode->SetPrev(pPrevNode); } else { // We're removing the last node, so we have a new tail _pTail = pPrevNode; } delete pNode; pNode = NULL; } else { // No previous, so we are the head of the list _pHead = pNextNode; if (pNextNode) { pNextNode->SetPrev(NULL); } else { // No previous, or next. There was only one node. _pHead = NULL; _pTail = NULL; } delete pNode; } _iCount--; } } template LISTNODE List::Find(const Type &item) { int i; Type curItem; LISTNODE pNode = NULL; LISTNODE pMatchNode = NULL; ListNode * pListNode = NULL; pNode = GetHeadPosition(); for (i = 0; i < _iCount; i++) { pListNode = (ListNode *)pNode; curItem = GetNext(pNode); if (curItem == item) { pMatchNode = (LISTNODE)pListNode; break; } } return pMatchNode; } template Type List::GetAt(LISTNODE pNode) { ListNode *pListNode = (ListNode *)pNode; // Faults if pListNode == NULL return pListNode->GetItem(); } #endif