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