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