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