有趣的数组类 模板
template <class T>
class CSimpleArrayEqualHelper
{
static bool isEqual(const T& t1, const T& t2)
{
return (t1 == t2);
}
};
template <class T, class TEqual = CSimpleArrayEqualHelper<T>, typename INARGTYPE = const T&>
class CSimpleArray
{
public:
CSimpleArray(): m_nSize(0), m_aT(NULL), m_nAllocSize(0)
{
}
// copy-constructor
CSimpleArray(const CSimpleArray<T, TEqual> &src):m_nSize(0), m_aT(NULL), m_nAllocSize(0)
{
if (src.getSize())
{
m_aT = (T *)calloc(src.getSize(), sizeof(T));
if (m_aT != NULL)
{
m_nAllocSize = src.getSize();
for (int i = 0; i < m_nAllocSize; i++)
{
add(src[i]);
}
}
}
}
CSimpleArray<T, TEqual>& operator= (const CSimpleArray<T, TEqual> &scr)
{
if (this != &src)
{
if (getSize() != src.getSize())
{
removeAll();
m_aT = (T *)calloc(src.getSize(), sizeof(T));
if (m_aT)
{
m_aAllocSize = src.getSize();
}
}
else
{
for (int i = getSize() - 1; i >= 0; i--)
removeAtIndex(i);
}
for (int i = 0; i < src.getSize(); i++)
{
add(src[i]);
}
}
return *this;
}
~CSimpleArray()
{
removeAll();
}
int getSize() const
{
return m_nSize;
}
bool add(INARGTYPE t)
{
if (getSize() == m_nAllocSize)
{
int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (2 * m_nAllocSize);
T* aT = (T *)realloc(m_aT, nNewAllocSize * sizeof(T));
if (aT == NULL)
return false;
m_nAllocSize = nNewAllocSize;
m_aT = aT;
}
InternalSetAtIndex(m_nSize, t);
m_nSize++;
return true;
}
bool remove(const T& t)
{
int index = find(t);
if (index == -1)
return false;
return removeAt(index);
}
bool removeAt(int index)
{
assert((index < m_nSize) && (index >= 0));
if ((index < 0) || (index > m_nSize))
return false;
m_aT[index].~T();
if (index != m_nSize - 1)
memcpy((void *)&m_aT[index], (void *)&m_aT[index + 1], (m_nSize - index - 1) * sizeof(T));
m_nSize--;
return true;
}
void removeAll()
{
if (m_aT != NULL)
{
for (int i = 0; i < m_nSize; i++)
m_aT[i].~T();
}
free(m_aT);
m_aT = NULL;
}
const T& operator[](int index) const
{
assert((index < m_nSize) && (index >= 0));
return m_aT[index];
}
T& operator[](int index)
{
assert((index < m_nSize) && (index >= 0));
return m_aT[index];
}
int find(const T &t)
{
for (int i = 0; i < m_nSize; i++)
{
if(TEqual::isEqual(t, m_aT[i]))
return i;
}
return -1;
}
class Wrapper
{
public:
Wrapper(const T& _t): t(_t)
{
}
template <class _Ty>
void * __cdecl operator new(size_t, _Ty *p)
{
return p;
}
template <class _Ty>
void __cdecl operator delete(void *, _Ty *)
{
}
T t;
};
void InternalSetAtIndex(int index, const T& t)
{
new(m_aT + index) Wrapper(t);
}
private:
int m_nSize;
T* m_aT;
int m_nAllocSize;
};