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