]> git.saurik.com Git - wxWidgets.git/blame - src/common/dynarray.cpp
fix for wxComboBox::GetSelection from inside event handler
[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
3096bd2f 20#include "wx/wxprec.h"
c801d85f
KB
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#include "wx/dynarray.h"
3096bd2f 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{
3093cef8
VZ
54 m_nSize =
55 m_nCount = 0;
c67daf87 56 m_pItems = (long *) NULL;
c801d85f
KB
57}
58
59// copy ctor
60wxBaseArray::wxBaseArray(const wxBaseArray& src)
61{
3093cef8
VZ
62 m_nSize = // not src.m_nSize to save memory
63 m_nCount = src.m_nCount;
c801d85f 64
3093cef8
VZ
65 if ( m_nSize != 0 ) {
66 m_pItems = new long[m_nSize];
67 memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(long));
3bfa4402 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{
a3622daa 76 wxDELETEA(m_pItems);
c801d85f 77
3093cef8
VZ
78 m_nSize = // not src.m_nSize to save memory
79 m_nCount = src.m_nCount;
c801d85f 80
3093cef8
VZ
81 if ( m_nSize != 0 ) {
82 m_pItems = new long[m_nSize];
83 memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(long));
3bfa4402 84 }
c801d85f 85 else
c67daf87 86 m_pItems = (long *) NULL;
c801d85f 87
c801d85f
KB
88 return *this;
89}
90
91// grow the array
92void wxBaseArray::Grow()
93{
94 // only do it if no more place
3093cef8
VZ
95 if( m_nCount == m_nSize ) {
96 if( m_nSize == 0 ) {
c801d85f 97 // was empty, alloc some memory
3093cef8
VZ
98 m_nSize = WX_ARRAY_DEFAULT_INITIAL_SIZE;
99 m_pItems = new long[m_nSize];
c801d85f
KB
100 }
101 else
102 {
103 // add 50% but not too much
3093cef8
VZ
104 size_t nIncrement = m_nSize < WX_ARRAY_DEFAULT_INITIAL_SIZE
105 ? WX_ARRAY_DEFAULT_INITIAL_SIZE : m_nSize >> 1;
106 if ( nIncrement > ARRAY_MAXSIZE_INCREMENT )
107 nIncrement = ARRAY_MAXSIZE_INCREMENT;
108 m_nSize += nIncrement;
109 long *pNew = new long[m_nSize];
c801d85f
KB
110
111 // copy data to new location
3093cef8 112 memcpy(pNew, m_pItems, m_nCount*sizeof(long));
c801d85f
KB
113 delete [] m_pItems;
114 m_pItems = pNew;
115 }
116 }
117}
118
119// dtor
120wxBaseArray::~wxBaseArray()
121{
a3622daa 122 wxDELETEA(m_pItems);
c801d85f
KB
123}
124
125// clears the list
126void wxBaseArray::Clear()
127{
3093cef8
VZ
128 m_nSize =
129 m_nCount = 0;
c801d85f 130
a3622daa 131 wxDELETEA(m_pItems);
c801d85f
KB
132}
133
134// pre-allocates memory (frees the previous data!)
3093cef8 135void wxBaseArray::Alloc(size_t nSize)
c801d85f 136{
c801d85f 137 // only if old buffer was not big enough
3093cef8 138 if ( nSize > m_nSize ) {
a3622daa 139 wxDELETEA(m_pItems);
3093cef8
VZ
140 m_pItems = new long[nSize];
141 m_nSize = nSize;
c801d85f
KB
142 }
143
3093cef8
VZ
144 m_nCount = 0;
145}
146
147// minimizes the memory usage by freeing unused memory
148void wxBaseArray::Shrink()
149{
150 // only do it if we have some memory to free
151 if( m_nCount < m_nSize ) {
152 // allocates exactly as much memory as we need
153 long *pNew = new long[m_nCount];
154
155 // copy data to new location
156 memcpy(pNew, m_pItems, m_nCount*sizeof(long));
157 delete [] m_pItems;
158 m_pItems = pNew;
159 }
c801d85f
KB
160}
161
162// searches the array for an item (forward or backwards)
05fafecd 163int wxBaseArray::Index(long lItem, bool bFromEnd) const
c801d85f
KB
164{
165 if ( bFromEnd ) {
3093cef8
VZ
166 if ( m_nCount > 0 ) {
167 size_t n = m_nCount;
c801d85f 168 do {
3093cef8
VZ
169 if ( m_pItems[--n] == lItem )
170 return n;
c801d85f 171 }
3093cef8 172 while ( n != 0 );
c801d85f
KB
173 }
174 }
175 else {
3093cef8
VZ
176 for( size_t n = 0; n < m_nCount; n++ ) {
177 if( m_pItems[n] == lItem )
178 return n;
c801d85f
KB
179 }
180 }
181
3c67202d 182 return wxNOT_FOUND;
c801d85f
KB
183}
184
b54e41c5
VZ
185// search for a place to insert an item into a sorted array (binary search)
186size_t wxBaseArray::IndexForInsert(long lItem, CMPFUNC fnCompare) const
3bfa4402 187{
c86f1403 188 size_t i,
3bfa4402 189 lo = 0,
3093cef8 190 hi = m_nCount;
3bfa4402
VZ
191 int res;
192
193 while ( lo < hi ) {
194 i = (lo + hi)/2;
195
196 res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]);
197 if ( res < 0 )
198 hi = i;
199 else if ( res > 0 )
200 lo = i + 1;
b54e41c5
VZ
201 else {
202 lo = i;
203 break;
204 }
3bfa4402
VZ
205 }
206
b54e41c5 207 return lo;
3bfa4402 208}
b54e41c5
VZ
209
210// search for an item in a sorted array (binary search)
211int wxBaseArray::Index(long lItem, CMPFUNC fnCompare) const
212{
213 size_t n = IndexForInsert(lItem, fnCompare);
214
e9d9f136 215 return n < m_nCount && m_pItems[n] == lItem ? (int)n : wxNOT_FOUND;
b54e41c5
VZ
216}
217
c801d85f
KB
218// add item at the end
219void wxBaseArray::Add(long lItem)
220{
221 Grow();
3093cef8 222 m_pItems[m_nCount++] = lItem;
c801d85f
KB
223}
224
3bfa4402
VZ
225// add item assuming the array is sorted with fnCompare function
226void wxBaseArray::Add(long lItem, CMPFUNC fnCompare)
227{
b54e41c5 228 Insert(lItem, IndexForInsert(lItem, fnCompare));
3bfa4402
VZ
229}
230
c801d85f 231// add item at the given position
3093cef8 232void wxBaseArray::Insert(long lItem, size_t nIndex)
c801d85f 233{
223d09f6 234 wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArray::Insert") );
c801d85f
KB
235
236 Grow();
237
3093cef8
VZ
238 memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex],
239 (m_nCount - nIndex)*sizeof(long));
240 m_pItems[nIndex] = lItem;
241 m_nCount++;
c801d85f
KB
242}
243
244// removes item from array (by index)
8a729bb8 245void wxBaseArray::RemoveAt(size_t nIndex)
c801d85f 246{
8a729bb8 247 wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArray::RemoveAt") );
c801d85f 248
3093cef8
VZ
249 memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1],
250 (m_nCount - nIndex - 1)*sizeof(long));
251 m_nCount--;
c801d85f
KB
252}
253
254// removes item from array (by value)
255void wxBaseArray::Remove(long lItem)
256{
257 int iIndex = Index(lItem);
258
3c67202d 259 wxCHECK_RET( iIndex != wxNOT_FOUND,
223d09f6 260 wxT("removing inexistent item in wxArray::Remove") );
c801d85f 261
f373f197 262 RemoveAt((size_t)iIndex);
c801d85f
KB
263}
264
265// sort array elements using passed comparaison function
266void wxBaseArray::Sort(CMPFUNC fCmp)
267{
3093cef8 268 qsort(m_pItems, m_nCount, sizeof(long), fCmp);
c801d85f 269}