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