]> git.saurik.com Git - wxWidgets.git/blame - src/common/dynarray.cpp
* New wxStream classes: wxStreamBuffer and wxObject*Stream.
[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"
27
28#include <stdlib.h>
3bfa4402 29#include <string.h> // for memmove
c801d85f
KB
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
51wxBaseArray::wxBaseArray()
52{
53 m_uiSize =
54 m_uiCount = 0;
55 m_pItems = NULL;
56}
57
58// copy ctor
59wxBaseArray::wxBaseArray(const wxBaseArray& src)
60{
3bfa4402 61 m_uiSize = // not src.m_uiSize to save memory
c801d85f
KB
62 m_uiCount = src.m_uiCount;
63
3bfa4402 64 if ( m_uiSize != 0 ) {
c801d85f 65 m_pItems = new long[m_uiSize];
3bfa4402
VZ
66 memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long));
67 }
c801d85f
KB
68 else
69 m_pItems = NULL;
c801d85f
KB
70}
71
3bfa4402 72// assignment operator
c801d85f
KB
73wxBaseArray& wxBaseArray::operator=(const wxBaseArray& src)
74{
75 DELETEA(m_pItems);
76
3bfa4402 77 m_uiSize = // not src.m_uiSize to save memory
c801d85f
KB
78 m_uiCount = src.m_uiCount;
79
3bfa4402 80 if ( m_uiSize != 0 ) {
c801d85f 81 m_pItems = new long[m_uiSize];
3bfa4402
VZ
82 memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long));
83 }
c801d85f
KB
84 else
85 m_pItems = NULL;
86
c801d85f
KB
87 return *this;
88}
89
90// grow the array
91void 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
118wxBaseArray::~wxBaseArray()
119{
120 DELETEA(m_pItems);
121}
122
123// clears the list
124void wxBaseArray::Clear()
125{
3bfa4402 126 m_uiSize =
c801d85f
KB
127 m_uiCount = 0;
128
129 DELETEA(m_pItems);
130 m_pItems = NULL;
131}
132
133// pre-allocates memory (frees the previous data!)
134void wxBaseArray::Alloc(uint uiSize)
135{
136 wxASSERT( uiSize > 0 );
137
138 // only if old buffer was not big enough
139 if ( uiSize > m_uiSize ) {
140 DELETEA(m_pItems);
141 m_pItems = new long[uiSize];
142 m_uiSize = uiSize;
143 }
144
145 m_uiCount = 0;
146}
147
148// searches the array for an item (forward or backwards)
05fafecd 149int wxBaseArray::Index(long lItem, bool bFromEnd) const
c801d85f
KB
150{
151 if ( bFromEnd ) {
152 if ( m_uiCount > 0 ) {
153 uint ui = m_uiCount;
154 do {
155 if ( m_pItems[--ui] == lItem )
156 return ui;
157 }
158 while ( ui != 0 );
159 }
160 }
161 else {
162 for( uint ui = 0; ui < m_uiCount; ui++ ) {
163 if( m_pItems[ui] == lItem )
164 return ui;
165 }
166 }
167
168 return NOT_FOUND;
169}
170
3bfa4402 171// search for an item in a sorted array (binary search)
e99c3048 172int wxBaseArray::Index(long lItem, CMPFUNC fnCompare) const
3bfa4402
VZ
173{
174 uint i,
175 lo = 0,
176 hi = m_uiCount;
177 int res;
178
179 while ( lo < hi ) {
180 i = (lo + hi)/2;
181
182 res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]);
183 if ( res < 0 )
184 hi = i;
185 else if ( res > 0 )
186 lo = i + 1;
187 else
188 return i;
189 }
190
191 return NOT_FOUND;
192}
c801d85f
KB
193// add item at the end
194void wxBaseArray::Add(long lItem)
195{
196 Grow();
197 m_pItems[m_uiCount++] = lItem;
198}
199
3bfa4402
VZ
200// add item assuming the array is sorted with fnCompare function
201void wxBaseArray::Add(long lItem, CMPFUNC fnCompare)
202{
203 uint i,
204 lo = 0,
205 hi = m_uiCount;
206 int res;
207
208 while ( lo < hi ) {
209 i = (lo + hi)/2;
210
211 res = (*fnCompare)((const void *)lItem, (const void *)m_pItems[i]);
212 if ( res < 0 )
213 hi = i;
214 else if ( res > 0 )
215 lo = i + 1;
216 else {
217 lo = hi = i;
218 break;
219 }
220 }
221
222 wxASSERT( lo == hi ); // I hope I got binary search right :-)
223
224 Insert(lItem, lo);
225}
226
c801d85f
KB
227// add item at the given position
228void wxBaseArray::Insert(long lItem, uint uiIndex)
229{
1311c7a9 230 wxCHECK_RET( uiIndex <= m_uiCount, "bad index in wxArray::Insert" );
c801d85f
KB
231
232 Grow();
233
3bfa4402 234 memmove(&m_pItems[uiIndex + 1], &m_pItems[uiIndex],
c801d85f
KB
235 (m_uiCount - uiIndex)*sizeof(long));
236 m_pItems[uiIndex] = lItem;
237 m_uiCount++;
238}
239
240// removes item from array (by index)
241void wxBaseArray::Remove(uint uiIndex)
242{
1311c7a9 243 wxCHECK_RET( uiIndex <= m_uiCount, "bad index in wxArray::Remove" );
c801d85f 244
3bfa4402 245 memmove(&m_pItems[uiIndex], &m_pItems[uiIndex + 1],
c801d85f
KB
246 (m_uiCount - uiIndex - 1)*sizeof(long));
247 m_uiCount--;
248}
249
250// removes item from array (by value)
251void wxBaseArray::Remove(long lItem)
252{
253 int iIndex = Index(lItem);
254
3bfa4402 255 wxCHECK_RET( iIndex != NOT_FOUND,
1311c7a9 256 "removing inexistent item in wxArray::Remove" );
c801d85f
KB
257
258 Remove((uint)iIndex);
259}
260
261// sort array elements using passed comparaison function
262void wxBaseArray::Sort(CMPFUNC fCmp)
263{
264 qsort(m_pItems, m_uiCount, sizeof(long), fCmp);
265}