1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: implementation of wxBaseArray class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
17 #pragma implementation "dynarray.h"
20 #include "wx/wxprec.h"
26 #include "wx/dynarray.h"
30 #include <string.h> // for memmove
33 #define max(a, b) (((a) > (b)) ? (a) : (b))
36 // ============================================================================
38 // ============================================================================
40 // size increment = max(50% of current size, ARRAY_MAXSIZE_INCREMENT)
41 #define ARRAY_MAXSIZE_INCREMENT 4096
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
48 // wxBaseArray - dynamice array of 'long's
49 // ----------------------------------------------------------------------------
52 wxBaseArray::wxBaseArray()
56 m_pItems
= (long *) NULL
;
60 wxBaseArray::wxBaseArray(const wxBaseArray
& src
)
62 m_nSize
= // not src.m_nSize to save memory
63 m_nCount
= src
.m_nCount
;
66 m_pItems
= new long[m_nSize
];
67 memcpy(m_pItems
, src
.m_pItems
, m_nCount
*sizeof(long));
70 m_pItems
= (long *) NULL
;
73 // assignment operator
74 wxBaseArray
& wxBaseArray::operator=(const wxBaseArray
& src
)
85 m_nSize
= // not src.m_nSize to save memory
86 m_nCount
= src
.m_nCount
;
89 m_pItems
= new long[m_nSize
];
90 memcpy(m_pItems
, src
.m_pItems
, m_nCount
*sizeof(long));
93 m_pItems
= (long *) NULL
;
99 void wxBaseArray::Grow()
101 // only do it if no more place
102 if( m_nCount
== m_nSize
) {
104 // was empty, alloc some memory
105 m_nSize
= WX_ARRAY_DEFAULT_INITIAL_SIZE
;
106 m_pItems
= new long[m_nSize
];
110 // add 50% but not too much
111 size_t nIncrement
= m_nSize
< WX_ARRAY_DEFAULT_INITIAL_SIZE
112 ? WX_ARRAY_DEFAULT_INITIAL_SIZE
: m_nSize
>> 1;
113 if ( nIncrement
> ARRAY_MAXSIZE_INCREMENT
)
114 nIncrement
= ARRAY_MAXSIZE_INCREMENT
;
115 m_nSize
+= nIncrement
;
116 long *pNew
= new long[m_nSize
];
118 // copy data to new location
119 memcpy(pNew
, m_pItems
, m_nCount
*sizeof(long));
127 wxBaseArray::~wxBaseArray()
133 void wxBaseArray::Clear()
141 // pre-allocates memory (frees the previous data!)
142 void wxBaseArray::Alloc(size_t nSize
)
144 wxASSERT( nSize
> 0 );
146 // only if old buffer was not big enough
147 if ( nSize
> m_nSize
) {
149 m_pItems
= new long[nSize
];
156 // minimizes the memory usage by freeing unused memory
157 void wxBaseArray::Shrink()
159 // only do it if we have some memory to free
160 if( m_nCount
< m_nSize
) {
161 // allocates exactly as much memory as we need
162 long *pNew
= new long[m_nCount
];
164 // copy data to new location
165 memcpy(pNew
, m_pItems
, m_nCount
*sizeof(long));
171 // searches the array for an item (forward or backwards)
172 int wxBaseArray::Index(long lItem
, bool bFromEnd
) const
175 if ( m_nCount
> 0 ) {
178 if ( m_pItems
[--n
] == lItem
)
185 for( size_t n
= 0; n
< m_nCount
; n
++ ) {
186 if( m_pItems
[n
] == lItem
)
194 // search for an item in a sorted array (binary search)
195 int wxBaseArray::Index(long lItem
, CMPFUNC fnCompare
) const
205 res
= (*fnCompare
)((const void *)lItem
, (const void *)m_pItems
[i
]);
216 // add item at the end
217 void wxBaseArray::Add(long lItem
)
220 m_pItems
[m_nCount
++] = lItem
;
223 // add item assuming the array is sorted with fnCompare function
224 void wxBaseArray::Add(long lItem
, CMPFUNC fnCompare
)
234 res
= (*fnCompare
)((const void *)lItem
, (const void *)m_pItems
[i
]);
245 wxASSERT( lo
== hi
); // I hope I got binary search right :-)
250 // add item at the given position
251 void wxBaseArray::Insert(long lItem
, size_t nIndex
)
253 wxCHECK_RET( nIndex
<= m_nCount
, wxT("bad index in wxArray::Insert") );
257 memmove(&m_pItems
[nIndex
+ 1], &m_pItems
[nIndex
],
258 (m_nCount
- nIndex
)*sizeof(long));
259 m_pItems
[nIndex
] = lItem
;
263 // removes item from array (by index)
264 void wxBaseArray::RemoveAt(size_t nIndex
)
266 wxCHECK_RET( nIndex
<= m_nCount
, wxT("bad index in wxArray::RemoveAt") );
268 memmove(&m_pItems
[nIndex
], &m_pItems
[nIndex
+ 1],
269 (m_nCount
- nIndex
- 1)*sizeof(long));
273 // removes item from array (by value)
274 void wxBaseArray::Remove(long lItem
)
276 int iIndex
= Index(lItem
);
278 wxCHECK_RET( iIndex
!= wxNOT_FOUND
,
279 wxT("removing inexistent item in wxArray::Remove") );
281 RemoveAt((size_t)iIndex
);
284 // sort array elements using passed comparaison function
285 void wxBaseArray::Sort(CMPFUNC fCmp
)
287 qsort(m_pItems
, m_nCount
, sizeof(long), fCmp
);