void CStringArray::InsertEmpty(int nIndex, int nCount) { ASSERT_VALID(this); ASSERT(nIndex >= 0); // will expand to meet need ASSERT(nCount > 0); // zero or negative size not allowed if (nIndex >= m_nSize) { // adding after the end of the array SetSize(nIndex + nCount); // grow so nIndex is valid } else { // inserting in the middle of the array int nOldSize = m_nSize; SetSize(m_nSize + nCount); // grow it to new size // shift old data up to fill gap memmove(&m_pData[nIndex+nCount], &m_pData[nIndex], (nOldSize-nIndex) * sizeof(CString)); // re-init slots we copied from ConstructElements(&m_pData[nIndex], nCount); } // insert new value in the gap ASSERT(nIndex + nCount <= m_nSize); }
void CStringArray::SetSize(int nNewSize, int nGrowBy) { ASSERT_VALID(this); ASSERT(nNewSize >= 0); if (nGrowBy != -1) m_nGrowBy = nGrowBy; // set new size if (nNewSize == 0) { // shrink to nothing DestructElements(m_pData, m_nSize); delete[] (BYTE*)m_pData; m_pData = NULL; m_nSize = m_nMaxSize = 0; } else if (m_pData == NULL) { // create one with exact size #ifdef SIZE_T_MAX ASSERT(nNewSize <= SIZE_T_MAX/sizeof(CString)); // no overflow #endif m_pData = (CString*) new BYTE[nNewSize * sizeof(CString)]; ConstructElements(m_pData, nNewSize); m_nSize = m_nMaxSize = nNewSize; } else if (nNewSize <= m_nMaxSize) { // it fits if (nNewSize > m_nSize) { // initialize the new elements ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize); } else if (m_nSize > nNewSize) // destroy the old elements DestructElements(&m_pData[nNewSize], m_nSize-nNewSize); m_nSize = nNewSize; } else { // otherwise, grow array int nGrowBy = m_nGrowBy; if (nGrowBy == 0) { // heuristically determine growth when nGrowBy == 0 // (this avoids heap fragmentation in many situations) nGrowBy = min(1024, max(4, m_nSize / 8)); } int nNewMax; if (nNewSize < m_nMaxSize + nGrowBy) nNewMax = m_nMaxSize + nGrowBy; // granularity else nNewMax = nNewSize; // no slush ASSERT(nNewMax >= m_nMaxSize); // no wrap around #ifdef SIZE_T_MAX ASSERT(nNewMax <= SIZE_T_MAX/sizeof(CString)); // no overflow #endif CString* pNewData = (CString*) new BYTE[nNewMax * sizeof(CString)]; // copy new data from old memcpy(pNewData, m_pData, m_nSize * sizeof(CString)); // construct remaining elements ASSERT(nNewSize > m_nSize); ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize); // get rid of old stuff (note: no destructors called) delete[] (BYTE*)m_pData; m_pData = pNewData; m_nSize = nNewSize; m_nMaxSize = nNewMax; } }
void CBotStringArray::SetSize(int nNewSize) { if (nNewSize == 0) { // shrink to nothing DestructElements(m_pData, m_nSize); delete[] reinterpret_cast<unsigned char *>(m_pData); m_pData = NULL; m_nSize = m_nMaxSize = 0; } else if (m_pData == NULL) { // create one with exact size m_pData = reinterpret_cast<CBotString*> (new unsigned char[nNewSize * sizeof(CBotString)]); ConstructElements(m_pData, nNewSize); m_nSize = m_nMaxSize = nNewSize; } else if (nNewSize <= m_nMaxSize) { // it fits if (nNewSize > m_nSize) { // initialize the new elements ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize); } else if (m_nSize > nNewSize) // destroy the old elements DestructElements(&m_pData[nNewSize], m_nSize-nNewSize); m_nSize = nNewSize; } else { // otherwise, grow array int nGrowBy; { // heuristically determine growth when nGrowBy == 0 // (this avoids heap fragmentation in many situations) nGrowBy = std::min(1024, std::max(4, m_nSize / 8)); } int nNewMax; if (nNewSize < m_nMaxSize + nGrowBy) nNewMax = m_nMaxSize + nGrowBy; // granularity else nNewMax = nNewSize; // no slush CBotString* pNewData = reinterpret_cast<CBotString*> (new unsigned char[nNewMax * sizeof(CBotString)]); // copy new data from old memcpy(pNewData, m_pData, m_nSize * sizeof(CBotString)); // construct remaining elements ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize); // Get rid of old stuff (note: no destructors called) delete[] reinterpret_cast<unsigned char *>(m_pData); m_pData = pNewData; m_nSize = nNewSize; m_nMaxSize = nNewMax; } }