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