Files
wnmj/Classes/Global/Array.h
2026-02-13 14:34:15 +08:00

737 lines
15 KiB
C++

#ifndef _ARRAY_TEMPLATE_HEAD_FILE
#define _ARRAY_TEMPLATE_HEAD_FILE
#pragma once
#include "cocos2d.h"
#include "PlatformHeader.h"
//////////////////////////////////////////////////////////////////////////
//数组模板类
template <class TYPE, class ARG_TYPE=const TYPE &>
class CArrayTemplate
{
//变量定义
protected:
TYPE *m_pData; //数组指针
int m_nMaxCount; //缓冲数目
int m_nGrowCount; //增长数目
int m_nElementCount; //元素数目
//函数定义
public:
//构造函数
CArrayTemplate(void);
//析构函数
virtual ~CArrayTemplate(void);
//信息函数
public:
//是否空组
bool IsEmpty() const;
//获取数目
int GetCount() const;
//获取上限
int GetUpperBound() const;
//功能函数
public:
//获取缓冲
TYPE * GetData();
//获取缓冲
const TYPE * GetData() const;
//释放内存
void FreeExtra();
//增加元素
int Add(ARG_TYPE newElement);
//增加不同的值
int AddDistinct( ARG_TYPE newElement );
//拷贝数组
int Copy(const CArrayTemplate & Src);
//追加数组
int Append(const CArrayTemplate & Src);
//获取元素
TYPE & GetAt(int nIndex);
//获取元素
const TYPE & GetAt(int nIndex) const;
//获取元素
TYPE & ElementAt(int nIndex);
//获取元素
const TYPE & ElementAt(int nIndex) const;
//操作函数
public:
//设置大小
void SetSize(int nNewSize);
//设置元素
void SetAt(int nIndex, ARG_TYPE newElement);
//设置元素
void SetAtGrow(int nIndex, ARG_TYPE newElement);
//插入数据
void InsertAt(int nIndex, const CArrayTemplate & Src);
//插入数据
void InsertAt(int nIndex, ARG_TYPE newElement, int nCount=1);
//删除数据
void RemoveAt(int nIndex, int nCount=1);
//删除指定元素
int RemoveItem( ARG_TYPE newElement );
//删除元素
void RemoveAll();
//降序排序,要求对象类型重载 >
void Sort(int nLower, int nUpper);
//快速排序法的数据分区,要求对象类型重载 >
int Partition(int nLower, int nUpper);
//交换变量
void SwitchValue( int a, int b );
//排序
template<typename FUNC_SHARRAY_COMPARE>
void SortEx(int nLower, int nUpper,FUNC_SHARRAY_COMPARE fp)
{
//是否排序完毕
if (nLower < nUpper)
{
// 分区排序
int nSplit = PartitionEx(nLower, nUpper,fp);
SortEx(nLower, nSplit-1,fp);//左区排序
SortEx(nSplit+1, nUpper,fp);//右区排序
}
}
//快速排序法的数据分区
template<typename FUNC_SHARRAY_COMPARE>
int PartitionEx(int nLower, int nUpper,FUNC_SHARRAY_COMPARE fp)
{
int nLeft = nLower + 1;
TYPE &RefObj = m_pData[nLower];
int nRight = nUpper;
TYPE Swap;
while (nLeft <= nRight)
{
while (nLeft <= nRight && fp(m_pData[nLeft],RefObj))
{
nLeft++;
}
while (nLeft <= nRight && !fp(m_pData[nRight],RefObj))
{
nRight--;
}
if (nLeft < nRight)
{
Swap = m_pData[nLeft];
m_pData[nLeft] = m_pData[nRight];
m_pData[nRight] = Swap;
nLeft++;
nRight--;
}
}
Swap = m_pData[nLower];
m_pData[nLower] = m_pData[nRight];
m_pData[nRight] = Swap;
return nRight;
}
//操作重载
public:
//操作重载
TYPE & operator[](int nIndex);
//操作重载
const TYPE & operator[](int nIndex) const;
//内部函数
private:
//申请内存
void AllocMemory(int nNewCount);
};
//////////////////////////////////////////////////////////////////////////
// CArrayTemplate<TYPE, ARG_TYPE> 内联函数
//是否空组
template<class TYPE, class ARG_TYPE>
inline bool CArrayTemplate<TYPE, ARG_TYPE>::IsEmpty() const
{
//ASSERT_VALID(this);
return (m_nElementCount==0);
}
//获取数目
template<class TYPE, class ARG_TYPE>
inline int CArrayTemplate<TYPE, ARG_TYPE>::GetCount() const
{
//ASSERT_VALID(this);
return m_nElementCount;
}
//获取上限
template<class TYPE, class ARG_TYPE>
inline int CArrayTemplate<TYPE, ARG_TYPE>::GetUpperBound() const
{
//ASSERT_VALID(this);
return m_nElementCount-1;
}
//增加元素
template<class TYPE, class ARG_TYPE>
inline int CArrayTemplate<TYPE,ARG_TYPE>::Add(ARG_TYPE newElement)
{
int nIndex=m_nElementCount;
SetAtGrow(nIndex,newElement);
return nIndex;
}
//操作重载
template<class TYPE, class ARG_TYPE>
inline TYPE & CArrayTemplate<TYPE, ARG_TYPE>::operator[](int nIndex)
{
return ElementAt(nIndex);
}
//操作重载
template<class TYPE, class ARG_TYPE>
inline const TYPE & CArrayTemplate<TYPE, ARG_TYPE>::operator[](int nIndex) const
{
return GetAt(nIndex);
}
//////////////////////////////////////////////////////////////////////////
// CArrayTemplate<TYPE, ARG_TYPE> 外联函数
//构造函数
template<class TYPE, class ARG_TYPE>
CArrayTemplate<TYPE, ARG_TYPE>::CArrayTemplate()
{
m_pData=NULL;
m_nMaxCount=0;
m_nGrowCount=0;
m_nElementCount=0;
return;
}
//构造函数
template<class TYPE, class ARG_TYPE>
CArrayTemplate<TYPE,ARG_TYPE>::~CArrayTemplate()
{
if (m_pData!=NULL)
{
for (int i=0;i<m_nElementCount;i++)
{
(m_pData+i)->~TYPE();
}
delete [] (BYTE *)m_pData;
m_pData=NULL;
}
return;
}
//获取缓冲
template<class TYPE, class ARG_TYPE>
TYPE * CArrayTemplate<TYPE,ARG_TYPE>::GetData()
{
ASSERT_VALID(this);
return m_pData;
}
//获取缓冲
template<class TYPE, class ARG_TYPE>
const TYPE * CArrayTemplate<TYPE,ARG_TYPE>::GetData() const
{
ASSERT_VALID(this);
return m_pData;
}
//释放内存
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::FreeExtra()
{
ASSERT_VALID(this);
if (m_nElementCount!=m_nMaxCount)
{
TYPE * pNewData=NULL;
if (m_nElementCount!=0)
{
pNewData=(TYPE *) new BYTE[m_nElementCount*sizeof(TYPE)];
//memcpy(pNewData,m_pData,m_nElementCount*sizeof(TYPE)); //old,flowing is modify by myz
memmove(pNewData,m_pData,m_nElementCount*sizeof(TYPE));
}
delete [] (BYTE *)m_pData;
m_pData=pNewData;
m_nMaxCount=m_nElementCount;
}
return;
}
//拷贝数组
template<class TYPE, class ARG_TYPE>
int CArrayTemplate<TYPE,ARG_TYPE>::Copy(const CArrayTemplate & Src)
{
//效验参数
ASSERT_VALID(this);
ASSERT(this!=&Src);
if (this==&Src)
{
return 0;
}
//拷贝数组
AllocMemory(Src.m_nElementCount);
if (m_nElementCount>0)
{
for (int i=0;i<m_nElementCount;i++)
{
(m_pData+i)->~TYPE();
}
memset(m_pData,0,m_nElementCount*sizeof(TYPE));
}
for (int i=0;i<Src.m_nElementCount;i++)
{
m_pData[i]=Src.m_pData[i];
}
m_nElementCount=Src.m_nElementCount;
return m_nElementCount;
}
//追加数组
template<class TYPE, class ARG_TYPE>
int CArrayTemplate<TYPE,ARG_TYPE>::Append(const CArrayTemplate & Src)
{
//效验参数
ASSERT_VALID(this);
ASSERT(this!=&Src);
//if (this==&Src) AfxThrowInvalidArgException();
//拷贝数组
if (Src.m_nElementCount>0)
{
AllocMemory(m_nElementCount+Src.m_nElementCount);
for (int i=0;i<Src.m_nElementCount;i++)
{
m_pData[m_nElementCount+i]=Src.m_pData[i];
}
m_nElementCount+=Src.m_nElementCount;
}
return m_nElementCount;
}
//获取元素
template<class TYPE, class ARG_TYPE>
TYPE & CArrayTemplate<TYPE,ARG_TYPE>::GetAt(int nIndex)
{
ASSERT((nIndex>=0)&&(nIndex<m_nElementCount));
if ((nIndex>=0)&&(nIndex<m_nElementCount))
{
return m_pData[nIndex];
}
//AfxThrowInvalidArgException();
}
//获取元素
template<class TYPE, class ARG_TYPE>
const TYPE & CArrayTemplate<TYPE,ARG_TYPE>::GetAt(int nIndex) const
{
ASSERT((nIndex>=0)&&(nIndex<m_nElementCount));
if ((nIndex>=0)&&(nIndex<m_nElementCount))
{
return m_pData[nIndex];
}
//AfxThrowInvalidArgException();
}
//获取元素
template<class TYPE, class ARG_TYPE>
TYPE & CArrayTemplate<TYPE,ARG_TYPE>::ElementAt(int nIndex)
{
ASSERT((nIndex>=0)&&(nIndex<m_nElementCount));
if ((nIndex>=0)&&(nIndex<m_nElementCount))
{
return m_pData[nIndex];
}
}
//获取元素
template<class TYPE, class ARG_TYPE>
const TYPE & CArrayTemplate<TYPE,ARG_TYPE>::ElementAt(int nIndex) const
{
ASSERT((nIndex>=0)&&(nIndex<m_nElementCount));
if ((nIndex>=0)&&(nIndex<m_nElementCount))
{
return m_pData[nIndex];
}
}
//设置大小
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::SetSize(int nNewSize)
{
//效验参数
//ASSERT_VALID(this);
ASSERT(nNewSize>=0);
//if (nNewSize<0) AfxThrowInvalidArgException();
//设置大小
AllocMemory(nNewSize);
if (nNewSize>m_nElementCount)
{
#pragma push_macro("new")
#undef new
for (int i=m_nElementCount;i<nNewSize;i++)
{
::new ((void *)(m_pData+i)) TYPE;
}
#pragma pop_macro("new")
}
else if (nNewSize<m_nElementCount)
{
for (int i=nNewSize;i<m_nElementCount;i++)
{
(m_pData+i)->~TYPE();
}
memset(m_pData+nNewSize,0,(m_nElementCount-nNewSize)*sizeof(TYPE));
}
m_nElementCount=nNewSize;
return;
}
//设置元素
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::SetAt(int nIndex, ARG_TYPE newElement)
{
ASSERT((nIndex>=0)&&(nIndex<m_nElementCount));
if ((nIndex>=0)&&(nIndex<m_nElementCount))
{
m_pData[nIndex]=newElement;
}
}
//设置元素
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement)
{
//效验参数
//ASSERT_VALID(this);
ASSERT(nIndex>=0);
//if (nIndex<0) AfxThrowInvalidArgException();
//设置元素
if (nIndex>=m_nElementCount)
{
SetSize(m_nElementCount+1);
}
m_pData[nIndex]=newElement;
return;
}
//插入数据
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::InsertAt(int nIndex, const CArrayTemplate & Src)
{
//效验参数
//ASSERT_VALID(this);
ASSERT(nIndex>=0);
//if (nIndex<0) AfxThrowInvalidArgException();
int nCount = Src.m_nElementCount;
if (nCount>0)
{
//申请数组
if (nIndex<m_nElementCount)
{
int nOldCount=m_nElementCount;
SetSize(m_nElementCount+nCount);
for (int i=0;i<nCount;i++)
{
(m_pData+nOldCount+i)->~TYPE();
}
memmove(m_pData+nIndex+nCount,m_pData+nIndex,(nOldCount-nIndex)*sizeof(TYPE));
memset(m_pData+nIndex,0,nCount*sizeof(TYPE));
#pragma push_macro("new")
#undef new
for (int i=0;i<nCount;i++)
{
#pragma warning(disable:4345)
::new (m_pData+nIndex+i) TYPE();
#pragma warning(default:4345)
}
#pragma pop_macro("new")
}
else
{
SetSize(nIndex+nCount);
}
//拷贝数组
ASSERT((nIndex+nCount)<=m_nElementCount);
for (int i=0;i<nCount;i++)
{
m_pData[nIndex+i]=Src.m_pData[i];
}
}
return;
}
//插入数据
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount)
{
//效验参数
//ASSERT_VALID(this);
ASSERT(nIndex>=0);
ASSERT(nCount>0);
//if ((nIndex<0)||(nCount<=0)) AfxThrowInvalidArgException();
//申请数组
if (nIndex<m_nElementCount)
{
int nOldCount=m_nElementCount;
SetSize(m_nElementCount+nCount);
for (int i=0;i<nCount;i++)
{
(m_pData+nOldCount+i)->~TYPE();
}
memmove(m_pData+nIndex+nCount,m_pData+nIndex,(nOldCount-nIndex)*sizeof(TYPE));
memset(m_pData+nIndex,0,nCount*sizeof(TYPE));
#pragma push_macro("new")
#undef new
for (int i=0;i<nCount;i++)
{
#pragma warning(disable:4345)
::new (m_pData+nIndex+i) TYPE();
#pragma warning(default:4345)
}
#pragma pop_macro("new")
}
else
{
SetSize(nIndex+nCount);
}
//拷贝数组
ASSERT((nIndex+nCount)<=m_nElementCount);
while (nCount--)
{
m_pData[nIndex++]=newElement;
}
return;
}
//删除数据
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::RemoveAt(int nIndex, int nCount)
{
//效验参数
//ASSERT_VALID(this);
ASSERT(nIndex>=0);
ASSERT(nCount>=0);
ASSERT(nIndex+nCount<=m_nElementCount);
//if ((nIndex<0)||(nCount<0)||((nIndex+nCount>m_nElementCount))) AfxThrowInvalidArgException();
//删除数据
int nMoveCount=m_nElementCount-(nIndex+nCount);
for (int i=0;i<nCount;i++)
{
(m_pData+nIndex+i)->~TYPE();
}
if (nMoveCount>0)
{
memmove(m_pData+nIndex,m_pData+nIndex+nCount,nMoveCount*sizeof(TYPE));
}
m_nElementCount-=nCount;
return;
}
//删除元素
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::RemoveAll()
{
//ASSERT_VALID(this);
if (m_nElementCount>0)
{
for (int i=0;i<m_nElementCount;i++)
{
(m_pData+i)->~TYPE();
}
memset(m_pData,0,m_nElementCount*sizeof(TYPE));
m_nElementCount=0;
}
return;
}
//降序排序,要求对象类型重载 >
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::Sort(int nLower, int nUpper)
{
//是否排序完毕
if (nLower < nUpper)
{
// 分区排序
int nSplit = Partition(nLower, nUpper);
Sort(nLower, nSplit-1);//左区排序
Sort(nSplit+1, nUpper);//右区排序
}
}
//快速排序法的数据分区
template<class TYPE, class ARG_TYPE>
int CArrayTemplate<TYPE,ARG_TYPE>::Partition(int nLower, int nUpper)
{
int nLeft = nLower + 1;
TYPE &RefObj = m_pData[nLower];
int nRight = nUpper;
TYPE Swap;
while (nLeft <= nRight)
{
while (nLeft <= nRight && (*m_pData[nLeft]) > (*RefObj))
{
nLeft++;
}
while (nLeft <= nRight && !((*m_pData[nRight]) > (*RefObj)))
{
nRight--;
}
if (nLeft < nRight)
{
Swap = m_pData[nLeft];
m_pData[nLeft] = m_pData[nRight];
m_pData[nRight] = Swap;
nLeft++;
nRight--;
}
}
Swap = m_pData[nLower];
m_pData[nLower] = m_pData[nRight];
m_pData[nRight] = Swap;
return nRight;
}
//申请内存
template<class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE,ARG_TYPE>::AllocMemory(int nNewCount)
{
//效验参数
//ASSERT_VALID(this);
ASSERT(nNewCount>=0);
if (nNewCount>m_nMaxCount)
{
//计算数目
int nGrowCount=m_nGrowCount;
if (nGrowCount==0)
{
nGrowCount=(m_nElementCount>>3);
nGrowCount=(nGrowCount<4)?4:((nGrowCount>1024)?1024:nGrowCount);
}
nNewCount+=nGrowCount;
//申请内存
TYPE * pNewData=(TYPE *) new BYTE[nNewCount*sizeof(TYPE)];
//memcpy(pNewData,m_pData,m_nElementCount*sizeof(TYPE)); //old modify by myz
memmove(pNewData,m_pData,m_nElementCount*sizeof(TYPE));
memset(pNewData+m_nElementCount,0,(nNewCount-m_nElementCount)*sizeof(TYPE));
delete [] (BYTE *)m_pData;
//设置变量
m_pData=pNewData;
m_nMaxCount=nNewCount;
}
}
//交换变量
template <class TYPE, class ARG_TYPE>
void CArrayTemplate<TYPE, ARG_TYPE>::SwitchValue( int a, int b )
{
//ASSERT_VALID(this);
ASSERT(a<m_nElementCount && b<m_nElementCount);
if (a<m_nElementCount && b<m_nElementCount)
{
TYPE temp=m_pData[a];
m_pData[a]=m_pData[b];
m_pData[b]=temp;
}
}
//增加不同的值
template <class TYPE, class ARG_TYPE>
int CArrayTemplate<TYPE, ARG_TYPE>::AddDistinct( ARG_TYPE newElement )
{
for ( int i=0; i<m_nElementCount; i++ )
{
if (m_pData[i]==newElement)
{
return i;
}
}
return Add(newElement);
}
//删除指定元素
template <class TYPE, class ARG_TYPE>
int CArrayTemplate<TYPE, ARG_TYPE>::RemoveItem( ARG_TYPE newElement )
{
for ( int i=0; i<m_nElementCount; i++ )
{
if (m_pData[i]==newElement)
{
RemoveAt(i);
return i;
}
}
return -1;
}
//////////////////////////////////////////////////////////////////////////
//常用数组类
typedef CArrayTemplate<void *> CSHPtrArray;
typedef CArrayTemplate<void *> CSHCPtrArray;
//删除CArrayTemplate指针数组
template<typename T>
void GGDeletePtrArray( CArrayTemplate<T*> &ary )
{
if (!ary.IsEmpty())
{
for ( int i=ary.GetCount()-1; i>=0; i-- )
{
T *&pObj=ary[i];
if (pObj!=NULL)
{
delete pObj;
}
}
ary.RemoveAll();
}
}
//释放CArrayTemplate指针数组
template<typename T>
void GGReleasePtrArray( CArrayTemplate<T*> &ary )
{
if (!ary.IsEmpty())
{
for ( int i=ary.GetCount()-1; i>=0; i-- )
{
T *&pObj=ary[i];
if (pObj!=NULL)
{
pObj->Release();
}
}
ary.RemoveAll();
}
}
//////////////////////////////////////////////////////////////////////////
#endif