void C4ValueArray::SetSlice(int32_t startIndex, int32_t endIndex, const C4Value &Val) { // maximum bounds if(startIndex >= MaxSize) throw C4AulExecError("array slice: start index exceeds maximum capacity"); // index from back if(startIndex < 0) startIndex += iSize; if(endIndex < 0) endIndex += iSize; // ensure relevant bounds if(startIndex < 0) throw C4AulExecError("array slice: start index out of range"); if(endIndex < 0) throw C4AulExecError("array slice: end index out of range"); if(endIndex < startIndex) endIndex = startIndex; // setting an array? if(Val.GetType() == C4V_Array) { const C4ValueArray &Other = *Val._getArray(); // Remember that &Other could be equal to this, carefull with modifying pData // Calculcate new size int32_t iNewEnd = std::min(startIndex + Other.GetSize(), (int32_t)MaxSize); int32_t iNewSize = iNewEnd; if(endIndex < iSize) iNewSize += iSize - endIndex; iNewSize = std::min(iNewSize, (int32_t)MaxSize); int32_t iOtherSize = Other.GetSize(); if(iNewSize != iSize) { int32_t i,j; C4Value* pnData = pData; if(iNewSize > iCapacity) { pnData = new C4Value [iNewSize]; // 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; i < iNewSize; ++i, ++j) { assert(j < iSize); pnData[i] = pData[j]; } // Copy the data // Since pnData and pData can be the same, we can not copy with //for(i = startIndex, j = 0; i < iNewEnd; ++i, ++j) // but have to start from the end of the copied sequence. That works, since j <= i for(i = iNewEnd - 1, j = iNewEnd - startIndex - 1; i >= startIndex; --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 for(int32_t i = startIndex, j = 0; j < iOtherSize; i++, j++) pData[i] = Other.pData[j]; } else { /* if(Val.GetType() != C4V_Array) */ if(endIndex > MaxSize) endIndex = iSize; // Need resize? if(endIndex > iSize) SetSize(endIndex); // Fill for(int32_t i = startIndex; i < endIndex; i++) pData[i] = Val; } }
bool operator ()(const C4Value &v1, const C4Value &v2) { return value_sort(v1._getArray()->GetItem(element_idx), v2._getArray()->GetItem(element_idx)); }