1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: implementation of wxBaseArray class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
17 #pragma implementation "dynarray.h"
20 #include "wx/wxprec.h"
26 #include "wx/dynarray.h"
30 #include <string.h> // for memmove
33 #define max(a, b) (((a) > (b)) ? (a) : (b))
36 // ============================================================================
38 // ============================================================================
40 // size increment = max(50% of current size, ARRAY_MAXSIZE_INCREMENT)
41 #define ARRAY_MAXSIZE_INCREMENT 4096
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
48 // wxBaseArray - dynamice array of 'long's
49 // ----------------------------------------------------------------------------
52 wxBaseArray::wxBaseArray()
56 m_pItems
= (long *) NULL
;
60 wxBaseArray::wxBaseArray(const wxBaseArray
& src
)
62 m_nSize
= // not src.m_nSize to save memory
63 m_nCount
= src
.m_nCount
;
66 m_pItems
= new long[m_nSize
];
67 memcpy(m_pItems
, src
.m_pItems
, m_nCount
*sizeof(long));
70 m_pItems
= (long *) NULL
;
73 // assignment operator
74 wxBaseArray
& wxBaseArray::operator=(const wxBaseArray
& src
)
78 m_nSize
= // not src.m_nSize to save memory
79 m_nCount
= src
.m_nCount
;
82 m_pItems
= new long[m_nSize
];
83 memcpy(m_pItems
, src
.m_pItems
, m_nCount
*sizeof(long));
86 m_pItems
= (long *) NULL
;
92 void wxBaseArray::Grow()
94 // only do it if no more place
95 if( m_nCount
== m_nSize
) {
97 // was empty, alloc some memory
98 m_nSize
= WX_ARRAY_DEFAULT_INITIAL_SIZE
;
99 m_pItems
= new long[m_nSize
];
103 // add 50% but not too much
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
];
111 // copy data to new location
112 memcpy(pNew
, m_pItems
, m_nCount
*sizeof(long));
120 wxBaseArray::~wxBaseArray()
126 void wxBaseArray::Clear()
134 // pre-allocates memory (frees the previous data!)
135 void wxBaseArray::Alloc(size_t nSize
)
137 // only if old buffer was not big enough
138 if ( nSize
> m_nSize
) {
140 m_pItems
= new long[nSize
];
147 // minimizes the memory usage by freeing unused memory
148 void wxBaseArray::Shrink()
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
];
155 // copy data to new location
156 memcpy(pNew
, m_pItems
, m_nCount
*sizeof(long));
162 // searches the array for an item (forward or backwards)
163 int wxBaseArray::Index(long lItem
, bool bFromEnd
) const
166 if ( m_nCount
> 0 ) {
169 if ( m_pItems
[--n
] == lItem
)
176 for( size_t n
= 0; n
< m_nCount
; n
++ ) {
177 if( m_pItems
[n
] == lItem
)
185 // search for a place to insert an item into a sorted array (binary search)
186 size_t wxBaseArray::IndexForInsert(long lItem
, CMPFUNC fnCompare
) const
196 res
= (*fnCompare
)((const void *)lItem
, (const void *)m_pItems
[i
]);
210 // search for an item in a sorted array (binary search)
211 int wxBaseArray::Index(long lItem
, CMPFUNC fnCompare
) const
213 size_t n
= IndexForInsert(lItem
, fnCompare
);
215 return n
< m_nCount
&& m_pItems
[n
] == lItem
? (int)n
: wxNOT_FOUND
;
218 // add item at the end
219 void wxBaseArray::Add(long lItem
)
222 m_pItems
[m_nCount
++] = lItem
;
225 // add item assuming the array is sorted with fnCompare function
226 void wxBaseArray::Add(long lItem
, CMPFUNC fnCompare
)
228 Insert(lItem
, IndexForInsert(lItem
, fnCompare
));
231 // add item at the given position
232 void wxBaseArray::Insert(long lItem
, size_t nIndex
)
234 wxCHECK_RET( nIndex
<= m_nCount
, wxT("bad index in wxArray::Insert") );
238 memmove(&m_pItems
[nIndex
+ 1], &m_pItems
[nIndex
],
239 (m_nCount
- nIndex
)*sizeof(long));
240 m_pItems
[nIndex
] = lItem
;
244 // removes item from array (by index)
245 void wxBaseArray::RemoveAt(size_t nIndex
)
247 wxCHECK_RET( nIndex
<= m_nCount
, wxT("bad index in wxArray::RemoveAt") );
249 memmove(&m_pItems
[nIndex
], &m_pItems
[nIndex
+ 1],
250 (m_nCount
- nIndex
- 1)*sizeof(long));
254 // removes item from array (by value)
255 void wxBaseArray::Remove(long lItem
)
257 int iIndex
= Index(lItem
);
259 wxCHECK_RET( iIndex
!= wxNOT_FOUND
,
260 wxT("removing inexistent item in wxArray::Remove") );
262 RemoveAt((size_t)iIndex
);
265 // sort array elements using passed comparaison function
266 void wxBaseArray::Sort(CMPFUNC fCmp
)
268 qsort(m_pItems
, m_nCount
, sizeof(long), fCmp
);