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