예제 #1
0
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;

    }

}
예제 #2
0
 bool operator ()(const C4Value &v1, const C4Value &v2)
 {
     return value_sort(v1._getArray()->GetItem(element_idx), v2._getArray()->GetItem(element_idx));
 }