]> git.saurik.com Git - wxWidgets.git/blob - include/wx/dynarray.h
Fixed a rare wxAuiFloatingFrame dtor crash on MSW using a registration mechanism...
[wxWidgets.git] / include / wx / dynarray.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/dynarray.h
3 // Purpose: auto-resizable (i.e. dynamic) array support
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 12.09.97
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _DYNARRAY_H
13 #define _DYNARRAY_H
14
15 #include "wx/defs.h"
16
17 #if wxUSE_STL
18 #include "wx/beforestd.h"
19 #include <vector>
20 #include <algorithm>
21 #include "wx/afterstd.h"
22 #endif
23
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 */
45
46 // ----------------------------------------------------------------------------
47 // constants
48 // ----------------------------------------------------------------------------
49
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
54 */
55 #define WX_ARRAY_DEFAULT_INITIAL_SIZE (16)
56
57 // ----------------------------------------------------------------------------
58 // types
59 // ----------------------------------------------------------------------------
60
61 /*
62 Callback compare function for quick sort.
63
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.
66 */
67 extern "C"
68 {
69 typedef int (wxCMPFUNC_CONV *CMPFUNC)(const void* pItem1, const void* pItem2);
70 }
71
72 // ----------------------------------------------------------------------------
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)
80 // ----------------------------------------------------------------------------
81
82 #if wxUSE_STL
83
84 template<class T>
85 class WXDLLIMPEXP_BASE wxArray_SortFunction
86 {
87 public:
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; }
93 private:
94 CMPFUNC m_f;
95 };
96
97 template<class T, typename F>
98 class WXDLLIMPEXP_BASE wxSortedArray_SortFunction
99 {
100 public:
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; }
106 private:
107 CMPFUNC m_f;
108 };
109
110 #define _WX_DECLARE_BASEARRAY(T, name, classexp) \
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) \
116 classexp name : public std::vector<T> \
117 { \
118 typedef predicate Predicate; \
119 typedef predicate::CMPFUNC SCMPFUNC; \
120 public: \
121 typedef wxArray_SortFunction<T>::CMPFUNC CMPFUNC; \
122 public: \
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 \
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 \
139 protected: \
140 T& Item(size_t uiIndex) const \
141 { wxASSERT( uiIndex < size() ); return (T&)operator[](uiIndex); } \
142 \
143 int Index(T e, bool bFromEnd = false) const; \
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); } \
148 size_t Add(T lItem, CMPFUNC fnCompare); \
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 { \
157 wxArray_SortFunction<T> p(fCmp); \
158 std::sort(begin(), end(), p); \
159 } \
160 }
161
162 #else // if !wxUSE_STL
163
164 #define _WX_DECLARE_BASEARRAY(T, name, classexp) \
165 classexp name \
166 { \
167 typedef CMPFUNC SCMPFUNC; /* for compatibility wuth wxUSE_STL */ \
168 public: \
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(); \
176 void Alloc(size_t n) { if ( n > m_nSize ) Realloc(n); } \
177 void Shrink(); \
178 \
179 size_t GetCount() const { return m_nCount; } \
180 void SetCount(size_t n, T defval = T()); \
181 bool IsEmpty() const { return m_nCount == 0; } \
182 size_t Count() const { return m_nCount; } \
183 \
184 typedef T base_type; \
185 \
186 protected: \
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 \
191 int Index(T lItem, bool bFromEnd = false) const; \
192 int Index(T lItem, CMPFUNC fnCompare) const; \
193 size_t IndexForInsert(T lItem, CMPFUNC fnCompare) const; \
194 void Add(T lItem, size_t nInsert = 1); \
195 size_t Add(T lItem, CMPFUNC fnCompare); \
196 void Insert(T lItem, size_t uiIndex, size_t nInsert = 1); \
197 void Remove(T lItem); \
198 void RemoveAt(size_t uiIndex, size_t nRemove = 1); \
199 \
200 void Sort(CMPFUNC fnCompare); \
201 \
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; } \
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);\
230 void pop_back() { RemoveAt(size() - 1); } \
231 void push_back(const value_type& v) { Add(v); } \
232 void reserve(size_type n) { Alloc(n); } \
233 void resize(size_type n, value_type v = value_type()) \
234 { SetCount(n, v); } \
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; } \
240 \
241 /* the following functions may be made directly public because */ \
242 /* they don't use the type of the elements at all */ \
243 public: \
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 \
249 private: \
250 void Grow(size_t nIncrement = 0); \
251 bool Realloc(size_t nSize); \
252 \
253 size_t m_nSize, \
254 m_nCount; \
255 \
256 T *m_pItems; \
257 }
258
259 #endif // !wxUSE_STL
260
261 // ============================================================================
262 // The private helper macros containing the core of the array classes
263 // ============================================================================
264
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()
274 // macro and T typedef: we can't use wxT() inside WX_DEFINE_ARRAY!
275
276 #define _WX_ERROR_REMOVE wxT("removing inexisting element in wxArray::Remove")
277
278 // ----------------------------------------------------------------------------
279 // _WX_DEFINE_TYPEARRAY: array for simple types
280 // ----------------------------------------------------------------------------
281
282 #if wxUSE_STL
283
284 #define _WX_DEFINE_TYPEARRAY(T, name, base, classexp) \
285 typedef int (CMPFUNC_CONV *CMPFUNC##T)(T *pItem1, T *pItem2); \
286 classexp name : public base \
287 { \
288 public: \
289 name() : base() { } \
290 name(size_type n) : base(n) { } \
291 name(size_type n, const_reference v) : base(n, v) { } \
292 \
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 \
298 { return Item(GetCount() - 1); } \
299 \
300 int Index(T e, bool bFromEnd = false) const \
301 { return base::Index(e, bFromEnd); } \
302 \
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); } \
307 \
308 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
309 { base::RemoveAt(uiIndex, nRemove); } \
310 void Remove(T lItem) \
311 { int iIndex = Index(lItem); \
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
319 #define _WX_DEFINE_TYPEARRAY_PTR(T, name, base, classexp) \
320 _WX_DEFINE_TYPEARRAY(T, name, base, classexp)
321
322 #else // if !wxUSE_STL
323
324 // common declaration used by both _WX_DEFINE_TYPEARRAY and
325 // _WX_DEFINE_TYPEARRAY_PTR
326 #define _WX_DEFINE_TYPEARRAY_HELPER(T, name, base, classexp, ptrop) \
327 wxCOMPILE_TIME_ASSERT2(sizeof(T) <= sizeof(base::base_type), \
328 TypeTooBigToBeStoredIn##base, \
329 name); \
330 typedef int (CMPFUNC_CONV *CMPFUNC##T)(T *pItem1, T *pItem2); \
331 classexp name : public base \
332 { \
333 public: \
334 name() { } \
335 ~name() { } \
336 \
337 T& operator[](size_t uiIndex) const \
338 { return (T&)(base::operator[](uiIndex)); } \
339 T& Item(size_t uiIndex) const \
340 { return (T&)(base::operator[](uiIndex)); } \
341 T& Last() const \
342 { return (T&)(base::operator[](GetCount() - 1)); } \
343 \
344 int Index(T lItem, bool bFromEnd = false) const \
345 { return base::Index((base_type)lItem, bFromEnd); } \
346 \
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) ; } \
351 \
352 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
353 { base::RemoveAt(uiIndex, nRemove); } \
354 void Remove(T lItem) \
355 { int iIndex = Index(lItem); \
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); } \
361 \
362 /* STL-like interface */ \
363 private: \
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; \
368 public: \
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 { \
381 typedef T value_type; \
382 typedef value_type& reference; \
383 typedef value_type* pointer; \
384 typedef reverse_iterator itor; \
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 \
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; } \
401 ptrop \
402 itor& operator++() { --m_ptr; return *this; } \
403 const itor operator++(int) \
404 { reverse_iterator tmp = *this; --m_ptr; return tmp; } \
405 itor& operator--() { ++m_ptr; return *this; } \
406 const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }\
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; }\
409 }; \
410 \
411 class const_reverse_iterator \
412 { \
413 typedef T value_type; \
414 typedef const value_type& reference; \
415 typedef const value_type* pointer; \
416 typedef const_reverse_iterator itor; \
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 \
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; } \
434 ptrop \
435 itor& operator++() { --m_ptr; return *this; } \
436 const itor operator++(int) \
437 { itor tmp = *this; --m_ptr; return tmp; } \
438 itor& operator--() { ++m_ptr; return *this; } \
439 const itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; }\
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; }\
442 }; \
443 \
444 name(size_type n) { assign(n, value_type()); } \
445 name(size_type n, const_reference v) { assign(n, v); } \
446 name(const_iterator first, const_iterator last) \
447 { assign(first, last); } \
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(); } \
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); } \
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; \
479 void reserve(size_type n) { base::reserve(n); } \
480 void resize(size_type n, value_type v = value_type()) \
481 { base::resize(n, v); } \
482 }
483
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)
489 #define _WX_DEFINE_TYPEARRAY_PTR(T, name, base, classexp) \
490 _WX_DEFINE_TYPEARRAY_HELPER(T, name, base, classexp, _WX_PTROP_NONE)
491
492 #endif // !wxUSE_STL
493
494 // ----------------------------------------------------------------------------
495 // _WX_DEFINE_SORTED_TYPEARRAY: sorted array for simple data types
496 // cannot handle types with size greater than pointer because of sorting
497 // ----------------------------------------------------------------------------
498
499 #define _WX_DEFINE_SORTED_TYPEARRAY_2(T, name, base, defcomp, classexp, comptype)\
500 wxCOMPILE_TIME_ASSERT2(sizeof(T) <= sizeof(base::base_type), \
501 TypeTooBigToBeStoredInSorted##base, \
502 name); \
503 classexp name : public base \
504 { \
505 typedef comptype SCMPFUNC; \
506 public: \
507 name(comptype fn defcomp) { m_fnCompare = fn; } \
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 \
516 { return (T&)(base::operator[](uiIndex)); } \
517 T& Item(size_t uiIndex) const \
518 { return (T&)(base::operator[](uiIndex)); } \
519 T& Last() const \
520 { return (T&)(base::operator[](size() - 1)); } \
521 \
522 int Index(T lItem) const \
523 { return base::Index(lItem, (CMPFUNC)m_fnCompare); } \
524 \
525 size_t IndexForInsert(T lItem) const \
526 { return base::IndexForInsert(lItem, (CMPFUNC)m_fnCompare); } \
527 \
528 void AddAt(T item, size_t index) \
529 { base::insert(begin() + index, item); } \
530 \
531 size_t Add(T lItem) \
532 { return base::Add(lItem, (CMPFUNC)m_fnCompare); } \
533 \
534 void RemoveAt(size_t uiIndex, size_t nRemove = 1) \
535 { base::erase(begin() + uiIndex, begin() + uiIndex + nRemove); } \
536 void Remove(T lItem) \
537 { int iIndex = Index(lItem); \
538 wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \
539 _WX_ERROR_REMOVE ); \
540 base::erase(begin() + iIndex); } \
541 \
542 private: \
543 comptype m_fnCompare; \
544 }
545
546
547 // ----------------------------------------------------------------------------
548 // _WX_DECLARE_OBJARRAY: an array for pointers to type T with owning semantics
549 // ----------------------------------------------------------------------------
550
551 #define _WX_DECLARE_OBJARRAY(T, name, base, classexp) \
552 typedef int (CMPFUNC_CONV *CMPFUNC##T)(T **pItem1, T **pItem2); \
553 classexp name : protected base \
554 { \
555 typedef int (CMPFUNC_CONV *CMPFUNC##base)(void **pItem1, void **pItem2); \
556 typedef base base_array; \
557 public: \
558 name() { } \
559 name(const name& src); \
560 name& operator=(const name& src); \
561 \
562 ~name(); \
563 \
564 void Alloc(size_t count) { base::reserve(count); } \
565 void reserve(size_t count) { base::reserve(count); } \
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(); } \
569 bool empty() const { return base_array::empty(); } \
570 size_t Count() const { return base_array::size(); } \
571 void Shrink() { base::Shrink(); } \
572 \
573 T& operator[](size_t uiIndex) const \
574 { return *(T*)base::operator[](uiIndex); } \
575 T& Item(size_t uiIndex) const \
576 { return *(T*)base::operator[](uiIndex); } \
577 T& Last() const \
578 { return *(T*)(base::operator[](size() - 1)); } \
579 \
580 int Index(const T& lItem, bool bFromEnd = false) const; \
581 \
582 void Add(const T& lItem, size_t nInsert = 1); \
583 void Add(const T* pItem) \
584 { base::push_back((T*)pItem); } \
585 void push_back(const T* pItem) \
586 { base::push_back((T*)pItem); } \
587 void push_back(const T& lItem) \
588 { Add(lItem); } \
589 \
590 void Insert(const T& lItem, size_t uiIndex, size_t nInsert = 1); \
591 void Insert(const T* pItem, size_t uiIndex) \
592 { base::insert(begin() + uiIndex, (T*)pItem); } \
593 \
594 void Empty() { DoEmpty(); base::clear(); } \
595 void Clear() { DoEmpty(); base::clear(); } \
596 \
597 T* Detach(size_t uiIndex) \
598 { T* p = (T*)base::operator[](uiIndex); \
599 base::erase(begin() + uiIndex); return p; } \
600 void RemoveAt(size_t uiIndex, size_t nRemove = 1); \
601 \
602 void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC##base)fCmp); } \
603 \
604 private: \
605 void DoEmpty(); \
606 void DoCopy(const name& src); \
607 }
608
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 //
618 // The first (just EXPORTED) macros do it if wxWidgets was compiled as a DLL
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 // ----------------------------------------------------------------------------
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) \
636 WX_DECLARE_USER_EXPORTED_BASEARRAY(T, name, WXDLLEXPORT)
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
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
648 // ----------------------------------------------------------------------------
649
650 #define WX_DEFINE_TYPEARRAY(T, name, base) \
651 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class wxARRAY_DEFAULT_EXPORT)
652
653 #define WX_DEFINE_TYPEARRAY_PTR(T, name, base) \
654 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, class wxARRAY_DEFAULT_EXPORT)
655
656 #define WX_DEFINE_EXPORTED_TYPEARRAY(T, name, base) \
657 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class WXDLLEXPORT)
658
659 #define WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, base) \
660 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, class WXDLLEXPORT)
661
662 #define WX_DEFINE_USER_EXPORTED_TYPEARRAY(T, name, base, expdecl) \
663 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class expdecl)
664
665 #define WX_DEFINE_USER_EXPORTED_TYPEARRAY_PTR(T, name, base, expdecl) \
666 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, class expdecl)
667
668 #define WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, classdecl) \
669 typedef T _wxArray##name; \
670 _WX_DEFINE_TYPEARRAY(_wxArray##name, name, base, classdecl)
671
672 #define WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, base, classdecl) \
673 typedef T _wxArray##name; \
674 _WX_DEFINE_TYPEARRAY_PTR(_wxArray##name, name, base, classdecl)
675
676 // ----------------------------------------------------------------------------
677 // WX_DEFINE_SORTED_TYPEARRAY: this is the same as the previous macro, but it
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
696 // is the same for all objects of a class, WX_DEFINE_SORTED_TYPEARRAY_CMP below
697 // is more convenient.
698 //
699 // Summary: use this class when the speed of Index() function is important, use
700 // the normal arrays otherwise.
701 // ----------------------------------------------------------------------------
702
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
707
708 #define WX_DEFINE_SORTED_TYPEARRAY(T, name, base) \
709 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, \
710 wxARRAY_DEFAULT_EXPORT)
711
712 #define WX_DEFINE_SORTED_EXPORTED_TYPEARRAY(T, name, base) \
713 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, WXDLLEXPORT)
714
715 #define WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, base, expmode) \
716 typedef T _wxArray##name; \
717 typedef int (CMPFUNC_CONV *SCMPFUNC##name)(T pItem1, T pItem2); \
718 _WX_DEFINE_SORTED_TYPEARRAY_2(_wxArray##name, name, base, \
719 wxARRAY_EMPTY, class expmode, SCMPFUNC##name)
720
721 // ----------------------------------------------------------------------------
722 // WX_DEFINE_SORTED_TYPEARRAY_CMP: exactly the same as above but the comparison
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 //
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
731 // ----------------------------------------------------------------------------
732
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)
736
737 #define WX_DEFINE_SORTED_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base) \
738 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
739 WXDLLEXPORT)
740
741 #define WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, base, \
742 expmode) \
743 typedef T _wxArray##name; \
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)
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"!
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 //
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) \
792 WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, WXDLLEXPORT)
793
794 #define WX_DECLARE_OBJARRAY_WITH_DECL(T, name, decl) \
795 typedef T _wxObjArray##name; \
796 _WX_DECLARE_OBJARRAY(_wxObjArray##name, name, wxArrayPtrVoid, decl)
797
798 #define WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, expmode) \
799 WX_DECLARE_OBJARRAY_WITH_DECL(T, name, class expmode)
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)
808 #define WX_DEFINE_USER_EXPORTED_OBJARRAY(name) WX_DEFINE_OBJARRAY(name)
809
810 // ----------------------------------------------------------------------------
811 // Some commonly used predefined base arrays
812 // ----------------------------------------------------------------------------
813
814 WX_DECLARE_USER_EXPORTED_BASEARRAY(const void *, wxBaseArrayPtrVoid,
815 WXDLLIMPEXP_BASE);
816 WX_DECLARE_USER_EXPORTED_BASEARRAY(char, wxBaseArrayChar, WXDLLIMPEXP_BASE);
817 WX_DECLARE_USER_EXPORTED_BASEARRAY(short, wxBaseArrayShort, WXDLLIMPEXP_BASE);
818 WX_DECLARE_USER_EXPORTED_BASEARRAY(int, wxBaseArrayInt, WXDLLIMPEXP_BASE);
819 WX_DECLARE_USER_EXPORTED_BASEARRAY(long, wxBaseArrayLong, WXDLLIMPEXP_BASE);
820 WX_DECLARE_USER_EXPORTED_BASEARRAY(size_t, wxBaseArraySizeT, WXDLLIMPEXP_BASE);
821 WX_DECLARE_USER_EXPORTED_BASEARRAY(double, wxBaseArrayDouble, WXDLLIMPEXP_BASE);
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)
829 #define WX_DEFINE_ARRAY_PTR(T, name) \
830 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayPtrVoid)
831 #define WX_DEFINE_EXPORTED_ARRAY(T, name) \
832 WX_DEFINE_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid)
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)
837 #define WX_DEFINE_USER_EXPORTED_ARRAY(T, name, expmode) \
838 WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, wxBaseArrayPtrVoid, wxARRAY_EMPTY expmode)
839 #define WX_DEFINE_USER_EXPORTED_ARRAY_PTR(T, name, expmode) \
840 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayPtrVoid, wxARRAY_EMPTY expmode)
841
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) \
847 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayChar, wxARRAY_EMPTY expmode)
848
849 #define WX_DEFINE_ARRAY_SHORT(T, name) \
850 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayShort)
851 #define WX_DEFINE_EXPORTED_ARRAY_SHORT(T, name) \
852 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayShort)
853 #define WX_DEFINE_USER_EXPORTED_ARRAY_SHORT(T, name, expmode) \
854 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayShort, wxARRAY_EMPTY expmode)
855
856 #define WX_DEFINE_ARRAY_INT(T, name) \
857 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayInt)
858 #define WX_DEFINE_EXPORTED_ARRAY_INT(T, name) \
859 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayInt)
860 #define WX_DEFINE_USER_EXPORTED_ARRAY_INT(T, name, expmode) \
861 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayInt, wxARRAY_EMPTY expmode)
862
863 #define WX_DEFINE_ARRAY_LONG(T, name) \
864 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayLong)
865 #define WX_DEFINE_EXPORTED_ARRAY_LONG(T, name) \
866 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayLong)
867 #define WX_DEFINE_USER_EXPORTED_ARRAY_LONG(T, name, expmode) \
868 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayLong, wxARRAY_EMPTY expmode)
869
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) \
875 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArraySizeT, wxARRAY_EMPTY expmode)
876
877 #define WX_DEFINE_ARRAY_DOUBLE(T, name) \
878 WX_DEFINE_TYPEARRAY_PTR(T, name, wxBaseArrayDouble)
879 #define WX_DEFINE_EXPORTED_ARRAY_DOUBLE(T, name) \
880 WX_DEFINE_EXPORTED_TYPEARRAY_PTR(T, name, wxBaseArrayDouble)
881 #define WX_DEFINE_USER_EXPORTED_ARRAY_DOUBLE(T, name, expmode) \
882 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(T, name, wxBaseArrayDouble, wxARRAY_EMPTY expmode)
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) \
893 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayPtrVoid, wxARRAY_EMPTY expmode)
894
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) \
900 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayChar, wxARRAY_EMPTY expmode)
901
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) \
907 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArrayShort, wxARRAY_EMPTY expmode)
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
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) \
928 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY(T, name, wxBaseArraySizeT, wxARRAY_EMPTY expmode)
929
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, \
941 wxBaseArrayPtrVoid, \
942 wxARRAY_EMPTY expmode)
943
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)
948 #define WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_CMP_CHAR(T, cmpfunc, \
949 name, expmode) \
950 WX_DEFINE_SORTED_USER_EXPORTED_TYPEARRAY_CMP(T, cmpfunc, name, \
951 wxBaseArrayChar, \
952 wxARRAY_EMPTY expmode)
953
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, \
961 wxBaseArrayShort, \
962 wxARRAY_EMPTY expmode)
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, \
971 wxBaseArrayInt, \
972 wxARRAY_EMPTY expmode)
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, \
981 wxBaseArrayLong, \
982 wxARRAY_EMPTY expmode)
983
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, \
991 wxBaseArraySizeT, \
992 wxARRAY_EMPTY expmode)
993
994 // ----------------------------------------------------------------------------
995 // Some commonly used predefined arrays
996 // ----------------------------------------------------------------------------
997
998 WX_DEFINE_USER_EXPORTED_ARRAY_SHORT(short, wxArrayShort, class WXDLLIMPEXP_BASE);
999 WX_DEFINE_USER_EXPORTED_ARRAY_INT(int, wxArrayInt, class WXDLLIMPEXP_BASE);
1000 WX_DEFINE_USER_EXPORTED_ARRAY_DOUBLE(double, wxArrayDouble, class WXDLLIMPEXP_BASE);
1001 WX_DEFINE_USER_EXPORTED_ARRAY_LONG(long, wxArrayLong, class WXDLLIMPEXP_BASE);
1002 WX_DEFINE_USER_EXPORTED_ARRAY_PTR(void *, wxArrayPtrVoid, class WXDLLIMPEXP_BASE);
1003
1004 // -----------------------------------------------------------------------------
1005 // convenience macros
1006 // -----------------------------------------------------------------------------
1007
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(); \
1014 (array).reserve(wxAAcnt); \
1015 for ( size_t wxAAn = 0; wxAAn < wxAAcnt; wxAAn++ ) \
1016 { \
1017 (array).Insert((other)[wxAAn], wxAAn); \
1018 } \
1019 }
1020
1021 // append all element of one array to another one
1022 #define WX_APPEND_ARRAY(array, other) \
1023 { \
1024 size_t wxAAcnt = (other).size(); \
1025 (array).reserve(wxAAcnt); \
1026 for ( size_t wxAAn = 0; wxAAn < wxAAcnt; wxAAn++ ) \
1027 { \
1028 (array).push_back((other)[wxAAn]); \
1029 } \
1030 }
1031
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 { \
1040 size_t wxAAcnt = (array).size(); \
1041 for ( size_t wxAAn = 0; wxAAn < wxAAcnt; wxAAn++ ) \
1042 { \
1043 delete (array)[wxAAn]; \
1044 } \
1045 \
1046 (array).clear(); \
1047 }
1048
1049 #endif // _DYNARRAY_H