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