]> git.saurik.com Git - wxWidgets.git/blob - include/wx/list.h
Use struct qualifier with objc_object (it is and always will be a struct)
[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 WXDLLIMPEXP_BASE 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 void Assign(const wxListBase& list)
450 { Clear(); DoCopy(list); }
451
452 // get list head/tail
453 wxNodeBase *GetFirst() const { return m_nodeFirst; }
454 wxNodeBase *GetLast() const { return m_nodeLast; }
455
456 // by (0-based) index
457 wxNodeBase *Item(size_t index) const;
458
459 // get the list item's data
460 void *operator[](size_t n) const
461 {
462 wxNodeBase *node = Item(n);
463
464 return node ? node->GetData() : (wxNodeBase *)NULL;
465 }
466
467 // operations
468 // append to end of list
469 wxNodeBase *Prepend(void *object)
470 { return (wxNodeBase *)wxListBase::Insert(object); }
471 // append to beginning of list
472 wxNodeBase *Append(void *object);
473 // insert a new item at the beginning of the list
474 wxNodeBase *Insert(void *object) { return Insert( (wxNodeBase*)NULL, object); }
475 // insert a new item at the given position
476 wxNodeBase *Insert(size_t pos, void *object)
477 { return pos == GetCount() ? Append(object)
478 : Insert(Item(pos), object); }
479 // insert before given node or at front of list if prev == NULL
480 wxNodeBase *Insert(wxNodeBase *prev, void *object);
481
482 // keyed append
483 wxNodeBase *Append(long key, void *object);
484 wxNodeBase *Append(const wxChar *key, void *object);
485
486 // removes node from the list but doesn't delete it (returns pointer
487 // to the node or NULL if it wasn't found in the list)
488 wxNodeBase *DetachNode(wxNodeBase *node);
489 // delete element from list, returns false if node not found
490 bool DeleteNode(wxNodeBase *node);
491 // finds object pointer and deletes node (and object if DeleteContents
492 // is on), returns false if object not found
493 bool DeleteObject(void *object);
494
495 // search (all return NULL if item not found)
496 // by data
497 wxNodeBase *Find(const void *object) const;
498
499 // by key
500 wxNodeBase *Find(const wxListKey& key) const;
501
502 // get 0-based index of object or wxNOT_FOUND
503 int IndexOf( void *object ) const;
504
505 // this function allows the sorting of arbitrary lists by giving
506 // a function to compare two list elements. The list is sorted in place.
507 void Sort(const wxSortCompareFunction compfunc);
508
509 // functions for iterating over the list
510 void *FirstThat(wxListIterateFunction func);
511 void ForEach(wxListIterateFunction func);
512 void *LastThat(wxListIterateFunction func);
513
514 // for STL interface, "last" points to one after the last node
515 // of the controlled sequence (NULL for the end of the list)
516 void Reverse();
517 void DeleteNodes(wxNodeBase* first, wxNodeBase* last);
518 private:
519 // helpers
520 // common part of copy ctor and assignment operator
521 void DoCopy(const wxListBase& list);
522 // common part of all Append()s
523 wxNodeBase *AppendCommon(wxNodeBase *node);
524 // free node's data and node itself
525 void DoDeleteNode(wxNodeBase *node);
526
527 size_t m_count; // number of elements in the list
528 bool m_destroy; // destroy user data when deleting list items?
529 wxNodeBase *m_nodeFirst, // pointers to the head and tail of the list
530 *m_nodeLast;
531
532 wxKeyType m_keyType; // type of our keys (may be wxKEY_NONE)
533 };
534
535 // -----------------------------------------------------------------------------
536 // macros for definition of "template" list type
537 // -----------------------------------------------------------------------------
538
539 // and now some heavy magic...
540
541 // declare a list type named 'name' and containing elements of type 'T *'
542 // (as a by product of macro expansion you also get wx##name##Node
543 // wxNode-derived type)
544 //
545 // implementation details:
546 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
547 // for the list of given type - this allows us to pass only the list name
548 // to WX_DEFINE_LIST() even if it needs both the name and the type
549 //
550 // 2. We redefine all non-type-safe wxList functions with type-safe versions
551 // which don't take any space (everything is inline), but bring compile
552 // time error checking.
553 //
554 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
555 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
556 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
557 // interesting capability to store polymorphic objects in the list and is
558 // particularly useful with, for example, "wxWindow *" list where the
559 // wxWindowBase pointers are put into the list, but wxWindow pointers are
560 // retrieved from it.
561 //
562 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
563 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
564 // it results in compiler warnings when this operator doesn't make sense
565 // (i.e. stored elements are not pointers)
566
567 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
568 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
569 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
570 \
571 classexp nodetype : public wxNodeBase \
572 { \
573 public: \
574 nodetype(wxListBase *list = (wxListBase *)NULL, \
575 nodetype *previous = (nodetype *)NULL, \
576 nodetype *next = (nodetype *)NULL, \
577 T *data = (T *)NULL, \
578 const wxListKey& key = wxDefaultListKey) \
579 : wxNodeBase(list, previous, next, data, key) { } \
580 \
581 nodetype *GetNext() const \
582 { return (nodetype *)wxNodeBase::GetNext(); } \
583 nodetype *GetPrevious() const \
584 { return (nodetype *)wxNodeBase::GetPrevious(); } \
585 \
586 T *GetData() const \
587 { return (T *)wxNodeBase::GetData(); } \
588 void SetData(T *data) \
589 { wxNodeBase::SetData(data); } \
590 \
591 virtual void DeleteData(); \
592 \
593 DECLARE_NO_COPY_CLASS(nodetype) \
594 }; \
595 \
596 classexp name : public wxListBase \
597 { \
598 public: \
599 typedef nodetype Node; \
600 typedef Node* compatibility_iterator; \
601 \
602 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
603 { } \
604 name(const name& list) : wxListBase(list.GetKeyType()) \
605 { Assign(list); } \
606 name(size_t count, T *elements[]) \
607 : wxListBase(count, (void **)elements) { } \
608 \
609 name& operator=(const name& list) \
610 { Assign(list); return *this; } \
611 \
612 nodetype *GetFirst() const \
613 { return (nodetype *)wxListBase::GetFirst(); } \
614 nodetype *GetLast() const \
615 { return (nodetype *)wxListBase::GetLast(); } \
616 \
617 nodetype *Item(size_t index) const \
618 { return (nodetype *)wxListBase::Item(index); } \
619 \
620 T *operator[](size_t index) const \
621 { \
622 nodetype *node = Item(index); \
623 return node ? (T*)(node->GetData()) : (T*)NULL; \
624 } \
625 \
626 nodetype *Append(Tbase *object) \
627 { return (nodetype *)wxListBase::Append(object); } \
628 nodetype *Insert(Tbase *object) \
629 { return (nodetype *)Insert((nodetype*)NULL, object); } \
630 nodetype *Insert(size_t pos, Tbase *object) \
631 { return (nodetype *)wxListBase::Insert(pos, object); } \
632 nodetype *Insert(nodetype *prev, Tbase *object) \
633 { return (nodetype *)wxListBase::Insert(prev, object); } \
634 \
635 nodetype *Append(long key, void *object) \
636 { return (nodetype *)wxListBase::Append(key, object); } \
637 nodetype *Append(const wxChar *key, void *object) \
638 { return (nodetype *)wxListBase::Append(key, object); } \
639 \
640 nodetype *DetachNode(nodetype *node) \
641 { return (nodetype *)wxListBase::DetachNode(node); } \
642 bool DeleteNode(nodetype *node) \
643 { return wxListBase::DeleteNode(node); } \
644 bool DeleteObject(Tbase *object) \
645 { return wxListBase::DeleteObject(object); } \
646 void Erase(compatibility_iterator it) \
647 { DeleteNode(it); } \
648 \
649 nodetype *Find(const Tbase *object) const \
650 { return (nodetype *)wxListBase::Find(object); } \
651 \
652 virtual nodetype *Find(const wxListKey& key) const \
653 { return (nodetype *)wxListBase::Find(key); } \
654 \
655 int IndexOf(Tbase *object) const \
656 { return wxListBase::IndexOf(object); } \
657 \
658 void Sort(wxSortFuncFor_##name func) \
659 { wxListBase::Sort((wxSortCompareFunction)func); } \
660 \
661 protected: \
662 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
663 void *data, \
664 const wxListKey& key = wxDefaultListKey) \
665 { \
666 return new nodetype(this, \
667 (nodetype *)prev, (nodetype *)next, \
668 (T *)data, key); \
669 } \
670 /* STL interface */ \
671 public: \
672 typedef size_t size_type; \
673 typedef int difference_type; \
674 typedef T* value_type; \
675 typedef Tbase* base_value_type; \
676 typedef value_type& reference; \
677 typedef const value_type& const_reference; \
678 typedef base_value_type& base_reference; \
679 typedef const base_value_type& const_base_reference; \
680 \
681 class iterator \
682 { \
683 typedef name list; \
684 public: \
685 typedef nodetype Node; \
686 typedef iterator itor; \
687 typedef T* value_type; \
688 typedef value_type* ptr_type; \
689 typedef value_type& reference; \
690 \
691 Node* m_node; \
692 Node* m_init; \
693 public: \
694 typedef reference reference_type; \
695 typedef ptr_type pointer_type; \
696 \
697 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
698 iterator() : m_node(NULL), m_init(NULL) { } \
699 reference_type operator*() const \
700 { return *(pointer_type)m_node->GetDataPtr(); } \
701 ptrop \
702 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
703 itor operator++(int) \
704 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
705 itor& operator--() \
706 { \
707 m_node = m_node ? m_node->GetPrevious() : m_init; \
708 return *this; \
709 } \
710 itor operator--(int) \
711 { \
712 itor tmp = *this; \
713 m_node = m_node ? m_node->GetPrevious() : m_init; \
714 return tmp; \
715 } \
716 bool operator!=(const itor& it) const \
717 { return it.m_node != m_node; } \
718 bool operator==(const itor& it) const \
719 { return it.m_node == m_node; } \
720 }; \
721 class const_iterator \
722 { \
723 typedef name list; \
724 public: \
725 typedef nodetype Node; \
726 typedef T* value_type; \
727 typedef const value_type& const_reference; \
728 typedef const_iterator itor; \
729 typedef value_type* ptr_type; \
730 \
731 Node* m_node; \
732 Node* m_init; \
733 public: \
734 typedef const_reference reference_type; \
735 typedef const ptr_type pointer_type; \
736 \
737 const_iterator(Node* node, Node* init) \
738 : m_node(node), m_init(init) { } \
739 const_iterator() : m_node(NULL), m_init(NULL) { } \
740 const_iterator(const iterator& it) \
741 : m_node(it.m_node), m_init(it.m_init) { } \
742 reference_type operator*() const \
743 { return *(pointer_type)m_node->GetDataPtr(); } \
744 ptrop \
745 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
746 itor operator++(int) \
747 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
748 itor& operator--() \
749 { \
750 m_node = m_node ? m_node->GetPrevious() : m_init; \
751 return *this; \
752 } \
753 itor operator--(int) \
754 { \
755 itor tmp = *this; \
756 m_node = m_node ? m_node->GetPrevious() : m_init; \
757 return tmp; \
758 } \
759 bool operator!=(const itor& it) const \
760 { return it.m_node != m_node; } \
761 bool operator==(const itor& it) const \
762 { return it.m_node == m_node; } \
763 }; \
764 class reverse_iterator \
765 { \
766 typedef name list; \
767 public: \
768 typedef nodetype Node; \
769 typedef T* value_type; \
770 typedef reverse_iterator itor; \
771 typedef value_type* ptr_type; \
772 typedef value_type& reference; \
773 \
774 Node* m_node; \
775 Node* m_init; \
776 public: \
777 typedef reference reference_type; \
778 typedef ptr_type pointer_type; \
779 \
780 reverse_iterator(Node* node, Node* init) \
781 : m_node(node), m_init(init) { } \
782 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
783 reference_type operator*() const \
784 { return *(pointer_type)m_node->GetDataPtr(); } \
785 ptrop \
786 itor& operator++() \
787 { m_node = m_node->GetPrevious(); return *this; } \
788 itor operator++(int) \
789 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
790 itor& operator--() \
791 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
792 itor operator--(int) \
793 { \
794 itor tmp = *this; \
795 m_node = m_node ? m_node->GetNext() : m_init; \
796 return tmp; \
797 } \
798 bool operator!=(const itor& it) const \
799 { return it.m_node != m_node; } \
800 bool operator==(const itor& it) const \
801 { return it.m_node == m_node; } \
802 }; \
803 class const_reverse_iterator \
804 { \
805 typedef name list; \
806 public: \
807 typedef nodetype Node; \
808 typedef T* value_type; \
809 typedef const_reverse_iterator itor; \
810 typedef value_type* ptr_type; \
811 typedef const value_type& const_reference; \
812 \
813 Node* m_node; \
814 Node* m_init; \
815 public: \
816 typedef const_reference reference_type; \
817 typedef const ptr_type pointer_type; \
818 \
819 const_reverse_iterator(Node* node, Node* init) \
820 : m_node(node), m_init(init) { } \
821 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
822 const_reverse_iterator(const reverse_iterator& it) \
823 : m_node(it.m_node), m_init(it.m_init) { } \
824 reference_type operator*() const \
825 { return *(pointer_type)m_node->GetDataPtr(); } \
826 ptrop \
827 itor& operator++() \
828 { m_node = m_node->GetPrevious(); return *this; } \
829 itor operator++(int) \
830 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
831 itor& operator--() \
832 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
833 itor operator--(int) \
834 { \
835 itor tmp = *this; \
836 m_node = m_node ? m_node->GetNext() : m_init; \
837 return tmp; \
838 } \
839 bool operator!=(const itor& it) const \
840 { return it.m_node != m_node; } \
841 bool operator==(const itor& it) const \
842 { return it.m_node == m_node; } \
843 }; \
844 \
845 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
846 { assign(n, v); } \
847 name(const_iterator first, const_iterator last) \
848 { assign(first, last); } \
849 iterator begin() { return iterator(GetFirst(), GetLast()); } \
850 const_iterator begin() const \
851 { return const_iterator(GetFirst(), GetLast()); } \
852 iterator end() { return iterator(NULL, GetLast()); } \
853 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
854 reverse_iterator rbegin() \
855 { return reverse_iterator(GetLast(), GetFirst()); } \
856 const_reverse_iterator rbegin() const \
857 { return const_reverse_iterator(GetLast(), GetFirst()); } \
858 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
859 const_reverse_iterator rend() const \
860 { return const_reverse_iterator(NULL, GetFirst()); } \
861 void resize(size_type n, value_type v = value_type()) \
862 { \
863 while (n < size()) \
864 pop_back(); \
865 while (n > size()) \
866 push_back(v); \
867 } \
868 size_type size() const { return GetCount(); } \
869 size_type max_size() const { return INT_MAX; } \
870 bool empty() const { return IsEmpty(); } \
871 reference front() { return *begin(); } \
872 const_reference front() const { return *begin(); } \
873 reference back() { return *--end(); } \
874 const_reference back() const { return *--end(); } \
875 void push_front(const_reference v = value_type()) \
876 { Insert(GetFirst(), (const_base_reference)v); } \
877 void pop_front() { DeleteNode(GetFirst()); } \
878 void push_back(const_reference v = value_type()) \
879 { Append((const_base_reference)v); } \
880 void pop_back() { DeleteNode(GetLast()); } \
881 void assign(const_iterator first, const_iterator last) \
882 { \
883 clear(); \
884 for(; first != last; ++first) \
885 Append((const_base_reference)*first); \
886 } \
887 void assign(size_type n, const_reference v = value_type()) \
888 { \
889 clear(); \
890 for(size_type i = 0; i < n; ++i) \
891 Append((const_base_reference)v); \
892 } \
893 iterator insert(iterator it, const_reference v = value_type()) \
894 { \
895 Insert(it.m_node, (const_base_reference)v); \
896 return iterator(it.m_node->GetPrevious(), GetLast()); \
897 } \
898 void insert(iterator it, size_type n, const_reference v = value_type())\
899 { \
900 for(size_type i = 0; i < n; ++i) \
901 Insert(it.m_node, (const_base_reference)v); \
902 } \
903 void insert(iterator it, const_iterator first, const_iterator last) \
904 { \
905 for(; first != last; ++first) \
906 Insert(it.m_node, (const_base_reference)*first); \
907 } \
908 iterator erase(iterator it) \
909 { \
910 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
911 DeleteNode(it.m_node); return next; \
912 } \
913 iterator erase(iterator first, iterator last) \
914 { \
915 iterator next = last; ++next; \
916 DeleteNodes(first.m_node, last.m_node); \
917 return next; \
918 } \
919 void clear() { Clear(); } \
920 void splice(iterator it, name& l, iterator first, iterator last) \
921 { insert(it, first, last); l.erase(first, last); } \
922 void splice(iterator it, name& l) \
923 { splice(it, l, l.begin(), l.end() ); } \
924 void splice(iterator it, name& l, iterator first) \
925 { \
926 iterator tmp = first; ++tmp; \
927 if(it == first || it == tmp) return; \
928 insert(it, *first); \
929 l.erase(first); \
930 } \
931 void remove(const_reference v) \
932 { DeleteObject((const_base_reference)v); } \
933 void reverse() \
934 { Reverse(); } \
935 /* void swap(name& l) \
936 { \
937 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
938 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
939 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
940 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
941 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
942 } */ \
943 }
944
945 #define WX_LIST_PTROP \
946 pointer_type operator->() const \
947 { return (pointer_type)m_node->GetDataPtr(); }
948 #define WX_LIST_PTROP_NONE
949
950 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
951 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
952 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
953 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
954
955 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
956 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
957 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
958 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
959
960 #define WX_DECLARE_LIST(elementtype, listname) \
961 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
962 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
963 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
964 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
965 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
966
967 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
968 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
969 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
970
971 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
972 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
973
974 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
975 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
976 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
977
978 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
979 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
980 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
981 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
982 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
983 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
984
985 // this macro must be inserted in your program after
986 // #include <wx/listimpl.cpp>
987 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
988
989 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
990 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
991
992 #endif // !wxUSE_STL
993
994 // ============================================================================
995 // now we can define classes 100% compatible with the old ones
996 // ============================================================================
997
998 // ----------------------------------------------------------------------------
999 // commonly used list classes
1000 // ----------------------------------------------------------------------------
1001
1002 #if defined(wxLIST_COMPATIBILITY)
1003
1004 // inline compatibility functions
1005
1006 #if !wxUSE_STL
1007
1008 // ----------------------------------------------------------------------------
1009 // wxNodeBase deprecated methods
1010 // ----------------------------------------------------------------------------
1011
1012 inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
1013 inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
1014 inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1015
1016 // ----------------------------------------------------------------------------
1017 // wxListBase deprecated methods
1018 // ----------------------------------------------------------------------------
1019
1020 inline int wxListBase::Number() const { return (int)GetCount(); }
1021 inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
1022 inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
1023 inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1024 inline wxListBase::operator wxList&() const { return *(wxList*)this; }
1025
1026 #endif
1027
1028 // define this to make a lot of noise about use of the old wxList classes.
1029 //#define wxWARN_COMPAT_LIST_USE
1030
1031 // ----------------------------------------------------------------------------
1032 // wxList compatibility class: in fact, it's a list of wxObjects
1033 // ----------------------------------------------------------------------------
1034
1035 WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1036 class WXDLLIMPEXP_BASE);
1037
1038 class WXDLLIMPEXP_BASE wxList : public wxObjectList
1039 {
1040 public:
1041 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1042 wxList() { };
1043 wxDEPRECATED( wxList(int key_type) );
1044 #elif !wxUSE_STL
1045 wxList(int key_type = wxKEY_NONE);
1046 #endif
1047
1048 // this destructor is required for Darwin
1049 ~wxList() { }
1050
1051 #if !wxUSE_STL
1052 wxList& operator=(const wxList& list)
1053 { (void) wxListBase::operator=(list); return *this; }
1054
1055 // compatibility methods
1056 void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
1057 #endif
1058
1059 #if wxUSE_STL
1060 #else
1061 wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
1062 #endif
1063
1064 private:
1065 #if !wxUSE_STL
1066 DECLARE_DYNAMIC_CLASS(wxList)
1067 #endif
1068 };
1069
1070 #if !wxUSE_STL
1071
1072 // -----------------------------------------------------------------------------
1073 // wxStringList class for compatibility with the old code
1074 // -----------------------------------------------------------------------------
1075 WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
1076
1077 class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1078 {
1079 public:
1080 // ctors and such
1081 // default
1082 #ifdef wxWARN_COMPAT_LIST_USE
1083 wxStringList();
1084 wxDEPRECATED( wxStringList(const wxChar *first ...) );
1085 #else
1086 wxStringList();
1087 wxStringList(const wxChar *first ...);
1088 #endif
1089
1090 // copying the string list: the strings are copied, too (extremely
1091 // inefficient!)
1092 wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(true); DoCopy(other); }
1093 wxStringList& operator=(const wxStringList& other)
1094 { Clear(); DoCopy(other); return *this; }
1095
1096 // operations
1097 // makes a copy of the string
1098 wxNode *Add(const wxChar *s);
1099
1100 // Append to beginning of list
1101 wxNode *Prepend(const wxChar *s);
1102
1103 bool Delete(const wxChar *s);
1104
1105 wxChar **ListToArray(bool new_copies = false) const;
1106 bool Member(const wxChar *s) const;
1107
1108 // alphabetic sort
1109 void Sort();
1110
1111 private:
1112 void DoCopy(const wxStringList&); // common part of copy ctor and operator=
1113
1114 DECLARE_DYNAMIC_CLASS(wxStringList)
1115 };
1116
1117 #else // if wxUSE_STL
1118
1119 WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLEXPORT);
1120
1121 class WXDLLEXPORT wxStringList : public wxStringListBase
1122 {
1123 public:
1124 compatibility_iterator Append(wxChar* s)
1125 { wxString tmp = s; delete[] s; return wxStringListBase::Append(tmp); }
1126 compatibility_iterator Insert(wxChar* s)
1127 { wxString tmp = s; delete[] s; return wxStringListBase::Insert(tmp); }
1128 compatibility_iterator Insert(size_t pos, wxChar* s)
1129 {
1130 wxString tmp = s;
1131 delete[] s;
1132 return wxStringListBase::Insert(pos, tmp);
1133 }
1134 compatibility_iterator Add(const wxChar* s)
1135 { push_back(s); return GetLast(); }
1136 compatibility_iterator Prepend(const wxChar* s)
1137 { push_front(s); return GetFirst(); }
1138 };
1139
1140 #endif // wxUSE_STL
1141
1142 #endif // wxLIST_COMPATIBILITY
1143
1144 // delete all list elements
1145 //
1146 // NB: the class declaration of the list elements must be visible from the
1147 // place where you use this macro, otherwise the proper destructor may not
1148 // be called (a decent compiler should give a warning about it, but don't
1149 // count on it)!
1150 #define WX_CLEAR_LIST(type, list) \
1151 { \
1152 type::iterator it, en; \
1153 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1154 delete *it; \
1155 (list).clear(); \
1156 }
1157
1158 #endif
1159 // _WX_LISTH__