diff --git a/docs/latex/wx/array.tex b/docs/latex/wx/array.tex index c493cd1fb7..aa07dce168 100644 --- a/docs/latex/wx/array.tex +++ b/docs/latex/wx/array.tex @@ -201,6 +201,7 @@ does exactly the same as \helpref{Item()}{wxarrayitem} method. \helpref{Add}{wxarrayadd}\\ \helpref{Insert}{wxarrayinsert}\\ +\helpref{SetCount}{wxarraysetcount}\\ \helpref{WX\_APPEND\_ARRAY}{wxappendarray} \membersection{Removing items} @@ -590,6 +591,19 @@ array.RemoveAt(n) See also \helpref{WX\_CLEAR\_ARRAY}{wxcleararray} macro which deletes all elements of a wxArray (supposed to contain pointers). +\membersection{wxArray::SetCount}\label{wxarraysetcount} + +\func{void}{SetCount}{\param{size\_t }{count}, \param{T }{defval = T($0$)}} + +This function ensures that the number of array elements is at least +{\it count}. If the array has already {\it count} or mroe items, nothing is +done. Otherwise, {\tt count - GetCount()} elements are added and initialized to +the value {\it defval}. + +\wxheading{See also} + +\helpref{GetCount}{wxarraygetcount} + \membersection{wxArray::Shrink}\label{wxarrayshrink} \func{void}{Shrink}{\void} diff --git a/include/wx/dynarray.h b/include/wx/dynarray.h index f3dfbd09d3..6ff3d60383 100644 --- a/include/wx/dynarray.h +++ b/include/wx/dynarray.h @@ -90,11 +90,13 @@ public: \ void Alloc(size_t uiSize); \ void Shrink(); \ \ - size_t GetCount() const { return m_nCount; } \ - bool IsEmpty() const { return m_nCount == 0; } \ - size_t Count() const { return m_nCount; } \ + size_t GetCount() const { return m_nCount; } \ + void SetCount(size_t n, T defval = T(0)); \ + bool IsEmpty() const { return m_nCount == 0; } \ + size_t Count() const { return m_nCount; } \ \ typedef T base_type; \ + \ protected: \ T& Item(size_t uiIndex) const \ { wxASSERT( uiIndex < m_nCount ); return m_pItems[uiIndex]; } \ @@ -112,8 +114,8 @@ protected: \ void Sort(CMPFUNC fnCompare); \ \ private: \ - \ - void Grow(size_t nIncrement = 0); \ + void Grow(size_t nIncrement = 0); \ + bool Realloc(size_t nSize); \ \ size_t m_nSize, \ m_nCount; \ diff --git a/src/common/dynarray.cpp b/src/common/dynarray.cpp index 4d0ee51d28..72284fcb73 100644 --- a/src/common/dynarray.cpp +++ b/src/common/dynarray.cpp @@ -106,6 +106,23 @@ name& name::operator=(const name& src) \ return *this; \ } \ \ +/* allocate new buffer of the given size and move our data to it */ \ +bool name::Realloc(size_t nSize) \ +{ \ + T *pNew = new T[nSize]; \ + /* only grow if allocation succeeded */ \ + if ( !pNew ) \ + return false; \ + \ + m_nSize = nSize; \ + /* copy data to new location */ \ + memcpy(pNew, m_pItems, m_nCount*sizeof(T)); \ + delete [] m_pItems; \ + m_pItems = pNew; \ + \ + return true; \ +} \ + \ /* grow the array */ \ void name::Grow(size_t nIncrement) \ { \ @@ -131,19 +148,34 @@ void name::Grow(size_t nIncrement) \ ndefIncrement = ARRAY_MAXSIZE_INCREMENT; \ if ( nIncrement < ndefIncrement ) \ nIncrement = ndefIncrement; \ - T *pNew = new T[m_nSize + nIncrement]; \ - /* only grow if allocation succeeded */ \ - if ( pNew ) { \ - m_nSize += nIncrement; \ - /* copy data to new location */ \ - memcpy(pNew, m_pItems, m_nCount*sizeof(T)); \ - delete [] m_pItems; \ - m_pItems = pNew; \ - } \ + Realloc(m_nSize + nIncrement); \ } \ } \ } \ \ +/* make sure that the array has at least count elements */ \ +void name::SetCount(size_t count, T defval) \ +{ \ + if ( m_nSize < count ) \ + { \ + /* need to realloc memory: don't overallocate it here as if */ \ + /* SetCount() is called, it probably means that the caller */ \ + /* knows in advance how many elements there will be in the */ \ + /* array and so it won't be necessary to realloc it later */ \ + if ( !Realloc(count) ) \ + { \ + /* out of memory -- what can we do? */ \ + return; \ + } \ + } \ + \ + /* add new elements if we extend the array */ \ + while ( m_nCount < count ) \ + { \ + m_pItems[m_nCount++] = defval; \ + } \ +} \ + \ /* dtor */ \ name::~name() \ { \