]> git.saurik.com Git - wxWidgets.git/blame - include/wx/list.h
readded wxEditableListBox as part of adv library
[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
a4c1cdc9 96#if !defined(__VISUALC__) || __VISUALC__ >= 1300 // == !VC6
168da56b 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
a4c1cdc9 112#else // if defined( __VISUALC__ ) && __VISUALC__ < 1300 // == VC6
168da56b 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 ? \
8a7afe4d
VS
131 ( m_CompFunc( wxListCastElementToVoidPtr(X), \
132 wxListCastElementToVoidPtr(Y) ) < 0 ) : \
168da56b
MB
133 ( X > Y ); \
134 } \
135 };
136
8a7afe4d
VS
137// helper for std::greater<elT> above:
138template<typename T>
139inline const void *wxListCastElementToVoidPtr(const T* ptr) { return ptr; }
140inline const void *wxListCastElementToVoidPtr(const wxString& str)
141 { return (const char*)str; }
142
a4c1cdc9 143#endif // VC6/!VC6
168da56b 144
30a29593 145/*
7d13fbc6 146 Note 1: the outer helper class _WX_LIST_HELPER_##liT below is a workaround
30a29593
VZ
147 for mingw 3.2.3 compiler bug that prevents a static function of liT class
148 from being exported into dll. A minimal code snippet reproducing the bug:
149
150 struct WXDLLEXPORT Foo
151 {
152 static void Bar();
153 struct SomeInnerClass
154 {
155 friend class Foo; // comment this out to make it link
156 };
157 ~Foo()
158 {
159 Bar();
160 }
161 };
162
163 The program does not link under mingw_gcc 3.2.3 producing undefined
164 reference to Foo::Bar() function
7d13fbc6
VZ
165
166
167 Note 2: the EmptyList is needed to allow having a NULL pointer-like
168 invalid iterator. We used to use just an uninitialized iterator object
169 instead but this fails with some debug/checked versions of STL, notably the
170 glibc version activated with _GLIBCXX_DEBUG, so we need to have a separate
171 invalid iterator.
30a29593
VZ
172 */
173
174// the real wxList-class declaration
ed1288c1 175#define WX_DECLARE_LIST_XO(elT, liT, decl) \
3871d4ca 176 decl _WX_LIST_HELPER_##liT \
30a29593
VZ
177 { \
178 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
179 public: \
180 static void DeleteFunction( _WX_LIST_ITEM_TYPE_##liT X ); \
181 }; \
182 \
168da56b 183 VC6_WORKAROUND(elT, liT, decl) \
831c2889
VZ
184 decl liT : public std::list<elT> \
185 { \
186 private: \
7d13fbc6
VZ
187 typedef std::list<elT> BaseListType; \
188 static BaseListType EmptyList; \
189 \
831c2889 190 bool m_destroy; \
cd840087 191 \
ed1288c1 192 public: \
d294c9db 193 decl compatibility_iterator \
df5168c4 194 { \
ed1288c1 195 private: \
cd840087
VZ
196 /* Workaround for broken VC6 nested class name resolution */ \
197 typedef std::list<elT>::iterator iterator; \
198 friend class liT; \
199 \
df5168c4
MB
200 iterator m_iter; \
201 liT * m_list; \
cd840087 202 \
df5168c4 203 public: \
ed1288c1 204 compatibility_iterator() \
7d13fbc6 205 : m_iter(EmptyList.end()), m_list( NULL ) {} \
ed1288c1
VZ
206 compatibility_iterator( liT* li, iterator i ) \
207 : m_iter( i ), m_list( li ) {} \
208 compatibility_iterator( const liT* li, iterator i ) \
209 : m_iter( i ), m_list( const_cast< liT* >( li ) ) {} \
210 \
211 compatibility_iterator* operator->() { return this; } \
212 const compatibility_iterator* operator->() const { return this; } \
213 \
60d8e886 214 bool operator==(const compatibility_iterator& i) const \
b4affacc
VZ
215 { \
216 wxASSERT_MSG( m_list && i.m_list, \
217 _T("comparing invalid iterators is illegal") ); \
218 return (m_list == i.m_list) && (m_iter == i.m_iter); \
219 } \
60d8e886 220 bool operator!=(const compatibility_iterator& i) const \
ed1288c1 221 { return !( operator==( i ) ); } \
df5168c4 222 operator bool() const \
ed1288c1 223 { return m_list ? m_iter != m_list->end() : false; } \
df5168c4 224 bool operator !() const \
ed1288c1 225 { return !( operator bool() ); } \
df5168c4 226 \
df5168c4 227 elT GetData() const \
ed1288c1
VZ
228 { return *m_iter; } \
229 void SetData( elT e ) \
230 { *m_iter = e; } \
231 \
232 compatibility_iterator GetNext() const \
df5168c4 233 { \
ed1288c1
VZ
234 iterator i = m_iter; \
235 return compatibility_iterator( m_list, ++i ); \
df5168c4 236 } \
ed1288c1 237 compatibility_iterator GetPrevious() const \
df5168c4 238 { \
5d9ef6de
VZ
239 if ( m_iter == m_list->begin() ) \
240 return compatibility_iterator(); \
241 \
ed1288c1
VZ
242 iterator i = m_iter; \
243 return compatibility_iterator( m_list, --i ); \
df5168c4 244 } \
ed1288c1 245 int IndexOf() const \
df5168c4 246 { \
0b6cf205
VZ
247 return *this ? std::distance( m_list->begin(), m_iter ) \
248 : wxNOT_FOUND; \
df5168c4 249 } \
df5168c4 250 }; \
ed1288c1
VZ
251 public: \
252 liT() : m_destroy( false ) {} \
253 \
254 compatibility_iterator Find( const elT e ) const \
df5168c4 255 { \
ed1288c1
VZ
256 liT* _this = const_cast< liT* >( this ); \
257 return compatibility_iterator( _this, \
258 std::find( _this->begin(), _this->end(), e ) ); \
df5168c4 259 } \
df5168c4 260 \
ed1288c1
VZ
261 bool IsEmpty() const \
262 { return empty(); } \
263 size_t GetCount() const \
264 { return size(); } \
265 int Number() const \
266 { return static_cast< int >( GetCount() ); } \
267 \
268 compatibility_iterator Item( size_t idx ) const \
df5168c4 269 { \
ed1288c1
VZ
270 iterator i = const_cast< liT* >(this)->begin(); \
271 std::advance( i, idx ); \
272 return compatibility_iterator( this, i ); \
273 } \
af867f95 274 elT operator[](size_t idx) const \
9ea1246b 275 { \
af867f95 276 return Item(idx).GetData(); \
9ea1246b
VZ
277 } \
278 \
ed1288c1
VZ
279 compatibility_iterator GetFirst() const \
280 { \
281 return compatibility_iterator( this, \
282 const_cast< liT* >(this)->begin() ); \
283 } \
284 compatibility_iterator GetLast() const \
285 { \
286 iterator i = const_cast< liT* >(this)->end(); \
287 return compatibility_iterator( this, !empty() ? --i : i ); \
288 } \
289 compatibility_iterator Member( elT e ) const \
290 { return Find( e ); } \
291 compatibility_iterator Nth( int n ) const \
292 { return Item( n ); } \
293 int IndexOf( elT e ) const \
294 { return Find( e ).IndexOf(); } \
295 \
296 compatibility_iterator Append( elT e ) \
297 { \
298 push_back( e ); \
299 return GetLast(); \
300 } \
301 compatibility_iterator Insert( elT e ) \
302 { \
303 push_front( e ); \
304 return compatibility_iterator( this, begin() ); \
305 } \
306 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
307 { \
308 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
309 } \
310 compatibility_iterator Insert( size_t idx, elT e ) \
311 { \
312 return compatibility_iterator( this, \
313 insert( Item( idx ).m_iter, e ) ); \
314 } \
315 \
316 void DeleteContents( bool destroy ) \
317 { m_destroy = destroy; } \
318 bool GetDeleteContents() const \
319 { return m_destroy; } \
320 void Erase( const compatibility_iterator& i ) \
321 { \
322 if ( m_destroy ) \
30a29593 323 _WX_LIST_HELPER_##liT::DeleteFunction( i->GetData() ); \
ed1288c1
VZ
324 erase( i.m_iter ); \
325 } \
326 bool DeleteNode( const compatibility_iterator& i ) \
327 { \
328 if( i ) \
df5168c4 329 { \
ed1288c1 330 Erase( i ); \
df5168c4
MB
331 return true; \
332 } \
333 return false; \
334 } \
ed1288c1 335 bool DeleteObject( elT e ) \
df5168c4 336 { \
ed1288c1 337 return DeleteNode( Find( e ) ); \
df5168c4 338 } \
ed1288c1 339 void Clear() \
df5168c4 340 { \
ed1288c1 341 if ( m_destroy ) \
30a29593
VZ
342 std::for_each( begin(), end(), \
343 _WX_LIST_HELPER_##liT::DeleteFunction ); \
ed1288c1 344 clear(); \
df5168c4 345 } \
831c2889 346 /* Workaround for broken VC6 std::list::sort() see above */ \
ed1288c1 347 void Sort( wxSortCompareFunction compfunc ) \
168da56b 348 { sort( WX_LIST_SORTFUNCTION( elT, compfunc ) ); } \
ed1288c1 349 ~liT() { Clear(); } \
cd840087
VZ
350 \
351 /* It needs access to our EmptyList */ \
352 friend decl compatibility_iterator; \
df5168c4
MB
353 }
354
355#define WX_DECLARE_LIST(elementtype, listname) \
f794be6a 356 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
6de44038
VZ
357#define WX_DECLARE_LIST_PTR(elementtype, listname) \
358 WX_DECLARE_LIST(elementtype, listname)
df5168c4
MB
359
360#define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
f794be6a 361 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
6de44038
VZ
362#define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
363 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
df5168c4
MB
364
365#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
f794be6a 366 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
6de44038
VZ
367#define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
368 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
df5168c4
MB
369
370// this macro must be inserted in your program after
c0089c96 371// #include "wx/listimpl.cpp"
df5168c4
MB
372#define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
373
374#define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
375#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
376
377#else // if !wxUSE_STL
378
df5168c4 379
df5168c4
MB
380// undef it to get rid of old, deprecated functions
381#define wxLIST_COMPATIBILITY
fd3f686c
VZ
382
383// -----------------------------------------------------------------------------
384// key stuff: a list may be optionally keyed on integer or string key
385// -----------------------------------------------------------------------------
386
387union wxListKeyValue
c801d85f 388{
c801d85f 389 long integer;
81727065 390 wxString *string;
c801d85f
KB
391};
392
fd3f686c
VZ
393// a struct which may contain both types of keys
394//
395// implementation note: on one hand, this class allows to have only one function
396// for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
397// resolve ambiguity which we would otherwise have with wxStringList::Find() and
398// wxList::Find(const char *).
bddd7a8d 399class WXDLLIMPEXP_BASE wxListKey
fd3f686c
VZ
400{
401public:
402 // implicit ctors
f2af4afb
GD
403 wxListKey() : m_keyType(wxKEY_NONE)
404 { }
405 wxListKey(long i) : m_keyType(wxKEY_INTEGER)
406 { m_key.integer = i; }
f2af4afb 407 wxListKey(const wxString& s) : m_keyType(wxKEY_STRING)
81727065 408 { m_key.string = new wxString(s); }
fd3f686c
VZ
409
410 // accessors
411 wxKeyType GetKeyType() const { return m_keyType; }
81727065
VS
412 const wxString GetString() const
413 { wxASSERT( m_keyType == wxKEY_STRING ); return *m_key.string; }
fd3f686c
VZ
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 )
81727065 426 delete m_key.string;
fd3f686c
VZ
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
81727065 456 wxString GetKeyString() const { return *m_key.string; }
74e34480 457 long GetKeyInteger() const { return m_key.integer; }
fd3f686c 458
4fabb575 459 // Necessary for some existing code
81727065 460 void SetKeyString(const wxString& s) { m_key.string = new wxString(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);
81727065 610 wxNodeBase *Append(const wxString& 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();
8a7afe4d 1227 wxDEPRECATED( wxStringList(const wxChar *first ...) ); // FIXME-UTF8
b1d4dd7a
RL
1228#else
1229 wxStringList();
8a7afe4d 1230 wxStringList(const wxChar *first ...); // FIXME-UTF8
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__