1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxList, wxStringList classes
4 // Author: Julian Smart
5 // Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
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
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
28 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) && \
29 !(defined(__MINGW32__) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
30 #pragma interface "list.h"
33 // -----------------------------------------------------------------------------
35 // -----------------------------------------------------------------------------
38 #include "wx/object.h"
39 #include "wx/string.h"
42 #include "wx/beforestd.h"
44 #include "wx/afterstd.h"
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
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
57 typedef int (* LINKAGEMODE wxSortCompareFunction
)(const void *elem1
, const void *elem2
);
60 class WXDLLIMPEXP_BASE wxObjectListNode
;
61 typedef wxObjectListNode wxNode
;
64 typedef int (* LINKAGEMODE wxListIterateFunction
)(void *current
);
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 #if !defined(wxENUM_KEY_TYPE_DEFINED)
71 #define wxENUM_KEY_TYPE_DEFINED
84 #define wxLIST_COMPATIBILITY
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)
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) \
96 #define WX_DECLARE_LIST_WITH_DECL(elT, liT, decl) \
97 WX_DECLARE_LIST_XO(elT*, liT, decl)
99 #define WX_DECLARE_LIST_XO(elT, liT, decl) \
100 decl liT : public std::list<elT> \
105 struct compatibility_iterator \
107 typedef std::list<elT>::iterator iterator; \
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; } \
127 typedef struct compatibility_iterator citer; \
131 typedef std::list<elT>::iterator it; \
132 typedef compatibility_iterator citer; \
134 elT GetData() const \
136 citer* i = (citer*)this; \
137 return *(i->m_iter); \
139 citer GetNext() const \
141 citer* i = (citer*)this; \
142 it lit = i->m_iter; \
143 return citer( i->m_list, ++lit ); \
145 citer GetPrevious() const \
147 citer* i = (citer*)this; \
148 it lit = i->m_iter; \
149 return citer( i->m_list, --lit ); \
151 void SetData( elT e ) \
153 citer* i = (citer*)this; \
160 iterator find( elT e ) \
163 for( it = begin(), en = end(); it != en; ++it ) \
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 ) \
179 iterator it = find( e ); \
187 void Erase( const compatibility_iterator& it ) \
189 erase( it.m_iter ); \
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 \
202 for( it = ((liT*)this)->begin(); idx; --idx ) \
204 return citer( this, it ); \
206 int IndexOf( elT e ) const \
208 const_iterator it, en; \
210 for( idx = 0, it = begin(), en = end(); it != en; ++it, ++idx ) \
213 return wxNOT_FOUND; \
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)
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)
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)
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!"
236 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
237 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
239 #else // if !wxUSE_STL
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
);
245 class WXDLLEXPORT wxObjectListNode
;
246 typedef wxObjectListNode wxNode
;
248 // undef it to get rid of old, deprecated functions
249 #define wxLIST_COMPATIBILITY
251 // -----------------------------------------------------------------------------
252 // key stuff: a list may be optionally keyed on integer or string key
253 // -----------------------------------------------------------------------------
261 // a struct which may contain both types of keys
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
271 wxListKey() : m_keyType(wxKEY_NONE
)
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()); }
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
; }
288 // Note: implementation moved to list.cpp to prevent BC++ inline
289 // expansion warning.
290 bool operator==(wxListKeyValue value
) const ;
295 if ( m_keyType
== wxKEY_STRING
)
301 wxListKeyValue m_key
;
304 // -----------------------------------------------------------------------------
305 // wxNodeBase class is a (base for) node in a double linked list
306 // -----------------------------------------------------------------------------
308 WXDLLIMPEXP_DATA_BASE(extern wxListKey
) wxDefaultListKey
;
310 class WXDLLIMPEXP_BASE wxListBase
;
312 class WXDLLIMPEXP_BASE wxNodeBase
314 friend class wxListBase
;
317 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
318 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
319 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
321 const wxListKey
& key
= wxDefaultListKey
);
323 virtual ~wxNodeBase();
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
; }
329 // Necessary for some existing code
330 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
331 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
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
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
; }
345 void *GetData() const { return m_data
; }
346 void SetData(void *data
) { m_data
= data
; }
348 // get 0-based index of this node within the list or wxNOT_FOUND
351 virtual void DeleteData() { }
353 // for wxList::iterator
354 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
356 // optional key stuff
357 wxListKeyValue m_key
;
359 void *m_data
; // user data
360 wxNodeBase
*m_next
, // next and previous nodes in the list
363 wxListBase
*m_list
; // list we belong to
365 DECLARE_NO_COPY_CLASS(wxNodeBase
)
368 // -----------------------------------------------------------------------------
369 // a double-linked list class
370 // -----------------------------------------------------------------------------
374 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
376 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
377 friend class wxHashTableBase
; // should be able to call untyped Find()
379 // common part of all ctors
380 void Init(wxKeyType keyType
= wxKEY_NONE
); // Must be declared before it's used (for VC++ 1.5)
382 // default ctor & dtor
383 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
385 virtual ~wxListBase();
388 // count of items in the list
389 size_t GetCount() const { return m_count
; }
391 // return TRUE if this list is empty
392 bool IsEmpty() const { return m_count
== 0; }
399 // instruct it to destroy user data when deleting nodes
400 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
402 // query if to delete
403 bool GetDeleteContents() const
404 { return m_destroy
; }
407 wxKeyType
GetKeyType() const
408 { return m_keyType
; }
410 // set the keytype (required by the serial code)
411 void SetKeyType(wxKeyType keyType
)
412 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
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
421 // kludge for typesafe list migration in core classes.
422 wxDEPRECATED( operator wxList
&() const );
423 #endif // wxLIST_COMPATIBILITY
427 // all methods here are "overloaded" in derived classes to provide compile
428 // time type checking
430 // create a node for the list of this type
431 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
433 const wxListKey
& key
= wxDefaultListKey
) = 0;
435 // Can't access these from derived classes otherwise (bug in Salford C++?)
442 wxListBase(size_t count
, void *elements
[]);
443 // from a sequence of objects
444 wxListBase(void *object
, ... /* terminate with NULL */);
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; }
453 // get list head/tail
454 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
455 wxNodeBase
*GetLast() const { return m_nodeLast
; }
457 // by (0-based) index
458 wxNodeBase
*Item(size_t index
) const;
460 // get the list item's data
461 void *operator[](size_t n
) const
463 wxNodeBase
*node
= Item(n
);
465 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
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
);
484 wxNodeBase
*Append(long key
, void *object
);
485 wxNodeBase
*Append(const wxChar
*key
, void *object
);
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
);
496 // search (all return NULL if item not found)
498 wxNodeBase
*Find(void *object
) const;
501 wxNodeBase
*Find(const wxListKey
& key
) const;
503 // get 0-based index of object or wxNOT_FOUND
504 int IndexOf( void *object
) const;
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
);
510 // functions for iterating over the list
511 void *FirstThat(wxListIterateFunction func
);
512 void ForEach(wxListIterateFunction func
);
513 void *LastThat(wxListIterateFunction func
);
515 // for STL interface, "last" points to one after the last node
516 // of the controlled sequence (NULL for the end of the list)
518 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
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
);
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
533 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
536 // -----------------------------------------------------------------------------
537 // macros for definition of "template" list type
538 // -----------------------------------------------------------------------------
540 // and now some heavy magic...
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)
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
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.
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.
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)
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 **); \
572 classexp nodetype : public wxNodeBase \
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) { } \
582 nodetype *GetNext() const \
583 { return (nodetype *)wxNodeBase::GetNext(); } \
584 nodetype *GetPrevious() const \
585 { return (nodetype *)wxNodeBase::GetPrevious(); } \
588 { return (T *)wxNodeBase::GetData(); } \
589 void SetData(T *data) \
590 { wxNodeBase::SetData(data); } \
592 virtual void DeleteData(); \
594 DECLARE_NO_COPY_CLASS(nodetype) \
597 classexp name : public wxListBase \
600 typedef nodetype Node; \
601 typedef Node* compatibility_iterator; \
603 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
605 name(size_t count, T *elements[]) \
606 : wxListBase(count, (void **)elements) { } \
608 name& operator=(const name& list) \
609 { (void) wxListBase::operator=(list); return *this; } \
611 nodetype *GetFirst() const \
612 { return (nodetype *)wxListBase::GetFirst(); } \
613 nodetype *GetLast() const \
614 { return (nodetype *)wxListBase::GetLast(); } \
616 nodetype *Item(size_t index) const \
617 { return (nodetype *)wxListBase::Item(index); } \
619 T *operator[](size_t index) const \
621 nodetype *node = Item(index); \
622 return node ? (T*)(node->GetData()) : (T*)NULL; \
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); } \
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); } \
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); } \
648 nodetype *Find(Tbase *object) const \
649 { return (nodetype *)wxListBase::Find(object); } \
651 virtual nodetype *Find(const wxListKey& key) const \
652 { return (nodetype *)wxListBase::Find(key); } \
654 int IndexOf(Tbase *object) const \
655 { return wxListBase::IndexOf(object); } \
657 void Sort(wxSortFuncFor_##name func) \
658 { wxListBase::Sort((wxSortCompareFunction)func); } \
661 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
663 const wxListKey& key = wxDefaultListKey) \
665 return new nodetype(this, \
666 (nodetype *)prev, (nodetype *)next, \
669 /* STL interface */ \
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; \
684 typedef nodetype Node; \
685 typedef iterator itor; \
686 typedef T* value_type; \
687 typedef value_type* ptr_type; \
688 typedef value_type& reference; \
693 typedef reference reference_type; \
694 typedef ptr_type pointer_type; \
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(); } \
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; }\
706 m_node = m_node ? m_node->GetPrevious() : m_init; \
709 itor operator--(int) \
712 m_node = m_node ? m_node->GetPrevious() : m_init; \
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; } \
720 class const_iterator \
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; \
733 typedef const_reference reference_type; \
734 typedef const ptr_type pointer_type; \
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(); } \
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; }\
749 m_node = m_node ? m_node->GetPrevious() : m_init; \
752 itor operator--(int) \
755 m_node = m_node ? m_node->GetPrevious() : m_init; \
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; } \
763 class reverse_iterator \
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; \
776 typedef reference reference_type; \
777 typedef ptr_type pointer_type; \
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(); } \
786 { m_node = m_node->GetPrevious(); return *this; } \
787 itor operator++(int) \
788 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
790 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
791 itor operator--(int) \
794 m_node = m_node ? m_node->GetNext() : m_init; \
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; } \
802 class const_reverse_iterator \
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; \
815 typedef const_reference reference_type; \
816 typedef const ptr_type pointer_type; \
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(); } \
827 { m_node = m_node->GetPrevious(); return *this; } \
828 itor operator++(int) \
829 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
831 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
832 itor operator--(int) \
835 m_node = m_node ? m_node->GetNext() : m_init; \
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; } \
844 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
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()) \
863 for(; n < size(); pop_back()); \
864 else if(n > size()) \
865 for(; n > size(); push_back(v)); \
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) \
883 for(; first != last; ++first) \
884 Append((const_base_reference)*first); \
886 void assign(size_type n, const_reference v = value_type()) \
889 for(size_type i = 0; i < n; ++i) \
890 Append((const_base_reference)v); \
892 iterator insert(iterator it, const_reference v = value_type()) \
894 Insert(it.m_node, (const_base_reference)v); \
895 return iterator(it.m_node->GetPrevious(), GetLast()); \
897 void insert(iterator it, size_type n, const_reference v = value_type())\
899 for(size_type i = 0; i < n; ++i) \
900 Insert(it.m_node, (const_base_reference)v); \
902 void insert(iterator it, const_iterator first, const_iterator last) \
904 for(; first != last; ++first) \
905 Insert(it.m_node, (const_base_reference)*first); \
907 iterator erase(iterator it) \
909 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
910 DeleteNode(it.m_node); return next; \
912 iterator erase(iterator first, iterator last) \
914 iterator next = last; ++next; \
915 DeleteNodes(first.m_node, last.m_node); \
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) \
925 iterator tmp = first; ++tmp; \
926 if(it == first || it == tmp) return; \
927 insert(it, *first); \
930 void remove(const_reference v) \
931 { DeleteObject((const_base_reference)v); } \
934 /* void swap(name& l) \
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; }\
944 #define WX_LIST_PTROP \
945 pointer_type operator->() const \
946 { return (pointer_type)m_node->GetDataPtr(); }
947 #define WX_LIST_PTROP_NONE
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)
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)
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)
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)
970 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
971 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
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)
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)
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!"
988 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
989 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
993 // ============================================================================
994 // now we can define classes 100% compatible with the old ones
995 // ============================================================================
997 // ----------------------------------------------------------------------------
998 // commonly used list classes
999 // ----------------------------------------------------------------------------
1001 #if defined(wxLIST_COMPATIBILITY)
1003 // inline compatibility functions
1007 // ----------------------------------------------------------------------------
1008 // wxNodeBase deprecated methods
1009 // ----------------------------------------------------------------------------
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(); }
1015 // ----------------------------------------------------------------------------
1016 // wxListBase deprecated methods
1017 // ----------------------------------------------------------------------------
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; }
1027 // define this to make a lot of noise about use of the old wxList classes.
1028 //#define wxWARN_COMPAT_LIST_USE
1030 // ----------------------------------------------------------------------------
1031 // wxList compatibility class: in fact, it's a list of wxObjects
1032 // ----------------------------------------------------------------------------
1034 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1035 class WXDLLIMPEXP_BASE
);
1037 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1040 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1042 wxDEPRECATED( wxList(int key_type
) );
1044 wxList(int key_type
= wxKEY_NONE
);
1047 // this destructor is required for Darwin
1051 wxList
& operator=(const wxList
& list
)
1052 { (void) wxListBase::operator=(list
); return *this; }
1054 // compatibility methods
1055 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
1060 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1065 DECLARE_DYNAMIC_CLASS(wxList
)
1071 // -----------------------------------------------------------------------------
1072 // wxStringList class for compatibility with the old code
1073 // -----------------------------------------------------------------------------
1074 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1076 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1081 #ifdef wxWARN_COMPAT_LIST_USE
1083 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1086 wxStringList(const wxChar
*first
...);
1089 // copying the string list: the strings are copied, too (extremely
1091 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(TRUE
); DoCopy(other
); }
1092 wxStringList
& operator=(const wxStringList
& other
)
1093 { Clear(); DoCopy(other
); return *this; }
1096 // makes a copy of the string
1097 wxNode
*Add(const wxChar
*s
);
1099 // Append to beginning of list
1100 wxNode
*Prepend(const wxChar
*s
);
1102 bool Delete(const wxChar
*s
);
1104 wxChar
**ListToArray(bool new_copies
= FALSE
) const;
1105 bool Member(const wxChar
*s
) const;
1111 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1113 DECLARE_DYNAMIC_CLASS(wxStringList
)
1116 #else // if wxUSE_STL
1118 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLEXPORT
);
1120 class WXDLLEXPORT wxStringList
: public wxStringListBase
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
)
1131 return wxStringListBase::Insert(pos
, tmp
);
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(); }
1141 #endif // wxLIST_COMPATIBILITY
1143 // delete all list elements
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
1149 #define WX_CLEAR_LIST(type, list) \
1151 type::iterator it, en; \
1152 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \