template
<
class
TYPE
>
class
CTArray
{//动态数组类
private:
UINTnSize;//actualsize
UINTnGrow;//growfactor
protected:
UINTnItems;//numberofelements(asitappearstotheuser)
TYPE*pData;//pointertoarrayofdata
public:
//blankconstructor
CTArray(){Init();}
//copyconstructor
CTArray(CTArray&Src){Init();Copy(Src);}
//typedcopyconstructor
CTArray(constTYPE*pSrc,UINTnCount=1)
{
Init();
SetLength(nCount);
for(UINTu=0;u<nItems;u++)pData[u]=pSrc[u];
}
//typedinitializingconstructor
CTArray(UINTnCount,TYPESrc)
{
Init();
SetLength(nCount);
for(UINTu=0;u<nItems;u++)pData[u]=Src;
}
//operators
constTYPE&operator[](UINTnIndex)const{returnpData[nIndex];}
TYPE&operator[](UINTnIndex){returnpData[nIndex];}
CTArray&operator=(CTArray&Src){Copy(Src);return*this;}
//initialise
voidInit(){pData=NULL;nSize=nItems=0;nGrow=8;}
//releasedata
virtualvoidClear(void){if(pData!=NULL)delete[]pData;Init();}
//copyfromother
voidCopy(CTArray&Src)
{
Clear();
SetLength(Src.Length());
for(UINTu=0;u<nItems;u++)pData[u]=Src.pData[u];
}
//growfactorget/set
UINTGrowFactor(void)const{returnnGrow;}
voidSetGrowFactor(UINTnNewGrow){nGrow=nNewGrow;if(nGrow==0)nGrow=1;}
//length(items)get
UINTLength(void){returnnItems;}
//setlengthregroworshrink
virtualboolSetLength(UINTnLength,boolbForce=false)
{
if(nLength==0)
{
Clear();
returntrue;
}
//allocnewstorage
TYPE*pNewData=NULL;
UINTnNewSize=((nLength/nGrow)+1)*nGrow;//新数组大小
//growonlyifeithertheamountweneedisgreaterthanwhatwehave
//alreadyoriftheamountis<=1/2,whatever'ssmaller
if(nNewSize>nSize||nNewSize<=nSize/2||bForce)
{
//创建新数组
if((pNewData=newTYPE[nNewSize])==NULL)
returnfalse;
//nowcopytheoldelementsintothenewarray,uptotheold
//numberofitemsortotheuser-setnewlength,whichever's
//smaller
for(UINTu=0;u<nItems&&u<nLength;u++)
pNewData[u]=pData[u];
//updateallthecurrentinfo
if(pData!=NULL)
delete[]pData;
pData=pNewData;
nSize=nNewSize;
}
nItems=nLength;
returntrue;
}
//setw/boundscheckbutnogrow
virtualboolSet(UINTnIndex,TYPESrc)const
{
if(nIndex>=nItems||pData==NULL)
returnfalse;
pData[nIndex]=Src;
returntrue;
}
//getw/boundscheckbutnogrow
virtualboolGet(TYPE&Dst,UINTnIndex)const
{
if(nIndex>=nItems||pData==NULL)
returnfalse;
Dst=pData[nIndex];
returntrue;
}
//getallelementstoatypedpointer;donotforgettodelete
//suchpointerafternolongerneeded
UINTGetAll(TYPE*&pDst)
{
pDst=newTYPE[nItems];
for(UINTu=0;u<nItems;u++)
pDst[u]=pData[u];
returnnItems;
}
//getallelementstoanunknownsizepointerofspecifiedsize;the
//pointermustbeinitializedbythecaller
UINTGetAll(void*pDst,intnSize)
{
for(UINTu=0;u<nItems;u++)
memcpy((void*)((BYTE*)pDst+u*nSize),(void*)(&pData[u]),nSize);
returnnItems;
}
//removeelementatgivenposition
virtualboolRemove(UINTnIndex)
{
if(nItems==0||pData==NULL)
returnfalse;
//startingwiththeelementweareremoving,workup
//copyingeachnextvaluedowntothecurrentspot
for(UINTu=nIndex;u<nItems-1;u++)
pData[u]=pData[u+1];
//thiswilleithersimplychangethenItemsvalueorreallocand
//freesomememory
SetLength(nItems-1);
returntrue;
}
//insertelementatgivenposition
virtualvoidInsert(TYPESrc,UINTnIndex)
{
//first,makeroom
SetLength(nItems+1);
//startingwiththelastelementworkbackuntilwegettotheone
//weareinsertingatandcopyforward
for(UINTu=nItems-1;u>nIndex;u--)
pData[u]=pData[u-1];
//finallyinsertnewvalue
pData[nIndex]=Src;
}
//appendelementtotheendofarray
virtualintAppend(TYPESrc)
{
//first,makeroom
SetLength(nItems+1);
//insertnewvalue
pData[nItems-1]=Src;
returnnItems;
}
//blankappend
virtualintAppend()
{
//justmakeroom
SetLength(nItems+1);
returnnItems;
}
//finderwithmemcompareandoptionalstart
intFind(TYPESrc,UINTnStart=0)
{
for(UINTu=nStart;u<nItems;u++)
{
if(memcmp(&pData[u],&Src,sizeof(TYPE))==0)
return(int)u;
}
return-1;
}
//swap
voidSwap(UINTi,UINTj)
{
if(i>=nItems||j>=nItems||i==j)
return;
TYPETmp=pData[i];
pData[i]=pData[j];
pData[j]=Tmp;
}
//sortwrapperwithcallbackandmethod
voidSort(int(__cdecl*compare)(constvoid*p1,constvoid*p2),intnMethod=0)
{
switch(nMethod)
{
case1:
{
//sortthearraywithfixedstartingitems,bycomparingneighbors
for(UINTi=0;i<nItems-1;i++)
{
//skipaneighborthatisinorder(asdeterminedbyanon-zero
//returnfromthecomparefunction)
if(compare((constvoid*)&pData[i],(constvoid*)&pData[i+1]))
continue;
//searchforanitemmatchingthelaststartingitem
UINTj=i+1;
while(!compare((constvoid*)&pData[i],(constvoid*)&pData[j])&&j<nItems-1)
j++;
//swapthematchingitemtoberightbelowthestartingitem
if(j<=nItems-1)
Swap(i+1,j);
}
break;
}
default:
qsort(pData,nItems,sizeof(TYPE),compare);
break;
}
}
//destructor
~CTArray(){Clear();}
} ;
typedefCTArray < DWORD > DWORDARRAY;
{//动态数组类
private:
UINTnSize;//actualsize
UINTnGrow;//growfactor
protected:
UINTnItems;//numberofelements(asitappearstotheuser)
TYPE*pData;//pointertoarrayofdata
public:
//blankconstructor
CTArray(){Init();}
//copyconstructor
CTArray(CTArray&Src){Init();Copy(Src);}
//typedcopyconstructor
CTArray(constTYPE*pSrc,UINTnCount=1)
{
Init();
SetLength(nCount);
for(UINTu=0;u<nItems;u++)pData[u]=pSrc[u];
}
//typedinitializingconstructor
CTArray(UINTnCount,TYPESrc)
{
Init();
SetLength(nCount);
for(UINTu=0;u<nItems;u++)pData[u]=Src;
}
//operators
constTYPE&operator[](UINTnIndex)const{returnpData[nIndex];}
TYPE&operator[](UINTnIndex){returnpData[nIndex];}
CTArray&operator=(CTArray&Src){Copy(Src);return*this;}
//initialise
voidInit(){pData=NULL;nSize=nItems=0;nGrow=8;}
//releasedata
virtualvoidClear(void){if(pData!=NULL)delete[]pData;Init();}
//copyfromother
voidCopy(CTArray&Src)
{
Clear();
SetLength(Src.Length());
for(UINTu=0;u<nItems;u++)pData[u]=Src.pData[u];
}
//growfactorget/set
UINTGrowFactor(void)const{returnnGrow;}
voidSetGrowFactor(UINTnNewGrow){nGrow=nNewGrow;if(nGrow==0)nGrow=1;}
//length(items)get
UINTLength(void){returnnItems;}
//setlengthregroworshrink
virtualboolSetLength(UINTnLength,boolbForce=false)
{
if(nLength==0)
{
Clear();
returntrue;
}
//allocnewstorage
TYPE*pNewData=NULL;
UINTnNewSize=((nLength/nGrow)+1)*nGrow;//新数组大小
//growonlyifeithertheamountweneedisgreaterthanwhatwehave
//alreadyoriftheamountis<=1/2,whatever'ssmaller
if(nNewSize>nSize||nNewSize<=nSize/2||bForce)
{
//创建新数组
if((pNewData=newTYPE[nNewSize])==NULL)
returnfalse;
//nowcopytheoldelementsintothenewarray,uptotheold
//numberofitemsortotheuser-setnewlength,whichever's
//smaller
for(UINTu=0;u<nItems&&u<nLength;u++)
pNewData[u]=pData[u];
//updateallthecurrentinfo
if(pData!=NULL)
delete[]pData;
pData=pNewData;
nSize=nNewSize;
}
nItems=nLength;
returntrue;
}
//setw/boundscheckbutnogrow
virtualboolSet(UINTnIndex,TYPESrc)const
{
if(nIndex>=nItems||pData==NULL)
returnfalse;
pData[nIndex]=Src;
returntrue;
}
//getw/boundscheckbutnogrow
virtualboolGet(TYPE&Dst,UINTnIndex)const
{
if(nIndex>=nItems||pData==NULL)
returnfalse;
Dst=pData[nIndex];
returntrue;
}
//getallelementstoatypedpointer;donotforgettodelete
//suchpointerafternolongerneeded
UINTGetAll(TYPE*&pDst)
{
pDst=newTYPE[nItems];
for(UINTu=0;u<nItems;u++)
pDst[u]=pData[u];
returnnItems;
}
//getallelementstoanunknownsizepointerofspecifiedsize;the
//pointermustbeinitializedbythecaller
UINTGetAll(void*pDst,intnSize)
{
for(UINTu=0;u<nItems;u++)
memcpy((void*)((BYTE*)pDst+u*nSize),(void*)(&pData[u]),nSize);
returnnItems;
}
//removeelementatgivenposition
virtualboolRemove(UINTnIndex)
{
if(nItems==0||pData==NULL)
returnfalse;
//startingwiththeelementweareremoving,workup
//copyingeachnextvaluedowntothecurrentspot
for(UINTu=nIndex;u<nItems-1;u++)
pData[u]=pData[u+1];
//thiswilleithersimplychangethenItemsvalueorreallocand
//freesomememory
SetLength(nItems-1);
returntrue;
}
//insertelementatgivenposition
virtualvoidInsert(TYPESrc,UINTnIndex)
{
//first,makeroom
SetLength(nItems+1);
//startingwiththelastelementworkbackuntilwegettotheone
//weareinsertingatandcopyforward
for(UINTu=nItems-1;u>nIndex;u--)
pData[u]=pData[u-1];
//finallyinsertnewvalue
pData[nIndex]=Src;
}
//appendelementtotheendofarray
virtualintAppend(TYPESrc)
{
//first,makeroom
SetLength(nItems+1);
//insertnewvalue
pData[nItems-1]=Src;
returnnItems;
}
//blankappend
virtualintAppend()
{
//justmakeroom
SetLength(nItems+1);
returnnItems;
}
//finderwithmemcompareandoptionalstart
intFind(TYPESrc,UINTnStart=0)
{
for(UINTu=nStart;u<nItems;u++)
{
if(memcmp(&pData[u],&Src,sizeof(TYPE))==0)
return(int)u;
}
return-1;
}
//swap
voidSwap(UINTi,UINTj)
{
if(i>=nItems||j>=nItems||i==j)
return;
TYPETmp=pData[i];
pData[i]=pData[j];
pData[j]=Tmp;
}
//sortwrapperwithcallbackandmethod
voidSort(int(__cdecl*compare)(constvoid*p1,constvoid*p2),intnMethod=0)
{
switch(nMethod)
{
case1:
{
//sortthearraywithfixedstartingitems,bycomparingneighbors
for(UINTi=0;i<nItems-1;i++)
{
//skipaneighborthatisinorder(asdeterminedbyanon-zero
//returnfromthecomparefunction)
if(compare((constvoid*)&pData[i],(constvoid*)&pData[i+1]))
continue;
//searchforanitemmatchingthelaststartingitem
UINTj=i+1;
while(!compare((constvoid*)&pData[i],(constvoid*)&pData[j])&&j<nItems-1)
j++;
//swapthematchingitemtoberightbelowthestartingitem
if(j<=nItems-1)
Swap(i+1,j);
}
break;
}
default:
qsort(pData,nItems,sizeof(TYPE),compare);
break;
}
}
//destructor
~CTArray(){Clear();}
} ;
typedefCTArray < DWORD > DWORDARRAY;