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