]> git.saurik.com Git - wxWidgets.git/blame - include/wx/dynarray.h
add possibility to specify the conversion to use in wxStringOutputStream; use it...
[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 \
5a1cad6e 337 T& operator[](size_t uiIndex) const \
df5168c4 338 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 339 T& Item(size_t uiIndex) const \
df5168c4 340 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 341 T& Last() const \
b4a980f4 342 { return (T&)(base::operator[](GetCount() - 1)); } \
5a1cad6e 343 \
222702b1
WS
344 int Index(T lItem, bool bFromEnd = false) const \
345 { return base::Index((base_type)lItem, bFromEnd); } \
5a1cad6e 346 \
222702b1
WS
347 void Add(T lItem, size_t nInsert = 1) \
348 { base::Add((base_type)lItem, nInsert); } \
349 void Insert(T lItem, size_t uiIndex, size_t nInsert = 1) \
350 { base::Insert((base_type)lItem, uiIndex, nInsert) ; } \
5a1cad6e 351 \
3b0b5f13
VZ
352 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
353 { base::RemoveAt(uiIndex, nRemove); } \
222702b1
WS
354 void Remove(T lItem) \
355 { int iIndex = Index(lItem); \
5a1cad6e
GD
356 wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \
357 _WX_ERROR_REMOVE); \
358 base::RemoveAt((size_t)iIndex); } \
359 \
360 void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC)fCmp); } \
df5168c4
MB
361 \
362 /* STL-like interface */ \
363private: \
364 typedef base::iterator biterator; \
365 typedef base::const_iterator bconst_iterator; \
366 typedef base::value_type bvalue_type; \
367 typedef base::const_reference bconst_reference; \
368public: \
369 typedef T value_type; \
370 typedef value_type* pointer; \
371 typedef const value_type* const_pointer; \
372 typedef value_type* iterator; \
373 typedef const value_type* const_iterator; \
374 typedef value_type& reference; \
375 typedef const value_type& const_reference; \
376 typedef base::difference_type difference_type; \
377 typedef base::size_type size_type; \
378 \
379 class reverse_iterator \
380 { \
c514cd53
MB
381 typedef T value_type; \
382 typedef value_type& reference; \
383 typedef value_type* pointer; \
df5168c4 384 typedef reverse_iterator itor; \
31222b7c
VZ
385 friend inline itor operator+(int o, const itor& it) \
386 { return it.m_ptr - o; } \
387 friend inline itor operator+(const itor& it, int o) \
388 { return it.m_ptr - o; } \
389 friend inline itor operator-(const itor& it, int o) \
390 { return it.m_ptr + o; } \
391 friend inline difference_type operator-(const itor& i1, \
392 const itor& i2) \
393 { return i1.m_ptr - i2.m_ptr; } \
394 \
df5168c4
MB
395 public: \
396 pointer m_ptr; \
397 reverse_iterator() : m_ptr(NULL) { } \
398 reverse_iterator(pointer ptr) : m_ptr(ptr) { } \
399 reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } \
400 reference operator*() const { return *m_ptr; } \
6108e3fd 401 ptrop \
60d8e886
VZ
402 itor& operator++() { --m_ptr; return *this; } \
403 const itor operator++(int) \
df5168c4 404 { reverse_iterator tmp = *this; --m_ptr; return tmp; } \
60d8e886
VZ
405 itor& operator--() { ++m_ptr; return *this; } \
406 const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }\
fbfb8bcc
VZ
407 bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; }\
408 bool operator !=(const itor& it) const { return m_ptr != it.m_ptr; }\
df5168c4
MB
409 }; \
410 \
411 class const_reverse_iterator \
412 { \
c514cd53
MB
413 typedef T value_type; \
414 typedef const value_type& reference; \
415 typedef const value_type* pointer; \
df5168c4 416 typedef const_reverse_iterator itor; \
31222b7c
VZ
417 friend inline itor operator+(int o, const itor& it) \
418 { return it.m_ptr - o; } \
419 friend inline itor operator+(const itor& it, int o) \
420 { return it.m_ptr - o; } \
421 friend inline itor operator-(const itor& it, int o) \
422 { return it.m_ptr + o; } \
423 friend inline difference_type operator-(const itor& i1, \
424 const itor& i2) \
425 { return i1.m_ptr - i2.m_ptr; } \
426 \
df5168c4
MB
427 public: \
428 pointer m_ptr; \
429 const_reverse_iterator() : m_ptr(NULL) { } \
430 const_reverse_iterator(pointer ptr) : m_ptr(ptr) { } \
431 const_reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } \
432 const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { }\
433 reference operator*() const { return *m_ptr; } \
6108e3fd 434 ptrop \
60d8e886
VZ
435 itor& operator++() { --m_ptr; return *this; } \
436 const itor operator++(int) \
df5168c4 437 { itor tmp = *this; --m_ptr; return tmp; } \
60d8e886
VZ
438 itor& operator--() { ++m_ptr; return *this; } \
439 const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }\
fbfb8bcc
VZ
440 bool operator ==(const itor& it) const { return m_ptr == it.m_ptr; }\
441 bool operator !=(const itor& it) const { return m_ptr != it.m_ptr; }\
df5168c4
MB
442 }; \
443 \
5041b46f 444 name(size_type n) { assign(n, value_type()); } \
584ad2a3
MB
445 name(size_type n, const_reference v) { assign(n, v); } \
446 name(const_iterator first, const_iterator last) \
447 { assign(first, last); } \
df5168c4
MB
448 void assign(const_iterator first, const_iterator last) \
449 { base::assign((bconst_iterator)first, (bconst_iterator)last); } \
450 void assign(size_type n, const_reference v) \
451 { base::assign(n, (bconst_reference)v); } \
452 reference back() { return *(end() - 1); } \
453 const_reference back() const { return *(end() - 1); } \
454 iterator begin() { return (iterator)base::begin(); } \
455 const_iterator begin() const { return (const_iterator)base::begin(); }\
456 size_type capacity() const { return base::capacity(); } \
df5168c4
MB
457 iterator end() { return (iterator)base::end(); } \
458 const_iterator end() const { return (const_iterator)base::end(); } \
459 iterator erase(iterator first, iterator last) \
460 { return (iterator)base::erase((biterator)first, (biterator)last); }\
461 iterator erase(iterator it) \
462 { return (iterator)base::erase((biterator)it); } \
463 reference front() { return *begin(); } \
464 const_reference front() const { return *begin(); } \
465 void insert(iterator it, size_type n, const_reference v) \
466 { base::insert((biterator)it, n, (bconst_reference)v); } \
467 iterator insert(iterator it, const_reference v = value_type()) \
468 { return (iterator)base::insert((biterator)it, (bconst_reference)v); }\
469 void insert(iterator it, const_iterator first, const_iterator last) \
470 { base::insert((biterator)it, (bconst_iterator)first, \
471 (bconst_iterator)last); } \
df5168c4
MB
472 void pop_back() { base::pop_back(); } \
473 void push_back(const_reference v) \
474 { base::push_back((bconst_reference)v); } \
475 reverse_iterator rbegin() { return reverse_iterator(end() - 1); } \
476 const_reverse_iterator rbegin() const; \
477 reverse_iterator rend() { return reverse_iterator(begin() - 1); } \
478 const_reverse_iterator rend() const; \
47b378bd 479 void reserve(size_type n) { base::reserve(n); } \
bf004951
VZ
480 void resize(size_type n, value_type v = value_type()) \
481 { base::resize(n, v); } \
31222b7c
VZ
482}
483
6108e3fd
VZ
484#define _WX_PTROP pointer operator->() const { return m_ptr; }
485#define _WX_PTROP_NONE
486
487#define _WX_DEFINE_TYPEARRAY(T, name, base, classexp) \
488 _WX_DEFINE_TYPEARRAY_HELPER(T, name, base, classexp, _WX_PTROP)
d5d29b8a 489#define _WX_DEFINE_TYPEARRAY_PTR(T, name, base, classexp) \
6108e3fd 490 _WX_DEFINE_TYPEARRAY_HELPER(T, name, base, classexp, _WX_PTROP_NONE)
df5168c4
MB
491
492#endif // !wxUSE_STL
c801d85f 493
3bfa4402 494// ----------------------------------------------------------------------------
5a1cad6e
GD
495// _WX_DEFINE_SORTED_TYPEARRAY: sorted array for simple data types
496// cannot handle types with size greater than pointer because of sorting
3bfa4402 497// ----------------------------------------------------------------------------
1a931653 498
df5168c4 499#define _WX_DEFINE_SORTED_TYPEARRAY_2(T, name, base, defcomp, classexp, comptype)\
1d6560d7
VZ
500wxCOMPILE_TIME_ASSERT2(sizeof(T) <= sizeof(base::base_type), \
501 TypeTooBigToBeStoredInSorted##base, \
502 name); \
5a1cad6e
GD
503classexp name : public base \
504{ \
f700f98c 505 typedef comptype SCMPFUNC; \
5a1cad6e 506public: \
df5168c4 507 name(comptype fn defcomp) { m_fnCompare = fn; } \
5a1cad6e
GD
508 \
509 name& operator=(const name& src) \
510 { base* temp = (base*) this; \
511 (*temp) = ((const base&)src); \
512 m_fnCompare = src.m_fnCompare; \
513 return *this; } \
514 \
515 T& operator[](size_t uiIndex) const \
df5168c4 516 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 517 T& Item(size_t uiIndex) const \
df5168c4 518 { return (T&)(base::operator[](uiIndex)); } \
5a1cad6e 519 T& Last() const \
df5168c4 520 { return (T&)(base::operator[](size() - 1)); } \
5a1cad6e 521 \
222702b1
WS
522 int Index(T lItem) const \
523 { return base::Index(lItem, (CMPFUNC)m_fnCompare); } \
5a1cad6e 524 \
222702b1
WS
525 size_t IndexForInsert(T lItem) const \
526 { return base::IndexForInsert(lItem, (CMPFUNC)m_fnCompare); } \
5a1cad6e
GD
527 \
528 void AddAt(T item, size_t index) \
df5168c4 529 { base::insert(begin() + index, item); } \
5a1cad6e 530 \
222702b1
WS
531 size_t Add(T lItem) \
532 { return base::Add(lItem, (CMPFUNC)m_fnCompare); } \
5a1cad6e 533 \
3b0b5f13 534 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
df5168c4 535 { base::erase(begin() + uiIndex, begin() + uiIndex + nRemove); } \
222702b1
WS
536 void Remove(T lItem) \
537 { int iIndex = Index(lItem); \
5a1cad6e
GD
538 wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \
539 _WX_ERROR_REMOVE ); \
df5168c4 540 base::erase(begin() + iIndex); } \
5a1cad6e
GD
541 \
542private: \
df5168c4 543 comptype m_fnCompare; \
3bfa4402
VZ
544}
545
df5168c4 546
c801d85f 547// ----------------------------------------------------------------------------
1a931653 548// _WX_DECLARE_OBJARRAY: an array for pointers to type T with owning semantics
c801d85f 549// ----------------------------------------------------------------------------
1a931653 550
5a1cad6e
GD
551#define _WX_DECLARE_OBJARRAY(T, name, base, classexp) \
552typedef int (CMPFUNC_CONV *CMPFUNC##T)(T **pItem1, T **pItem2); \
df5168c4 553classexp name : protected base \
5a1cad6e
GD
554{ \
555typedef int (CMPFUNC_CONV *CMPFUNC##base)(void **pItem1, void **pItem2); \
df5168c4 556typedef base base_array; \
5a1cad6e
GD
557public: \
558 name() { } \
559 name(const name& src); \
560 name& operator=(const name& src); \
561 \
562 ~name(); \
563 \
43de4157
VS
564 void Alloc(size_t count) { base::reserve(count); } \
565 void reserve(size_t count) { base::reserve(count); } \
df5168c4
MB
566 size_t GetCount() const { return base_array::size(); } \
567 size_t size() const { return base_array::size(); } \
568 bool IsEmpty() const { return base_array::empty(); } \
009c4392 569 bool empty() const { return base_array::empty(); } \
df5168c4
MB
570 size_t Count() const { return base_array::size(); } \
571 void Shrink() { base::Shrink(); } \
572 \
5a1cad6e 573 T& operator[](size_t uiIndex) const \
df5168c4 574 { return *(T*)base::operator[](uiIndex); } \
5a1cad6e 575 T& Item(size_t uiIndex) const \
df5168c4 576 { return *(T*)base::operator[](uiIndex); } \
5a1cad6e 577 T& Last() const \
df5168c4 578 { return *(T*)(base::operator[](size() - 1)); } \
5a1cad6e 579 \
222702b1 580 int Index(const T& lItem, bool bFromEnd = false) const; \
5a1cad6e 581 \
222702b1 582 void Add(const T& lItem, size_t nInsert = 1); \
5a1cad6e 583 void Add(const T* pItem) \
df5168c4
MB
584 { base::push_back((T*)pItem); } \
585 void push_back(const T* pItem) \
586 { base::push_back((T*)pItem); } \
222702b1
WS
587 void push_back(const T& lItem) \
588 { Add(lItem); } \
5a1cad6e 589 \
222702b1 590 void Insert(const T& lItem, size_t uiIndex, size_t nInsert = 1); \
5a1cad6e 591 void Insert(const T* pItem, size_t uiIndex) \
df5168c4 592 { base::insert(begin() + uiIndex, (T*)pItem); } \
5a1cad6e 593 \
df5168c4
MB
594 void Empty() { DoEmpty(); base::clear(); } \
595 void Clear() { DoEmpty(); base::clear(); } \
5a1cad6e
GD
596 \
597 T* Detach(size_t uiIndex) \
df5168c4
MB
598 { T* p = (T*)base::operator[](uiIndex); \
599 base::erase(begin() + uiIndex); return p; } \
3b0b5f13 600 void RemoveAt(size_t uiIndex, size_t nRemove = 1); \
5a1cad6e
GD
601 \
602 void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC##base)fCmp); } \
603 \
604private: \
605 void DoEmpty(); \
606 void DoCopy(const name& src); \
c801d85f
KB
607}
608
1a931653
VZ
609// ============================================================================
610// The public macros for declaration and definition of the dynamic arrays
611// ============================================================================
612
613// Please note that for each macro WX_FOO_ARRAY we also have
614// WX_FOO_EXPORTED_ARRAY and WX_FOO_USER_EXPORTED_ARRAY which are exactly the
615// same except that they use an additional __declspec(dllexport) or equivalent
616// under Windows if needed.
617//
77ffb593 618// The first (just EXPORTED) macros do it if wxWidgets was compiled as a DLL
1a931653
VZ
619// and so must be used used inside the library. The second kind (USER_EXPORTED)
620// allow the user code to do it when it wants. This is needed if you have a dll
621// that wants to export a wxArray daubed with your own import/export goo.
622//
623// Finally, you can define the macro below as something special to modify the
624// arrays defined by a simple WX_FOO_ARRAY as well. By default is is empty.
625#define wxARRAY_DEFAULT_EXPORT
626
627// ----------------------------------------------------------------------------
5a1cad6e
GD
628// WX_DECLARE_BASEARRAY(T, name) declare an array class named "name" containing
629// the elements of type T
630// ----------------------------------------------------------------------------
631
632#define WX_DECLARE_BASEARRAY(T, name) \
633 WX_DECLARE_USER_EXPORTED_BASEARRAY(T, name, wxARRAY_DEFAULT_EXPORT)
634
635#define WX_DECLARE_EXPORTED_BASEARRAY(T, name) \
53a2db12 636 WX_DECLARE_USER_EXPORTED_BASEARRAY(T, name, WXDLLIMPEXP_CORE)
5a1cad6e
GD
637
638#define WX_DECLARE_USER_EXPORTED_BASEARRAY(T, name, expmode) \
639 typedef T _wxArray##name; \
640 _WX_DECLARE_BASEARRAY(_wxArray##name, name, class expmode)
641
642// ----------------------------------------------------------------------------
643// WX_DEFINE_TYPEARRAY(T, name, base) define an array class named "name" deriving
644// from class "base" containing the elements of type T
1a931653
VZ
645//
646// Note that the class defined has only inline function and doesn't take any
647// space at all so there is no size penalty for defining multiple array classes
c801d85f 648// ----------------------------------------------------------------------------
c801d85f 649
5a1cad6e 650#define WX_DEFINE_TYPEARRAY(T, name, base) \
68559fd5 651 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class wxARRAY_DEFAULT_EXPORT)
1a931653 652
d5d29b8a
VZ
653#define WX_DEFINE_TYPEARRAY_PTR(T, name, base) \
654 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, class wxARRAY_DEFAULT_EXPORT)
6108e3fd 655
5a1cad6e 656#define WX_DEFINE_EXPORTED_TYPEARRAY(T, name, base) \
53a2db12 657 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class WXDLLIMPEXP_CORE)
1a931653 658
d5d29b8a 659#define WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, base) \
53a2db12 660 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, class WXDLLIMPEXP_CORE)
6108e3fd 661
68559fd5
VZ
662#define WX_DEFINE_USER_EXPORTED_TYPEARRAY(T, name, base, expdecl) \
663 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class expdecl)
664
d5d29b8a
VZ
665#define WX_DEFINE_USER_EXPORTED_TYPEARRAY_PTR(T, name, base, expdecl) \
666 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, class expdecl)
6108e3fd 667
68559fd5 668#define WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, classdecl) \
df5168c4 669 typedef T _wxArray##name; \
68559fd5 670 _WX_DEFINE_TYPEARRAY(_wxArray##name, name, base, classdecl)
1a931653 671
d5d29b8a 672#define WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, classdecl) \
6108e3fd 673 typedef T _wxArray##name; \
d5d29b8a 674 _WX_DEFINE_TYPEARRAY_PTR(_wxArray##name, name, base, classdecl)
6108e3fd 675
1a931653 676// ----------------------------------------------------------------------------
5a1cad6e 677// WX_DEFINE_SORTED_TYPEARRAY: this is the same as the previous macro, but it
1a931653
VZ
678// defines a sorted array.
679//
680// Differences:
681// 1) it must be given a COMPARE function in ctor which takes 2 items of type
682// T* and should return -1, 0 or +1 if the first one is less/greater
683// than/equal to the second one.
684// 2) the Add() method inserts the item in such was that the array is always
685// sorted (it uses the COMPARE function)
686// 3) it has no Sort() method because it's always sorted
687// 4) Index() method is much faster (the sorted arrays use binary search
688// instead of linear one), but Add() is slower.
689// 5) there is no Insert() method because you can't insert an item into the
690// given position in a sorted array but there is IndexForInsert()/AddAt()
691// pair which may be used to optimize a common operation of "insert only if
692// not found"
693//
694// Note that you have to specify the comparison function when creating the
695// objects of this array type. If, as in 99% of cases, the comparison function
5a1cad6e
GD
696// is the same for all objects of a class, WX_DEFINE_SORTED_TYPEARRAY_CMP below
697// is more convenient.
1a931653
VZ
698//
699// Summary: use this class when the speed of Index() function is important, use
700// the normal arrays otherwise.
c801d85f
KB
701// ----------------------------------------------------------------------------
702
c75cc2e8
VZ
703// we need a macro which expands to nothing to pass correct number of
704// parameters to a nested macro invocation even when we don't have anything to
705// pass it
706#define wxARRAY_EMPTY
17e656b0 707
5a1cad6e
GD
708#define WX_DEFINE_SORTED_TYPEARRAY(T, name, base) \
709 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, \
710 wxARRAY_DEFAULT_EXPORT)
a497618a 711
5a1cad6e 712#define WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, base) \
53a2db12 713 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, WXDLLIMPEXP_CORE)
a497618a 714
5a1cad6e
GD
715#define WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, expmode) \
716 typedef T _wxArray##name; \
3e49e577
MB
717 typedef int (CMPFUNC_CONV *SCMPFUNC##name)(T pItem1, T pItem2); \
718 _WX_DEFINE_SORTED_TYPEARRAY_2(_wxArray##name, name, base, \
c75cc2e8 719 wxARRAY_EMPTY, class expmode, SCMPFUNC##name)
1a931653
VZ
720
721// ----------------------------------------------------------------------------
5a1cad6e 722// WX_DEFINE_SORTED_TYPEARRAY_CMP: exactly the same as above but the comparison
1a931653
VZ
723// function is provided by this macro and the objects of this class have a
724// default constructor which just uses it.
725//
726// The arguments are: the element type, the comparison function and the array
727// name
728//
5a1cad6e
GD
729// NB: this is, of course, how WX_DEFINE_SORTED_TYPEARRAY() should have worked
730// from the very beginning - unfortunately I didn't think about this earlier
1a931653 731// ----------------------------------------------------------------------------
76314141 732
5a1cad6e
GD
733#define WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, base) \
734 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
735 wxARRAY_DEFAULT_EXPORT)
76314141 736
5a1cad6e
GD
737#define WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base) \
738 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
53a2db12 739 WXDLLIMPEXP_CORE)
1a931653 740
5a1cad6e
GD
741#define WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
742 expmode) \
1a931653 743 typedef T _wxArray##name; \
3e49e577
MB
744 typedef int (CMPFUNC_CONV *SCMPFUNC##name)(T pItem1, T pItem2); \
745 _WX_DEFINE_SORTED_TYPEARRAY_2(_wxArray##name, name, base, = cmpfunc, \
746 class expmode, SCMPFUNC##name)
1a931653
VZ
747
748// ----------------------------------------------------------------------------
749// WX_DECLARE_OBJARRAY(T, name): this macro generates a new array class
750// named "name" which owns the objects of type T it contains, i.e. it will
751// delete them when it is destroyed.
752//
753// An element is of type T*, but arguments of type T& are taken (see below!)
754// and T& is returned.
755//
756// Don't use this for simple types such as "int" or "long"!
1a931653
VZ
757//
758// Note on Add/Insert functions:
759// 1) function(T*) gives the object to the array, i.e. it will delete the
760// object when it's removed or in the array's dtor
761// 2) function(T&) will create a copy of the object and work with it
762//
763// Also:
764// 1) Remove() will delete the object after removing it from the array
765// 2) Detach() just removes the object from the array (returning pointer to it)
766//
767// NB1: Base type T should have an accessible copy ctor if Add(T&) is used
768// NB2: Never ever cast a array to it's base type: as dtor is not virtual
769// and so you risk having at least the memory leaks and probably worse
770//
771// Some functions of this class are not inline, so it takes some space to
772// define new class from this template even if you don't use it - which is not
773// the case for the simple (non-object) array classes
774//
1a931653
VZ
775// To use an objarray class you must
776// #include "dynarray.h"
777// WX_DECLARE_OBJARRAY(element_type, list_class_name)
778// #include "arrimpl.cpp"
779// WX_DEFINE_OBJARRAY(list_class_name) // name must be the same as above!
780//
781// This is necessary because at the moment of DEFINE_OBJARRAY class parsing the
782// element_type must be fully defined (i.e. forward declaration is not
783// enough), while WX_DECLARE_OBJARRAY may be done anywhere. The separation of
784// two allows to break cicrcular dependencies with classes which have member
785// variables of objarray type.
786// ----------------------------------------------------------------------------
787
788#define WX_DECLARE_OBJARRAY(T, name) \
789 WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, wxARRAY_DEFAULT_EXPORT)
790
791#define WX_DECLARE_EXPORTED_OBJARRAY(T, name) \
53a2db12 792 WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, WXDLLIMPEXP_CORE)
1a931653 793
fd68cfdb 794#define WX_DECLARE_OBJARRAY_WITH_DECL(T, name, decl) \
1a931653 795 typedef T _wxObjArray##name; \
fd68cfdb 796 _WX_DECLARE_OBJARRAY(_wxObjArray##name, name, wxArrayPtrVoid, decl)
68379eaf 797
fd68cfdb
VS
798#define WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, expmode) \
799 WX_DECLARE_OBJARRAY_WITH_DECL(T, name, class expmode)
1a931653
VZ
800
801// WX_DEFINE_OBJARRAY is going to be redefined when arrimpl.cpp is included,
802// try to provoke a human-understandable error if it used incorrectly.
803//
804// there is no real need for 3 different macros in the DEFINE case but do it
805// anyhow for consistency
806#define WX_DEFINE_OBJARRAY(name) DidYouIncludeArrimplCpp
807#define WX_DEFINE_EXPORTED_OBJARRAY(name) WX_DEFINE_OBJARRAY(name)
76314141 808#define WX_DEFINE_USER_EXPORTED_OBJARRAY(name) WX_DEFINE_OBJARRAY(name)
76314141 809
5a1cad6e
GD
810// ----------------------------------------------------------------------------
811// Some commonly used predefined base arrays
812// ----------------------------------------------------------------------------
813
eee614d3
VS
814WX_DECLARE_USER_EXPORTED_BASEARRAY(const void *, wxBaseArrayPtrVoid,
815 WXDLLIMPEXP_BASE);
1ffc8d7a 816WX_DECLARE_USER_EXPORTED_BASEARRAY(char, wxBaseArrayChar, WXDLLIMPEXP_BASE);
6108e3fd
VZ
817WX_DECLARE_USER_EXPORTED_BASEARRAY(short, wxBaseArrayShort, WXDLLIMPEXP_BASE);
818WX_DECLARE_USER_EXPORTED_BASEARRAY(int, wxBaseArrayInt, WXDLLIMPEXP_BASE);
819WX_DECLARE_USER_EXPORTED_BASEARRAY(long, wxBaseArrayLong, WXDLLIMPEXP_BASE);
d2213b1f 820WX_DECLARE_USER_EXPORTED_BASEARRAY(size_t, wxBaseArraySizeT, WXDLLIMPEXP_BASE);
6108e3fd 821WX_DECLARE_USER_EXPORTED_BASEARRAY(double, wxBaseArrayDouble, WXDLLIMPEXP_BASE);
5a1cad6e
GD
822
823// ----------------------------------------------------------------------------
824// Convenience macros to define arrays from base arrays
825// ----------------------------------------------------------------------------
826
827#define WX_DEFINE_ARRAY(T, name) \
828 WX_DEFINE_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
d5d29b8a
VZ
829#define WX_DEFINE_ARRAY_PTR(T, name) \
830 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayPtrVoid)
5a1cad6e
GD
831#define WX_DEFINE_EXPORTED_ARRAY(T, name) \
832 WX_DEFINE_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
d5d29b8a
VZ
833#define WX_DEFINE_EXPORTED_ARRAY_PTR(T, name) \
834 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayPtrVoid)
835#define WX_DEFINE_ARRAY_WITH_DECL_PTR(T, name, decl) \
836 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayPtrVoid, decl)
5a1cad6e 837#define WX_DEFINE_USER_EXPORTED_ARRAY(T, name, expmode) \
c75cc2e8 838 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, wxBaseArrayPtrVoid, wxARRAY_EMPTY expmode)
d5d29b8a 839#define WX_DEFINE_USER_EXPORTED_ARRAY_PTR(T, name, expmode) \
c75cc2e8 840 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayPtrVoid, wxARRAY_EMPTY expmode)
5a1cad6e 841
1ffc8d7a
VZ
842#define WX_DEFINE_ARRAY_CHAR(T, name) \
843 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayChar)
844#define WX_DEFINE_EXPORTED_ARRAY_CHAR(T, name) \
845 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayChar)
846#define WX_DEFINE_USER_EXPORTED_ARRAY_CHAR(T, name, expmode) \
c75cc2e8 847 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayChar, wxARRAY_EMPTY expmode)
1ffc8d7a 848
5a1cad6e 849#define WX_DEFINE_ARRAY_SHORT(T, name) \
d5d29b8a 850 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayShort)
5a1cad6e 851#define WX_DEFINE_EXPORTED_ARRAY_SHORT(T, name) \
d5d29b8a 852 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayShort)
5a1cad6e 853#define WX_DEFINE_USER_EXPORTED_ARRAY_SHORT(T, name, expmode) \
c75cc2e8 854 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayShort, wxARRAY_EMPTY expmode)
5a1cad6e
GD
855
856#define WX_DEFINE_ARRAY_INT(T, name) \
d5d29b8a 857 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayInt)
5a1cad6e 858#define WX_DEFINE_EXPORTED_ARRAY_INT(T, name) \
d5d29b8a 859 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayInt)
5a1cad6e 860#define WX_DEFINE_USER_EXPORTED_ARRAY_INT(T, name, expmode) \
c75cc2e8 861 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayInt, wxARRAY_EMPTY expmode)
5a1cad6e
GD
862
863#define WX_DEFINE_ARRAY_LONG(T, name) \
d5d29b8a 864 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayLong)
5a1cad6e 865#define WX_DEFINE_EXPORTED_ARRAY_LONG(T, name) \
d5d29b8a 866 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayLong)
5a1cad6e 867#define WX_DEFINE_USER_EXPORTED_ARRAY_LONG(T, name, expmode) \
c75cc2e8 868 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayLong, wxARRAY_EMPTY expmode)
5a1cad6e 869
d2213b1f
VZ
870#define WX_DEFINE_ARRAY_SIZE_T(T, name) \
871 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArraySizeT)
872#define WX_DEFINE_EXPORTED_ARRAY_SIZE_T(T, name) \
873 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArraySizeT)
874#define WX_DEFINE_USER_EXPORTED_ARRAY_SIZE_T(T, name, expmode) \
c75cc2e8 875 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArraySizeT, wxARRAY_EMPTY expmode)
d2213b1f 876
5a1cad6e 877#define WX_DEFINE_ARRAY_DOUBLE(T, name) \
d5d29b8a 878 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayDouble)
5a1cad6e 879#define WX_DEFINE_EXPORTED_ARRAY_DOUBLE(T, name) \
d5d29b8a 880 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayDouble)
5a1cad6e 881#define WX_DEFINE_USER_EXPORTED_ARRAY_DOUBLE(T, name, expmode) \
c75cc2e8 882 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayDouble, wxARRAY_EMPTY expmode)
5a1cad6e
GD
883
884// ----------------------------------------------------------------------------
885// Convenience macros to define sorted arrays from base arrays
886// ----------------------------------------------------------------------------
887
888#define WX_DEFINE_SORTED_ARRAY(T, name) \
889 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
890#define WX_DEFINE_SORTED_EXPORTED_ARRAY(T, name) \
891 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
892#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY(T, name, expmode) \
c75cc2e8 893 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid, wxARRAY_EMPTY expmode)
5a1cad6e 894
1ffc8d7a
VZ
895#define WX_DEFINE_SORTED_ARRAY_CHAR(T, name) \
896 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayChar)
897#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CHAR(T, name) \
898 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayChar)
899#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CHAR(T, name, expmode) \
c75cc2e8 900 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayChar, wxARRAY_EMPTY expmode)
1ffc8d7a 901
5a1cad6e
GD
902#define WX_DEFINE_SORTED_ARRAY_SHORT(T, name) \
903 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayShort)
904#define WX_DEFINE_SORTED_EXPORTED_ARRAY_SHORT(T, name) \
905 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayShort)
906#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SHORT(T, name, expmode) \
c75cc2e8 907 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayShort, wxARRAY_EMPTY expmode)
5a1cad6e
GD
908
909#define WX_DEFINE_SORTED_ARRAY_INT(T, name) \
910 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayInt)
911#define WX_DEFINE_SORTED_EXPORTED_ARRAY_INT(T, name) \
912 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayInt)
913#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_INT(T, name, expmode) \
914 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayInt, expmode)
915
916#define WX_DEFINE_SORTED_ARRAY_LONG(T, name) \
917 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArrayLong)
918#define WX_DEFINE_SORTED_EXPORTED_ARRAY_LONG(T, name) \
919 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArrayLong)
920#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_LONG(T, name, expmode) \
921 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayLong, expmode)
922
d2213b1f
VZ
923#define WX_DEFINE_SORTED_ARRAY_SIZE_T(T, name) \
924 WX_DEFINE_SORTED_TYPEARRAY(T, name, wxBaseArraySizeT)
925#define WX_DEFINE_SORTED_EXPORTED_ARRAY_SIZE_T(T, name) \
926 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, wxBaseArraySizeT)
927#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(T, name, expmode) \
c75cc2e8 928 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArraySizeT, wxARRAY_EMPTY expmode)
d2213b1f 929
5a1cad6e
GD
930// ----------------------------------------------------------------------------
931// Convenience macros to define sorted arrays from base arrays
932// ----------------------------------------------------------------------------
933
934#define WX_DEFINE_SORTED_ARRAY_CMP(T, cmpfunc, name) \
935 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayPtrVoid)
936#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP(T, cmpfunc, name) \
937 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayPtrVoid)
938#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP(T, cmpfunc, \
939 name, expmode) \
940 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
c75cc2e8
VZ
941 wxBaseArrayPtrVoid, \
942 wxARRAY_EMPTY expmode)
5a1cad6e 943
1ffc8d7a
VZ
944#define WX_DEFINE_SORTED_ARRAY_CMP_CHAR(T, cmpfunc, name) \
945 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayChar)
946#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_CHAR(T, cmpfunc, name) \
947 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayChar)
c75cc2e8 948#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_CHAR(T, cmpfunc, \
1ffc8d7a
VZ
949 name, expmode) \
950 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
c75cc2e8
VZ
951 wxBaseArrayChar, \
952 wxARRAY_EMPTY expmode)
1ffc8d7a 953
5a1cad6e
GD
954#define WX_DEFINE_SORTED_ARRAY_CMP_SHORT(T, cmpfunc, name) \
955 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayShort)
956#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_SHORT(T, cmpfunc, name) \
957 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayShort)
958#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_SHORT(T, cmpfunc, \
959 name, expmode) \
960 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
c75cc2e8
VZ
961 wxBaseArrayShort, \
962 wxARRAY_EMPTY expmode)
5a1cad6e
GD
963
964#define WX_DEFINE_SORTED_ARRAY_CMP_INT(T, cmpfunc, name) \
965 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayInt)
966#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_INT(T, cmpfunc, name) \
967 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayInt)
968#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_INT(T, cmpfunc, \
969 name, expmode) \
970 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
c75cc2e8
VZ
971 wxBaseArrayInt, \
972 wxARRAY_EMPTY expmode)
5a1cad6e
GD
973
974#define WX_DEFINE_SORTED_ARRAY_CMP_LONG(T, cmpfunc, name) \
975 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayLong)
976#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_LONG(T, cmpfunc, name) \
977 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArrayLong)
978#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_LONG(T, cmpfunc, \
979 name, expmode) \
980 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
c75cc2e8
VZ
981 wxBaseArrayLong, \
982 wxARRAY_EMPTY expmode)
5a1cad6e 983
d2213b1f
VZ
984#define WX_DEFINE_SORTED_ARRAY_CMP_SIZE_T(T, cmpfunc, name) \
985 WX_DEFINE_SORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArraySizeT)
986#define WX_DEFINE_SORTED_EXPORTED_ARRAY_CMP_SIZE_T(T, cmpfunc, name) \
987 WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, wxBaseArraySizeT)
988#define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_SIZE_T(T, cmpfunc, \
989 name, expmode) \
990 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
c75cc2e8
VZ
991 wxBaseArraySizeT, \
992 wxARRAY_EMPTY expmode)
d2213b1f 993
c801d85f 994// ----------------------------------------------------------------------------
1a931653 995// Some commonly used predefined arrays
c801d85f
KB
996// ----------------------------------------------------------------------------
997
6108e3fd
VZ
998WX_DEFINE_USER_EXPORTED_ARRAY_SHORT(short, wxArrayShort, class WXDLLIMPEXP_BASE);
999WX_DEFINE_USER_EXPORTED_ARRAY_INT(int, wxArrayInt, class WXDLLIMPEXP_BASE);
87cc1cc7 1000WX_DEFINE_USER_EXPORTED_ARRAY_DOUBLE(double, wxArrayDouble, class WXDLLIMPEXP_BASE);
6108e3fd 1001WX_DEFINE_USER_EXPORTED_ARRAY_LONG(long, wxArrayLong, class WXDLLIMPEXP_BASE);
d5d29b8a 1002WX_DEFINE_USER_EXPORTED_ARRAY_PTR(void *, wxArrayPtrVoid, class WXDLLIMPEXP_BASE);
c801d85f 1003
2b9bd418 1004// -----------------------------------------------------------------------------
0cbff120 1005// convenience macros
2b9bd418
VZ
1006// -----------------------------------------------------------------------------
1007
bf7f7793
RR
1008// prepend all element of one array to another one; e.g. if first array contains
1009// elements X,Y,Z and the second contains A,B,C (in those orders), then the
1010// first array will be result as A,B,C,X,Y,Z
1011#define WX_PREPEND_ARRAY(array, other) \
1012 { \
1013 size_t wxAAcnt = (other).size(); \
cd643444 1014 (array).reserve(wxAAcnt); \
bf7f7793
RR
1015 for ( size_t wxAAn = 0; wxAAn < wxAAcnt; wxAAn++ ) \
1016 { \
1017 (array).Insert((other)[wxAAn], wxAAn); \
1018 } \
1019 }
1020
4f6aed9c
VZ
1021// append all element of one array to another one
1022#define WX_APPEND_ARRAY(array, other) \
1023 { \
17a1ebd1 1024 size_t wxAAcnt = (other).size(); \
cd643444 1025 (array).reserve(wxAAcnt); \
17a1ebd1 1026 for ( size_t wxAAn = 0; wxAAn < wxAAcnt; wxAAn++ ) \
4f6aed9c 1027 { \
17a1ebd1 1028 (array).push_back((other)[wxAAn]); \
4f6aed9c
VZ
1029 } \
1030 }
1031
2b9bd418
VZ
1032// delete all array elements
1033//
1034// NB: the class declaration of the array elements must be visible from the
1035// place where you use this macro, otherwise the proper destructor may not
1036// be called (a decent compiler should give a warning about it, but don't
1037// count on it)!
1038#define WX_CLEAR_ARRAY(array) \
1039 { \
17a1ebd1
VZ
1040 size_t wxAAcnt = (array).size(); \
1041 for ( size_t wxAAn = 0; wxAAn < wxAAcnt; wxAAn++ ) \
2b9bd418 1042 { \
17a1ebd1 1043 delete (array)[wxAAn]; \
2b9bd418 1044 } \
2c356747 1045 \
df5168c4 1046 (array).clear(); \
2b9bd418 1047 }
a497618a 1048
c801d85f 1049#endif // _DYNARRAY_H