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