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