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