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