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