Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1015 lines
23 KiB

//---------------------------------------------------------------------------
//
// Module: clist.h
//
// Description: list classes
//
//
//@@BEGIN_MSINTERNAL
// Development Team:
// Mike McLaughlin
//
// History: Date Author Comment
//
//@@END_MSINTERNAL
//---------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Macros
//---------------------------------------------------------------------------
#define FOR_EACH_LIST_ITEM(pl, p) { \
PCLIST_ITEM pli; \
for(pli = (pl)->GetListFirst(); \
!(pl)->IsListEnd(pli); \
pli = (pl)->GetListNext(pli)) { \
p = (pl)->GetListData(pli); \
(pl)->AssertList(p);
#define FOR_EACH_LIST_ITEM_DELETE(pl, p) { \
PCLIST_ITEM pli, pliNext; \
for(pli = (pl)->GetListFirst(); !(pl)->IsListEnd(pli); pli = pliNext) { \
pliNext = (pl)->GetListNext(pli); \
p = (pl)->GetListData(pli); \
(pl)->AssertList(p);
#define DELETE_LIST_ITEM(pl) \
pliNext = (pl)->GetListFirst();
#define FOR_EACH_LIST_ITEM_BACKWARD(pl, p) { \
PCLIST_ITEM pli; \
for(pli = (pl)->GetListLast(); \
!(pl)->IsListEnd(pli); \
pli = (pl)->GetListPrevious(pli)) { \
p = (pl)->GetListData(pli); \
(pl)->AssertList(p);
#define END_EACH_LIST_ITEM } }
//---------------------------------------------------------------------------
#define FOR_EACH_CLIST_ITEM(pl, p) { \
for(p = (pl)->GetListFirst(); \
!(pl)->IsListEnd(p); \
p = (pl)->GetListNext(p)) { \
Assert(p);
#define FOR_EACH_CLIST_ITEM_DELETE(pl, p, type) { \
type *pNext; \
for(p = (pl)->GetListFirst(); !(pl)->IsListEnd(p); p = pNext) { \
Assert(p); \
pNext = (pl)->GetListNext(p);
#define END_EACH_CLIST_ITEM } }
//---------------------------------------------------------------------------
// Abstract List Classes
//---------------------------------------------------------------------------
typedef class CList : public CObj
{
public:
} CLIST, *PCLIST;
typedef class CListItem : public CObj
{
public:
} CLIST_ITEM, *PCLIST_ITEM;
//---------------------------------------------------------------------------
// Singlely Linked List
//---------------------------------------------------------------------------
typedef class CListSingle : public CList
{
friend class CListSingleItem;
public:
CListSingle()
{
m_plsiHead = NULL;
};
VOID DestroyList()
{
m_plsiHead = NULL;
};
BOOL IsLstEmpty()
{
Assert(this);
return(m_plsiHead == NULL);
};
CListSingleItem *GetListFirst()
{
Assert(this);
return(m_plsiHead);
};
BOOL IsListEnd(CListSingleItem *plsi)
{
Assert(this);
return(plsi == NULL);
};
CListSingleItem *GetListData(CListSingleItem *plsi)
{
return plsi;
}
CListSingleItem *GetListNext(CListSingleItem *plsi);
CListSingleItem **GetListEnd();
ENUMFUNC EnumerateList(
IN ENUMFUNC (CListSingleItem::*pfn)(
)
);
ENUMFUNC EnumerateList(
IN ENUMFUNC (CListSingleItem::*pfn)(
PVOID pReference
),
PVOID pReference
);
void ReverseList();
protected:
CListSingleItem *m_plsiHead;
public:
DefineSignature(0x2048534C); // LSH
} CLIST_SINGLE, *PCLIST_SINGLE;
//---------------------------------------------------------------------------
typedef class CListSingleItem : public CListItem
{
friend class CListData;
friend class CListSingle;
public:
CListSingleItem()
{
m_plsiNext = NULL;
};
VOID AddList(CListSingle *pls)
{
Assert(pls);
Assert(this);
ASSERT(m_plsiNext == NULL);
m_plsiNext = pls->m_plsiHead;
pls->m_plsiHead = this;
};
VOID AddListEnd(CListSingle *pls)
{
Assert(pls);
Assert(this);
ASSERT(m_plsiNext == NULL);
*(pls->GetListEnd()) = this;
};
VOID RemoveList(CListSingle *pls);
private:
CListSingleItem *m_plsiNext;
public:
DefineSignature(0x2049534C); // LSI
} CLIST_SINGLE_ITEM, *PCLIST_SINGLE_ITEM;
inline CListSingleItem *
CListSingle::GetListNext(CListSingleItem *plsi)
{
Assert(this);
return plsi->m_plsiNext;
}
//---------------------------------------------------------------------------
// Doublely Linked List
//---------------------------------------------------------------------------
typedef class CListDouble : public CList
{
friend class CListDoubleItem;
public:
CListDouble()
{
InitializeListHead(&m_leHead);
};
VOID DestroyList()
{
};
BOOL IsLstEmpty()
{
Assert(this);
return IsListEmpty(&m_leHead);
};
ULONG CountList();
CListDoubleItem *GetListFirst();
CListDoubleItem *GetListLast();
BOOL IsListEnd(CListDoubleItem *pldi);
CListDoubleItem *GetListNext(CListDoubleItem *pldi);
CListDoubleItem *GetListPrevious(CListDoubleItem *pldi);
CListDoubleItem *GetListData(CListDoubleItem *pldi)
{
return pldi;
};
ENUMFUNC EnumerateList(
IN ENUMFUNC (CListDoubleItem::*pfn)(
)
);
ENUMFUNC EnumerateList(
IN ENUMFUNC (CListDoubleItem::*pfn)(
PVOID pReference
),
PVOID pReference
);
protected:
LIST_ENTRY m_leHead;
public:
DefineSignature(0x2048424C); // LBH
} CLIST_DOUBLE, *PCLIST_DOUBLE;
//---------------------------------------------------------------------------
typedef class CListDoubleItem : public CListItem
{
friend class CListDouble;
public:
VOID AddList(CListDouble *plb)
{
Assert(plb);
Assert(this);
ASSERT(m_le.Flink == NULL);
ASSERT(m_le.Blink == NULL);
InsertHeadList(&plb->m_leHead, &m_le);
};
VOID AddListEnd(CListDouble *plb)
{
Assert(plb);
Assert(this);
ASSERT(m_le.Flink == NULL);
ASSERT(m_le.Blink == NULL);
InsertTailList(&plb->m_leHead, &m_le);
};
VOID RemoveList()
{
Assert(this);
ASSERT(m_le.Flink != NULL);
ASSERT(m_le.Blink != NULL);
RemoveEntryList(&m_le);
m_le.Flink = NULL;
m_le.Blink = NULL;
};
VOID RemoveListCheck()
{
Assert(this);
if(m_le.Flink != NULL) {
RemoveList();
}
};
protected:
LIST_ENTRY m_le;
public:
DefineSignature(0x2049424C); // LBI
} CLIST_DOUBLE_ITEM, *PCLIST_DOUBLE_ITEM;
inline CListDoubleItem *
CListDouble::GetListFirst()
{
Assert(this);
ASSERT(m_leHead.Flink != NULL);
return CONTAINING_RECORD(m_leHead.Flink, CListDoubleItem, m_le);
}
inline CListDoubleItem *
CListDouble::GetListLast()
{
Assert(this);
ASSERT(m_leHead.Blink != NULL);
return CONTAINING_RECORD(m_leHead.Blink, CListDoubleItem, m_le);
}
inline BOOL
CListDouble::IsListEnd(CListDoubleItem *pldi)
{
Assert(this);
return(&pldi->m_le == &m_leHead);
}
inline CListDoubleItem *
CListDouble::GetListNext(CListDoubleItem *pldi)
{
Assert(this);
ASSERT(pldi->m_le.Flink != NULL);
return CONTAINING_RECORD(pldi->m_le.Flink, CListDoubleItem, m_le);
}
inline CListDoubleItem *
CListDouble::GetListPrevious(CListDoubleItem *pldi)
{
Assert(this);
ASSERT(pldi->m_le.Blink != NULL);
return CONTAINING_RECORD(pldi->m_le.Blink, CListDoubleItem, m_le);
}
//---------------------------------------------------------------------------
// Linked List of Data Pointers
//---------------------------------------------------------------------------
class CListDataItem;
typedef class CListDataData : public CListSingleItem
{
friend class CListData;
public:
CListDataData(
CListDataItem *pldi
)
{
m_pldiData = pldi;
};
CListDataData(
PVOID p
)
{
m_pldiData = (CListDataItem *)p;
};
private:
CListDataItem *m_pldiData;
public:
DefineSignature(0x2044444C); // LDD
} CLIST_DATA_DATA, *PCLIST_DATA_DATA;
//---------------------------------------------------------------------------
typedef class CListData : public CListSingle
{
public:
~CListData()
{
CListData::DestroyList();
};
VOID DestroyList();
ULONG CountList();
CListDataData *GetListFirst()
{
Assert(this);
return (CListDataData *)CListSingle::GetListFirst();
};
CListDataData *GetListNext(CListDataData *pldd)
{
Assert(this);
return (CListDataData *)CListSingle::GetListNext(pldd);
};
CListDataItem *GetListData(CListDataData *pldd)
{
Assert(this);
return pldd->m_pldiData;
};
CListDataItem *GetListFirstData()
{
Assert(this);
return GetListData(GetListFirst());
};
ENUMFUNC EnumerateList(
IN ENUMFUNC (CListDataItem::*pfn)(
)
);
ENUMFUNC EnumerateList(
IN ENUMFUNC (CListDataItem::*pfn)(
PVOID pReference
),
PVOID pReference
);
NTSTATUS CreateUniqueList(
OUT CListData *pldOut,
IN PVOID (*GetFunction)(
IN PVOID pData
),
IN BOOL (*CompareFunction)(
IN PVOID pIn,
IN PVOID pOut
)
);
BOOL CheckDupList(
PVOID p
);
NTSTATUS AddList(
PVOID p
);
NTSTATUS AddListDup(
PVOID p
);
NTSTATUS AddListEnd(
PVOID p
);
NTSTATUS AddListOrdered(
PVOID p,
LONG lFieldOffset
);
VOID RemoveList(
PVOID p
);
VOID JoinList(
CListData *pld
);
private:
CListDataData **GetListEnd()
{
return((CListDataData **)CListSingle::GetListEnd());
};
public:
DefineSignature(0x2048444C); // LDH
} CLIST_DATA, *PCLIST_DATA;
//---------------------------------------------------------------------------
typedef class CListDataItem : public CListItem
{
public:
ENUMFUNC Destroy()
{
delete this;
return(STATUS_CONTINUE);
};
BOOL CheckDupList(
PCLIST_DATA pld
)
{
Assert(this);
return(pld->CheckDupList((PVOID)this));
};
NTSTATUS AddList(
PCLIST_DATA pld
)
{
Assert(this);
return(pld->AddList((PVOID)this));
};
NTSTATUS AddListDup(
PCLIST_DATA pld
)
{
Assert(this);
return(pld->AddListDup((PVOID)this));
};
NTSTATUS AddListEnd(
PCLIST_DATA pld
)
{
Assert(this);
return(pld->AddListEnd((PVOID)this));
};
VOID RemoveList(
PCLIST_DATA pld
)
{
Assert(this);
pld->RemoveList((PVOID)this);
};
DefineSignature(0x2049444C); // LDI
} CLIST_DATA_ITEM, *PCLIST_DATA_ITEM;
typedef PVOID (*UNIQUE_LIST_PFN)(PVOID);
typedef BOOL (*UNIQUE_LIST_PFN2)(PVOID, PVOID);
//---------------------------------------------------------------------------
// Multi-Headed Linked List
//---------------------------------------------------------------------------
typedef class CListMultiData : public CListDoubleItem
{
friend class CListMulti;
friend class CListMultiItem;
public:
CListMultiData(
PVOID p
)
{
m_plmiData = (CListMultiItem *)p;
};
~CListMultiData()
{
CListMultiData::RemoveList();
};
VOID RemoveList()
{
Assert(this);
CListDoubleItem::RemoveList();
m_ldiItem.RemoveList();
};
private:
CListDoubleItem m_ldiItem;
CListMultiItem *m_plmiData;
public:
DefineSignature(0x20444d4C); // LMD
} CLIST_MULTI_DATA, *PCLIST_MULTI_DATA;
//---------------------------------------------------------------------------
typedef class CListMulti : public CListDouble
{
friend class CListMultiItem;
public:
~CListMulti()
{
CListMulti::DestroyList();
};
VOID DestroyList();
ENUMFUNC EnumerateList(
ENUMFUNC (CListMultiItem::*pfn)(
)
);
ENUMFUNC EnumerateList(
ENUMFUNC (CListMultiItem::*pfn)(
PVOID pReference
),
PVOID pReference
);
CListMultiData *GetListFirst()
{
Assert(this);
return (CListMultiData *)CListDouble::GetListFirst();
};
CListMultiData *GetListLast()
{
Assert(this);
return (CListMultiData *)CListDouble::GetListLast();
};
BOOL IsListEnd(CListMultiData *plmd)
{
Assert(this);
return CListDouble::IsListEnd(plmd);
};
CListMultiData *GetListNext(CListMultiData *plmd)
{
Assert(this);
return (CListMultiData *)CListDouble::GetListNext(plmd);
};
CListMultiData *GetListPrevious(CListMultiData *plmd)
{
Assert(this);
return (CListMultiData *)CListDouble::GetListPrevious(plmd);
};
CListMultiItem *GetListData(CListMultiData *plmd)
{
Assert(this);
return plmd->m_plmiData;
};
CListMultiItem *GetListFirstData()
{
Assert(this);
return GetListData(GetListFirst());
};
BOOL CheckDupList(
PVOID p
);
NTSTATUS AddList(
PVOID p,
CListMultiItem *plmi
);
NTSTATUS AddList(
CListMultiItem *plmi
)
{
Assert(this);
return(AddList((PVOID)plmi, plmi));
};
NTSTATUS AddListEnd(
PVOID p,
CListMultiItem *plmi
);
NTSTATUS AddListEnd(
CListMultiItem *plmi
)
{
Assert(this);
return(AddListEnd((PVOID)plmi, plmi));
};
NTSTATUS AddListOrdered(
PVOID p,
CListMultiItem *plmi,
LONG lFieldOffset
);
NTSTATUS AddListOrdered(
CListMultiItem *plmi,
LONG lFieldOffset
)
{
Assert(this);
return(AddListOrdered((PVOID)plmi, plmi, lFieldOffset));
};
VOID RemoveList(
PVOID p
);
VOID JoinList(
CListMulti *plm
);
DefineSignature(0x20484D4C); // LMH
} CLIST_MULTI, *PCLIST_MULTI;
//---------------------------------------------------------------------------
typedef class CListMultiItem : public CListDouble
{
public:
~CListMultiItem();
BOOL CheckDupList(
PCLIST_MULTI plm
)
{
return(plm->CheckDupList((PVOID)this));
};
NTSTATUS AddList(
PCLIST_MULTI plm
)
{
Assert(plm);
Assert(this);
return(plm->AddList(this));
};
NTSTATUS AddListEnd(
PCLIST_MULTI plm
)
{
Assert(plm);
Assert(this);
return(plm->AddListEnd(this));
};
NTSTATUS AddListOrdered(
PCLIST_MULTI plm,
LONG lFieldOffset
)
{
Assert(plm);
Assert(this);
return(plm->AddListOrdered(this, lFieldOffset));
};
VOID RemoveList(
PCLIST_MULTI plm
)
{
Assert(this);
plm->RemoveList((PVOID)this);
};
DefineSignature(0x20494d4C); // LMI
} CLIST_MULTI_ITEM, *PCLIST_MULTI_ITEM;
//---------------------------------------------------------------------------
// Templates
//---------------------------------------------------------------------------
template<class TYPE>
class ListSingleDestroy : public CListSingle
{
public:
~ListSingleDestroy()
{
ListSingleDestroy::DestroyList();
};
VOID DestroyList()
{
ListSingleDestroy::EnumerateList(TYPE::Destroy);
CListSingle::DestroyList();
};
VOID AssertList(TYPE *p)
{
Assert(p);
};
ENUMFUNC EnumerateList(
IN ENUMFUNC (TYPE::*pfn)(
)
)
{
return CListSingle::EnumerateList(
(ENUMFUNC (CListSingleItem::*)())pfn);
};
ENUMFUNC EnumerateList(
IN ENUMFUNC (TYPE::*pfn)(
PVOID pReference
),
PVOID pReference
)
{
return CListSingle::EnumerateList(
(ENUMFUNC (CListSingleItem::*)(PVOID))pfn,
pReference);
};
PCLIST_ITEM GetListFirst()
{
return CListSingle::GetListFirst();
};
BOOL IsListEnd(PCLIST_ITEM pli)
{
return CListSingle::IsListEnd((CListSingleItem *)pli);
};
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
{
return CListSingle::GetListNext((CListSingleItem *)pli);
};
TYPE *GetListData(PCLIST_ITEM pli)
{
return (TYPE *)CListSingle::GetListData((CListSingleItem *)pli);
};
TYPE *GetListFirstData()
{
return (TYPE *)CListSingle::GetListData(CListSingle::GetListFirst());
};
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
template<class TYPE>
class ListDouble : public CListDouble
{
public:
VOID AssertList(TYPE *p)
{
Assert(p);
};
ENUMFUNC EnumerateList(
IN ENUMFUNC (TYPE::*pfn)()
)
{
return CListDouble::EnumerateList(
(ENUMFUNC (CListDoubleItem::*)())pfn);
};
ENUMFUNC EnumerateList(
IN ENUMFUNC (TYPE::*pfn)(
PVOID pReference
),
PVOID pReference
)
{
return CListDouble::EnumerateList(
(ENUMFUNC (CListDoubleItem::*)(PVOID))pfn,
pReference);
};
PCLIST_ITEM GetListFirst()
{
return CListDouble::GetListFirst();
};
PCLIST_ITEM GetListLast()
{
return CListDouble::GetListLast();
};
BOOL IsListEnd(PCLIST_ITEM pli)
{
return CListDouble::IsListEnd((CListDoubleItem *)pli);
};
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
{
return CListDouble::GetListNext((CListDoubleItem *)pli);
};
PCLIST_ITEM GetListPrevious(PCLIST_ITEM pli)
{
return CListDouble::GetListPrevious((CListDoubleItem *)pli);
};
TYPE *GetListData(PCLIST_ITEM pli)
{
return (TYPE *)CListDouble::GetListData((CListDoubleItem *)pli);
};
};
//---------------------------------------------------------------------------
template<class TYPE>
class ListDoubleDestroy : public ListDouble<TYPE>
{
public:
~ListDoubleDestroy()
{
ListDoubleDestroy::DestroyList();
};
VOID DestroyList()
{
ListDoubleDestroy::EnumerateList(TYPE::Destroy);
CListDouble::DestroyList();
};
};
//---------------------------------------------------------------------------
template<class TYPE>
class ListDoubleField : public CListDouble
{
public:
VOID AssertList(TYPE *p)
{
Assert(p);
};
CListItem *GetListFirst()
{
return (CListItem *)CONTAINING_RECORD(
CListDouble::GetListFirst(), TYPE, ldiNext);
};
BOOL IsListEnd(CListItem *pli)
{
return CListDouble::IsListEnd(&((TYPE *)pli)->ldiNext);
};
CListItem *GetListNext(CListItem *pli)
{
return (CListItem *)CONTAINING_RECORD(
CListDouble::GetListNext(&((TYPE *)pli)->ldiNext), TYPE, ldiNext);
};
TYPE *GetListData(CListItem *pli)
{
return CONTAINING_RECORD(
CListDouble::GetListData(&((TYPE *)pli)->ldiNext), TYPE, ldiNext);
};
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
template<class TYPE>
class ListDataAssertLess : public CListData
{
public:
VOID AssertList(TYPE *p)
{
};
PCLIST_ITEM GetListFirst()
{
return CListData::GetListFirst();
};
BOOL IsListEnd(PCLIST_ITEM pli)
{
return CListData::IsListEnd((CListDataData *)pli);
};
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
{
return CListData::GetListNext((CListDataData *)pli);
};
TYPE *GetListData(PCLIST_ITEM pli)
{
return (TYPE *)CListData::GetListData((CListDataData *)pli);
};
TYPE *GetListFirstData()
{
return (TYPE *)CListData::GetListFirstData();
};
NTSTATUS AddList(
TYPE *p
)
{
return CListData::AddList((PVOID)p);
};
NTSTATUS AddListDup(
TYPE *p
)
{
return CListData::AddListDup((PVOID)p);
};
NTSTATUS AddListEnd(
TYPE *p
)
{
return CListData::AddListEnd((PVOID)p);
};
NTSTATUS AddListOrdered(
TYPE *p,
LONG lFieldOffset
)
{
return CListData::AddListOrdered((PVOID)p, lFieldOffset);
};
VOID RemoveList(
TYPE *p
)
{
CListData::RemoveList((PVOID)p);
};
};
//---------------------------------------------------------------------------
template<class TYPE>
class ListData : public ListDataAssertLess<TYPE>
{
public:
VOID AssertList(TYPE *p)
{
Assert(p);
};
ENUMFUNC EnumerateList(
ENUMFUNC (TYPE::*pfn)()
)
{
return CListData::EnumerateList((ENUMFUNC (CListDataItem::*)())pfn);
};
ENUMFUNC EnumerateList(
ENUMFUNC (TYPE::*pfn)(
PVOID pReference
),
PVOID pReference
)
{
return CListData::EnumerateList(
(ENUMFUNC (CListDataItem::*)(PVOID))pfn,
pReference);
};
};
//---------------------------------------------------------------------------
template<class TYPE>
class ListDataDestroy : public ListData<TYPE>
{
public:
~ListDataDestroy()
{
ListDataDestroy::DestroyList();
};
VOID DestroyList()
{
ListDataDestroy::EnumerateList(TYPE::Destroy);
CListData::DestroyList();
};
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
template<class TYPE>
class ListMulti : public CListMulti
{
public:
VOID AssertList(TYPE *p)
{
Assert(p);
};
PCLIST_ITEM GetListFirst()
{
return CListMulti::GetListFirst();
};
PCLIST_ITEM GetListLast()
{
return CListMulti::GetListLast();
};
BOOL IsListEnd(PCLIST_ITEM pli)
{
return CListMulti::IsListEnd((CListMultiData *)pli);
};
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
{
return CListMulti::GetListNext((CListMultiData *)pli);
};
PCLIST_ITEM GetListPrevious(PCLIST_ITEM pli)
{
return CListMulti::GetListPrevious((CListMultiData *)pli);
};
TYPE *GetListData(PCLIST_ITEM pli)
{
return (TYPE *)CListMulti::GetListData((CListMultiData *)pli);
};
TYPE *GetListFirstData()
{
return (TYPE *)CListMulti::GetListFirstData();
};
ENUMFUNC EnumerateList(
ENUMFUNC (TYPE::*pfn)()
)
{
return CListMulti::EnumerateList((ENUMFUNC (CListMultiItem::*)())pfn);
};
ENUMFUNC EnumerateList(
ENUMFUNC (TYPE::*pfn)(
PVOID pReference
),
PVOID pReference
)
{
return CListMulti::EnumerateList(
(ENUMFUNC (CListMultiItem::*)(PVOID))pfn,
pReference);
};
};
//---------------------------------------------------------------------------
template<class TYPE>
class ListMultiDestroy : public ListMulti<TYPE>
{
public:
~ListMultiDestroy()
{
ListMultiDestroy::DestroyList();
};
VOID DestroyList()
{
ListMultiDestroy::EnumerateList(TYPE::Destroy);
CListMulti::DestroyList();
};
};
//---------------------------------------------------------------------------
// End of File: clist.h
//---------------------------------------------------------------------------