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