]> git.saurik.com Git - wxWidgets.git/blame - include/wx/list.h
fixed wxString iterators linked list corruption
[wxWidgets.git] / include / wx / list.h
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
c0089c96 2// Name: wx/list.h
c801d85f
KB
3// Purpose: wxList, wxStringList classes
4// Author: Julian Smart
fd3f686c 5// Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added
c801d85f
KB
6// Created: 29/01/98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Julian Smart
65571936 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
fd3f686c
VZ
12/*
13 All this is quite ugly but serves two purposes:
14 1. Be almost 100% compatible with old, untyped, wxList class
15 2. Ensure compile-time type checking for the linked lists
16
17 The idea is to have one base class (wxListBase) working with "void *" data,
18 but to hide these untyped functions - i.e. make them protected, so they
19 can only be used from derived classes which have inline member functions
20 working with right types. This achieves the 2nd goal. As for the first one,
21 we provide a special derivation of wxListBase called wxList which looks just
22 like the old class.
23*/
24
34138703
JS
25#ifndef _WX_LISTH__
26#define _WX_LISTH__
c801d85f 27
fd3f686c
VZ
28// -----------------------------------------------------------------------------
29// headers
30// -----------------------------------------------------------------------------
31
c801d85f
KB
32#include "wx/defs.h"
33#include "wx/object.h"
3bef6c4c 34#include "wx/string.h"
c801d85f 35
df5168c4
MB
36#if wxUSE_STL
37 #include "wx/beforestd.h"
ed1288c1
VZ
38 #include <algorithm>
39 #include <iterator>
df5168c4
MB
40 #include <list>
41 #include "wx/afterstd.h"
df5168c4
MB
42#endif
43
44// ----------------------------------------------------------------------------
45// types
46// ----------------------------------------------------------------------------
47
48// type of compare function for list sort operation (as in 'qsort'): it should
49// return a negative value, 0 or positive value if the first element is less
50// than, equal or greater than the second
5e967044 51
df5168c4
MB
52extern "C"
53{
54typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2);
55}
56
bddd7a8d 57class WXDLLIMPEXP_BASE wxObjectListNode;
fd3f686c
VZ
58typedef wxObjectListNode wxNode;
59
df5168c4
MB
60//
61typedef int (* LINKAGEMODE wxListIterateFunction)(void *current);
c801d85f 62
df5168c4 63#if wxUSE_STL
fd3f686c 64
df5168c4
MB
65#define wxLIST_COMPATIBILITY
66
67#define WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl) \
f794be6a 68 WX_DECLARE_LIST_WITH_DECL(elT, liT, decl)
6de44038
VZ
69#define WX_DECLARE_LIST_PTR_3(elT, dummy1, liT, dummy2, decl) \
70 WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl)
df5168c4
MB
71
72#define WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
f794be6a 73 WX_DECLARE_LIST_WITH_DECL(elT, liT, decl)
6de44038
VZ
74#define WX_DECLARE_LIST_PTR_2(elT, liT, dummy, decl) \
75 WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
df5168c4 76
f794be6a 77#define WX_DECLARE_LIST_WITH_DECL(elT, liT, decl) \
df5168c4
MB
78 WX_DECLARE_LIST_XO(elT*, liT, decl)
79
a4c1cdc9 80#if !defined(__VISUALC__) || __VISUALC__ >= 1300 // == !VC6
168da56b 81
30bda36c
MB
82template<class T>
83class WXDLLIMPEXP_BASE wxList_SortFunction
84{
85public:
86 wxList_SortFunction(wxSortCompareFunction f) : m_f(f) { }
87 bool operator()(const T& i1, const T& i2)
88 { return m_f((T*)&i1, (T*)&i2) < 0; }
89private:
90 wxSortCompareFunction m_f;
91};
92
168da56b
MB
93#define WX_LIST_SORTFUNCTION( elT, f ) wxList_SortFunction<elT>(f)
94#define VC6_WORKAROUND(elT, liT, decl)
95
a4c1cdc9 96#else // if defined( __VISUALC__ ) && __VISUALC__ < 1300 // == VC6
168da56b 97
543ab300 98#define WX_LIST_SORTFUNCTION( elT, f ) std::greater<elT>( f )
168da56b
MB
99#define VC6_WORKAROUND(elT, liT, decl) \
100 decl liT; \
101 \
102 /* Workaround for broken VC6 STL incorrectly requires a std::greater<> */ \
103 /* to be passed into std::list::sort() */ \
104 template <> \
105 struct std::greater<elT> \
106 { \
107 private: \
108 wxSortCompareFunction m_CompFunc; \
109 public: \
110 greater( wxSortCompareFunction compfunc = NULL ) \
111 : m_CompFunc( compfunc ) {} \
112 bool operator()(const elT X, const elT Y) const \
113 { \
114 return m_CompFunc ? \
8a7afe4d
VS
115 ( m_CompFunc( wxListCastElementToVoidPtr(X), \
116 wxListCastElementToVoidPtr(Y) ) < 0 ) : \
168da56b
MB
117 ( X > Y ); \
118 } \
119 };
120
8a7afe4d
VS
121// helper for std::greater<elT> above:
122template<typename T>
123inline const void *wxListCastElementToVoidPtr(const T* ptr) { return ptr; }
124inline const void *wxListCastElementToVoidPtr(const wxString& str)
125 { return (const char*)str; }
126
a4c1cdc9 127#endif // VC6/!VC6
168da56b 128
30a29593 129/*
7d13fbc6 130 Note 1: the outer helper class _WX_LIST_HELPER_##liT below is a workaround
30a29593
VZ
131 for mingw 3.2.3 compiler bug that prevents a static function of liT class
132 from being exported into dll. A minimal code snippet reproducing the bug:
133
134 struct WXDLLEXPORT Foo
135 {
136 static void Bar();
137 struct SomeInnerClass
138 {
139 friend class Foo; // comment this out to make it link
140 };
141 ~Foo()
142 {
143 Bar();
144 }
145 };
146
147 The program does not link under mingw_gcc 3.2.3 producing undefined
148 reference to Foo::Bar() function
7d13fbc6
VZ
149
150
151 Note 2: the EmptyList is needed to allow having a NULL pointer-like
152 invalid iterator. We used to use just an uninitialized iterator object
153 instead but this fails with some debug/checked versions of STL, notably the
154 glibc version activated with _GLIBCXX_DEBUG, so we need to have a separate
155 invalid iterator.
30a29593
VZ
156 */
157
158// the real wxList-class declaration
ed1288c1 159#define WX_DECLARE_LIST_XO(elT, liT, decl) \
3871d4ca 160 decl _WX_LIST_HELPER_##liT \
30a29593
VZ
161 { \
162 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
163 public: \
164 static void DeleteFunction( _WX_LIST_ITEM_TYPE_##liT X ); \
165 }; \
166 \
168da56b 167 VC6_WORKAROUND(elT, liT, decl) \
831c2889
VZ
168 decl liT : public std::list<elT> \
169 { \
170 private: \
7d13fbc6
VZ
171 typedef std::list<elT> BaseListType; \
172 static BaseListType EmptyList; \
173 \
831c2889 174 bool m_destroy; \
cd840087 175 \
ed1288c1 176 public: \
d294c9db 177 decl compatibility_iterator \
df5168c4 178 { \
ed1288c1 179 private: \
cd840087
VZ
180 /* Workaround for broken VC6 nested class name resolution */ \
181 typedef std::list<elT>::iterator iterator; \
182 friend class liT; \
183 \
df5168c4
MB
184 iterator m_iter; \
185 liT * m_list; \
cd840087 186 \
df5168c4 187 public: \
ed1288c1 188 compatibility_iterator() \
7d13fbc6 189 : m_iter(EmptyList.end()), m_list( NULL ) {} \
ed1288c1
VZ
190 compatibility_iterator( liT* li, iterator i ) \
191 : m_iter( i ), m_list( li ) {} \
192 compatibility_iterator( const liT* li, iterator i ) \
193 : m_iter( i ), m_list( const_cast< liT* >( li ) ) {} \
194 \
195 compatibility_iterator* operator->() { return this; } \
196 const compatibility_iterator* operator->() const { return this; } \
197 \
60d8e886 198 bool operator==(const compatibility_iterator& i) const \
b4affacc
VZ
199 { \
200 wxASSERT_MSG( m_list && i.m_list, \
201 _T("comparing invalid iterators is illegal") ); \
202 return (m_list == i.m_list) && (m_iter == i.m_iter); \
203 } \
60d8e886 204 bool operator!=(const compatibility_iterator& i) const \
ed1288c1 205 { return !( operator==( i ) ); } \
df5168c4 206 operator bool() const \
ed1288c1 207 { return m_list ? m_iter != m_list->end() : false; } \
df5168c4 208 bool operator !() const \
ed1288c1 209 { return !( operator bool() ); } \
df5168c4 210 \
df5168c4 211 elT GetData() const \
ed1288c1
VZ
212 { return *m_iter; } \
213 void SetData( elT e ) \
214 { *m_iter = e; } \
215 \
216 compatibility_iterator GetNext() const \
df5168c4 217 { \
ed1288c1
VZ
218 iterator i = m_iter; \
219 return compatibility_iterator( m_list, ++i ); \
df5168c4 220 } \
ed1288c1 221 compatibility_iterator GetPrevious() const \
df5168c4 222 { \
5d9ef6de
VZ
223 if ( m_iter == m_list->begin() ) \
224 return compatibility_iterator(); \
225 \
ed1288c1
VZ
226 iterator i = m_iter; \
227 return compatibility_iterator( m_list, --i ); \
df5168c4 228 } \
ed1288c1 229 int IndexOf() const \
df5168c4 230 { \
0b6cf205
VZ
231 return *this ? std::distance( m_list->begin(), m_iter ) \
232 : wxNOT_FOUND; \
df5168c4 233 } \
df5168c4 234 }; \
ed1288c1
VZ
235 public: \
236 liT() : m_destroy( false ) {} \
237 \
238 compatibility_iterator Find( const elT e ) const \
df5168c4 239 { \
ed1288c1
VZ
240 liT* _this = const_cast< liT* >( this ); \
241 return compatibility_iterator( _this, \
242 std::find( _this->begin(), _this->end(), e ) ); \
df5168c4 243 } \
df5168c4 244 \
ed1288c1
VZ
245 bool IsEmpty() const \
246 { return empty(); } \
247 size_t GetCount() const \
248 { return size(); } \
249 int Number() const \
250 { return static_cast< int >( GetCount() ); } \
251 \
252 compatibility_iterator Item( size_t idx ) const \
df5168c4 253 { \
ed1288c1
VZ
254 iterator i = const_cast< liT* >(this)->begin(); \
255 std::advance( i, idx ); \
256 return compatibility_iterator( this, i ); \
257 } \
af867f95 258 elT operator[](size_t idx) const \
9ea1246b 259 { \
af867f95 260 return Item(idx).GetData(); \
9ea1246b
VZ
261 } \
262 \
ed1288c1
VZ
263 compatibility_iterator GetFirst() const \
264 { \
265 return compatibility_iterator( this, \
266 const_cast< liT* >(this)->begin() ); \
267 } \
268 compatibility_iterator GetLast() const \
269 { \
270 iterator i = const_cast< liT* >(this)->end(); \
271 return compatibility_iterator( this, !empty() ? --i : i ); \
272 } \
273 compatibility_iterator Member( elT e ) const \
274 { return Find( e ); } \
275 compatibility_iterator Nth( int n ) const \
276 { return Item( n ); } \
277 int IndexOf( elT e ) const \
278 { return Find( e ).IndexOf(); } \
279 \
280 compatibility_iterator Append( elT e ) \
281 { \
282 push_back( e ); \
283 return GetLast(); \
284 } \
285 compatibility_iterator Insert( elT e ) \
286 { \
287 push_front( e ); \
288 return compatibility_iterator( this, begin() ); \
289 } \
290 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
291 { \
292 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
293 } \
294 compatibility_iterator Insert( size_t idx, elT e ) \
295 { \
296 return compatibility_iterator( this, \
297 insert( Item( idx ).m_iter, e ) ); \
298 } \
299 \
300 void DeleteContents( bool destroy ) \
301 { m_destroy = destroy; } \
302 bool GetDeleteContents() const \
303 { return m_destroy; } \
304 void Erase( const compatibility_iterator& i ) \
305 { \
306 if ( m_destroy ) \
30a29593 307 _WX_LIST_HELPER_##liT::DeleteFunction( i->GetData() ); \
ed1288c1
VZ
308 erase( i.m_iter ); \
309 } \
310 bool DeleteNode( const compatibility_iterator& i ) \
311 { \
312 if( i ) \
df5168c4 313 { \
ed1288c1 314 Erase( i ); \
df5168c4
MB
315 return true; \
316 } \
317 return false; \
318 } \
ed1288c1 319 bool DeleteObject( elT e ) \
df5168c4 320 { \
ed1288c1 321 return DeleteNode( Find( e ) ); \
df5168c4 322 } \
ed1288c1 323 void Clear() \
df5168c4 324 { \
ed1288c1 325 if ( m_destroy ) \
30a29593
VZ
326 std::for_each( begin(), end(), \
327 _WX_LIST_HELPER_##liT::DeleteFunction ); \
ed1288c1 328 clear(); \
df5168c4 329 } \
831c2889 330 /* Workaround for broken VC6 std::list::sort() see above */ \
ed1288c1 331 void Sort( wxSortCompareFunction compfunc ) \
168da56b 332 { sort( WX_LIST_SORTFUNCTION( elT, compfunc ) ); } \
ed1288c1 333 ~liT() { Clear(); } \
cd840087
VZ
334 \
335 /* It needs access to our EmptyList */ \
336 friend decl compatibility_iterator; \
df5168c4
MB
337 }
338
339#define WX_DECLARE_LIST(elementtype, listname) \
f794be6a 340 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
6de44038
VZ
341#define WX_DECLARE_LIST_PTR(elementtype, listname) \
342 WX_DECLARE_LIST(elementtype, listname)
df5168c4
MB
343
344#define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
f794be6a 345 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
6de44038
VZ
346#define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
347 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
df5168c4
MB
348
349#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
f794be6a 350 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
6de44038
VZ
351#define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
352 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
df5168c4
MB
353
354// this macro must be inserted in your program after
c0089c96 355// #include "wx/listimpl.cpp"
df5168c4
MB
356#define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
357
358#define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
359#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
360
361#else // if !wxUSE_STL
362
df5168c4 363
df5168c4
MB
364// undef it to get rid of old, deprecated functions
365#define wxLIST_COMPATIBILITY
fd3f686c
VZ
366
367// -----------------------------------------------------------------------------
368// key stuff: a list may be optionally keyed on integer or string key
369// -----------------------------------------------------------------------------
370
371union wxListKeyValue
c801d85f 372{
c801d85f 373 long integer;
81727065 374 wxString *string;
c801d85f
KB
375};
376
fd3f686c
VZ
377// a struct which may contain both types of keys
378//
379// implementation note: on one hand, this class allows to have only one function
380// for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
381// resolve ambiguity which we would otherwise have with wxStringList::Find() and
382// wxList::Find(const char *).
bddd7a8d 383class WXDLLIMPEXP_BASE wxListKey
fd3f686c
VZ
384{
385public:
386 // implicit ctors
f2af4afb
GD
387 wxListKey() : m_keyType(wxKEY_NONE)
388 { }
389 wxListKey(long i) : m_keyType(wxKEY_INTEGER)
390 { m_key.integer = i; }
f2af4afb 391 wxListKey(const wxString& s) : m_keyType(wxKEY_STRING)
81727065 392 { m_key.string = new wxString(s); }
fd3f686c
VZ
393
394 // accessors
395 wxKeyType GetKeyType() const { return m_keyType; }
81727065
VS
396 const wxString GetString() const
397 { wxASSERT( m_keyType == wxKEY_STRING ); return *m_key.string; }
fd3f686c
VZ
398 long GetNumber() const
399 { wxASSERT( m_keyType == wxKEY_INTEGER ); return m_key.integer; }
400
6164d85e
JS
401 // comparison
402 // Note: implementation moved to list.cpp to prevent BC++ inline
403 // expansion warning.
404 bool operator==(wxListKeyValue value) const ;
fd3f686c
VZ
405
406 // dtor
407 ~wxListKey()
408 {
409 if ( m_keyType == wxKEY_STRING )
81727065 410 delete m_key.string;
fd3f686c
VZ
411 }
412
413private:
414 wxKeyType m_keyType;
415 wxListKeyValue m_key;
416};
417
418// -----------------------------------------------------------------------------
419// wxNodeBase class is a (base for) node in a double linked list
420// -----------------------------------------------------------------------------
421
16cba29d 422extern WXDLLIMPEXP_DATA_BASE(wxListKey) wxDefaultListKey;
2432b92d 423
bddd7a8d 424class WXDLLIMPEXP_BASE wxListBase;
fbfb3fb3 425
bddd7a8d 426class WXDLLIMPEXP_BASE wxNodeBase
fd3f686c
VZ
427{
428friend class wxListBase;
429public:
430 // ctor
431 wxNodeBase(wxListBase *list = (wxListBase *)NULL,
432 wxNodeBase *previous = (wxNodeBase *)NULL,
433 wxNodeBase *next = (wxNodeBase *)NULL,
434 void *data = NULL,
2432b92d 435 const wxListKey& key = wxDefaultListKey);
fd3f686c
VZ
436
437 virtual ~wxNodeBase();
438
f03fc89f 439 // FIXME no check is done that the list is really keyed on strings
81727065 440 wxString GetKeyString() const { return *m_key.string; }
74e34480 441 long GetKeyInteger() const { return m_key.integer; }
fd3f686c 442
4fabb575 443 // Necessary for some existing code
81727065 444 void SetKeyString(const wxString& s) { m_key.string = new wxString(s); }
4fabb575
JS
445 void SetKeyInteger(long i) { m_key.integer = i; }
446
fd3f686c 447#ifdef wxLIST_COMPATIBILITY
b1d4dd7a
RL
448 // compatibility methods, use Get* instead.
449 wxDEPRECATED( wxNode *Next() const );
450 wxDEPRECATED( wxNode *Previous() const );
451 wxDEPRECATED( wxObject *Data() const );
fd3f686c
VZ
452#endif // wxLIST_COMPATIBILITY
453
454protected:
455 // all these are going to be "overloaded" in the derived classes
456 wxNodeBase *GetNext() const { return m_next; }
457 wxNodeBase *GetPrevious() const { return m_previous; }
458
459 void *GetData() const { return m_data; }
460 void SetData(void *data) { m_data = data; }
461
3c67202d 462 // get 0-based index of this node within the list or wxNOT_FOUND
77c5eefb
VZ
463 int IndexOf() const;
464
fd3f686c 465 virtual void DeleteData() { }
df5168c4
MB
466public:
467 // for wxList::iterator
468 void** GetDataPtr() const { return &(((wxNodeBase*)this)->m_data); }
fd3f686c
VZ
469private:
470 // optional key stuff
471 wxListKeyValue m_key;
472
473 void *m_data; // user data
474 wxNodeBase *m_next, // next and previous nodes in the list
475 *m_previous;
476
477 wxListBase *m_list; // list we belong to
f2af4afb
GD
478
479 DECLARE_NO_COPY_CLASS(wxNodeBase)
fd3f686c
VZ
480};
481
482// -----------------------------------------------------------------------------
483// a double-linked list class
484// -----------------------------------------------------------------------------
f98bd52a 485
446e5259 486class WXDLLIMPEXP_BASE wxList;
b1d4dd7a 487
bddd7a8d 488class WXDLLIMPEXP_BASE wxListBase : public wxObject
fd3f686c 489{
bddd7a8d 490friend class WXDLLIMPEXP_BASE wxNodeBase; // should be able to call DetachNode()
bcaa23de 491friend class wxHashTableBase; // should be able to call untyped Find()
5a8231ef 492
fd3f686c
VZ
493public:
494 // default ctor & dtor
f2af4afb
GD
495 wxListBase(wxKeyType keyType = wxKEY_NONE)
496 { Init(keyType); }
fd3f686c
VZ
497 virtual ~wxListBase();
498
499 // accessors
500 // count of items in the list
501 size_t GetCount() const { return m_count; }
c801d85f 502
f644b28c 503 // return true if this list is empty
b79a8705
VZ
504 bool IsEmpty() const { return m_count == 0; }
505
fd3f686c 506 // operations
e146b8c8 507
fd3f686c 508 // delete all nodes
db9504c5 509 void Clear();
e146b8c8 510
fd3f686c
VZ
511 // instruct it to destroy user data when deleting nodes
512 void DeleteContents(bool destroy) { m_destroy = destroy; }
513
907789a0
RR
514 // query if to delete
515 bool GetDeleteContents() const
516 { return m_destroy; }
e146b8c8 517
907789a0
RR
518 // get the keytype
519 wxKeyType GetKeyType() const
520 { return m_keyType; }
521
522 // set the keytype (required by the serial code)
523 void SetKeyType(wxKeyType keyType)
524 { wxASSERT( m_count==0 ); m_keyType = keyType; }
525
e146b8c8 526#ifdef wxLIST_COMPATIBILITY
b1d4dd7a
RL
527 // compatibility methods from old wxList
528 wxDEPRECATED( int Number() const ); // use GetCount instead.
529 wxDEPRECATED( wxNode *First() const ); // use GetFirst
530 wxDEPRECATED( wxNode *Last() const ); // use GetLast
531 wxDEPRECATED( wxNode *Nth(size_t n) const ); // use Item
532
533 // kludge for typesafe list migration in core classes.
534 wxDEPRECATED( operator wxList&() const );
e146b8c8
VZ
535#endif // wxLIST_COMPATIBILITY
536
fd3f686c 537protected:
a3ef5bf5 538
fd3f686c
VZ
539 // all methods here are "overloaded" in derived classes to provide compile
540 // time type checking
541
542 // create a node for the list of this type
543 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next,
544 void *data,
2432b92d 545 const wxListKey& key = wxDefaultListKey) = 0;
fd3f686c 546
a3ef5bf5
JS
547// Can't access these from derived classes otherwise (bug in Salford C++?)
548#ifdef __SALFORDC__
549public:
550#endif
551
fd3f686c
VZ
552 // ctors
553 // from an array
554 wxListBase(size_t count, void *elements[]);
555 // from a sequence of objects
556 wxListBase(void *object, ... /* terminate with NULL */);
557
a3ef5bf5 558protected:
00e09270
VZ
559 void Assign(const wxListBase& list)
560 { Clear(); DoCopy(list); }
fd3f686c
VZ
561
562 // get list head/tail
563 wxNodeBase *GetFirst() const { return m_nodeFirst; }
564 wxNodeBase *GetLast() const { return m_nodeLast; }
565
566 // by (0-based) index
567 wxNodeBase *Item(size_t index) const;
568
569 // get the list item's data
2b5f62a0
VZ
570 void *operator[](size_t n) const
571 {
572 wxNodeBase *node = Item(n);
573
574 return node ? node->GetData() : (wxNodeBase *)NULL;
575 }
fd3f686c
VZ
576
577 // operations
578 // append to end of list
890f8a7c
RR
579 wxNodeBase *Prepend(void *object)
580 { return (wxNodeBase *)wxListBase::Insert(object); }
581 // append to beginning of list
fd3f686c
VZ
582 wxNodeBase *Append(void *object);
583 // insert a new item at the beginning of the list
a802c3a1 584 wxNodeBase *Insert(void *object) { return Insert( (wxNodeBase*)NULL, object); }
d8996187
VZ
585 // insert a new item at the given position
586 wxNodeBase *Insert(size_t pos, void *object)
587 { return pos == GetCount() ? Append(object)
588 : Insert(Item(pos), object); }
fd3f686c
VZ
589 // insert before given node or at front of list if prev == NULL
590 wxNodeBase *Insert(wxNodeBase *prev, void *object);
591
592 // keyed append
593 wxNodeBase *Append(long key, void *object);
81727065 594 wxNodeBase *Append(const wxString& key, void *object);
fd3f686c
VZ
595
596 // removes node from the list but doesn't delete it (returns pointer
597 // to the node or NULL if it wasn't found in the list)
598 wxNodeBase *DetachNode(wxNodeBase *node);
f644b28c 599 // delete element from list, returns false if node not found
fd3f686c
VZ
600 bool DeleteNode(wxNodeBase *node);
601 // finds object pointer and deletes node (and object if DeleteContents
f644b28c 602 // is on), returns false if object not found
77c5eefb 603 bool DeleteObject(void *object);
fd3f686c
VZ
604
605 // search (all return NULL if item not found)
606 // by data
22d080f3 607 wxNodeBase *Find(const void *object) const;
fd3f686c
VZ
608
609 // by key
610 wxNodeBase *Find(const wxListKey& key) const;
611
3c67202d 612 // get 0-based index of object or wxNOT_FOUND
77c5eefb
VZ
613 int IndexOf( void *object ) const;
614
fd3f686c
VZ
615 // this function allows the sorting of arbitrary lists by giving
616 // a function to compare two list elements. The list is sorted in place.
6164d85e 617 void Sort(const wxSortCompareFunction compfunc);
fd3f686c
VZ
618
619 // functions for iterating over the list
620 void *FirstThat(wxListIterateFunction func);
621 void ForEach(wxListIterateFunction func);
622 void *LastThat(wxListIterateFunction func);
e146b8c8 623
df5168c4
MB
624 // for STL interface, "last" points to one after the last node
625 // of the controlled sequence (NULL for the end of the list)
626 void Reverse();
627 void DeleteNodes(wxNodeBase* first, wxNodeBase* last);
fd3f686c 628private:
5a8231ef
WS
629
630 // common part of all ctors
631 void Init(wxKeyType keyType = wxKEY_NONE);
632
fd3f686c 633 // helpers
fd3f686c
VZ
634 // common part of copy ctor and assignment operator
635 void DoCopy(const wxListBase& list);
636 // common part of all Append()s
637 wxNodeBase *AppendCommon(wxNodeBase *node);
638 // free node's data and node itself
639 void DoDeleteNode(wxNodeBase *node);
640
641 size_t m_count; // number of elements in the list
642 bool m_destroy; // destroy user data when deleting list items?
643 wxNodeBase *m_nodeFirst, // pointers to the head and tail of the list
644 *m_nodeLast;
645
646 wxKeyType m_keyType; // type of our keys (may be wxKEY_NONE)
647};
648
649// -----------------------------------------------------------------------------
650// macros for definition of "template" list type
651// -----------------------------------------------------------------------------
652
653// and now some heavy magic...
654
655// declare a list type named 'name' and containing elements of type 'T *'
656// (as a by product of macro expansion you also get wx##name##Node
ce3ed50d 657// wxNode-derived type)
fd3f686c
VZ
658//
659// implementation details:
ce3ed50d 660// 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
fd3f686c
VZ
661// for the list of given type - this allows us to pass only the list name
662// to WX_DEFINE_LIST() even if it needs both the name and the type
663//
ce3ed50d
JS
664// 2. We redefine all non-type-safe wxList functions with type-safe versions
665// which don't take any space (everything is inline), but bring compile
fd3f686c 666// time error checking.
f03fc89f
VZ
667//
668// 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
669// a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
670// generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
671// interesting capability to store polymorphic objects in the list and is
672// particularly useful with, for example, "wxWindow *" list where the
673// wxWindowBase pointers are put into the list, but wxWindow pointers are
674// retrieved from it.
6de44038
VZ
675//
676// 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
677// WX_DECLARE_LIST_4 to allow defining classes without operator->() as
678// it results in compiler warnings when this operator doesn't make sense
679// (i.e. stored elements are not pointers)
f03fc89f 680
6de44038
VZ
681// common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
682#define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
ba059d80 683 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
fd3f686c 684 \
f6bcfd97 685 classexp nodetype : public wxNodeBase \
fd3f686c
VZ
686 { \
687 public: \
688 nodetype(wxListBase *list = (wxListBase *)NULL, \
689 nodetype *previous = (nodetype *)NULL, \
690 nodetype *next = (nodetype *)NULL, \
7f985bd3 691 T *data = (T *)NULL, \
e146b8c8 692 const wxListKey& key = wxDefaultListKey) \
fd3f686c
VZ
693 : wxNodeBase(list, previous, next, data, key) { } \
694 \
695 nodetype *GetNext() const \
696 { return (nodetype *)wxNodeBase::GetNext(); } \
697 nodetype *GetPrevious() const \
698 { return (nodetype *)wxNodeBase::GetPrevious(); } \
699 \
700 T *GetData() const \
701 { return (T *)wxNodeBase::GetData(); } \
702 void SetData(T *data) \
703 { wxNodeBase::SetData(data); } \
704 \
60d8e886 705 protected: \
fd3f686c 706 virtual void DeleteData(); \
cd989b24
VZ
707 \
708 DECLARE_NO_COPY_CLASS(nodetype) \
fd3f686c
VZ
709 }; \
710 \
f6bcfd97 711 classexp name : public wxListBase \
fd3f686c
VZ
712 { \
713 public: \
e2a3cc0c 714 typedef nodetype Node; \
d294c9db 715 classexp compatibility_iterator \
0cc70962
VZ
716 { \
717 public: \
718 compatibility_iterator(Node *ptr = NULL) : m_ptr(ptr) { } \
719 \
720 Node *operator->() const { return m_ptr; } \
721 operator Node *() const { return m_ptr; } \
722 \
723 private: \
724 Node *m_ptr; \
725 }; \
e2a3cc0c 726 \
fd3f686c
VZ
727 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
728 { } \
00e09270
VZ
729 name(const name& list) : wxListBase(list.GetKeyType()) \
730 { Assign(list); } \
fd3f686c
VZ
731 name(size_t count, T *elements[]) \
732 : wxListBase(count, (void **)elements) { } \
733 \
f6bcfd97 734 name& operator=(const name& list) \
00e09270 735 { Assign(list); return *this; } \
f6bcfd97 736 \
2e4b087e 737 nodetype *GetFirst() const \
fd3f686c 738 { return (nodetype *)wxListBase::GetFirst(); } \
2e4b087e 739 nodetype *GetLast() const \
fd3f686c
VZ
740 { return (nodetype *)wxListBase::GetLast(); } \
741 \
2e4b087e 742 nodetype *Item(size_t index) const \
fd3f686c
VZ
743 { return (nodetype *)wxListBase::Item(index); } \
744 \
745 T *operator[](size_t index) const \
746 { \
747 nodetype *node = Item(index); \
7f985bd3 748 return node ? (T*)(node->GetData()) : (T*)NULL; \
fd3f686c
VZ
749 } \
750 \
2e4b087e 751 nodetype *Append(Tbase *object) \
fd3f686c 752 { return (nodetype *)wxListBase::Append(object); } \
2e4b087e 753 nodetype *Insert(Tbase *object) \
a802c3a1 754 { return (nodetype *)Insert((nodetype*)NULL, object); } \
2e4b087e 755 nodetype *Insert(size_t pos, Tbase *object) \
d8996187 756 { return (nodetype *)wxListBase::Insert(pos, object); } \
2e4b087e 757 nodetype *Insert(nodetype *prev, Tbase *object) \
fd3f686c
VZ
758 { return (nodetype *)wxListBase::Insert(prev, object); } \
759 \
2e4b087e 760 nodetype *Append(long key, void *object) \
fd3f686c 761 { return (nodetype *)wxListBase::Append(key, object); } \
2e4b087e 762 nodetype *Append(const wxChar *key, void *object) \
fd3f686c
VZ
763 { return (nodetype *)wxListBase::Append(key, object); } \
764 \
765 nodetype *DetachNode(nodetype *node) \
766 { return (nodetype *)wxListBase::DetachNode(node); } \
767 bool DeleteNode(nodetype *node) \
768 { return wxListBase::DeleteNode(node); } \
f03fc89f 769 bool DeleteObject(Tbase *object) \
fd3f686c 770 { return wxListBase::DeleteObject(object); } \
2e4b087e 771 void Erase(nodetype *it) \
df5168c4 772 { DeleteNode(it); } \
fd3f686c 773 \
2e4b087e 774 nodetype *Find(const Tbase *object) const \
fd3f686c
VZ
775 { return (nodetype *)wxListBase::Find(object); } \
776 \
777 virtual nodetype *Find(const wxListKey& key) const \
778 { return (nodetype *)wxListBase::Find(key); } \
779 \
f03fc89f 780 int IndexOf(Tbase *object) const \
77c5eefb
VZ
781 { return wxListBase::IndexOf(object); } \
782 \
ed1288c1
VZ
783 void Sort(wxSortCompareFunction func) \
784 { wxListBase::Sort(func); } \
fd3f686c 785 void Sort(wxSortFuncFor_##name func) \
ed1288c1 786 { Sort((wxSortCompareFunction)func); } \
fd3f686c
VZ
787 \
788 protected: \
ea48aff3 789 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
fd3f686c 790 void *data, \
e146b8c8 791 const wxListKey& key = wxDefaultListKey) \
fd3f686c
VZ
792 { \
793 return new nodetype(this, \
794 (nodetype *)prev, (nodetype *)next, \
795 (T *)data, key); \
796 } \
df5168c4
MB
797 /* STL interface */ \
798 public: \
799 typedef size_t size_type; \
800 typedef int difference_type; \
801 typedef T* value_type; \
802 typedef Tbase* base_value_type; \
803 typedef value_type& reference; \
804 typedef const value_type& const_reference; \
805 typedef base_value_type& base_reference; \
806 typedef const base_value_type& const_base_reference; \
807 \
d294c9db 808 classexp iterator \
df5168c4
MB
809 { \
810 typedef name list; \
811 public: \
37589419 812 typedef nodetype Node; \
df5168c4 813 typedef iterator itor; \
37589419
MB
814 typedef T* value_type; \
815 typedef value_type* ptr_type; \
816 typedef value_type& reference; \
df5168c4
MB
817 \
818 Node* m_node; \
819 Node* m_init; \
820 public: \
37589419 821 typedef reference reference_type; \
df5168c4
MB
822 typedef ptr_type pointer_type; \
823 \
824 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
825 iterator() : m_node(NULL), m_init(NULL) { } \
826 reference_type operator*() const \
827 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 828 ptrop \
df5168c4 829 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
60d8e886 830 const itor operator++(int) \
df5168c4
MB
831 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
832 itor& operator--() \
833 { \
834 m_node = m_node ? m_node->GetPrevious() : m_init; \
835 return *this; \
836 } \
60d8e886 837 const itor operator--(int) \
df5168c4
MB
838 { \
839 itor tmp = *this; \
840 m_node = m_node ? m_node->GetPrevious() : m_init; \
841 return tmp; \
842 } \
843 bool operator!=(const itor& it) const \
844 { return it.m_node != m_node; } \
845 bool operator==(const itor& it) const \
846 { return it.m_node == m_node; } \
847 }; \
d294c9db 848 classexp const_iterator \
df5168c4
MB
849 { \
850 typedef name list; \
851 public: \
37589419
MB
852 typedef nodetype Node; \
853 typedef T* value_type; \
854 typedef const value_type& const_reference; \
df5168c4 855 typedef const_iterator itor; \
37589419 856 typedef value_type* ptr_type; \
df5168c4
MB
857 \
858 Node* m_node; \
859 Node* m_init; \
860 public: \
37589419 861 typedef const_reference reference_type; \
df5168c4
MB
862 typedef const ptr_type pointer_type; \
863 \
864 const_iterator(Node* node, Node* init) \
865 : m_node(node), m_init(init) { } \
866 const_iterator() : m_node(NULL), m_init(NULL) { } \
867 const_iterator(const iterator& it) \
868 : m_node(it.m_node), m_init(it.m_init) { } \
869 reference_type operator*() const \
870 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 871 ptrop \
df5168c4 872 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
60d8e886 873 const itor operator++(int) \
df5168c4
MB
874 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
875 itor& operator--() \
876 { \
877 m_node = m_node ? m_node->GetPrevious() : m_init; \
878 return *this; \
879 } \
60d8e886 880 const itor operator--(int) \
df5168c4
MB
881 { \
882 itor tmp = *this; \
883 m_node = m_node ? m_node->GetPrevious() : m_init; \
884 return tmp; \
885 } \
886 bool operator!=(const itor& it) const \
887 { return it.m_node != m_node; } \
888 bool operator==(const itor& it) const \
889 { return it.m_node == m_node; } \
890 }; \
d294c9db 891 classexp reverse_iterator \
df5168c4
MB
892 { \
893 typedef name list; \
894 public: \
37589419
MB
895 typedef nodetype Node; \
896 typedef T* value_type; \
df5168c4 897 typedef reverse_iterator itor; \
37589419
MB
898 typedef value_type* ptr_type; \
899 typedef value_type& reference; \
df5168c4
MB
900 \
901 Node* m_node; \
902 Node* m_init; \
903 public: \
37589419 904 typedef reference reference_type; \
df5168c4
MB
905 typedef ptr_type pointer_type; \
906 \
907 reverse_iterator(Node* node, Node* init) \
908 : m_node(node), m_init(init) { } \
909 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
910 reference_type operator*() const \
911 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 912 ptrop \
df5168c4
MB
913 itor& operator++() \
914 { m_node = m_node->GetPrevious(); return *this; } \
60d8e886 915 const itor operator++(int) \
df5168c4
MB
916 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
917 itor& operator--() \
918 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
60d8e886 919 const itor operator--(int) \
df5168c4
MB
920 { \
921 itor tmp = *this; \
922 m_node = m_node ? m_node->GetNext() : m_init; \
923 return tmp; \
924 } \
925 bool operator!=(const itor& it) const \
926 { return it.m_node != m_node; } \
927 bool operator==(const itor& it) const \
928 { return it.m_node == m_node; } \
929 }; \
d294c9db 930 classexp const_reverse_iterator \
df5168c4
MB
931 { \
932 typedef name list; \
933 public: \
37589419
MB
934 typedef nodetype Node; \
935 typedef T* value_type; \
df5168c4 936 typedef const_reverse_iterator itor; \
37589419
MB
937 typedef value_type* ptr_type; \
938 typedef const value_type& const_reference; \
df5168c4
MB
939 \
940 Node* m_node; \
941 Node* m_init; \
942 public: \
37589419 943 typedef const_reference reference_type; \
df5168c4
MB
944 typedef const ptr_type pointer_type; \
945 \
946 const_reverse_iterator(Node* node, Node* init) \
947 : m_node(node), m_init(init) { } \
948 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
949 const_reverse_iterator(const reverse_iterator& it) \
950 : m_node(it.m_node), m_init(it.m_init) { } \
951 reference_type operator*() const \
952 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 953 ptrop \
df5168c4
MB
954 itor& operator++() \
955 { m_node = m_node->GetPrevious(); return *this; } \
60d8e886 956 const itor operator++(int) \
df5168c4
MB
957 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
958 itor& operator--() \
959 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
60d8e886 960 const itor operator--(int) \
df5168c4
MB
961 { \
962 itor tmp = *this; \
963 m_node = m_node ? m_node->GetNext() : m_init; \
964 return tmp; \
965 } \
966 bool operator!=(const itor& it) const \
967 { return it.m_node != m_node; } \
968 bool operator==(const itor& it) const \
969 { return it.m_node == m_node; } \
970 }; \
971 \
972 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
973 { assign(n, v); } \
60d8e886 974 name(const const_iterator& first, const const_iterator& last) \
df5168c4
MB
975 { assign(first, last); } \
976 iterator begin() { return iterator(GetFirst(), GetLast()); } \
977 const_iterator begin() const \
978 { return const_iterator(GetFirst(), GetLast()); } \
979 iterator end() { return iterator(NULL, GetLast()); } \
980 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
981 reverse_iterator rbegin() \
982 { return reverse_iterator(GetLast(), GetFirst()); } \
983 const_reverse_iterator rbegin() const \
984 { return const_reverse_iterator(GetLast(), GetFirst()); } \
985 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
986 const_reverse_iterator rend() const \
987 { return const_reverse_iterator(NULL, GetFirst()); } \
988 void resize(size_type n, value_type v = value_type()) \
989 { \
5751dd32
JS
990 while (n < size()) \
991 pop_back(); \
992 while (n > size()) \
d56cc7b1 993 push_back(v); \
df5168c4
MB
994 } \
995 size_type size() const { return GetCount(); } \
996 size_type max_size() const { return INT_MAX; } \
997 bool empty() const { return IsEmpty(); } \
998 reference front() { return *begin(); } \
999 const_reference front() const { return *begin(); } \
60d8e886
VZ
1000 reference back() { iterator tmp = end(); return *--tmp; } \
1001 const_reference back() const { const_iterator tmp = end(); return *--tmp; }\
df5168c4
MB
1002 void push_front(const_reference v = value_type()) \
1003 { Insert(GetFirst(), (const_base_reference)v); } \
1004 void pop_front() { DeleteNode(GetFirst()); } \
1005 void push_back(const_reference v = value_type()) \
1006 { Append((const_base_reference)v); } \
1007 void pop_back() { DeleteNode(GetLast()); } \
60d8e886 1008 void assign(const_iterator first, const const_iterator& last) \
df5168c4
MB
1009 { \
1010 clear(); \
1011 for(; first != last; ++first) \
1012 Append((const_base_reference)*first); \
1013 } \
1014 void assign(size_type n, const_reference v = value_type()) \
1015 { \
1016 clear(); \
1017 for(size_type i = 0; i < n; ++i) \
1018 Append((const_base_reference)v); \
1019 } \
60d8e886 1020 iterator insert(const iterator& it, const_reference v = value_type())\
df5168c4
MB
1021 { \
1022 Insert(it.m_node, (const_base_reference)v); \
b46b1d59
VZ
1023 iterator itprev(it); \
1024 return itprev--; \
df5168c4 1025 } \
60d8e886 1026 void insert(const iterator& it, size_type n, const_reference v = value_type())\
df5168c4
MB
1027 { \
1028 for(size_type i = 0; i < n; ++i) \
1029 Insert(it.m_node, (const_base_reference)v); \
1030 } \
60d8e886 1031 void insert(const iterator& it, const_iterator first, const const_iterator& last)\
df5168c4
MB
1032 { \
1033 for(; first != last; ++first) \
1034 Insert(it.m_node, (const_base_reference)*first); \
1035 } \
60d8e886 1036 iterator erase(const iterator& it) \
df5168c4
MB
1037 { \
1038 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
1039 DeleteNode(it.m_node); return next; \
1040 } \
60d8e886 1041 iterator erase(const iterator& first, const iterator& last) \
df5168c4
MB
1042 { \
1043 iterator next = last; ++next; \
1044 DeleteNodes(first.m_node, last.m_node); \
1045 return next; \
1046 } \
1047 void clear() { Clear(); } \
60d8e886 1048 void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
df5168c4 1049 { insert(it, first, last); l.erase(first, last); } \
60d8e886 1050 void splice(const iterator& it, name& l) \
df5168c4 1051 { splice(it, l, l.begin(), l.end() ); } \
60d8e886 1052 void splice(const iterator& it, name& l, const iterator& first) \
df5168c4
MB
1053 { \
1054 iterator tmp = first; ++tmp; \
1055 if(it == first || it == tmp) return; \
1056 insert(it, *first); \
1057 l.erase(first); \
1058 } \
1059 void remove(const_reference v) \
1060 { DeleteObject((const_base_reference)v); } \
1061 void reverse() \
1062 { Reverse(); } \
1063 /* void swap(name& l) \
1064 { \
1065 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
1066 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1067 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1068 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1069 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1070 } */ \
385bcb35 1071 }
fd3f686c 1072
6de44038
VZ
1073#define WX_LIST_PTROP \
1074 pointer_type operator->() const \
1075 { return (pointer_type)m_node->GetDataPtr(); }
1076#define WX_LIST_PTROP_NONE
1077
1078#define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1079 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1080#define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1081 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1082
f6bcfd97
BP
1083#define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1084 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
6de44038
VZ
1085#define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1086 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
f03fc89f 1087
fd3f686c
VZ
1088#define WX_DECLARE_LIST(elementtype, listname) \
1089 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
f6bcfd97 1090 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
6de44038
VZ
1091#define WX_DECLARE_LIST_PTR(elementtype, listname) \
1092 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1093 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
f6bcfd97 1094
45c1de35 1095#define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
f6bcfd97 1096 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
45c1de35 1097 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
f644b28c 1098
45c1de35
VS
1099#define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1100 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1101
6de44038
VZ
1102#define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1103 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1104 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
fd3f686c 1105
0b9ab0bd
RL
1106#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1107 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1108 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
6de44038
VZ
1109#define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1110 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1111 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
0b9ab0bd 1112
fd3f686c 1113// this macro must be inserted in your program after
c0089c96 1114// #include "wx/listimpl.cpp"
fd3f686c
VZ
1115#define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1116
0b9ab0bd
RL
1117#define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1118#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1119
df5168c4 1120#endif // !wxUSE_STL
0b9ab0bd 1121
69b9f4cc 1122// ============================================================================
fd3f686c 1123// now we can define classes 100% compatible with the old ones
69b9f4cc 1124// ============================================================================
fd3f686c 1125
e146b8c8 1126// ----------------------------------------------------------------------------
f03fc89f 1127// commonly used list classes
e146b8c8
VZ
1128// ----------------------------------------------------------------------------
1129
69b9f4cc 1130#if defined(wxLIST_COMPATIBILITY)
fd3f686c 1131
137b7303
VZ
1132// inline compatibility functions
1133
69b9f4cc
MB
1134#if !wxUSE_STL
1135
1136// ----------------------------------------------------------------------------
137b7303 1137// wxNodeBase deprecated methods
69b9f4cc 1138// ----------------------------------------------------------------------------
137b7303
VZ
1139
1140inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
1141inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
1142inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1143
69b9f4cc 1144// ----------------------------------------------------------------------------
137b7303 1145// wxListBase deprecated methods
69b9f4cc 1146// ----------------------------------------------------------------------------
137b7303
VZ
1147
1148inline int wxListBase::Number() const { return (int)GetCount(); }
1149inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
1150inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
1151inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1152inline wxListBase::operator wxList&() const { return *(wxList*)this; }
1153
69b9f4cc 1154#endif
137b7303 1155
b1d4dd7a
RL
1156// define this to make a lot of noise about use of the old wxList classes.
1157//#define wxWARN_COMPAT_LIST_USE
1158
69b9f4cc 1159// ----------------------------------------------------------------------------
fd3f686c 1160// wxList compatibility class: in fact, it's a list of wxObjects
69b9f4cc 1161// ----------------------------------------------------------------------------
6de44038
VZ
1162
1163WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1164 class WXDLLIMPEXP_BASE);
fd3f686c 1165
bddd7a8d 1166class WXDLLIMPEXP_BASE wxList : public wxObjectList
c801d85f 1167{
fd3f686c 1168public:
df5168c4 1169#if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
728c62b6
MB
1170 wxList() { };
1171 wxDEPRECATED( wxList(int key_type) );
df5168c4 1172#elif !wxUSE_STL
b1d4dd7a
RL
1173 wxList(int key_type = wxKEY_NONE);
1174#endif
1175
799ea011 1176 // this destructor is required for Darwin
f11bdd03 1177 ~wxList() { }
fd3f686c 1178
df5168c4 1179#if !wxUSE_STL
f6bcfd97 1180 wxList& operator=(const wxList& list)
f2af4afb 1181 { (void) wxListBase::operator=(list); return *this; }
f6bcfd97 1182
fd3f686c 1183 // compatibility methods
3bef6c4c 1184 void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
df5168c4 1185#endif
3bef6c4c 1186
df5168c4
MB
1187#if wxUSE_STL
1188#else
fd3f686c 1189 wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
df5168c4 1190#endif
f98bd52a
VZ
1191
1192private:
df5168c4 1193#if !wxUSE_STL
f98bd52a 1194 DECLARE_DYNAMIC_CLASS(wxList)
df5168c4 1195#endif
c801d85f
KB
1196};
1197
df5168c4
MB
1198#if !wxUSE_STL
1199
fd3f686c
VZ
1200// -----------------------------------------------------------------------------
1201// wxStringList class for compatibility with the old code
1202// -----------------------------------------------------------------------------
bddd7a8d 1203WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
fd3f686c 1204
bddd7a8d 1205class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
c801d85f 1206{
fd3f686c
VZ
1207public:
1208 // ctors and such
1209 // default
b1d4dd7a 1210#ifdef wxWARN_COMPAT_LIST_USE
728c62b6 1211 wxStringList();
8a7afe4d 1212 wxDEPRECATED( wxStringList(const wxChar *first ...) ); // FIXME-UTF8
b1d4dd7a
RL
1213#else
1214 wxStringList();
8a7afe4d 1215 wxStringList(const wxChar *first ...); // FIXME-UTF8
b1d4dd7a 1216#endif
fd3f686c 1217
db9504c5
VZ
1218 // copying the string list: the strings are copied, too (extremely
1219 // inefficient!)
f644b28c 1220 wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(true); DoCopy(other); }
db9504c5
VZ
1221 wxStringList& operator=(const wxStringList& other)
1222 { Clear(); DoCopy(other); return *this; }
1223
fd3f686c
VZ
1224 // operations
1225 // makes a copy of the string
f526f752 1226 wxNode *Add(const wxChar *s);
f644b28c 1227
890f8a7c 1228 // Append to beginning of list
f526f752 1229 wxNode *Prepend(const wxChar *s);
fd3f686c 1230
9d2f3c71 1231 bool Delete(const wxChar *s);
fd3f686c 1232
f644b28c 1233 wxChar **ListToArray(bool new_copies = false) const;
9d2f3c71 1234 bool Member(const wxChar *s) const;
fd3f686c
VZ
1235
1236 // alphabetic sort
1237 void Sort();
1238
db9504c5
VZ
1239private:
1240 void DoCopy(const wxStringList&); // common part of copy ctor and operator=
f98bd52a
VZ
1241
1242 DECLARE_DYNAMIC_CLASS(wxStringList)
c801d85f
KB
1243};
1244
df5168c4
MB
1245#else // if wxUSE_STL
1246
f455ffb2 1247WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLIMPEXP_BASE);
df5168c4 1248
f455ffb2 1249class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
df5168c4
MB
1250{
1251public:
fd82f4e6
MB
1252 compatibility_iterator Append(wxChar* s)
1253 { wxString tmp = s; delete[] s; return wxStringListBase::Append(tmp); }
1254 compatibility_iterator Insert(wxChar* s)
1255 { wxString tmp = s; delete[] s; return wxStringListBase::Insert(tmp); }
1256 compatibility_iterator Insert(size_t pos, wxChar* s)
1257 {
1258 wxString tmp = s;
1259 delete[] s;
1260 return wxStringListBase::Insert(pos, tmp);
1261 }
1262 compatibility_iterator Add(const wxChar* s)
1263 { push_back(s); return GetLast(); }
1264 compatibility_iterator Prepend(const wxChar* s)
1265 { push_front(s); return GetFirst(); }
df5168c4
MB
1266};
1267
1268#endif // wxUSE_STL
1269
fd3f686c
VZ
1270#endif // wxLIST_COMPATIBILITY
1271
df5168c4
MB
1272// delete all list elements
1273//
1274// NB: the class declaration of the list elements must be visible from the
1275// place where you use this macro, otherwise the proper destructor may not
1276// be called (a decent compiler should give a warning about it, but don't
1277// count on it)!
1278#define WX_CLEAR_LIST(type, list) \
1279 { \
1280 type::iterator it, en; \
1281 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1282 delete *it; \
1283 (list).clear(); \
1284 }
1285
c0089c96 1286#endif // _WX_LISTH__