//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (c) 1998-1998 Microsoft Corporation // // File: tlist.cpp // //-------------------------------------------------------------------------- // // tlist.cpp // //#include "stdafx.h" #include "tlist.h" template TListItem::~TListItem() { //if (m_pNext != NULL) { delete m_pNext; } // IMPORTANT: user of the list is required to delete content first! //ZeroMemory(&m_Tinfo, sizeof(T)); } template void TListItem::Delete(TListItem* pFirst) { TListItem* pScan = pFirst; TListItem* pNext = NULL; while (pScan) { pNext = pScan->m_pNext; delete pScan; pScan = pNext; } } template LONG TListItem::GetCount(void) const { LONG l; const TListItem *li; for(l=0,li=this; li!=NULL ; li=li->m_pNext,++l); return l; } template TListItem* TListItem::Cat(TListItem *pItem) { TListItem *li; if(this==NULL) return pItem; for(li=this ; li->m_pNext!=NULL ; li=li->m_pNext); li->m_pNext=pItem; return this; } template TListItem* TListItem::Remove(TListItem *pItem) { TListItem *li,*prev; if(pItem==this) return m_pNext; prev=NULL; for(li=this; li!=NULL && li!=pItem ; li=li->m_pNext) prev=li; if(li==NULL) // item not found in list return this; // here it is guaranteed that prev is non-NULL since we checked for // that condition at the very beginning prev->SetNext(li->m_pNext); li->SetNext(NULL); return this; } template TListItem* TListItem::GetPrev(TListItem *pItem) const { const TListItem *li,*prev; prev=NULL; for(li=this ; li!=NULL && li!=pItem ; li=li->m_pNext) prev=li; return (TListItem*)prev; } template TListItem * TListItem::GetItem(LONG index) { TListItem *scan; for (scan = this; scan!=NULL && index; scan = scan->m_pNext) { index--; } return (scan); } template TListItem* TListItem::MergeSort(BOOL (* fcnCompare) (T&, T&)) { if (m_pNext != NULL) { TListItem *pList1, *pList2; Divide(pList1, pList2); return pList1->MergeSort(fcnCompare)->Merge(pList2->MergeSort(fcnCompare), fcnCompare); } return this; } template void TListItem::Divide(TListItem*& pHead1, TListItem*& pHead2) { TListItem *pCurrent = this, *pTail1 = NULL, *pTail2 = NULL; do { pHead1 = pCurrent; pCurrent = pCurrent->m_pNext; pHead1->m_pNext = pTail1; pTail1 = pHead1; if (pCurrent != NULL) { pHead2 = pCurrent; pCurrent = pCurrent->m_pNext; pHead2->m_pNext = pTail2; pTail2 = pHead2; } } while (pCurrent != NULL); } template TListItem* TListItem::Merge(TListItem* pOtherList, BOOL (* fcnCompare) (T&, T&)) { if (!pOtherList) return this; TListItem *pThisList = this, *pResultHead = NULL, *pResultTail = NULL, *pMergeItem = NULL; while (pThisList && pOtherList) { if ( fcnCompare(pThisList->m_Tinfo, pOtherList->m_Tinfo) ) { pMergeItem = pThisList; pThisList = pThisList->GetNext(); } else { pMergeItem = pOtherList; pOtherList = pOtherList->GetNext(); } pMergeItem->SetNext(NULL); if (!pResultTail) { pResultHead = pResultTail = pMergeItem; } else { pResultTail->SetNext(pMergeItem); pResultTail = pMergeItem; } } if (pThisList) pResultTail->SetNext(pThisList); else pResultTail->SetNext(pOtherList); return pResultHead; } template void TList::InsertBefore(TListItem *pItem,TListItem *pInsert) { TListItem *prev = GetPrev(pItem); pInsert->SetNext(pItem); if (prev) prev->SetNext(pInsert); else m_pHead = pInsert; } template void TList::AddTail(TListItem *pItem) { m_pHead = m_pHead->AddTail(pItem); } template void TList::MergeSort(BOOL (* fcnCompare) (T&, T&)) { if (m_pHead != NULL && m_pHead->GetNext() != NULL) m_pHead = m_pHead->MergeSort(fcnCompare); } template void TList::Reverse(void) { if( m_pHead ) { TListItem* pNewHead = m_pHead; TListItem* pNext = m_pHead->GetNext(); pNewHead->SetNext(NULL); for( m_pHead = pNext; m_pHead; m_pHead = pNext ) { pNext = m_pHead->GetNext(); m_pHead->SetNext(pNewHead); pNewHead = m_pHead; } m_pHead = pNewHead; } } template HRESULT TList::Copy(TList& rList) { HRESULT hr = S_OK; TListItem* pScan = m_pHead; for (; pScan; pScan = pScan->GetNext()) { T& rScan = pScan->GetItemValue(); TListItem* pNew = new TListItem(rScan); if (pNew) { rList.AddHead(pNew); } else { hr = E_OUTOFMEMORY; break; } } if (SUCCEEDED(hr)) { rList.Reverse(); } return hr; }