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