16 #define ListFunc_Internal // Includes internal defines (currently unused) 22 #if (defined(_DEBUG) && defined(_WIN32) && defined(_MSC_VER)) 35 static bool IsBadRWPtr( PVOID Addr, UINT Len )
37 BOOL isBad = IsBadReadPtr( Addr, Len );
38 if (!isBad) isBad = IsBadWritePtr( Addr, Len );
46 #define _F(s) _T("[%s] ") _T(s), __FUNCTION__ 48 #define dimof(x) (sizeof(x)/sizeof(x[0])) 50 static void __cdecl
DPrint( UINT Lv, PCTSTR Txt, ... )
56 #pragma warning( disable: 4996 ) 57 _vsntprintf( szBuf,
dimof(szBuf), Txt, va );
58 #pragma warning( default: 4996 ) 60 OutputDebugString( szBuf );
80 _grabList( ListHead );
107 Entry->Flink =
Flink;
109 Flink->Blink = Entry;
110 this->
Flink = Entry;
125 LastEntry->Flink =
this;
126 FirstEntry->Blink =
Blink;
127 Blink->Flink = FirstEntry;
131 for(
PLIST_ENTRY Entry = FirstEntry; Entry !=
this; nrAdded++, Entry = Entry->Flink );
135 if (ppFirst) *ppFirst = FirstEntry;
141 ListToAppend->Count = 0;
149 #if DBG_LIST // Do some sanity check on behalf of the caller.. 161 static const void* _TAG = (
void*) 0xfeeefeeefeeefeee;
163 static const void* _TAG = (
void*) 0xfeeefeee;
165 bool deleted = (Entry == _TAG);
166 if (!deleted) deleted = (Entry->Flink == _TAG) || (Entry->Blink == _TAG);
176 while( Item !=
this )
178 if (Item == Entry)
return true;
183 __notFound: ((void)0);
196 next = Current->Flink;
197 if (next ==
this) next =
Flink;
207 next = Current->Blink;
208 if (next ==
this) next =
Blink;
222 _Blink->Flink = _Flink;
223 _Flink->Blink = _Blink;
243 if (ItemAction)
while(
Flink !=
this )
247 #else // Retain the entry for which the callback returned false. 260 if ( !ItemAction( item, UserData ))
280 for(
PLIST_ENTRY Entry =
Flink; Entry !=
this; Entry = Entry->Flink, Index-- )
281 if (Index == 0)
return Entry;
292 while( Entry !=
this )
295 if (Match( Entry, UserData ))
return Entry;
307 while( Entry !=
this )
310 if (Match( Entry, UserData ))
return Entry;
321 while( Entry !=
this )
324 if (!Action( Entry, UserData ))
return false;
341 void DLinkList::_qsortRecursion(
348 if ((*ppHead !=
this) && (*ppTail !=
this) && (*ppHead != *ppTail))
350 _qsortPartition( ppHead, ppTail, Compare, Context );
351 _qsortRecursion( ppHead, &(pPivot->Blink), Compare, Context );
352 _qsortRecursion( &(pPivot->Flink), ppTail, Compare, Context );
356 if (pPivot->Blink !=
this)
357 pPivot->Blink->Flink = pPivot;
359 if (pPivot->Flink !=
this)
360 pPivot->Flink->Blink = pPivot;
364 void DLinkList::_qsortPartition(
373 while( pCurr != pPivot )
375 int cmp = Compare( pCurr, pPivot, Context );
378 if (pCurr->Blink !=
this)
379 pCurr->Blink->Flink = pCurr->Flink;
381 if (pCurr->Flink !=
this)
382 pCurr->Flink->Blink = pCurr->Blink;
385 pCurr = pCurr->Flink;
386 if (pCurr->Blink ==
this)
389 pNewTail->Blink = *ppTail;
390 pNewTail->Flink =
this;
391 (*ppTail)->Flink = pNewTail;
395 pCurr = pCurr->Flink;
398 if (pPivot->Blink !=
this)
399 pPivot->Blink->Flink =
this;
401 if (pPivot->Flink !=
this)
402 pPivot->Flink->Blink =
this;
411 _grabList( SrcListHead );
421 Flink = ListHead->Flink;
422 Blink = ListHead->Blink;
428 for(
Count = 0; Entry !=
this;
Count++, Entry = Entry->Flink );
436 ListHead->Flink =
Flink;
437 ListHead->Blink =
Blink;
438 ListHead->Blink->Flink = ListHead->Flink->Blink = ListHead;
454 _grabList( ListHead );
455 if (ppFirst) *ppFirst =
Flink;
468 *Target = FirstEntry;
489 LastEntry->Flink =
this;
490 FirstEntry->Blink =
Blink;
491 Blink->Flink = FirstEntry;
495 for( Entry = FirstEntry; Entry !=
this; nrAdded++, Entry = Entry->Flink );
497 if (ppFirst) *ppFirst = FirstEntry;
506 #define SLIST_SPEEDY 0 510 #if SEMICIRCULAR_SLIST // Work in progress.. 511 return (
Next ==
this);
513 return (
Next == NULL);
527 #else // Call "transmutable" C function 545 #else // Call "transmutable" C function 565 while (item->Next != NULL)
569 Entry->Next = item->Next;
579 if (!Entry ||
IsEmpty())
return NULL;
583 while( Item != Entry )
587 if (!Item)
return NULL;
590 Prev->Next = Item->Next;
599 if (Index == 0)
return Entry;
607 else while(
Next != NULL )
608 if (!ItemAction(
PopEntry(), UserData ))
break;
616 while( Entry != NULL )
619 if (Match( Entry, UserData ))
return Entry;
631 while( Entry != NULL )
634 if (!Action( Entry, UserData ))
return false;
PLIST_ENTRY FirstThat(PDListFunc Match, void *UserData=NULL)
UINT ExportToListHead(PLIST_ENTRY ListHead)
bool(__stdcall * PSListFunc)(PSINGLE_LIST_ENTRY Entry, void *UserData)
UINT ImportFromListHead(IN PLIST_ENTRY ListHead, OPTOUT PLIST_ENTRY *ppFirst)
PLIST_ENTRY LastThat(PDListFunc Match, void *UserData=NULL)
PLIST_ENTRY operator [](size_t Index)
void _InitializeEntryList(PSINGLE_LIST_ENTRY EntryOrHead)
UINT ImportHeadlessList(IN PLIST_ENTRY Circular, OPTOUT PLIST_ENTRY *ppFirst)
bool Exist(PLIST_ENTRY Entry)
bool ForEach(PDListFunc Action, void *UserData=NULL)
void __cdecl DPrint(int Level, CSTR Fmt,...)
UINT AppendList(IN PLIST_ENTRY ListToAppend, OPTOUT PLIST_ENTRY *ppFirst)
struct _LIST_ENTRY * PLIST_ENTRY
bool(__stdcall * PDListFunc)(PLIST_ENTRY Entry, void *UserData)
DLinkList(bool Safe=true)
#define UnlinkListEntry(E)
PLIST_ENTRY GetNext(PLIST_ENTRY Current)
void _PushEntryList(PSINGLE_LIST_ENTRY ListHead, PSINGLE_LIST_ENTRY Entry)
PDLinkList operator=(PLIST_ENTRY ListHead)
bool ForEach(PSListFunc Action, void *UserData=NULL)
PLIST_ENTRY Prepend(PLIST_ENTRY Entry)
BOOL(WINAPI *SysImgList::Shell_GetImageLists)(HIMAGELIST *pimlLarge
void RemoveAll(PSListFunc ItemAction, void *UserData=NULL)
PLIST_ENTRY Append(PLIST_ENTRY Entry)
int(__stdcall * PDListComp)(PLIST_ENTRY X, PLIST_ENTRY Y, void *UserData)
void _InitializeListHead(PLIST_ENTRY ListHead)
void _RemoveEntryList(PLIST_ENTRY Entry)
void QuickSort(PDListComp Compare, void *UserData=NULL)
struct _LIST_ENTRY * Blink
PSINGLE_LIST_ENTRY FirstThat(PSListFunc Match, void *UserData=NULL)
bool __forceinline IsEmpty()
struct _SINGLE_LIST_ENTRY * PSINGLE_LIST_ENTRY
PSINGLE_LIST_ENTRY Remove(PSINGLE_LIST_ENTRY Entry)
void RemoveAll(PDListFunc ItemAction, void *UserData=NULL)
class DLinkList * PDLinkList
bool _IsListEmpty(PLIST_ENTRY ListHead)
PSINGLE_LIST_ENTRY PopEntry()
PSINGLE_LIST_ENTRY _PopEntryList(PSINGLE_LIST_ENTRY ListHead)
PSINGLE_LIST_ENTRY operator [](size_t Index)
UINT ExportToHeadlessList(PLIST_ENTRY *Circular)
PLIST_ENTRY RemoveFirst()
PSINGLE_LIST_ENTRY Append(PSINGLE_LIST_ENTRY Entry)
struct _SINGLE_LIST_ENTRY * Next
struct _LIST_ENTRY * Flink
PLIST_ENTRY RemoveEntry(PLIST_ENTRY Entry)
PSINGLE_LIST_ENTRY PushEntry(PSINGLE_LIST_ENTRY Entry)
PLIST_ENTRY GetPrev(PLIST_ENTRY Current)