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