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