]> git.saurik.com Git - wxWidgets.git/blame - src/common/dynarray.cpp
* Fixed two memory leaks.
[wxWidgets.git] / src / common / dynarray.cpp
CommitLineData
c801d85f
KB
1///////////////////////////////////////////////////////////////////////////////
2// Name: dynarray.cpp
3// Purpose: implementation of wxBaseArray class
4// Author: Vadim Zeitlin
3bfa4402 5// Modified by:
c801d85f
KB
6// Created: 12.09.97
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// headers
14// ============================================================================
15
16#ifdef __GNUG__
17#pragma implementation "dynarray.h"
18#endif
19
20#include <wx/wxprec.h>
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#include "wx/dynarray.h"
1a5a8367 27#include <wx/intl.h>
c801d85f
KB
28
29#include <stdlib.h>
3bfa4402 30#include <string.h> // for memmove
c801d85f
KB
31
32#ifndef max
33 #define max(a, b) (((a) > (b)) ? (a) : (b))
34#endif
35
36// ============================================================================
37// constants
38// ============================================================================
39
40// size increment = max(50% of current size, ARRAY_MAXSIZE_INCREMENT)
41#define ARRAY_MAXSIZE_INCREMENT 4096
42
43// ============================================================================
44// implementation
45// ============================================================================
46
47// ----------------------------------------------------------------------------
48// wxBaseArray - dynamice array of 'long's
49// ----------------------------------------------------------------------------
50
51// ctor
52wxBaseArray::wxBaseArray()
53{
54 m_uiSize =
55 m_uiCount = 0;
c67daf87 56 m_pItems = (long *) NULL;
c801d85f
KB
57}
58
59// copy ctor
60wxBaseArray::wxBaseArray(const wxBaseArray& src)
61{
3bfa4402 62 m_uiSize = // not src.m_uiSize to save memory
c801d85f
KB
63 m_uiCount = src.m_uiCount;
64
3bfa4402 65 if ( m_uiSize != 0 ) {
c801d85f 66 m_pItems = new long[m_uiSize];
3bfa4402
VZ
67 memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long));
68 }
c801d85f 69 else
c67daf87 70 m_pItems = (long *) NULL;
c801d85f
KB
71}
72
3bfa4402 73// assignment operator
c801d85f
KB
74wxBaseArray& wxBaseArray::operator=(const wxBaseArray& src)
75{
c67daf87 76#if 0
a3622daa 77 wxDELETEA(m_pItems);
c67daf87
UR
78#else
79 if ( (m_pItems)) {
80 delete (m_pItems);
81 (m_pItems) = 0;
82 }
83#endif
c801d85f 84
3bfa4402 85 m_uiSize = // not src.m_uiSize to save memory
c801d85f
KB
86 m_uiCount = src.m_uiCount;
87
3bfa4402 88 if ( m_uiSize != 0 ) {
c801d85f 89 m_pItems = new long[m_uiSize];
3bfa4402
VZ
90 memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long));
91 }
c801d85f 92 else
c67daf87 93 m_pItems = (long *) NULL;
c801d85f 94
c801d85f
KB
95 return *this;
96}
97
98// grow the array
99void wxBaseArray::Grow()
100{
101 // only do it if no more place
102 if( m_uiCount == m_uiSize ) {
103 if( m_uiSize == 0 ) {
104 // was empty, alloc some memory
105 m_uiSize = WX_ARRAY_DEFAULT_INITIAL_SIZE;
106 m_pItems = new long[m_uiSize];
107 }
108 else
109 {
110 // add 50% but not too much
c86f1403 111 size_t uiIncrement = m_uiSize < WX_ARRAY_DEFAULT_INITIAL_SIZE
d93f63db 112 ? WX_ARRAY_DEFAULT_INITIAL_SIZE : m_uiSize >> 1;
c801d85f
KB
113 if ( uiIncrement > ARRAY_MAXSIZE_INCREMENT )
114 uiIncrement = ARRAY_MAXSIZE_INCREMENT;
115 m_uiSize += uiIncrement;
116 long *pNew = new long[m_uiSize];
117
118 // copy data to new location
119 memcpy(pNew, m_pItems, m_uiCount*sizeof(long));
120 delete [] m_pItems;
121 m_pItems = pNew;
122 }
123 }
124}
125
126// dtor
127wxBaseArray::~wxBaseArray()
128{
a3622daa 129 wxDELETEA(m_pItems);
c801d85f
KB
130}
131
132// clears the list
133void wxBaseArray::Clear()
134{
3bfa4402 135 m_uiSize =
c801d85f
KB
136 m_uiCount = 0;
137
a3622daa 138 wxDELETEA(m_pItems);
c801d85f
KB
139}
140
141// pre-allocates memory (frees the previous data!)
c86f1403 142void wxBaseArray::Alloc(size_t uiSize)
c801d85f
KB
143{
144 wxASSERT( uiSize > 0 );
145
146 // only if old buffer was not big enough
147 if ( uiSize > m_uiSize ) {
a3622daa 148 wxDELETEA(m_pItems);
c801d85f
KB
149 m_pItems = new long[uiSize];
150 m_uiSize = uiSize;
151 }
152
153 m_uiCount = 0;
154}
155
156// searches the array for an item (forward or backwards)
05fafecd 157int wxBaseArray::Index(long lItem, bool bFromEnd) const
c801d85f
KB
158{
159 if ( bFromEnd ) {
160 if ( m_uiCount > 0 ) {
c86f1403 161 size_t ui = m_uiCount;
c801d85f
KB
162 do {
163 if ( m_pItems[--ui] == lItem )
164 return ui;
165 }
166 while ( ui != 0 );
167 }
168 }
169 else {
c86f1403 170 for( size_t ui = 0; ui < m_uiCount; ui++ ) {
c801d85f
KB
171 if( m_pItems[ui] == lItem )
172 return ui;
173 }
174 }
175
176 return NOT_FOUND;
177}
178
3bfa4402 179// search for an item in a sorted array (binary search)
e99c3048 180int wxBaseArray::Index(long lItem, CMPFUNC fnCompare) const
3bfa4402 181{
c86f1403 182 size_t i,
3bfa4402
VZ
183 lo = 0,
184 hi = m_uiCount;
185 int res;
186
187 while ( lo < hi ) {
188 i = (lo + hi)/2;
189
190 res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]);
191 if ( res < 0 )
192 hi = i;
193 else if ( res > 0 )
194 lo = i + 1;
195 else
196 return i;
197 }
198
199 return NOT_FOUND;
200}
c801d85f
KB
201// add item at the end
202void wxBaseArray::Add(long lItem)
203{
204 Grow();
205 m_pItems[m_uiCount++] = lItem;
206}
207
3bfa4402
VZ
208// add item assuming the array is sorted with fnCompare function
209void wxBaseArray::Add(long lItem, CMPFUNC fnCompare)
210{
c86f1403 211 size_t i,
3bfa4402
VZ
212 lo = 0,
213 hi = m_uiCount;
214 int res;
215
216 while ( lo < hi ) {
217 i = (lo + hi)/2;
218
219 res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]);
220 if ( res < 0 )
221 hi = i;
222 else if ( res > 0 )
223 lo = i + 1;
224 else {
225 lo = hi = i;
226 break;
227 }
228 }
229
230 wxASSERT( lo == hi ); // I hope I got binary search right :-)
231
232 Insert(lItem, lo);
233}
234
c801d85f 235// add item at the given position
c86f1403 236void wxBaseArray::Insert(long lItem, size_t uiIndex)
c801d85f 237{
1a5a8367 238 wxCHECK_RET( uiIndex <= m_uiCount, _("bad index in wxArray::Insert") );
c801d85f
KB
239
240 Grow();
241
3bfa4402 242 memmove(&m_pItems[uiIndex + 1], &m_pItems[uiIndex],
c801d85f
KB
243 (m_uiCount - uiIndex)*sizeof(long));
244 m_pItems[uiIndex] = lItem;
245 m_uiCount++;
246}
247
248// removes item from array (by index)
c86f1403 249void wxBaseArray::Remove(size_t uiIndex)
c801d85f 250{
1a5a8367 251 wxCHECK_RET( uiIndex <= m_uiCount, _("bad index in wxArray::Remove") );
c801d85f 252
3bfa4402 253 memmove(&m_pItems[uiIndex], &m_pItems[uiIndex + 1],
c801d85f
KB
254 (m_uiCount - uiIndex - 1)*sizeof(long));
255 m_uiCount--;
256}
257
258// removes item from array (by value)
259void wxBaseArray::Remove(long lItem)
260{
261 int iIndex = Index(lItem);
262
3bfa4402 263 wxCHECK_RET( iIndex != NOT_FOUND,
1a5a8367 264 _("removing inexistent item in wxArray::Remove") );
c801d85f 265
c86f1403 266 Remove((size_t)iIndex);
c801d85f
KB
267}
268
269// sort array elements using passed comparaison function
270void wxBaseArray::Sort(CMPFUNC fCmp)
271{
272 qsort(m_pItems, m_uiCount, sizeof(long), fCmp);
273}