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