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