]> git.saurik.com Git - wxWidgets.git/blame - include/wx/dynarray.h
compilation fix
[wxWidgets.git] / include / wx / dynarray.h
CommitLineData
c801d85f
KB
1///////////////////////////////////////////////////////////////////////////////
2// Name: dynarray.h
3// Purpose: auto-resizable (i.e. dynamic) array support
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>
371a5b4e 9// Licence: wxWindows licence
c801d85f
KB
10///////////////////////////////////////////////////////////////////////////////
11
12#ifndef _DYNARRAY_H
13#define _DYNARRAY_H
14
df5168c4
MB
15#if defined(__GNUG__) && !defined(__APPLE__) && \
16 !(defined(__MINGW32__) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
c801d85f
KB
17#pragma interface "dynarray.h"
18#endif
19
20#include "wx/defs.h"
c801d85f 21
df5168c4
MB
22#if wxUSE_STL
23 #include "wx/beforestd.h"
24 #include <vector>
25 #include <algorithm>
26 #include "wx/afterstd.h"
df5168c4
MB
27#endif
28
1a931653
VZ
29/*
30 This header defines the dynamic arrays and object arrays (i.e. arrays which
31 own their elements). Dynamic means that the arrays grow automatically as
32 needed.
33
34 These macros are ugly (especially if you look in the sources ;-), but they
35 allow us to define "template" classes without actually using templates and so
36 this works with all compilers (and may be also much faster to compile even
37 with a compiler which does support templates). The arrays defined with these
38 macros are type-safe.
39
40 Range checking is performed in debug build for both arrays and objarrays but
41 not in release build - so using an invalid index will just lead to a crash
42 then.
43
44 Note about memory usage: arrays never shrink automatically (although you may
45 use Shrink() function explicitly), they only grow, so loading 10 millions in
46 an array only to delete them 2 lines below might be a bad idea if the array
47 object is not going to be destroyed soon. However, as it does free memory
48 when destroyed, it is ok if the array is a local variable.
49 */
c801d85f
KB
50
51// ----------------------------------------------------------------------------
52// constants
53// ----------------------------------------------------------------------------
54
1a931653
VZ
55/*
56 The initial size by which an array grows when an element is added default
57 value avoids allocate one or two bytes when the array is created which is
58 rather inefficient
c801d85f 59*/
1a931653 60#define WX_ARRAY_DEFAULT_INITIAL_SIZE (16)
c801d85f
KB
61
62// ----------------------------------------------------------------------------
63// types
64// ----------------------------------------------------------------------------
65
1a931653
VZ
66/*
67 Callback compare function for quick sort.
3b0b5f13 68
1a931653
VZ
69 It must return negative value, 0 or positive value if the first item is
70 less than, equal to or greater than the second one.
c801d85f 71 */
90350682
VZ
72extern "C"
73{
0661ec39 74typedef int (wxCMPFUNC_CONV *CMPFUNC)(const void* pItem1, const void* pItem2);
90350682 75}
c801d85f
KB
76
77// ----------------------------------------------------------------------------
1a931653
VZ
78// Base class managing data having size of type 'long' (not used directly)
79//
80// NB: for efficiency this often used class has no virtual functions (hence no
81// virtual table), even dtor is *not* virtual. If used as expected it
82// won't create any problems because ARRAYs from DEFINE_ARRAY have no dtor
83// at all, so it's not too important if it's not called (this happens when
84// you cast "SomeArray *" as "BaseArray *" and then delete it)
c801d85f 85// ----------------------------------------------------------------------------
1a931653 86
df5168c4
MB
87#if wxUSE_STL
88
f700f98c
MB
89template<class T>
90class WXDLLIMPEXP_BASE wxArray_SortFunction
91{
92public:
93 typedef int (wxCMPFUNC_CONV *CMPFUNC)(T* pItem1, T* pItem2);
94
95 wxArray_SortFunction(CMPFUNC f) : m_f(f) { }
96 bool operator()(const T& i1, const T& i2)
97 { return m_f((T*)&i1, (T*)&i2) < 0; }
98private:
99 CMPFUNC m_f;
100};
101
102template<class T, typename F>
103class WXDLLIMPEXP_BASE wxSortedArray_SortFunction
104{
105public:
106 typedef F CMPFUNC;
107
108 wxSortedArray_SortFunction(CMPFUNC f) : m_f(f) { }
109 bool operator()(const T& i1, const T& i2)
110 { return m_f(i1, i2) < 0; }
111private:
112 CMPFUNC m_f;
113};
114
df5168c4 115#define _WX_DECLARE_BASEARRAY(T, name, classexp) \
f700f98c
MB
116 typedef int (wxCMPFUNC_CONV *CMPFUN##name)(T pItem1, T pItem2); \
117 typedef wxSortedArray_SortFunction<T, CMPFUN##name> name##_Predicate; \
118 _WX_DECLARE_BASEARRAY_2(T, name, name##_Predicate, classexp)
119
120#define _WX_DECLARE_BASEARRAY_2(T, name, predicate, classexp) \
df5168c4
MB
121classexp name : public std::vector<T> \
122{ \
f700f98c
MB
123 typedef predicate Predicate; \
124 typedef predicate::CMPFUNC SCMPFUNC; \
7df07b10 125public: \
f700f98c 126 typedef wxArray_SortFunction<T>::CMPFUNC CMPFUNC; \
df5168c4
MB
127public: \
128 void Empty() { clear(); } \
129 void Clear() { clear(); } \
130 void Alloc(size_t uiSize) { reserve(uiSize); } \
131 void Shrink(); \
132 \
133 size_t GetCount() const { return size(); } \
134 void SetCount(size_t n, T v = T()) { resize(n, v); } \
135 bool IsEmpty() const { return empty(); } \
136 size_t Count() const { return size(); } \
137 \
138 typedef T base_type; \
139 \
140protected: \
141 T& Item(size_t uiIndex) const \
142 { wxASSERT( uiIndex < size() ); return (T&)operator[](uiIndex); } \
143 \
144 int Index(T e, bool bFromEnd = FALSE) const; \
145 int Index(T lItem, CMPFUNC fnCompare) const; \
146 size_t IndexForInsert(T lItem, CMPFUNC fnCompare) const; \
147 void Add(T lItem, size_t nInsert = 1) \
148 { insert(end(), nInsert, lItem); } \
6992d326 149 size_t Add(T lItem, CMPFUNC fnCompare); \
df5168c4
MB
150 void Insert(T lItem, size_t uiIndex, size_t nInsert = 1) \
151 { insert(begin() + uiIndex, nInsert, lItem); } \
152 void Remove(T lItem); \
153 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
154 { erase(begin() + uiIndex, begin() + uiIndex + nRemove); } \
155 \
156 void Sort(CMPFUNC fCmp) \
157 { \
f700f98c 158 wxArray_SortFunction<T> p(fCmp); \
df5168c4
MB
159 std::sort(begin(), end(), p); \
160 } \
df5168c4
MB
161}
162
163#else // if !wxUSE_STL
164
5a1cad6e
GD
165#define _WX_DECLARE_BASEARRAY(T, name, classexp) \
166classexp name \
167{ \
f700f98c 168 typedef CMPFUNC SCMPFUNC; /* for compatibility wuth wxUSE_STL */ \
5a1cad6e
GD
169public: \
170 name(); \
171 name(const name& array); \
172 name& operator=(const name& src); \
173 ~name(); \
174 \
175 void Empty() { m_nCount = 0; } \
176 void Clear(); \
177 void Alloc(size_t uiSize); \
178 void Shrink(); \
179 \
2abb9d2f
VZ
180 size_t GetCount() const { return m_nCount; } \
181 void SetCount(size_t n, T defval = T(0)); \
182 bool IsEmpty() const { return m_nCount == 0; } \
183 size_t Count() const { return m_nCount; } \
5a1cad6e 184 \
75d7ef36 185 typedef T base_type; \
2abb9d2f 186 \
5a1cad6e
GD
187protected: \
188 T& Item(size_t uiIndex) const \
189 { wxASSERT( uiIndex < m_nCount ); return m_pItems[uiIndex]; } \
190 T& operator[](size_t uiIndex) const { return Item(uiIndex); } \
191 \
192 int Index(T lItem, bool bFromEnd = FALSE) const; \
193 int Index(T lItem, CMPFUNC fnCompare) const; \
194 size_t IndexForInsert(T lItem, CMPFUNC fnCompare) const; \
3b0b5f13 195 void Add(T lItem, size_t nInsert = 1); \
6992d326 196 size_t Add(T lItem, CMPFUNC fnCompare); \
3b0b5f13 197 void Insert(T lItem, size_t uiIndex, size_t nInsert = 1); \
5a1cad6e 198 void Remove(T lItem); \
3b0b5f13 199 void RemoveAt(size_t uiIndex, size_t nRemove = 1); \
5a1cad6e
GD
200 \
201 void Sort(CMPFUNC fnCompare); \
202 \
df5168c4
MB
203 /* *minimal* STL-ish interface, for derived classes */ \
204 typedef T value_type; \
205 typedef value_type* iterator; \
206 typedef const value_type* const_iterator; \
207 typedef value_type& reference; \
208 typedef const value_type& const_reference; \
209 typedef int difference_type; \
210 typedef size_t size_type; \
211 \
212 void assign(const_iterator first, const_iterator last); \
213 void assign(size_type n, const_reference v); \
214 size_type capacity() const { return m_nSize; } \
215 void clear() { Clear(); } \
216 bool empty() const { return IsEmpty(); } \
217 iterator erase(iterator first, iterator last) \
218 { \
219 size_type idx = first - begin(); \
220 RemoveAt(idx, last - first); \
221 return begin() + idx; \
222 } \
223 iterator erase(iterator it) { return erase(it, it + 1); } \
224 void insert(iterator it, size_type n, const value_type& v) \
225 { Insert(v, it - begin(), n); } \
226 iterator insert(iterator it, const value_type& v = value_type()) \
227 { \
228 size_type idx = it - begin(); \
229 Insert(v, idx); \
230 return begin() + idx; \
231 } \
232 void insert(iterator it, const_iterator first, const_iterator last);\
233 size_type max_size() const { return INT_MAX; } \
234 void pop_back() { RemoveAt(size() - 1); } \
235 void push_back(const value_type& v) { Add(v); } \
236 void reserve(size_type n) { if(n > m_nSize) Realloc(n); } \
237 void resize(size_type n, value_type v = value_type()); \
238 size_type size() const { return GetCount(); } \
239 \
240 iterator begin() { return m_pItems; } \
241 iterator end() { return m_pItems + m_nCount; } \
242 const_iterator begin() const { return m_pItems; } \
243 const_iterator end() const { return m_pItems + m_nCount; } \
5a1cad6e 244private: \
2abb9d2f
VZ
245 void Grow(size_t nIncrement = 0); \
246 bool Realloc(size_t nSize); \
5a1cad6e
GD
247 \
248 size_t m_nSize, \
249 m_nCount; \
250 \
251 T *m_pItems; \
e9bb94cf 252}
c801d85f 253
df5168c4
MB
254#endif // !wxUSE_STL
255
c801d85f 256// ============================================================================
1a931653 257// The private helper macros containing the core of the array classes
c801d85f
KB
258// ============================================================================
259
1a931653
VZ
260// Implementation notes:
261//
262// JACS: Salford C++ doesn't like 'var->operator=' syntax, as in:
263// { ((wxBaseArray *)this)->operator=((const wxBaseArray&)src);
264// so using a temporary variable instead.
265//
266// The classes need a (even trivial) ~name() to link under Mac X
267//
268// _WX_ERROR_REMOVE is needed to resolve the name conflict between the wxT()
5a1cad6e 269// macro and T typedef: we can't use wxT() inside WX_DEFINE_ARRAY!
1a931653
VZ
270
271#define _WX_ERROR_REMOVE wxT("removing inexisting element in wxArray::Remove")
e90c1d2a 272
c801d85f 273// ----------------------------------------------------------------------------
5a1cad6e 274// _WX_DEFINE_TYPEARRAY: array for simple types
c801d85f 275// ----------------------------------------------------------------------------
1a931653 276
df5168c4
MB
277#if wxUSE_STL
278
279#define _WX_DEFINE_TYPEARRAY(T, name, base, classexp) \
280typedef int (CMPFUNC_CONV *CMPFUNC##T)(T *pItem1, T *pItem2); \
281classexp name : public base \
282{ \
283public: \
284 T& operator[](size_t uiIndex) const \
285 { return (T&)(base::operator[](uiIndex)); } \
286 T& Item(size_t uiIndex) const \
287 { return (T&)/*const cast*/base::operator[](uiIndex); } \
288 T& Last() const \
289 { return Item(Count() - 1); } \
290 \
291 int Index(T e, bool bFromEnd = FALSE) const \
292 { return base::Index(e, bFromEnd); } \
293 \
294 void Add(T Item, size_t nInsert = 1) \
295 { insert(end(), nInsert, Item); } \
296 void Insert(T Item, size_t uiIndex, size_t nInsert = 1) \
297 { insert(begin() + uiIndex, nInsert, Item); } \
298 \
299 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
300 { base::RemoveAt(uiIndex, nRemove); } \
301 void Remove(T Item) \
302 { int iIndex = Index(Item); \
303 wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \
304 _WX_ERROR_REMOVE); \
305 RemoveAt((size_t)iIndex); } \
306 \
307 void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC)fCmp); } \
308}
309
6108e3fd
VZ
310#define _WX_DEFINE_TYPEARRAY_NO_PTR(T, name, base, classexp) \
311 _WX_DEFINE_TYPEARRAY(T, name, base, classexp)
312
df5168c4
MB
313#else // if !wxUSE_STL
314
6108e3fd
VZ
315// common declaration used by both _WX_DEFINE_TYPEARRAY and
316// _WX_DEFINE_TYPEARRAY_NO_PTR
317#define _WX_DEFINE_TYPEARRAY_HELPER(T, name, base, classexp, ptrop) \
5a1cad6e
GD
318wxCOMPILE_TIME_ASSERT2(sizeof(T) <= sizeof(base::base_type), \
319 TypeTooBigToBeStoredIn##base, \
320 name); \
321typedef int (CMPFUNC_CONV *CMPFUNC##T)(T *pItem1, T *pItem2); \
322classexp name : public base \
323{ \
324public: \
325 name() { } \
326 ~name() { } \
327 \
328 name& operator=(const name& src) \
329 { base* temp = (base*) this; \
330 (*temp) = ((const base&)src); \
331 return *this; } \
332 \
333 T& operator[](size_t uiIndex) const \
df5168c4 334 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 335 T& Item(size_t uiIndex) const \
df5168c4 336 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 337 T& Last() const \
df5168c4 338 { return (T&)(base::operator[](Count() - 1)); } \
5a1cad6e
GD
339 \
340 int Index(T Item, bool bFromEnd = FALSE) const \
e38ed919 341 { return base::Index((base_type)Item, bFromEnd); } \
5a1cad6e 342 \
3b0b5f13 343 void Add(T Item, size_t nInsert = 1) \
e38ed919 344 { base::Add((base_type)Item, nInsert); } \
3b0b5f13 345 void Insert(T Item, size_t uiIndex, size_t nInsert = 1) \
e38ed919 346 { base::Insert((base_type)Item, uiIndex, nInsert) ; } \
5a1cad6e 347 \
3b0b5f13
VZ
348 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
349 { base::RemoveAt(uiIndex, nRemove); } \
5a1cad6e
GD
350 void Remove(T Item) \
351 { int iIndex = Index(Item); \
352 wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \
353 _WX_ERROR_REMOVE); \
354 base::RemoveAt((size_t)iIndex); } \
355 \
356 void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC)fCmp); } \
df5168c4
MB
357 \
358 /* STL-like interface */ \
359private: \
360 typedef base::iterator biterator; \
361 typedef base::const_iterator bconst_iterator; \
362 typedef base::value_type bvalue_type; \
363 typedef base::const_reference bconst_reference; \
364public: \
365 typedef T value_type; \
366 typedef value_type* pointer; \
367 typedef const value_type* const_pointer; \
368 typedef value_type* iterator; \
369 typedef const value_type* const_iterator; \
370 typedef value_type& reference; \
371 typedef const value_type& const_reference; \
372 typedef base::difference_type difference_type; \
373 typedef base::size_type size_type; \
374 \
375 class reverse_iterator \
376 { \
c514cd53
MB
377 typedef T value_type; \
378 typedef value_type& reference; \
379 typedef value_type* pointer; \
df5168c4 380 typedef reverse_iterator itor; \
31222b7c
VZ
381 friend inline itor operator+(int o, const itor& it) \
382 { return it.m_ptr - o; } \
383 friend inline itor operator+(const itor& it, int o) \
384 { return it.m_ptr - o; } \
385 friend inline itor operator-(const itor& it, int o) \
386 { return it.m_ptr + o; } \
387 friend inline difference_type operator-(const itor& i1, \
388 const itor& i2) \
389 { return i1.m_ptr - i2.m_ptr; } \
390 \
df5168c4
MB
391 public: \
392 pointer m_ptr; \
393 reverse_iterator() : m_ptr(NULL) { } \
394 reverse_iterator(pointer ptr) : m_ptr(ptr) { } \
395 reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } \
396 reference operator*() const { return *m_ptr; } \
6108e3fd 397 ptrop \
df5168c4
MB
398 itor operator++() { --m_ptr; return *this; } \
399 itor operator++(int) \
400 { reverse_iterator tmp = *this; --m_ptr; return tmp; } \
401 itor operator--() { ++m_ptr; return *this; } \
402 itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } \
403 bool operator ==(const itor& it) { return m_ptr == it.m_ptr; } \
404 bool operator !=(const itor& it) { return m_ptr != it.m_ptr; } \
405 }; \
406 \
407 class const_reverse_iterator \
408 { \
c514cd53
MB
409 typedef T value_type; \
410 typedef const value_type& reference; \
411 typedef const value_type* pointer; \
df5168c4 412 typedef const_reverse_iterator itor; \
31222b7c
VZ
413 friend inline itor operator+(int o, const itor& it) \
414 { return it.m_ptr - o; } \
415 friend inline itor operator+(const itor& it, int o) \
416 { return it.m_ptr - o; } \
417 friend inline itor operator-(const itor& it, int o) \
418 { return it.m_ptr + o; } \
419 friend inline difference_type operator-(const itor& i1, \
420 const itor& i2) \
421 { return i1.m_ptr - i2.m_ptr; } \
422 \
df5168c4
MB
423 public: \
424 pointer m_ptr; \
425 const_reverse_iterator() : m_ptr(NULL) { } \
426 const_reverse_iterator(pointer ptr) : m_ptr(ptr) { } \
427 const_reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } \
428 const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { }\
429 reference operator*() const { return *m_ptr; } \
6108e3fd 430 ptrop \
df5168c4
MB
431 itor operator++() { --m_ptr; return *this; } \
432 itor operator++(int) \
433 { itor tmp = *this; --m_ptr; return tmp; } \
434 itor operator--() { ++m_ptr; return *this; } \
435 itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } \
436 bool operator ==(const itor& it) { return m_ptr == it.m_ptr; } \
437 bool operator !=(const itor& it) { return m_ptr != it.m_ptr; } \
438 }; \
439 \
440 void assign(const_iterator first, const_iterator last) \
441 { base::assign((bconst_iterator)first, (bconst_iterator)last); } \
442 void assign(size_type n, const_reference v) \
443 { base::assign(n, (bconst_reference)v); } \
444 reference back() { return *(end() - 1); } \
445 const_reference back() const { return *(end() - 1); } \
446 iterator begin() { return (iterator)base::begin(); } \
447 const_iterator begin() const { return (const_iterator)base::begin(); }\
448 size_type capacity() const { return base::capacity(); } \
449 void clear() { base::clear(); } \
450 bool empty() const { return base::empty(); } \
451 iterator end() { return (iterator)base::end(); } \
452 const_iterator end() const { return (const_iterator)base::end(); } \
453 iterator erase(iterator first, iterator last) \
454 { return (iterator)base::erase((biterator)first, (biterator)last); }\
455 iterator erase(iterator it) \
456 { return (iterator)base::erase((biterator)it); } \
457 reference front() { return *begin(); } \
458 const_reference front() const { return *begin(); } \
459 void insert(iterator it, size_type n, const_reference v) \
460 { base::insert((biterator)it, n, (bconst_reference)v); } \
461 iterator insert(iterator it, const_reference v = value_type()) \
462 { return (iterator)base::insert((biterator)it, (bconst_reference)v); }\
463 void insert(iterator it, const_iterator first, const_iterator last) \
464 { base::insert((biterator)it, (bconst_iterator)first, \
465 (bconst_iterator)last); } \
466 size_type max_size() const { return base::max_size(); } \
467 void pop_back() { base::pop_back(); } \
468 void push_back(const_reference v) \
469 { base::push_back((bconst_reference)v); } \
470 reverse_iterator rbegin() { return reverse_iterator(end() - 1); } \
471 const_reverse_iterator rbegin() const; \
472 reverse_iterator rend() { return reverse_iterator(begin() - 1); } \
473 const_reverse_iterator rend() const; \
474 void reserve(size_type n) { base::reserve(n); }; \
475 void resize(size_type n, value_type v = value_type()); \
476 size_type size() const { return base::size(); } \
31222b7c
VZ
477}
478
6108e3fd
VZ
479#define _WX_PTROP pointer operator->() const { return m_ptr; }
480#define _WX_PTROP_NONE
481
482#define _WX_DEFINE_TYPEARRAY(T, name, base, classexp) \
483 _WX_DEFINE_TYPEARRAY_HELPER(T, name, base, classexp, _WX_PTROP)
484#define _WX_DEFINE_TYPEARRAY_NO_PTR(T, name, base, classexp) \
485 _WX_DEFINE_TYPEARRAY_HELPER(T, name, base, classexp, _WX_PTROP_NONE)
df5168c4
MB
486
487#endif // !wxUSE_STL
c801d85f 488
3bfa4402 489// ----------------------------------------------------------------------------
5a1cad6e
GD
490// _WX_DEFINE_SORTED_TYPEARRAY: sorted array for simple data types
491// cannot handle types with size greater than pointer because of sorting
3bfa4402 492// ----------------------------------------------------------------------------
1a931653 493
df5168c4 494#define _WX_DEFINE_SORTED_TYPEARRAY_2(T, name, base, defcomp, classexp, comptype)\
335991af 495wxCOMPILE_TIME_ASSERT2(sizeof(T) <= sizeof(base::base_type), \
5a1cad6e
GD
496 TypeTooBigToBeStoredInSorted##base, \
497 name); \
5a1cad6e
GD
498classexp name : public base \
499{ \
f700f98c 500 typedef comptype SCMPFUNC; \
5a1cad6e 501public: \
df5168c4 502 name(comptype fn defcomp) { m_fnCompare = fn; } \
5a1cad6e
GD
503 \
504 name& operator=(const name& src) \
505 { base* temp = (base*) this; \
506 (*temp) = ((const base&)src); \
507 m_fnCompare = src.m_fnCompare; \
508 return *this; } \
509 \
510 T& operator[](size_t uiIndex) const \
df5168c4 511 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 512 T& Item(size_t uiIndex) const \
df5168c4 513 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 514 T& Last() const \
df5168c4 515 { return (T&)(base::operator[](size() - 1)); } \
5a1cad6e
GD
516 \
517 int Index(T Item) const \
518 { return base::Index(Item, (CMPFUNC)m_fnCompare); } \
519 \
520 size_t IndexForInsert(T Item) const \
521 { return base::IndexForInsert(Item, (CMPFUNC)m_fnCompare); } \
522 \
523 void AddAt(T item, size_t index) \
df5168c4 524 { base::insert(begin() + index, item); } \
5a1cad6e 525 \
6992d326
MB
526 size_t Add(T Item) \
527 { return base::Add(Item, (CMPFUNC)m_fnCompare); } \
5a1cad6e 528 \
3b0b5f13 529 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
df5168c4 530 { base::erase(begin() + uiIndex, begin() + uiIndex + nRemove); } \
5a1cad6e
GD
531 void Remove(T Item) \
532 { int iIndex = Index(Item); \
533 wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \
534 _WX_ERROR_REMOVE ); \
df5168c4 535 base::erase(begin() + iIndex); } \
5a1cad6e
GD
536 \
537private: \
df5168c4 538 comptype m_fnCompare; \
3bfa4402
VZ
539}
540
df5168c4 541
c801d85f 542// ----------------------------------------------------------------------------
1a931653 543// _WX_DECLARE_OBJARRAY: an array for pointers to type T with owning semantics
c801d85f 544// ----------------------------------------------------------------------------
1a931653 545
5a1cad6e
GD
546#define _WX_DECLARE_OBJARRAY(T, name, base, classexp) \
547typedef int (CMPFUNC_CONV *CMPFUNC##T)(T **pItem1, T **pItem2); \
df5168c4 548classexp name : protected base \
5a1cad6e
GD
549{ \
550typedef int (CMPFUNC_CONV *CMPFUNC##base)(void **pItem1, void **pItem2); \
df5168c4 551typedef base base_array; \
5a1cad6e
GD
552public: \
553 name() { } \
554 name(const name& src); \
555 name& operator=(const name& src); \
556 \
557 ~name(); \
558 \
df5168c4
MB
559 void Alloc(size_t count) { reserve(count); } \
560 size_t GetCount() const { return base_array::size(); } \
561 size_t size() const { return base_array::size(); } \
562 bool IsEmpty() const { return base_array::empty(); } \
563 size_t Count() const { return base_array::size(); } \
564 void Shrink() { base::Shrink(); } \
565 \
5a1cad6e 566 T& operator[](size_t uiIndex) const \
df5168c4 567 { return *(T*)base::operator[](uiIndex); } \
5a1cad6e 568 T& Item(size_t uiIndex) const \
df5168c4 569 { return *(T*)base::operator[](uiIndex); } \
5a1cad6e 570 T& Last() const \
df5168c4 571 { return *(T*)(base::operator[](size() - 1)); } \
5a1cad6e
GD
572 \
573 int Index(const T& Item, bool bFromEnd = FALSE) const; \
574 \
3b0b5f13 575 void Add(const T& Item, size_t nInsert = 1); \
5a1cad6e 576 void Add(const T* pItem) \
df5168c4
MB
577 { base::push_back((T*)pItem); } \
578 void push_back(const T* pItem) \
579 { base::push_back((T*)pItem); } \
580 void push_back(const T& Item) \
581 { Add(Item); } \
5a1cad6e 582 \
3b0b5f13 583 void Insert(const T& Item, size_t uiIndex, size_t nInsert = 1); \
5a1cad6e 584 void Insert(const T* pItem, size_t uiIndex) \
df5168c4 585 { base::insert(begin() + uiIndex, (T*)pItem); } \
5a1cad6e 586 \
df5168c4
MB
587 void Empty() { DoEmpty(); base::clear(); } \
588 void Clear() { DoEmpty(); base::clear(); } \
5a1cad6e
GD
589 \
590 T* Detach(size_t uiIndex) \
df5168c4
MB
591 { T* p = (T*)base::operator[](uiIndex); \
592 base::erase(begin() + uiIndex); return p; } \
3b0b5f13 593 void RemoveAt(size_t uiIndex, size_t nRemove = 1); \
5a1cad6e
GD
594 \
595 void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC##base)fCmp); } \
596 \
597private: \
598 void DoEmpty(); \
599 void DoCopy(const name& src); \
c801d85f
KB
600}
601
1a931653
VZ
602// ============================================================================
603// The public macros for declaration and definition of the dynamic arrays
604// ============================================================================
605
606// Please note that for each macro WX_FOO_ARRAY we also have
607// WX_FOO_EXPORTED_ARRAY and WX_FOO_USER_EXPORTED_ARRAY which are exactly the
608// same except that they use an additional __declspec(dllexport) or equivalent
609// under Windows if needed.
610//
611// The first (just EXPORTED) macros do it if wxWindows was compiled as a DLL
612// and so must be used used inside the library. The second kind (USER_EXPORTED)
613// allow the user code to do it when it wants. This is needed if you have a dll
614// that wants to export a wxArray daubed with your own import/export goo.
615//
616// Finally, you can define the macro below as something special to modify the
617// arrays defined by a simple WX_FOO_ARRAY as well. By default is is empty.
618#define wxARRAY_DEFAULT_EXPORT
619
620// ----------------------------------------------------------------------------
5a1cad6e
GD
621// WX_DECLARE_BASEARRAY(T, name) declare an array class named "name" containing
622// the elements of type T
623// ----------------------------------------------------------------------------
624
625#define WX_DECLARE_BASEARRAY(T, name) \
626 WX_DECLARE_USER_EXPORTED_BASEARRAY(T, name, wxARRAY_DEFAULT_EXPORT)
627
628#define WX_DECLARE_EXPORTED_BASEARRAY(T, name) \
629 WX_DECLARE_USER_EXPORTED_BASEARRAY(T, name, WXDLLEXPORT)
630
631#define WX_DECLARE_USER_EXPORTED_BASEARRAY(T, name, expmode) \
632 typedef T _wxArray##name; \
633 _WX_DECLARE_BASEARRAY(_wxArray##name, name, class expmode)
634
635// ----------------------------------------------------------------------------
636// WX_DEFINE_TYPEARRAY(T, name, base) define an array class named "name" deriving
637// from class "base" containing the elements of type T
1a931653
VZ
638//
639// Note that the class defined has only inline function and doesn't take any
640// space at all so there is no size penalty for defining multiple array classes
c801d85f 641// ----------------------------------------------------------------------------
c801d85f 642
5a1cad6e 643#define WX_DEFINE_TYPEARRAY(T, name, base) \
68559fd5 644 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class wxARRAY_DEFAULT_EXPORT)
1a931653 645
6108e3fd
VZ
646#define WX_DEFINE_TYPEARRAY_NO_PTR(T, name, base) \
647 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, base, class wxARRAY_DEFAULT_EXPORT)
648
5a1cad6e 649#define WX_DEFINE_EXPORTED_TYPEARRAY(T, name, base) \
68559fd5 650 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class WXDLLEXPORT)
1a931653 651
6108e3fd
VZ
652#define WX_DEFINE_EXPORTED_TYPEARRAY_NO_PTR(T, name, base) \
653 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, base, class WXDLLEXPORT)
654
68559fd5
VZ
655#define WX_DEFINE_USER_EXPORTED_TYPEARRAY(T, name, base, expdecl) \
656 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class expdecl)
657
6108e3fd
VZ
658#define WX_DEFINE_USER_EXPORTED_TYPEARRAY_NO_PTR(T, name, base, expdecl) \
659 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, base, class expdecl)
660
68559fd5 661#define WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, classdecl) \
df5168c4 662 typedef T _wxArray##name; \
68559fd5 663 _WX_DEFINE_TYPEARRAY(_wxArray##name, name, base, classdecl)
1a931653 664
6108e3fd
VZ
665#define WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, base, classdecl) \
666 typedef T _wxArray##name; \
667 _WX_DEFINE_TYPEARRAY_NO_PTR(_wxArray##name, name, base, classdecl)
668
1a931653 669// ----------------------------------------------------------------------------
5a1cad6e 670// WX_DEFINE_SORTED_TYPEARRAY: this is the same as the previous macro, but it
1a931653
VZ
671// defines a sorted array.
672//
673// Differences:
674// 1) it must be given a COMPARE function in ctor which takes 2 items of type
675// T* and should return -1, 0 or +1 if the first one is less/greater
676// than/equal to the second one.
677// 2) the Add() method inserts the item in such was that the array is always
678// sorted (it uses the COMPARE function)
679// 3) it has no Sort() method because it's always sorted
680// 4) Index() method is much faster (the sorted arrays use binary search
681// instead of linear one), but Add() is slower.
682// 5) there is no Insert() method because you can't insert an item into the
683// given position in a sorted array but there is IndexForInsert()/AddAt()
684// pair which may be used to optimize a common operation of "insert only if
685// not found"
686//
687// Note that you have to specify the comparison function when creating the
688// objects of this array type. If, as in 99% of cases, the comparison function
5a1cad6e
GD
689// is the same for all objects of a class, WX_DEFINE_SORTED_TYPEARRAY_CMP below
690// is more convenient.
1a931653
VZ
691//
692// Summary: use this class when the speed of Index() function is important, use
693// the normal arrays otherwise.
c801d85f
KB
694// ----------------------------------------------------------------------------
695
17e656b0
VZ
696#define wxARRAY_EMPTY_CMP
697
5a1cad6e
GD
698#define WX_DEFINE_SORTED_TYPEARRAY(T, name, base) \
699 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, \
700 wxARRAY_DEFAULT_EXPORT)
a497618a 701
5a1cad6e
GD
702#define WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, base) \
703 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, WXDLLEXPORT)
a497618a 704
5a1cad6e
GD
705#define WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, expmode) \
706 typedef T _wxArray##name; \
3e49e577
MB
707 typedef int (CMPFUNC_CONV *SCMPFUNC##name)(T pItem1, T pItem2); \
708 _WX_DEFINE_SORTED_TYPEARRAY_2(_wxArray##name, name, base, \
709 wxARRAY_EMPTY_CMP, class expmode, SCMPFUNC##name)
1a931653
VZ
710
711// ----------------------------------------------------------------------------
5a1cad6e 712// WX_DEFINE_SORTED_TYPEARRAY_CMP: exactly the same as above but the comparison
1a931653
VZ
713// function is provided by this macro and the objects of this class have a
714// default constructor which just uses it.
715//
716// The arguments are: the element type, the comparison function and the array
717// name
718//
5a1cad6e
GD
719// NB: this is, of course, how WX_DEFINE_SORTED_TYPEARRAY() should have worked
720// from the very beginning - unfortunately I didn't think about this earlier
1a931653 721// ----------------------------------------------------------------------------
76314141 722
5a1cad6e
GD
723#define WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, base) \
724 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
725 wxARRAY_DEFAULT_EXPORT)
76314141 726
5a1cad6e
GD
727#define WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base) \
728 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
729 WXDLLEXPORT)
1a931653 730
5a1cad6e
GD
731#define WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
732 expmode) \
1a931653 733 typedef T _wxArray##name; \
3e49e577
MB
734 typedef int (CMPFUNC_CONV *SCMPFUNC##name)(T pItem1, T pItem2); \
735 _WX_DEFINE_SORTED_TYPEARRAY_2(_wxArray##name, name, base, = cmpfunc, \
736 class expmode, SCMPFUNC##name)
1a931653
VZ
737
738// ----------------------------------------------------------------------------
739// WX_DECLARE_OBJARRAY(T, name): this macro generates a new array class
740// named "name" which owns the objects of type T it contains, i.e. it will
741// delete them when it is destroyed.
742//
743// An element is of type T*, but arguments of type T& are taken (see below!)
744// and T& is returned.
745//
746// Don't use this for simple types such as "int" or "long"!
1a931653
VZ
747//
748// Note on Add/Insert functions:
749// 1) function(T*) gives the object to the array, i.e. it will delete the
750// object when it's removed or in the array's dtor
751// 2) function(T&) will create a copy of the object and work with it
752//
753// Also:
754// 1) Remove() will delete the object after removing it from the array
755// 2) Detach() just removes the object from the array (returning pointer to it)
756//
757// NB1: Base type T should have an accessible copy ctor if Add(T&) is used
758// NB2: Never ever cast a array to it's base type: as dtor is not virtual
759// and so you risk having at least the memory leaks and probably worse
760//
761// Some functions of this class are not inline, so it takes some space to
762// define new class from this template even if you don't use it - which is not
763// the case for the simple (non-object) array classes
764//
1a931653
VZ
765// To use an objarray class you must
766// #include "dynarray.h"
767// WX_DECLARE_OBJARRAY(element_type, list_class_name)
768// #include "arrimpl.cpp"
769// WX_DEFINE_OBJARRAY(list_class_name) // name must be the same as above!
770//
771// This is necessary because at the moment of DEFINE_OBJARRAY class parsing the
772// element_type must be fully defined (i.e. forward declaration is not
773// enough), while WX_DECLARE_OBJARRAY may be done anywhere. The separation of
774// two allows to break cicrcular dependencies with classes which have member
775// variables of objarray type.
776// ----------------------------------------------------------------------------
777
778#define WX_DECLARE_OBJARRAY(T, name) \
779 WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, wxARRAY_DEFAULT_EXPORT)
780
781#define WX_DECLARE_EXPORTED_OBJARRAY(T, name) \
782 WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, WXDLLEXPORT)
783
fd68cfdb 784#define WX_DECLARE_OBJARRAY_WITH_DECL(T, name, decl) \
1a931653 785 typedef T _wxObjArray##name; \
fd68cfdb
VS
786 _WX_DECLARE_OBJARRAY(_wxObjArray##name, name, wxArrayPtrVoid, decl)
787
788#define WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, expmode) \
789 WX_DECLARE_OBJARRAY_WITH_DECL(T, name, class expmode)
1a931653
VZ
790
791// WX_DEFINE_OBJARRAY is going to be redefined when arrimpl.cpp is included,
792// try to provoke a human-understandable error if it used incorrectly.
793//
794// there is no real need for 3 different macros in the DEFINE case but do it
795// anyhow for consistency
796#define WX_DEFINE_OBJARRAY(name) DidYouIncludeArrimplCpp
797#define WX_DEFINE_EXPORTED_OBJARRAY(name) WX_DEFINE_OBJARRAY(name)
76314141 798#define WX_DEFINE_USER_EXPORTED_OBJARRAY(name) WX_DEFINE_OBJARRAY(name)
76314141 799
5a1cad6e
GD
800// ----------------------------------------------------------------------------
801// Some commonly used predefined base arrays
802// ----------------------------------------------------------------------------
803
eee614d3
VS
804WX_DECLARE_USER_EXPORTED_BASEARRAY(const void *, wxBaseArrayPtrVoid,
805 WXDLLIMPEXP_BASE);
6108e3fd
VZ
806WX_DECLARE_USER_EXPORTED_BASEARRAY(short, wxBaseArrayShort, WXDLLIMPEXP_BASE);
807WX_DECLARE_USER_EXPORTED_BASEARRAY(int, wxBaseArrayInt, WXDLLIMPEXP_BASE);
808WX_DECLARE_USER_EXPORTED_BASEARRAY(long, wxBaseArrayLong, WXDLLIMPEXP_BASE);
809WX_DECLARE_USER_EXPORTED_BASEARRAY(double, wxBaseArrayDouble, WXDLLIMPEXP_BASE);
5a1cad6e
GD
810
811// ----------------------------------------------------------------------------
812// Convenience macros to define arrays from base arrays
813// ----------------------------------------------------------------------------
814
815#define WX_DEFINE_ARRAY(T, name) \
816 WX_DEFINE_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
6108e3fd
VZ
817#define WX_DEFINE_ARRAY_NO_PTR(T, name) \
818 WX_DEFINE_TYPEARRAY_NO_PTR(T, name, wxBaseArrayPtrVoid)
5a1cad6e
GD
819#define WX_DEFINE_EXPORTED_ARRAY(T, name) \
820 WX_DEFINE_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
6108e3fd
VZ
821#define WX_DEFINE_EXPORTED_ARRAY_NO_PTR(T, name) \
822 WX_DEFINE_EXPORTED_TYPEARRAY_NO_PTR(T, name, wxBaseArrayPtrVoid)
5a1cad6e 823#define WX_DEFINE_USER_EXPORTED_ARRAY(T, name, expmode) \
991023b4 824 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, wxBaseArrayPtrVoid, expmode)
6108e3fd
VZ
825#define WX_DEFINE_USER_EXPORTED_ARRAY_NO_PTR(T, name, expmode) \
826 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, wxBaseArrayPtrVoid, expmode)
5a1cad6e
GD
827
828#define WX_DEFINE_ARRAY_SHORT(T, name) \
6108e3fd 829 WX_DEFINE_TYPEARRAY_NO_PTR(T, name, wxBaseArrayShort)
5a1cad6e 830#define WX_DEFINE_EXPORTED_ARRAY_SHORT(T, name) \
6108e3fd 831 WX_DEFINE_EXPORTED_TYPEARRAY_NO_PTR(T, name, wxBaseArrayShort)
5a1cad6e 832#define WX_DEFINE_USER_EXPORTED_ARRAY_SHORT(T, name, expmode) \
6108e3fd 833 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, wxBaseArrayShort, expmode)
5a1cad6e
GD
834
835#define WX_DEFINE_ARRAY_INT(T, name) \
6108e3fd 836 WX_DEFINE_TYPEARRAY_NO_PTR(T, name, wxBaseArrayInt)
5a1cad6e 837#define WX_DEFINE_EXPORTED_ARRAY_INT(T, name) \
6108e3fd 838 WX_DEFINE_EXPORTED_TYPEARRAY_NO_PTR(T, name, wxBaseArrayInt)
5a1cad6e 839#define WX_DEFINE_USER_EXPORTED_ARRAY_INT(T, name, expmode) \
6108e3fd 840 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, wxBaseArrayInt, expmode)
5a1cad6e
GD
841
842#define WX_DEFINE_ARRAY_LONG(T, name) \
6108e3fd 843 WX_DEFINE_TYPEARRAY_NO_PTR(T, name, wxBaseArrayLong)
5a1cad6e 844#define WX_DEFINE_EXPORTED_ARRAY_LONG(T, name) \
6108e3fd 845 WX_DEFINE_EXPORTED_TYPEARRAY_NO_PTR(T, name, wxBaseArrayLong)
5a1cad6e 846#define WX_DEFINE_USER_EXPORTED_ARRAY_LONG(T, name, expmode) \
6108e3fd 847 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, wxBaseArrayLong, expmode)
5a1cad6e
GD
848
849#define WX_DEFINE_ARRAY_DOUBLE(T, name) \
6108e3fd 850 WX_DEFINE_TYPEARRAY_NO_PTR(T, name, wxBaseArrayDouble)
5a1cad6e 851#define WX_DEFINE_EXPORTED_ARRAY_DOUBLE(T, name) \
6108e3fd 852 WX_DEFINE_EXPORTED_TYPEARRAY_NO_PTR(T, name, wxBaseArrayDouble)
5a1cad6e 853#define WX_DEFINE_USER_EXPORTED_ARRAY_DOUBLE(T, name, expmode) \
6108e3fd 854 WX_DEFINE_TYPEARRAY_WITH_DECL_NO_PTR(T, name, wxBaseArrayDouble, expmode)
5a1cad6e
GD
855
856// ----------------------------------------------------------------------------
857// Convenience macros to define sorted arrays from base arrays
858// ----------------------------------------------------------------------------
859
860#define WX_DEFINE_SORTED_ARRAY(T, name) \
861 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
862#define WX_DEFINE_SORTED_EXPORTED_ARRAY(T, name) \
863 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
864#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY(T, name, expmode) \
865 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid, expmode)
866
867#define WX_DEFINE_SORTED_ARRAY_SHORT(T, name) \
868 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayShort)
869#define WX_DEFINE_SORTED_EXPORTED_ARRAY_SHORT(T, name) \
870 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayShort)
871#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SHORT(T, name, expmode) \
872 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayShort, expmode)
873
874#define WX_DEFINE_SORTED_ARRAY_INT(T, name) \
875 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayInt)
876#define WX_DEFINE_SORTED_EXPORTED_ARRAY_INT(T, name) \
877 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayInt)
878#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_INT(T, name, expmode) \
879 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayInt, expmode)
880
881#define WX_DEFINE_SORTED_ARRAY_LONG(T, name) \
882 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayLong)
883#define WX_DEFINE_SORTED_EXPORTED_ARRAY_LONG(T, name) \
884 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayLong)
885#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_LONG(T, name, expmode) \
886 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayLong, expmode)
887
888// ----------------------------------------------------------------------------
889// Convenience macros to define sorted arrays from base arrays
890// ----------------------------------------------------------------------------
891
892#define WX_DEFINE_SORTED_ARRAY_CMP(T, cmpfunc, name) \
893 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayPtrVoid)
894#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP(T, cmpfunc, name) \
895 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayPtrVoid)
896#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP(T, cmpfunc, \
897 name, expmode) \
898 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
899 wxBaseArrayPtrVoid, expmode)
900
901#define WX_DEFINE_SORTED_ARRAY_CMP_SHORT(T, cmpfunc, name) \
902 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayShort)
903#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_SHORT(T, cmpfunc, name) \
904 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayShort)
905#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_SHORT(T, cmpfunc, \
906 name, expmode) \
907 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
908 wxBaseArrayShort, expmode)
909
910#define WX_DEFINE_SORTED_ARRAY_CMP_INT(T, cmpfunc, name) \
911 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayInt)
912#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_INT(T, cmpfunc, name) \
913 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayInt)
914#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_INT(T, cmpfunc, \
915 name, expmode) \
916 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
917 wxBaseArrayInt, expmode)
918
919#define WX_DEFINE_SORTED_ARRAY_CMP_LONG(T, cmpfunc, name) \
920 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayLong)
921#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_LONG(T, cmpfunc, name) \
922 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayLong)
923#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_LONG(T, cmpfunc, \
924 name, expmode) \
925 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
926 wxBaseArrayLong, expmode)
927
c801d85f 928// ----------------------------------------------------------------------------
1a931653 929// Some commonly used predefined arrays
c801d85f
KB
930// ----------------------------------------------------------------------------
931
6108e3fd
VZ
932WX_DEFINE_USER_EXPORTED_ARRAY_SHORT(short, wxArrayShort, class WXDLLIMPEXP_BASE);
933WX_DEFINE_USER_EXPORTED_ARRAY_INT(int, wxArrayInt, class WXDLLIMPEXP_BASE);
934WX_DEFINE_USER_EXPORTED_ARRAY_LONG(long, wxArrayLong, class WXDLLIMPEXP_BASE);
935WX_DEFINE_USER_EXPORTED_ARRAY_NO_PTR(void *, wxArrayPtrVoid, class WXDLLIMPEXP_BASE);
c801d85f 936
2b9bd418 937// -----------------------------------------------------------------------------
0cbff120 938// convenience macros
2b9bd418
VZ
939// -----------------------------------------------------------------------------
940
4f6aed9c
VZ
941// append all element of one array to another one
942#define WX_APPEND_ARRAY(array, other) \
943 { \
df5168c4 944 size_t count = (other).size(); \
4f6aed9c
VZ
945 for ( size_t n = 0; n < count; n++ ) \
946 { \
df5168c4 947 (array).push_back((other)[n]); \
4f6aed9c
VZ
948 } \
949 }
950
2b9bd418
VZ
951// delete all array elements
952//
953// NB: the class declaration of the array elements must be visible from the
954// place where you use this macro, otherwise the proper destructor may not
955// be called (a decent compiler should give a warning about it, but don't
956// count on it)!
957#define WX_CLEAR_ARRAY(array) \
958 { \
df5168c4 959 size_t count = (array).size(); \
2b9bd418
VZ
960 for ( size_t n = 0; n < count; n++ ) \
961 { \
5d5b1c0c 962 delete (array)[n]; \
2b9bd418 963 } \
2c356747 964 \
df5168c4 965 (array).clear(); \
2b9bd418 966 }
a497618a 967
c801d85f
KB
968#endif // _DYNARRAY_H
969