#ifndef _TVector_H_
#define _TVector_H_
#pragma warning(disable:4291) template<
class TValue,
class EqualsFunctionType = DefaultNoEquals,
class CompareFunctionType = DefaultNoCompare
>
class TVector {
protected:
TValue* m_pvalue;
int m_count;
int m_countAlloc;
EqualsFunctionType m_fnEquals;
CompareFunctionType m_fnCompare;
public:
TVector(int count = 0) :
m_count(count),
m_countAlloc(count)
{
ZAssert(m_countAlloc >= 0);
if (m_countAlloc == 0) {
m_pvalue = NULL;
} else {
m_pvalue = new TValue[m_countAlloc];
}
}
TVector(int countAlloc, int initCount) :
m_count(initCount),
m_countAlloc(countAlloc)
{
ZAssert(m_countAlloc >= 0);
ZAssert(m_count <= m_countAlloc);
if (m_countAlloc == 0) {
m_pvalue = NULL;
} else {
m_pvalue = new TValue[m_countAlloc];
}
}
TVector(const TVector& tvec) :
m_count(tvec.GetCount()),
m_countAlloc(tvec.GetCount())
{
if (m_countAlloc == 0) {
m_pvalue = NULL;
} else {
m_pvalue = new TValue[m_countAlloc];
for (int index = 0; index < m_count; index++) {
m_pvalue[index] = tvec[index];
}
}
}
TVector(int count, TValue* pvalue, bool bStatic = false) :
m_count(count)
{
ZAssert(count >= 0);
if (bStatic) {
m_countAlloc = 0;
m_pvalue = pvalue;
} else {
m_countAlloc = m_count;
m_pvalue = new TValue[m_count];
for (int index = 0; index < m_count; index++) {
m_pvalue[index] = pvalue[index];
}
}
}
~TVector()
{
if (m_countAlloc != 0) {
delete[] m_pvalue;
}
}
void SetCount(int count)
{
if (m_countAlloc == 0) {
if (count > m_count) {
m_countAlloc = count;
TValue* m_pvalueNew = new TValue[m_countAlloc];
for(int index = 0; index < m_count; index++) {
m_pvalueNew[index] = m_pvalue[index];
}
m_pvalue = m_pvalueNew;
}
} else if (count > m_countAlloc) {
while (m_countAlloc < count) m_countAlloc *= 2;
TValue* m_pvalueNew = new TValue[m_countAlloc];
for(int index = 0; index < m_count; index++) {
m_pvalueNew[index] = m_pvalue[index];
}
delete[] m_pvalue;
m_pvalue = m_pvalueNew;
}
m_count = count;
}
void Reserve(int count)
{
ZAssert(count > 0);
if (count <= 0)
return;
if (m_countAlloc == 0) {
m_pvalue = new TValue[count];
} else if (count > m_countAlloc) {
TValue* m_pvalueNew = new TValue[count];
for(int index = 0; index < m_count; index++) {
m_pvalueNew[index] = m_pvalue[index];
}
delete[] m_pvalue;
m_pvalue = m_pvalueNew;
}
m_countAlloc = count;
}
void SetWritable()
{
if (m_countAlloc == 0 && m_count != 0) {
m_countAlloc = m_count;
TValue* m_pvalueNew = new TValue[m_countAlloc];
for(int index = 0; index < m_count; index++) {
m_pvalueNew[index] = m_pvalue[index];
}
m_pvalue = m_pvalueNew;
}
}
void operator=(const TVector& tvec)
{
SetCount(tvec.GetCount());
SetWritable();
for (int index = 0; index < m_count; index++) {
m_pvalue[index] = tvec.m_pvalue[index];
}
}
const TValue& operator[](int index) const
{
ZAssert(index >= 0 && index < m_count);
return m_pvalue[index];
}
TValue& Get(int index)
{
ZAssert(index >= 0 && index < m_count);
SetWritable();
return m_pvalue[index];
}
void Set(int index, const TValue& value)
{
ZAssert(index >= 0 && index < m_count);
SetWritable();
m_pvalue[index] = value;
}
void SetEmpty()
{
if (m_countAlloc != 0) {
delete[] m_pvalue;
}
m_pvalue = NULL;
m_count = 0;
m_countAlloc = 0;
}
void SetAll(const TValue& value)
{
SetWritable();
for (int index = 0; index < m_count; index++) {
m_pvalue[index] = value;
}
}
TValue& GetFront() const
{
ZAssert(m_count > 0);
return m_pvalue[0];
}
TValue& GetEnd() const
{
ZAssert(m_count > 0);
return m_pvalue[m_count - 1];
}
void Remove(int index)
{
ZAssert(index >= 0 && index < m_count);
SetWritable();
for (int i = index; i < m_count - 1; i++) {
m_pvalue[i] = m_pvalue[i+1];
}
m_count--;
}
int Remove(const TValue& value)
{
int index = Find(value);
if (index != -1) {
Remove(index);
}
return index;
}
void Insert(int index, const TValue& value)
{
ZAssert(index >= 0 && index <= m_count);
SetCount(m_count + 1);
SetWritable();
for (int i = m_count - 1; i > index; i--) {
m_pvalue[i] = m_pvalue[i-1];
}
m_pvalue[index] = value;
}
void Insert(int index)
{
ZAssert(index >= 0 && index <= m_count);
SetCount(m_count + 1);
SetWritable();
for (int i = m_count - 1; i > index; i--) {
m_pvalue[i] = m_pvalue[i-1];
}
}
void PushFront(const TValue& value)
{
Insert(0, value);
}
void PushFront()
{
Insert(0);
}
void PushEnd(const TValue& value)
{
Insert(GetCount(), value);
}
void PushEnd()
{
Insert(GetCount());
}
template<class Type>
void PushEnd(const TVector<Type>& values)
{
int count = m_count;
int pushCount = values.GetCount();
SetCount(count + pushCount);
SetWritable();
for (int index = 0; index < pushCount; index++) {
m_pvalue[index + count] = values[index];
}
}
int Find(const TValue& value)
{
for (int index = 0; index < m_count; index++) {
if (m_fnEquals(((const TValue&)m_pvalue[index]), value)) {
return index;
}
}
return -1;
}
int GetCount() const
{
return m_count;
}
void Sort(int startArg, int endArg)
{
endArg--;
if (startArg < endArg) {
int start = startArg;
int end = endArg;
TValue valueMid = m_pvalue[(start + end) / 2];
do {
while (start < end && !m_fnCompare(m_pvalue[start], valueMid)) {
start++;
}
while (start < end && !m_fnCompare(valueMid, m_pvalue[end])) {
end--;
}
if (start < end) {
TValue valueTemp = m_pvalue[start];
m_pvalue[start] = m_pvalue[end];
m_pvalue[end] = valueTemp;
start++;
end--;
}
} while (start < end);
Sort(startArg, start);
Sort(start + 1, endArg + 1);
}
}
void Sort()
{
SetWritable();
Sort(0, m_count);
}
};
#endif