X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c801d85f158c4cba50b588807daabdcbd0ed3853..d1427b705318677afe28b1291867f6930c8823a7:/src/common/dynarray.cpp diff --git a/src/common/dynarray.cpp b/src/common/dynarray.cpp index cf2334db57..40ada21b23 100644 --- a/src/common/dynarray.cpp +++ b/src/common/dynarray.cpp @@ -2,7 +2,7 @@ // Name: dynarray.cpp // Purpose: implementation of wxBaseArray class // Author: Vadim Zeitlin -// Modified by: +// Modified by: // Created: 12.09.97 // RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin @@ -24,8 +24,10 @@ #endif #include "wx/dynarray.h" +#include #include +#include // for memmove #ifndef max #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -57,34 +59,32 @@ wxBaseArray::wxBaseArray() // copy ctor wxBaseArray::wxBaseArray(const wxBaseArray& src) { - m_uiSize = src.m_uiSize; + m_uiSize = // not src.m_uiSize to save memory m_uiCount = src.m_uiCount; - if ( m_uiSize != 0 ) + if ( m_uiSize != 0 ) { m_pItems = new long[m_uiSize]; + memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long)); + } else m_pItems = NULL; - - if ( m_uiCount != 0 ) - memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long)); } -// copy operator +// assignment operator wxBaseArray& wxBaseArray::operator=(const wxBaseArray& src) { - DELETEA(m_pItems); + wxDELETEA(m_pItems); - m_uiSize = src.m_uiSize; + m_uiSize = // not src.m_uiSize to save memory m_uiCount = src.m_uiCount; - if ( m_uiSize != 0 ) + if ( m_uiSize != 0 ) { m_pItems = new long[m_uiSize]; + memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long)); + } else m_pItems = NULL; - if ( m_uiCount != 0 ) - memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long)); - return *this; } @@ -101,7 +101,8 @@ void wxBaseArray::Grow() else { // add 50% but not too much - uint uiIncrement = m_uiSize >> 1; + uint uiIncrement = m_uiSize < WX_ARRAY_DEFAULT_INITIAL_SIZE + ? WX_ARRAY_DEFAULT_INITIAL_SIZE : m_uiSize >> 1; if ( uiIncrement > ARRAY_MAXSIZE_INCREMENT ) uiIncrement = ARRAY_MAXSIZE_INCREMENT; m_uiSize += uiIncrement; @@ -118,17 +119,16 @@ void wxBaseArray::Grow() // dtor wxBaseArray::~wxBaseArray() { - DELETEA(m_pItems); + wxDELETEA(m_pItems); } // clears the list void wxBaseArray::Clear() { - m_uiSize = + m_uiSize = m_uiCount = 0; - DELETEA(m_pItems); - m_pItems = NULL; + wxDELETEA(m_pItems); } // pre-allocates memory (frees the previous data!) @@ -138,7 +138,7 @@ void wxBaseArray::Alloc(uint uiSize) // only if old buffer was not big enough if ( uiSize > m_uiSize ) { - DELETEA(m_pItems); + wxDELETEA(m_pItems); m_pItems = new long[uiSize]; m_uiSize = uiSize; } @@ -147,7 +147,7 @@ void wxBaseArray::Alloc(uint uiSize) } // searches the array for an item (forward or backwards) -int wxBaseArray::Index(long lItem, Bool bFromEnd) const +int wxBaseArray::Index(long lItem, bool bFromEnd) const { if ( bFromEnd ) { if ( m_uiCount > 0 ) { @@ -169,6 +169,28 @@ int wxBaseArray::Index(long lItem, Bool bFromEnd) const return NOT_FOUND; } +// search for an item in a sorted array (binary search) +int wxBaseArray::Index(long lItem, CMPFUNC fnCompare) const +{ + uint i, + lo = 0, + hi = m_uiCount; + int res; + + while ( lo < hi ) { + i = (lo + hi)/2; + + res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]); + if ( res < 0 ) + hi = i; + else if ( res > 0 ) + lo = i + 1; + else + return i; + } + + return NOT_FOUND; +} // add item at the end void wxBaseArray::Add(long lItem) { @@ -176,14 +198,41 @@ void wxBaseArray::Add(long lItem) m_pItems[m_uiCount++] = lItem; } +// add item assuming the array is sorted with fnCompare function +void wxBaseArray::Add(long lItem, CMPFUNC fnCompare) +{ + uint i, + lo = 0, + hi = m_uiCount; + int res; + + while ( lo < hi ) { + i = (lo + hi)/2; + + res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]); + if ( res < 0 ) + hi = i; + else if ( res > 0 ) + lo = i + 1; + else { + lo = hi = i; + break; + } + } + + wxASSERT( lo == hi ); // I hope I got binary search right :-) + + Insert(lItem, lo); +} + // add item at the given position void wxBaseArray::Insert(long lItem, uint uiIndex) { - wxCHECK( uiIndex <= m_uiCount ); + wxCHECK_RET( uiIndex <= m_uiCount, _("bad index in wxArray::Insert") ); Grow(); - memmove(&m_pItems[uiIndex + 1], &m_pItems[uiIndex], + memmove(&m_pItems[uiIndex + 1], &m_pItems[uiIndex], (m_uiCount - uiIndex)*sizeof(long)); m_pItems[uiIndex] = lItem; m_uiCount++; @@ -192,9 +241,9 @@ void wxBaseArray::Insert(long lItem, uint uiIndex) // removes item from array (by index) void wxBaseArray::Remove(uint uiIndex) { - wxCHECK( uiIndex <= m_uiCount ); + wxCHECK_RET( uiIndex <= m_uiCount, _("bad index in wxArray::Remove") ); - memmove(&m_pItems[uiIndex], &m_pItems[uiIndex + 1], + memmove(&m_pItems[uiIndex], &m_pItems[uiIndex + 1], (m_uiCount - uiIndex - 1)*sizeof(long)); m_uiCount--; } @@ -204,7 +253,8 @@ void wxBaseArray::Remove(long lItem) { int iIndex = Index(lItem); - wxCHECK( iIndex != NOT_FOUND ); + wxCHECK_RET( iIndex != NOT_FOUND, + _("removing inexistent item in wxArray::Remove") ); Remove((uint)iIndex); }