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