]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/dynarray.cpp
fixed slider value rounding once again
[wxWidgets.git] / src / common / dynarray.cpp
... / ...
CommitLineData
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#include "wx/intl.h"
28
29#include <stdlib.h>
30#include <string.h> // for memmove
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_nSize =
55 m_nCount = 0;
56 m_pItems = (long *) NULL;
57}
58
59// copy ctor
60wxBaseArray::wxBaseArray(const wxBaseArray& src)
61{
62 m_nSize = // not src.m_nSize to save memory
63 m_nCount = src.m_nCount;
64
65 if ( m_nSize != 0 ) {
66 m_pItems = new long[m_nSize];
67 memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(long));
68 }
69 else
70 m_pItems = (long *) NULL;
71}
72
73// assignment operator
74wxBaseArray& wxBaseArray::operator=(const wxBaseArray& src)
75{
76#if 0
77 wxDELETEA(m_pItems);
78#else
79 if ( (m_pItems)) {
80 delete (m_pItems);
81 (m_pItems) = 0;
82 }
83#endif
84
85 m_nSize = // not src.m_nSize to save memory
86 m_nCount = src.m_nCount;
87
88 if ( m_nSize != 0 ) {
89 m_pItems = new long[m_nSize];
90 memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(long));
91 }
92 else
93 m_pItems = (long *) NULL;
94
95 return *this;
96}
97
98// grow the array
99void wxBaseArray::Grow()
100{
101 // only do it if no more place
102 if( m_nCount == m_nSize ) {
103 if( m_nSize == 0 ) {
104 // was empty, alloc some memory
105 m_nSize = WX_ARRAY_DEFAULT_INITIAL_SIZE;
106 m_pItems = new long[m_nSize];
107 }
108 else
109 {
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];
117
118 // copy data to new location
119 memcpy(pNew, m_pItems, m_nCount*sizeof(long));
120 delete [] m_pItems;
121 m_pItems = pNew;
122 }
123 }
124}
125
126// dtor
127wxBaseArray::~wxBaseArray()
128{
129 wxDELETEA(m_pItems);
130}
131
132// clears the list
133void wxBaseArray::Clear()
134{
135 m_nSize =
136 m_nCount = 0;
137
138 wxDELETEA(m_pItems);
139}
140
141// pre-allocates memory (frees the previous data!)
142void wxBaseArray::Alloc(size_t nSize)
143{
144 // only if old buffer was not big enough
145 if ( nSize > m_nSize ) {
146 wxDELETEA(m_pItems);
147 m_pItems = new long[nSize];
148 m_nSize = nSize;
149 }
150
151 m_nCount = 0;
152}
153
154// minimizes the memory usage by freeing unused memory
155void wxBaseArray::Shrink()
156{
157 // only do it if we have some memory to free
158 if( m_nCount < m_nSize ) {
159 // allocates exactly as much memory as we need
160 long *pNew = new long[m_nCount];
161
162 // copy data to new location
163 memcpy(pNew, m_pItems, m_nCount*sizeof(long));
164 delete [] m_pItems;
165 m_pItems = pNew;
166 }
167}
168
169// searches the array for an item (forward or backwards)
170int wxBaseArray::Index(long lItem, bool bFromEnd) const
171{
172 if ( bFromEnd ) {
173 if ( m_nCount > 0 ) {
174 size_t n = m_nCount;
175 do {
176 if ( m_pItems[--n] == lItem )
177 return n;
178 }
179 while ( n != 0 );
180 }
181 }
182 else {
183 for( size_t n = 0; n < m_nCount; n++ ) {
184 if( m_pItems[n] == lItem )
185 return n;
186 }
187 }
188
189 return wxNOT_FOUND;
190}
191
192// search for an item in a sorted array (binary search)
193int wxBaseArray::Index(long lItem, CMPFUNC fnCompare) const
194{
195 size_t i,
196 lo = 0,
197 hi = m_nCount;
198 int res;
199
200 while ( lo < hi ) {
201 i = (lo + hi)/2;
202
203 res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]);
204 if ( res < 0 )
205 hi = i;
206 else if ( res > 0 )
207 lo = i + 1;
208 else
209 return i;
210 }
211
212 return wxNOT_FOUND;
213}
214// add item at the end
215void wxBaseArray::Add(long lItem)
216{
217 Grow();
218 m_pItems[m_nCount++] = lItem;
219}
220
221// add item assuming the array is sorted with fnCompare function
222void wxBaseArray::Add(long lItem, CMPFUNC fnCompare)
223{
224 size_t i,
225 lo = 0,
226 hi = m_nCount;
227 int res;
228
229 while ( lo < hi ) {
230 i = (lo + hi)/2;
231
232 res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]);
233 if ( res < 0 )
234 hi = i;
235 else if ( res > 0 )
236 lo = i + 1;
237 else {
238 lo = hi = i;
239 break;
240 }
241 }
242
243 wxASSERT( lo == hi ); // I hope I got binary search right :-)
244
245 Insert(lItem, lo);
246}
247
248// add item at the given position
249void wxBaseArray::Insert(long lItem, size_t nIndex)
250{
251 wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArray::Insert") );
252
253 Grow();
254
255 memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex],
256 (m_nCount - nIndex)*sizeof(long));
257 m_pItems[nIndex] = lItem;
258 m_nCount++;
259}
260
261// removes item from array (by index)
262void wxBaseArray::RemoveAt(size_t nIndex)
263{
264 wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArray::RemoveAt") );
265
266 memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1],
267 (m_nCount - nIndex - 1)*sizeof(long));
268 m_nCount--;
269}
270
271// removes item from array (by value)
272void wxBaseArray::Remove(long lItem)
273{
274 int iIndex = Index(lItem);
275
276 wxCHECK_RET( iIndex != wxNOT_FOUND,
277 wxT("removing inexistent item in wxArray::Remove") );
278
279 RemoveAt((size_t)iIndex);
280}
281
282// sort array elements using passed comparaison function
283void wxBaseArray::Sort(CMPFUNC fCmp)
284{
285 qsort(m_pItems, m_nCount, sizeof(long), fCmp);
286}