Fix C4ValueArray

floating-point
Julius Michaelis 2012-04-09 22:04:03 +02:00
parent 6238c1d5be
commit 335a6e0598
2 changed files with 46 additions and 35 deletions

View File

@ -28,18 +28,18 @@
#include <C4Object.h>
C4ValueArray::C4ValueArray()
: iRefCnt(0), iSize(0), pData(NULL)
: iRefCnt(0), iSize(0), iCapacity(0), pData(NULL)
{
}
C4ValueArray::C4ValueArray(int32_t inSize)
: iRefCnt(0), iSize(0), pData(NULL)
: iRefCnt(0), iSize(0), iCapacity(0), pData(NULL)
{
SetSize(inSize);
}
C4ValueArray::C4ValueArray(const C4ValueArray &ValueArray2)
: iSize(0), pData(NULL)
: iSize(0), iCapacity(0), pData(NULL)
{
SetSize(ValueArray2.GetSize());
for (int32_t i = 0; i < iSize; i++)
@ -49,7 +49,7 @@ C4ValueArray::C4ValueArray(const C4ValueArray &ValueArray2)
C4ValueArray::~C4ValueArray()
{
delete[] pData; pData = NULL;
iSize = 0;
iSize = iCapacity = 0;
}
C4ValueArray &C4ValueArray::operator =(const C4ValueArray& ValueArray2)
@ -134,10 +134,10 @@ void C4ValueArray::SetSize(int32_t inSize)
{
if(inSize == iSize) return;
// array made smaller? Well, just ignore the additional allocated mem then
if (inSize < iSize)
// array not larger than allocated memory? Well, just ignore the additional allocated mem then
if (inSize <= iCapacity)
{
// free values in undefined area
// free values in undefined area, do nothing if new is larger than old
for (int i=inSize; i<iSize; i++) pData[i].Set0();
iSize=inSize;
return;
@ -158,7 +158,7 @@ void C4ValueArray::SetSize(int32_t inSize)
// replace
delete[] pData;
pData = pnData;
iSize = inSize;
iSize = iCapacity = inSize;
}
bool C4ValueArray::operator==(const C4ValueArray& IntList2) const
@ -173,7 +173,7 @@ bool C4ValueArray::operator==(const C4ValueArray& IntList2) const
void C4ValueArray::Reset()
{
delete[] pData; pData = NULL;
iSize = 0;
iSize = iCapacity = 0;
}
void C4ValueArray::Denumerate(C4ValueNumbers * numbers)
@ -221,12 +221,7 @@ C4ValueArray * C4ValueArray::GetSlice(int32_t startIndex, int32_t endIndex)
void C4ValueArray::SetSlice(int32_t startIndex, int32_t endIndex, const C4Value &Val)
{
// maximum bounds
if(startIndex > MaxSize) throw new C4AulExecError(NULL, "array slice: start index exceeds maximum range");
if(endIndex > MaxSize)
{
if(endIndex == INT_MAX) endIndex = iSize;
else throw new C4AulExecError(NULL, "array slice: end index exceeds maximum range");
}
if(startIndex >= MaxSize) throw new C4AulExecError(NULL, "array slice: start index exceeds maximum capacity");
// index from back
if(startIndex < 0) startIndex += iSize;
@ -244,40 +239,55 @@ void C4ValueArray::SetSlice(int32_t startIndex, int32_t endIndex, const C4Value
const C4ValueArray &Other = *Val._getArray(); // Remember that &Other could be equal to this, carefull with modifying pData
// Calculcate new size
int32_t iNewEnd = startIndex + Other.GetSize();
int32_t iNewEnd = Min(startIndex + Other.GetSize(), (int32_t)MaxSize);
int32_t iNewSize = iNewEnd;
if(endIndex < iSize)
iNewSize += iSize - endIndex;
iNewSize = Min(iNewSize, (int32_t)MaxSize);
int32_t iOtherSize = Other.GetSize();
if(iNewSize != iSize)
{
C4Value* pnData = new C4Value [iNewSize];
int32_t i,j;
C4Value* pnData = pData;
// Copy first part of old array
for(i = 0; i < startIndex && i < iSize; ++i)
pnData[i] = pData[i];
if(iNewSize > iCapacity)
{
pnData = new C4Value [iNewSize];
// Copy the data
for(i = startIndex, j = 0; j < iOtherSize; i++, j++)
pnData[i] = Other.pData[j];
// Copy first part of old array
for(i = 0; i < startIndex && i < iSize; ++i)
pnData[i] = pData[i];
}
// Copy the second slice of the new array
for(i = iNewEnd, j = endIndex; j < iSize; ++i, ++j)
for(i = iNewEnd, j = endIndex; i < iNewSize; ++i, ++j)
{
assert(i < iNewSize);
assert(j < iSize);
pnData[i] = pData[j];
}
// Other values should have been initialized to 0 by new
// Now replace pData
while(iSize--)
pData[iSize].Set0();
delete [] pData;
pData = pnData;
iSize = iNewSize;
// Copy the data
for(i = startIndex, j = 0; i < iNewEnd; ++i, ++j)
{
assert(j < iOtherSize);
pnData[i] = Other.pData[j];
}
// Other values should have been initialized to 0 by new
if(pData != pnData)
{
delete [] pData;
pData = pnData;
iCapacity = iSize = iNewSize;
}
else
{
// "ignore" the now unused part
for(i = iNewSize; i < iSize; ++i)
pData[i].Set0();
iSize = iNewSize;
}
} else // slice has the same size as inserted array
// Copy the data. changing pData does not break because if &Other == this and iNewSize == iSize, nothing happens at all
@ -285,6 +295,7 @@ void C4ValueArray::SetSlice(int32_t startIndex, int32_t endIndex, const C4Value
pData[i] = Other.pData[j];
} else /* if(Val.GetType() != C4V_Array) */ {
if(endIndex > MaxSize) endIndex = iSize;
// Need resize?
if(endIndex > iSize) SetSize(endIndex);

View File

@ -51,10 +51,10 @@ public:
}
C4Value operator[](int32_t iElem) const { return GetItem(iElem); }
C4Value &operator[](int32_t iElem);
C4Value &operator[](int32_t iElem); // interface for the engine, asserts that 0 <= index < MaxSize
void Reset();
void SetItem(int32_t iElemNr, const C4Value &Value);
void SetItem(int32_t iElemNr, const C4Value &Value); // interface for script
void SetSize(int32_t inSize); // (enlarge only!)
void Denumerate(C4ValueNumbers *);
@ -80,7 +80,7 @@ public:
private:
// Reference counter
unsigned int iRefCnt;
int32_t iSize;
int32_t iSize, iCapacity;
C4Value* pData;
};