]> git.saurik.com Git - wxWidgets.git/blame - include/wx/list.h
process pending wx events before sending idle events
[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); }
5abefd04
VS
393 wxListKey(const char *s) : m_keyType(wxKEY_STRING)
394 { m_key.string = new wxString(s); }
395 wxListKey(const wchar_t *s) : m_keyType(wxKEY_STRING)
396 { m_key.string = new wxString(s); }
fd3f686c
VZ
397
398 // accessors
399 wxKeyType GetKeyType() const { return m_keyType; }
81727065
VS
400 const wxString GetString() const
401 { wxASSERT( m_keyType == wxKEY_STRING ); return *m_key.string; }
fd3f686c
VZ
402 long GetNumber() const
403 { wxASSERT( m_keyType == wxKEY_INTEGER ); return m_key.integer; }
404
6164d85e
JS
405 // comparison
406 // Note: implementation moved to list.cpp to prevent BC++ inline
407 // expansion warning.
408 bool operator==(wxListKeyValue value) const ;
fd3f686c
VZ
409
410 // dtor
411 ~wxListKey()
412 {
413 if ( m_keyType == wxKEY_STRING )
81727065 414 delete m_key.string;
fd3f686c
VZ
415 }
416
417private:
418 wxKeyType m_keyType;
419 wxListKeyValue m_key;
420};
421
422// -----------------------------------------------------------------------------
423// wxNodeBase class is a (base for) node in a double linked list
424// -----------------------------------------------------------------------------
425
16cba29d 426extern WXDLLIMPEXP_DATA_BASE(wxListKey) wxDefaultListKey;
2432b92d 427
bddd7a8d 428class WXDLLIMPEXP_BASE wxListBase;
fbfb3fb3 429
bddd7a8d 430class WXDLLIMPEXP_BASE wxNodeBase
fd3f686c
VZ
431{
432friend class wxListBase;
433public:
434 // ctor
435 wxNodeBase(wxListBase *list = (wxListBase *)NULL,
436 wxNodeBase *previous = (wxNodeBase *)NULL,
437 wxNodeBase *next = (wxNodeBase *)NULL,
438 void *data = NULL,
2432b92d 439 const wxListKey& key = wxDefaultListKey);
fd3f686c
VZ
440
441 virtual ~wxNodeBase();
442
f03fc89f 443 // FIXME no check is done that the list is really keyed on strings
81727065 444 wxString GetKeyString() const { return *m_key.string; }
74e34480 445 long GetKeyInteger() const { return m_key.integer; }
fd3f686c 446
4fabb575 447 // Necessary for some existing code
81727065 448 void SetKeyString(const wxString& s) { m_key.string = new wxString(s); }
4fabb575
JS
449 void SetKeyInteger(long i) { m_key.integer = i; }
450
fd3f686c 451#ifdef wxLIST_COMPATIBILITY
b1d4dd7a
RL
452 // compatibility methods, use Get* instead.
453 wxDEPRECATED( wxNode *Next() const );
454 wxDEPRECATED( wxNode *Previous() const );
455 wxDEPRECATED( wxObject *Data() const );
fd3f686c
VZ
456#endif // wxLIST_COMPATIBILITY
457
458protected:
459 // all these are going to be "overloaded" in the derived classes
460 wxNodeBase *GetNext() const { return m_next; }
461 wxNodeBase *GetPrevious() const { return m_previous; }
462
463 void *GetData() const { return m_data; }
464 void SetData(void *data) { m_data = data; }
465
3c67202d 466 // get 0-based index of this node within the list or wxNOT_FOUND
77c5eefb
VZ
467 int IndexOf() const;
468
fd3f686c 469 virtual void DeleteData() { }
df5168c4
MB
470public:
471 // for wxList::iterator
472 void** GetDataPtr() const { return &(((wxNodeBase*)this)->m_data); }
fd3f686c
VZ
473private:
474 // optional key stuff
475 wxListKeyValue m_key;
476
477 void *m_data; // user data
478 wxNodeBase *m_next, // next and previous nodes in the list
479 *m_previous;
480
481 wxListBase *m_list; // list we belong to
f2af4afb
GD
482
483 DECLARE_NO_COPY_CLASS(wxNodeBase)
fd3f686c
VZ
484};
485
486// -----------------------------------------------------------------------------
487// a double-linked list class
488// -----------------------------------------------------------------------------
f98bd52a 489
446e5259 490class WXDLLIMPEXP_BASE wxList;
b1d4dd7a 491
bddd7a8d 492class WXDLLIMPEXP_BASE wxListBase : public wxObject
fd3f686c 493{
bddd7a8d 494friend class WXDLLIMPEXP_BASE wxNodeBase; // should be able to call DetachNode()
bcaa23de 495friend class wxHashTableBase; // should be able to call untyped Find()
5a8231ef 496
fd3f686c
VZ
497public:
498 // default ctor & dtor
f2af4afb
GD
499 wxListBase(wxKeyType keyType = wxKEY_NONE)
500 { Init(keyType); }
fd3f686c
VZ
501 virtual ~wxListBase();
502
503 // accessors
504 // count of items in the list
505 size_t GetCount() const { return m_count; }
c801d85f 506
f644b28c 507 // return true if this list is empty
b79a8705
VZ
508 bool IsEmpty() const { return m_count == 0; }
509
fd3f686c 510 // operations
e146b8c8 511
fd3f686c 512 // delete all nodes
db9504c5 513 void Clear();
e146b8c8 514
fd3f686c
VZ
515 // instruct it to destroy user data when deleting nodes
516 void DeleteContents(bool destroy) { m_destroy = destroy; }
517
907789a0
RR
518 // query if to delete
519 bool GetDeleteContents() const
520 { return m_destroy; }
e146b8c8 521
907789a0
RR
522 // get the keytype
523 wxKeyType GetKeyType() const
524 { return m_keyType; }
525
526 // set the keytype (required by the serial code)
527 void SetKeyType(wxKeyType keyType)
528 { wxASSERT( m_count==0 ); m_keyType = keyType; }
529
e146b8c8 530#ifdef wxLIST_COMPATIBILITY
b1d4dd7a
RL
531 // compatibility methods from old wxList
532 wxDEPRECATED( int Number() const ); // use GetCount instead.
533 wxDEPRECATED( wxNode *First() const ); // use GetFirst
534 wxDEPRECATED( wxNode *Last() const ); // use GetLast
535 wxDEPRECATED( wxNode *Nth(size_t n) const ); // use Item
536
537 // kludge for typesafe list migration in core classes.
538 wxDEPRECATED( operator wxList&() const );
e146b8c8
VZ
539#endif // wxLIST_COMPATIBILITY
540
fd3f686c 541protected:
a3ef5bf5 542
fd3f686c
VZ
543 // all methods here are "overloaded" in derived classes to provide compile
544 // time type checking
545
546 // create a node for the list of this type
547 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next,
548 void *data,
2432b92d 549 const wxListKey& key = wxDefaultListKey) = 0;
fd3f686c 550
a3ef5bf5
JS
551// Can't access these from derived classes otherwise (bug in Salford C++?)
552#ifdef __SALFORDC__
553public:
554#endif
555
fd3f686c
VZ
556 // ctors
557 // from an array
558 wxListBase(size_t count, void *elements[]);
559 // from a sequence of objects
560 wxListBase(void *object, ... /* terminate with NULL */);
561
a3ef5bf5 562protected:
00e09270
VZ
563 void Assign(const wxListBase& list)
564 { Clear(); DoCopy(list); }
fd3f686c
VZ
565
566 // get list head/tail
567 wxNodeBase *GetFirst() const { return m_nodeFirst; }
568 wxNodeBase *GetLast() const { return m_nodeLast; }
569
570 // by (0-based) index
571 wxNodeBase *Item(size_t index) const;
572
573 // get the list item's data
2b5f62a0
VZ
574 void *operator[](size_t n) const
575 {
576 wxNodeBase *node = Item(n);
577
578 return node ? node->GetData() : (wxNodeBase *)NULL;
579 }
fd3f686c
VZ
580
581 // operations
582 // append to end of list
890f8a7c
RR
583 wxNodeBase *Prepend(void *object)
584 { return (wxNodeBase *)wxListBase::Insert(object); }
585 // append to beginning of list
fd3f686c
VZ
586 wxNodeBase *Append(void *object);
587 // insert a new item at the beginning of the list
a802c3a1 588 wxNodeBase *Insert(void *object) { return Insert( (wxNodeBase*)NULL, object); }
d8996187
VZ
589 // insert a new item at the given position
590 wxNodeBase *Insert(size_t pos, void *object)
591 { return pos == GetCount() ? Append(object)
592 : Insert(Item(pos), object); }
fd3f686c
VZ
593 // insert before given node or at front of list if prev == NULL
594 wxNodeBase *Insert(wxNodeBase *prev, void *object);
595
596 // keyed append
597 wxNodeBase *Append(long key, void *object);
81727065 598 wxNodeBase *Append(const wxString& key, void *object);
fd3f686c
VZ
599
600 // removes node from the list but doesn't delete it (returns pointer
601 // to the node or NULL if it wasn't found in the list)
602 wxNodeBase *DetachNode(wxNodeBase *node);
f644b28c 603 // delete element from list, returns false if node not found
fd3f686c
VZ
604 bool DeleteNode(wxNodeBase *node);
605 // finds object pointer and deletes node (and object if DeleteContents
f644b28c 606 // is on), returns false if object not found
77c5eefb 607 bool DeleteObject(void *object);
fd3f686c
VZ
608
609 // search (all return NULL if item not found)
610 // by data
22d080f3 611 wxNodeBase *Find(const void *object) const;
fd3f686c
VZ
612
613 // by key
614 wxNodeBase *Find(const wxListKey& key) const;
615
3c67202d 616 // get 0-based index of object or wxNOT_FOUND
77c5eefb
VZ
617 int IndexOf( void *object ) const;
618
fd3f686c
VZ
619 // this function allows the sorting of arbitrary lists by giving
620 // a function to compare two list elements. The list is sorted in place.
6164d85e 621 void Sort(const wxSortCompareFunction compfunc);
fd3f686c
VZ
622
623 // functions for iterating over the list
624 void *FirstThat(wxListIterateFunction func);
625 void ForEach(wxListIterateFunction func);
626 void *LastThat(wxListIterateFunction func);
e146b8c8 627
df5168c4
MB
628 // for STL interface, "last" points to one after the last node
629 // of the controlled sequence (NULL for the end of the list)
630 void Reverse();
631 void DeleteNodes(wxNodeBase* first, wxNodeBase* last);
fd3f686c 632private:
5a8231ef
WS
633
634 // common part of all ctors
635 void Init(wxKeyType keyType = wxKEY_NONE);
636
fd3f686c 637 // helpers
fd3f686c
VZ
638 // common part of copy ctor and assignment operator
639 void DoCopy(const wxListBase& list);
640 // common part of all Append()s
641 wxNodeBase *AppendCommon(wxNodeBase *node);
642 // free node's data and node itself
643 void DoDeleteNode(wxNodeBase *node);
644
645 size_t m_count; // number of elements in the list
646 bool m_destroy; // destroy user data when deleting list items?
647 wxNodeBase *m_nodeFirst, // pointers to the head and tail of the list
648 *m_nodeLast;
649
650 wxKeyType m_keyType; // type of our keys (may be wxKEY_NONE)
651};
652
653// -----------------------------------------------------------------------------
654// macros for definition of "template" list type
655// -----------------------------------------------------------------------------
656
657// and now some heavy magic...
658
659// declare a list type named 'name' and containing elements of type 'T *'
660// (as a by product of macro expansion you also get wx##name##Node
ce3ed50d 661// wxNode-derived type)
fd3f686c
VZ
662//
663// implementation details:
ce3ed50d 664// 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
fd3f686c
VZ
665// for the list of given type - this allows us to pass only the list name
666// to WX_DEFINE_LIST() even if it needs both the name and the type
667//
ce3ed50d
JS
668// 2. We redefine all non-type-safe wxList functions with type-safe versions
669// which don't take any space (everything is inline), but bring compile
fd3f686c 670// time error checking.
f03fc89f
VZ
671//
672// 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
673// a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
674// generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
675// interesting capability to store polymorphic objects in the list and is
676// particularly useful with, for example, "wxWindow *" list where the
677// wxWindowBase pointers are put into the list, but wxWindow pointers are
678// retrieved from it.
6de44038
VZ
679//
680// 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
681// WX_DECLARE_LIST_4 to allow defining classes without operator->() as
682// it results in compiler warnings when this operator doesn't make sense
683// (i.e. stored elements are not pointers)
f03fc89f 684
6de44038
VZ
685// common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
686#define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
ba059d80 687 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
fd3f686c 688 \
f6bcfd97 689 classexp nodetype : public wxNodeBase \
fd3f686c
VZ
690 { \
691 public: \
692 nodetype(wxListBase *list = (wxListBase *)NULL, \
693 nodetype *previous = (nodetype *)NULL, \
694 nodetype *next = (nodetype *)NULL, \
7f985bd3 695 T *data = (T *)NULL, \
e146b8c8 696 const wxListKey& key = wxDefaultListKey) \
fd3f686c
VZ
697 : wxNodeBase(list, previous, next, data, key) { } \
698 \
699 nodetype *GetNext() const \
700 { return (nodetype *)wxNodeBase::GetNext(); } \
701 nodetype *GetPrevious() const \
702 { return (nodetype *)wxNodeBase::GetPrevious(); } \
703 \
704 T *GetData() const \
705 { return (T *)wxNodeBase::GetData(); } \
706 void SetData(T *data) \
707 { wxNodeBase::SetData(data); } \
708 \
60d8e886 709 protected: \
fd3f686c 710 virtual void DeleteData(); \
cd989b24
VZ
711 \
712 DECLARE_NO_COPY_CLASS(nodetype) \
fd3f686c
VZ
713 }; \
714 \
f6bcfd97 715 classexp name : public wxListBase \
fd3f686c
VZ
716 { \
717 public: \
e2a3cc0c 718 typedef nodetype Node; \
d294c9db 719 classexp compatibility_iterator \
0cc70962
VZ
720 { \
721 public: \
722 compatibility_iterator(Node *ptr = NULL) : m_ptr(ptr) { } \
723 \
724 Node *operator->() const { return m_ptr; } \
725 operator Node *() const { return m_ptr; } \
726 \
727 private: \
728 Node *m_ptr; \
729 }; \
e2a3cc0c 730 \
fd3f686c
VZ
731 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
732 { } \
00e09270
VZ
733 name(const name& list) : wxListBase(list.GetKeyType()) \
734 { Assign(list); } \
fd3f686c
VZ
735 name(size_t count, T *elements[]) \
736 : wxListBase(count, (void **)elements) { } \
737 \
f6bcfd97 738 name& operator=(const name& list) \
00e09270 739 { Assign(list); return *this; } \
f6bcfd97 740 \
2e4b087e 741 nodetype *GetFirst() const \
fd3f686c 742 { return (nodetype *)wxListBase::GetFirst(); } \
2e4b087e 743 nodetype *GetLast() const \
fd3f686c
VZ
744 { return (nodetype *)wxListBase::GetLast(); } \
745 \
2e4b087e 746 nodetype *Item(size_t index) const \
fd3f686c
VZ
747 { return (nodetype *)wxListBase::Item(index); } \
748 \
749 T *operator[](size_t index) const \
750 { \
751 nodetype *node = Item(index); \
7f985bd3 752 return node ? (T*)(node->GetData()) : (T*)NULL; \
fd3f686c
VZ
753 } \
754 \
2e4b087e 755 nodetype *Append(Tbase *object) \
fd3f686c 756 { return (nodetype *)wxListBase::Append(object); } \
2e4b087e 757 nodetype *Insert(Tbase *object) \
a802c3a1 758 { return (nodetype *)Insert((nodetype*)NULL, object); } \
2e4b087e 759 nodetype *Insert(size_t pos, Tbase *object) \
d8996187 760 { return (nodetype *)wxListBase::Insert(pos, object); } \
2e4b087e 761 nodetype *Insert(nodetype *prev, Tbase *object) \
fd3f686c
VZ
762 { return (nodetype *)wxListBase::Insert(prev, object); } \
763 \
2e4b087e 764 nodetype *Append(long key, void *object) \
fd3f686c 765 { return (nodetype *)wxListBase::Append(key, object); } \
2e4b087e 766 nodetype *Append(const wxChar *key, void *object) \
fd3f686c
VZ
767 { return (nodetype *)wxListBase::Append(key, object); } \
768 \
769 nodetype *DetachNode(nodetype *node) \
770 { return (nodetype *)wxListBase::DetachNode(node); } \
771 bool DeleteNode(nodetype *node) \
772 { return wxListBase::DeleteNode(node); } \
f03fc89f 773 bool DeleteObject(Tbase *object) \
fd3f686c 774 { return wxListBase::DeleteObject(object); } \
2e4b087e 775 void Erase(nodetype *it) \
df5168c4 776 { DeleteNode(it); } \
fd3f686c 777 \
2e4b087e 778 nodetype *Find(const Tbase *object) const \
fd3f686c
VZ
779 { return (nodetype *)wxListBase::Find(object); } \
780 \
781 virtual nodetype *Find(const wxListKey& key) const \
782 { return (nodetype *)wxListBase::Find(key); } \
783 \
f03fc89f 784 int IndexOf(Tbase *object) const \
77c5eefb
VZ
785 { return wxListBase::IndexOf(object); } \
786 \
ed1288c1
VZ
787 void Sort(wxSortCompareFunction func) \
788 { wxListBase::Sort(func); } \
fd3f686c 789 void Sort(wxSortFuncFor_##name func) \
ed1288c1 790 { Sort((wxSortCompareFunction)func); } \
fd3f686c
VZ
791 \
792 protected: \
ea48aff3 793 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
fd3f686c 794 void *data, \
e146b8c8 795 const wxListKey& key = wxDefaultListKey) \
fd3f686c
VZ
796 { \
797 return new nodetype(this, \
798 (nodetype *)prev, (nodetype *)next, \
799 (T *)data, key); \
800 } \
df5168c4
MB
801 /* STL interface */ \
802 public: \
803 typedef size_t size_type; \
804 typedef int difference_type; \
805 typedef T* value_type; \
806 typedef Tbase* base_value_type; \
807 typedef value_type& reference; \
808 typedef const value_type& const_reference; \
809 typedef base_value_type& base_reference; \
810 typedef const base_value_type& const_base_reference; \
811 \
d294c9db 812 classexp iterator \
df5168c4
MB
813 { \
814 typedef name list; \
815 public: \
37589419 816 typedef nodetype Node; \
df5168c4 817 typedef iterator itor; \
37589419
MB
818 typedef T* value_type; \
819 typedef value_type* ptr_type; \
820 typedef value_type& reference; \
df5168c4
MB
821 \
822 Node* m_node; \
823 Node* m_init; \
824 public: \
37589419 825 typedef reference reference_type; \
df5168c4
MB
826 typedef ptr_type pointer_type; \
827 \
828 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
829 iterator() : m_node(NULL), m_init(NULL) { } \
830 reference_type operator*() const \
831 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 832 ptrop \
df5168c4 833 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
60d8e886 834 const itor operator++(int) \
df5168c4
MB
835 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
836 itor& operator--() \
837 { \
838 m_node = m_node ? m_node->GetPrevious() : m_init; \
839 return *this; \
840 } \
60d8e886 841 const itor operator--(int) \
df5168c4
MB
842 { \
843 itor tmp = *this; \
844 m_node = m_node ? m_node->GetPrevious() : m_init; \
845 return tmp; \
846 } \
847 bool operator!=(const itor& it) const \
848 { return it.m_node != m_node; } \
849 bool operator==(const itor& it) const \
850 { return it.m_node == m_node; } \
851 }; \
d294c9db 852 classexp const_iterator \
df5168c4
MB
853 { \
854 typedef name list; \
855 public: \
37589419
MB
856 typedef nodetype Node; \
857 typedef T* value_type; \
858 typedef const value_type& const_reference; \
df5168c4 859 typedef const_iterator itor; \
37589419 860 typedef value_type* ptr_type; \
df5168c4
MB
861 \
862 Node* m_node; \
863 Node* m_init; \
864 public: \
37589419 865 typedef const_reference reference_type; \
df5168c4
MB
866 typedef const ptr_type pointer_type; \
867 \
868 const_iterator(Node* node, Node* init) \
869 : m_node(node), m_init(init) { } \
870 const_iterator() : m_node(NULL), m_init(NULL) { } \
871 const_iterator(const iterator& it) \
872 : m_node(it.m_node), m_init(it.m_init) { } \
873 reference_type operator*() const \
874 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 875 ptrop \
df5168c4 876 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
60d8e886 877 const itor operator++(int) \
df5168c4
MB
878 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
879 itor& operator--() \
880 { \
881 m_node = m_node ? m_node->GetPrevious() : m_init; \
882 return *this; \
883 } \
60d8e886 884 const itor operator--(int) \
df5168c4
MB
885 { \
886 itor tmp = *this; \
887 m_node = m_node ? m_node->GetPrevious() : m_init; \
888 return tmp; \
889 } \
890 bool operator!=(const itor& it) const \
891 { return it.m_node != m_node; } \
892 bool operator==(const itor& it) const \
893 { return it.m_node == m_node; } \
894 }; \
d294c9db 895 classexp reverse_iterator \
df5168c4
MB
896 { \
897 typedef name list; \
898 public: \
37589419
MB
899 typedef nodetype Node; \
900 typedef T* value_type; \
df5168c4 901 typedef reverse_iterator itor; \
37589419
MB
902 typedef value_type* ptr_type; \
903 typedef value_type& reference; \
df5168c4
MB
904 \
905 Node* m_node; \
906 Node* m_init; \
907 public: \
37589419 908 typedef reference reference_type; \
df5168c4
MB
909 typedef ptr_type pointer_type; \
910 \
911 reverse_iterator(Node* node, Node* init) \
912 : m_node(node), m_init(init) { } \
913 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
914 reference_type operator*() const \
915 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 916 ptrop \
df5168c4
MB
917 itor& operator++() \
918 { m_node = m_node->GetPrevious(); return *this; } \
60d8e886 919 const itor operator++(int) \
df5168c4
MB
920 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
921 itor& operator--() \
922 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
60d8e886 923 const itor operator--(int) \
df5168c4
MB
924 { \
925 itor tmp = *this; \
926 m_node = m_node ? m_node->GetNext() : m_init; \
927 return tmp; \
928 } \
929 bool operator!=(const itor& it) const \
930 { return it.m_node != m_node; } \
931 bool operator==(const itor& it) const \
932 { return it.m_node == m_node; } \
933 }; \
d294c9db 934 classexp const_reverse_iterator \
df5168c4
MB
935 { \
936 typedef name list; \
937 public: \
37589419
MB
938 typedef nodetype Node; \
939 typedef T* value_type; \
df5168c4 940 typedef const_reverse_iterator itor; \
37589419
MB
941 typedef value_type* ptr_type; \
942 typedef const value_type& const_reference; \
df5168c4
MB
943 \
944 Node* m_node; \
945 Node* m_init; \
946 public: \
37589419 947 typedef const_reference reference_type; \
df5168c4
MB
948 typedef const ptr_type pointer_type; \
949 \
950 const_reverse_iterator(Node* node, Node* init) \
951 : m_node(node), m_init(init) { } \
952 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
953 const_reverse_iterator(const reverse_iterator& it) \
954 : m_node(it.m_node), m_init(it.m_init) { } \
955 reference_type operator*() const \
956 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 957 ptrop \
df5168c4
MB
958 itor& operator++() \
959 { m_node = m_node->GetPrevious(); return *this; } \
60d8e886 960 const itor operator++(int) \
df5168c4
MB
961 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
962 itor& operator--() \
963 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
60d8e886 964 const itor operator--(int) \
df5168c4
MB
965 { \
966 itor tmp = *this; \
967 m_node = m_node ? m_node->GetNext() : m_init; \
968 return tmp; \
969 } \
970 bool operator!=(const itor& it) const \
971 { return it.m_node != m_node; } \
972 bool operator==(const itor& it) const \
973 { return it.m_node == m_node; } \
974 }; \
975 \
976 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
977 { assign(n, v); } \
60d8e886 978 name(const const_iterator& first, const const_iterator& last) \
df5168c4
MB
979 { assign(first, last); } \
980 iterator begin() { return iterator(GetFirst(), GetLast()); } \
981 const_iterator begin() const \
982 { return const_iterator(GetFirst(), GetLast()); } \
983 iterator end() { return iterator(NULL, GetLast()); } \
984 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
985 reverse_iterator rbegin() \
986 { return reverse_iterator(GetLast(), GetFirst()); } \
987 const_reverse_iterator rbegin() const \
988 { return const_reverse_iterator(GetLast(), GetFirst()); } \
989 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
990 const_reverse_iterator rend() const \
991 { return const_reverse_iterator(NULL, GetFirst()); } \
992 void resize(size_type n, value_type v = value_type()) \
993 { \
5751dd32
JS
994 while (n < size()) \
995 pop_back(); \
996 while (n > size()) \
d56cc7b1 997 push_back(v); \
df5168c4
MB
998 } \
999 size_type size() const { return GetCount(); } \
1000 size_type max_size() const { return INT_MAX; } \
1001 bool empty() const { return IsEmpty(); } \
1002 reference front() { return *begin(); } \
1003 const_reference front() const { return *begin(); } \
60d8e886
VZ
1004 reference back() { iterator tmp = end(); return *--tmp; } \
1005 const_reference back() const { const_iterator tmp = end(); return *--tmp; }\
df5168c4
MB
1006 void push_front(const_reference v = value_type()) \
1007 { Insert(GetFirst(), (const_base_reference)v); } \
1008 void pop_front() { DeleteNode(GetFirst()); } \
1009 void push_back(const_reference v = value_type()) \
1010 { Append((const_base_reference)v); } \
1011 void pop_back() { DeleteNode(GetLast()); } \
60d8e886 1012 void assign(const_iterator first, const const_iterator& last) \
df5168c4
MB
1013 { \
1014 clear(); \
1015 for(; first != last; ++first) \
1016 Append((const_base_reference)*first); \
1017 } \
1018 void assign(size_type n, const_reference v = value_type()) \
1019 { \
1020 clear(); \
1021 for(size_type i = 0; i < n; ++i) \
1022 Append((const_base_reference)v); \
1023 } \
60d8e886 1024 iterator insert(const iterator& it, const_reference v = value_type())\
df5168c4
MB
1025 { \
1026 Insert(it.m_node, (const_base_reference)v); \
b46b1d59
VZ
1027 iterator itprev(it); \
1028 return itprev--; \
df5168c4 1029 } \
60d8e886 1030 void insert(const iterator& it, size_type n, const_reference v = value_type())\
df5168c4
MB
1031 { \
1032 for(size_type i = 0; i < n; ++i) \
1033 Insert(it.m_node, (const_base_reference)v); \
1034 } \
60d8e886 1035 void insert(const iterator& it, const_iterator first, const const_iterator& last)\
df5168c4
MB
1036 { \
1037 for(; first != last; ++first) \
1038 Insert(it.m_node, (const_base_reference)*first); \
1039 } \
60d8e886 1040 iterator erase(const iterator& it) \
df5168c4
MB
1041 { \
1042 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
1043 DeleteNode(it.m_node); return next; \
1044 } \
60d8e886 1045 iterator erase(const iterator& first, const iterator& last) \
df5168c4
MB
1046 { \
1047 iterator next = last; ++next; \
1048 DeleteNodes(first.m_node, last.m_node); \
1049 return next; \
1050 } \
1051 void clear() { Clear(); } \
60d8e886 1052 void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
df5168c4 1053 { insert(it, first, last); l.erase(first, last); } \
60d8e886 1054 void splice(const iterator& it, name& l) \
df5168c4 1055 { splice(it, l, l.begin(), l.end() ); } \
60d8e886 1056 void splice(const iterator& it, name& l, const iterator& first) \
df5168c4
MB
1057 { \
1058 iterator tmp = first; ++tmp; \
1059 if(it == first || it == tmp) return; \
1060 insert(it, *first); \
1061 l.erase(first); \
1062 } \
1063 void remove(const_reference v) \
1064 { DeleteObject((const_base_reference)v); } \
1065 void reverse() \
1066 { Reverse(); } \
1067 /* void swap(name& l) \
1068 { \
1069 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
1070 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1071 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1072 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1073 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1074 } */ \
385bcb35 1075 }
fd3f686c 1076
6de44038
VZ
1077#define WX_LIST_PTROP \
1078 pointer_type operator->() const \
1079 { return (pointer_type)m_node->GetDataPtr(); }
1080#define WX_LIST_PTROP_NONE
1081
1082#define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1083 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1084#define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1085 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1086
f6bcfd97
BP
1087#define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1088 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
6de44038
VZ
1089#define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1090 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
f03fc89f 1091
fd3f686c
VZ
1092#define WX_DECLARE_LIST(elementtype, listname) \
1093 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
f6bcfd97 1094 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
6de44038
VZ
1095#define WX_DECLARE_LIST_PTR(elementtype, listname) \
1096 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1097 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
f6bcfd97 1098
45c1de35 1099#define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
f6bcfd97 1100 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
45c1de35 1101 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
f644b28c 1102
45c1de35
VS
1103#define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1104 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1105
6de44038
VZ
1106#define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1107 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1108 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
fd3f686c 1109
0b9ab0bd
RL
1110#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1111 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1112 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
6de44038
VZ
1113#define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1114 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1115 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
0b9ab0bd 1116
fd3f686c 1117// this macro must be inserted in your program after
c0089c96 1118// #include "wx/listimpl.cpp"
fd3f686c
VZ
1119#define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1120
0b9ab0bd
RL
1121#define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1122#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1123
df5168c4 1124#endif // !wxUSE_STL
0b9ab0bd 1125
69b9f4cc 1126// ============================================================================
fd3f686c 1127// now we can define classes 100% compatible with the old ones
69b9f4cc 1128// ============================================================================
fd3f686c 1129
e146b8c8 1130// ----------------------------------------------------------------------------
f03fc89f 1131// commonly used list classes
e146b8c8
VZ
1132// ----------------------------------------------------------------------------
1133
69b9f4cc 1134#if defined(wxLIST_COMPATIBILITY)
fd3f686c 1135
137b7303
VZ
1136// inline compatibility functions
1137
69b9f4cc
MB
1138#if !wxUSE_STL
1139
1140// ----------------------------------------------------------------------------
137b7303 1141// wxNodeBase deprecated methods
69b9f4cc 1142// ----------------------------------------------------------------------------
137b7303
VZ
1143
1144inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
1145inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
1146inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1147
69b9f4cc 1148// ----------------------------------------------------------------------------
137b7303 1149// wxListBase deprecated methods
69b9f4cc 1150// ----------------------------------------------------------------------------
137b7303
VZ
1151
1152inline int wxListBase::Number() const { return (int)GetCount(); }
1153inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
1154inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
1155inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1156inline wxListBase::operator wxList&() const { return *(wxList*)this; }
1157
69b9f4cc 1158#endif
137b7303 1159
b1d4dd7a
RL
1160// define this to make a lot of noise about use of the old wxList classes.
1161//#define wxWARN_COMPAT_LIST_USE
1162
69b9f4cc 1163// ----------------------------------------------------------------------------
fd3f686c 1164// wxList compatibility class: in fact, it's a list of wxObjects
69b9f4cc 1165// ----------------------------------------------------------------------------
6de44038
VZ
1166
1167WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1168 class WXDLLIMPEXP_BASE);
fd3f686c 1169
bddd7a8d 1170class WXDLLIMPEXP_BASE wxList : public wxObjectList
c801d85f 1171{
fd3f686c 1172public:
df5168c4 1173#if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
728c62b6
MB
1174 wxList() { };
1175 wxDEPRECATED( wxList(int key_type) );
df5168c4 1176#elif !wxUSE_STL
b1d4dd7a
RL
1177 wxList(int key_type = wxKEY_NONE);
1178#endif
1179
799ea011 1180 // this destructor is required for Darwin
f11bdd03 1181 ~wxList() { }
fd3f686c 1182
df5168c4 1183#if !wxUSE_STL
f6bcfd97 1184 wxList& operator=(const wxList& list)
f2af4afb 1185 { (void) wxListBase::operator=(list); return *this; }
f6bcfd97 1186
fd3f686c 1187 // compatibility methods
3bef6c4c 1188 void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
df5168c4 1189#endif
3bef6c4c 1190
df5168c4
MB
1191#if wxUSE_STL
1192#else
fd3f686c 1193 wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
df5168c4 1194#endif
f98bd52a
VZ
1195
1196private:
df5168c4 1197#if !wxUSE_STL
f98bd52a 1198 DECLARE_DYNAMIC_CLASS(wxList)
df5168c4 1199#endif
c801d85f
KB
1200};
1201
df5168c4
MB
1202#if !wxUSE_STL
1203
fd3f686c
VZ
1204// -----------------------------------------------------------------------------
1205// wxStringList class for compatibility with the old code
1206// -----------------------------------------------------------------------------
bddd7a8d 1207WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
fd3f686c 1208
bddd7a8d 1209class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
c801d85f 1210{
fd3f686c
VZ
1211public:
1212 // ctors and such
1213 // default
b1d4dd7a 1214#ifdef wxWARN_COMPAT_LIST_USE
728c62b6 1215 wxStringList();
8a7afe4d 1216 wxDEPRECATED( wxStringList(const wxChar *first ...) ); // FIXME-UTF8
b1d4dd7a
RL
1217#else
1218 wxStringList();
8a7afe4d 1219 wxStringList(const wxChar *first ...); // FIXME-UTF8
b1d4dd7a 1220#endif
fd3f686c 1221
db9504c5
VZ
1222 // copying the string list: the strings are copied, too (extremely
1223 // inefficient!)
f644b28c 1224 wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(true); DoCopy(other); }
db9504c5
VZ
1225 wxStringList& operator=(const wxStringList& other)
1226 { Clear(); DoCopy(other); return *this; }
1227
fd3f686c
VZ
1228 // operations
1229 // makes a copy of the string
f526f752 1230 wxNode *Add(const wxChar *s);
f644b28c 1231
890f8a7c 1232 // Append to beginning of list
f526f752 1233 wxNode *Prepend(const wxChar *s);
fd3f686c 1234
9d2f3c71 1235 bool Delete(const wxChar *s);
fd3f686c 1236
f644b28c 1237 wxChar **ListToArray(bool new_copies = false) const;
9d2f3c71 1238 bool Member(const wxChar *s) const;
fd3f686c
VZ
1239
1240 // alphabetic sort
1241 void Sort();
1242
db9504c5
VZ
1243private:
1244 void DoCopy(const wxStringList&); // common part of copy ctor and operator=
f98bd52a
VZ
1245
1246 DECLARE_DYNAMIC_CLASS(wxStringList)
c801d85f
KB
1247};
1248
df5168c4
MB
1249#else // if wxUSE_STL
1250
f455ffb2 1251WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLIMPEXP_BASE);
df5168c4 1252
f455ffb2 1253class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
df5168c4
MB
1254{
1255public:
fd82f4e6
MB
1256 compatibility_iterator Append(wxChar* s)
1257 { wxString tmp = s; delete[] s; return wxStringListBase::Append(tmp); }
1258 compatibility_iterator Insert(wxChar* s)
1259 { wxString tmp = s; delete[] s; return wxStringListBase::Insert(tmp); }
1260 compatibility_iterator Insert(size_t pos, wxChar* s)
1261 {
1262 wxString tmp = s;
1263 delete[] s;
1264 return wxStringListBase::Insert(pos, tmp);
1265 }
1266 compatibility_iterator Add(const wxChar* s)
1267 { push_back(s); return GetLast(); }
1268 compatibility_iterator Prepend(const wxChar* s)
1269 { push_front(s); return GetFirst(); }
df5168c4
MB
1270};
1271
1272#endif // wxUSE_STL
1273
fd3f686c
VZ
1274#endif // wxLIST_COMPATIBILITY
1275
df5168c4
MB
1276// delete all list elements
1277//
1278// NB: the class declaration of the list elements must be visible from the
1279// place where you use this macro, otherwise the proper destructor may not
1280// be called (a decent compiler should give a warning about it, but don't
1281// count on it)!
1282#define WX_CLEAR_LIST(type, list) \
1283 { \
1284 type::iterator it, en; \
1285 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1286 delete *it; \
1287 (list).clear(); \
1288 }
1289
c0089c96 1290#endif // _WX_LISTH__