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( const 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( 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 \
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 #if WXWIN_COMPATIBILITY_2_4
244 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
247 class WXDLLEXPORT wxObjectListNode
;
248 typedef wxObjectListNode wxNode
;
250 // undef it to get rid of old, deprecated functions
251 #define wxLIST_COMPATIBILITY
253 // -----------------------------------------------------------------------------
254 // key stuff: a list may be optionally keyed on integer or string key
255 // -----------------------------------------------------------------------------
263 // a struct which may contain both types of keys
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
273 wxListKey() : m_keyType(wxKEY_NONE
)
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()); }
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
; }
290 // Note: implementation moved to list.cpp to prevent BC++ inline
291 // expansion warning.
292 bool operator==(wxListKeyValue value
) const ;
297 if ( m_keyType
== wxKEY_STRING
)
303 wxListKeyValue m_key
;
306 // -----------------------------------------------------------------------------
307 // wxNodeBase class is a (base for) node in a double linked list
308 // -----------------------------------------------------------------------------
310 WXDLLIMPEXP_DATA_BASE(extern wxListKey
) wxDefaultListKey
;
312 class WXDLLIMPEXP_BASE wxListBase
;
314 class WXDLLIMPEXP_BASE wxNodeBase
316 friend class wxListBase
;
319 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
320 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
321 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
323 const wxListKey
& key
= wxDefaultListKey
);
325 virtual ~wxNodeBase();
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
; }
331 // Necessary for some existing code
332 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
333 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
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
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
; }
347 void *GetData() const { return m_data
; }
348 void SetData(void *data
) { m_data
= data
; }
350 // get 0-based index of this node within the list or wxNOT_FOUND
353 virtual void DeleteData() { }
355 // for wxList::iterator
356 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
358 // optional key stuff
359 wxListKeyValue m_key
;
361 void *m_data
; // user data
362 wxNodeBase
*m_next
, // next and previous nodes in the list
365 wxListBase
*m_list
; // list we belong to
367 DECLARE_NO_COPY_CLASS(wxNodeBase
)
370 // -----------------------------------------------------------------------------
371 // a double-linked list class
372 // -----------------------------------------------------------------------------
374 class WXDLLIMPEXP_BASE wxList
;
376 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
378 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
379 friend class wxHashTableBase
; // should be able to call untyped Find()
381 // common part of all ctors
382 void Init(wxKeyType keyType
= wxKEY_NONE
); // Must be declared before it's used (for VC++ 1.5)
384 // default ctor & dtor
385 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
387 virtual ~wxListBase();
390 // count of items in the list
391 size_t GetCount() const { return m_count
; }
393 // return TRUE if this list is empty
394 bool IsEmpty() const { return m_count
== 0; }
401 // instruct it to destroy user data when deleting nodes
402 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
404 // query if to delete
405 bool GetDeleteContents() const
406 { return m_destroy
; }
409 wxKeyType
GetKeyType() const
410 { return m_keyType
; }
412 // set the keytype (required by the serial code)
413 void SetKeyType(wxKeyType keyType
)
414 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
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
423 // kludge for typesafe list migration in core classes.
424 wxDEPRECATED( operator wxList
&() const );
425 #endif // wxLIST_COMPATIBILITY
429 // all methods here are "overloaded" in derived classes to provide compile
430 // time type checking
432 // create a node for the list of this type
433 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
435 const wxListKey
& key
= wxDefaultListKey
) = 0;
437 // Can't access these from derived classes otherwise (bug in Salford C++?)
444 wxListBase(size_t count
, void *elements
[]);
445 // from a sequence of objects
446 wxListBase(void *object
, ... /* terminate with NULL */);
449 // copy ctor and assignment operator
450 wxListBase(const wxListBase
& list
) : wxObject()
451 { Init(); DoCopy(list
); }
452 wxListBase
& operator=(const wxListBase
& list
)
453 { Clear(); DoCopy(list
); return *this; }
455 // get list head/tail
456 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
457 wxNodeBase
*GetLast() const { return m_nodeLast
; }
459 // by (0-based) index
460 wxNodeBase
*Item(size_t index
) const;
462 // get the list item's data
463 void *operator[](size_t n
) const
465 wxNodeBase
*node
= Item(n
);
467 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
471 // append to end of list
472 wxNodeBase
*Prepend(void *object
)
473 { return (wxNodeBase
*)wxListBase::Insert(object
); }
474 // append to beginning of list
475 wxNodeBase
*Append(void *object
);
476 // insert a new item at the beginning of the list
477 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
478 // insert a new item at the given position
479 wxNodeBase
*Insert(size_t pos
, void *object
)
480 { return pos
== GetCount() ? Append(object
)
481 : Insert(Item(pos
), object
); }
482 // insert before given node or at front of list if prev == NULL
483 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
486 wxNodeBase
*Append(long key
, void *object
);
487 wxNodeBase
*Append(const wxChar
*key
, void *object
);
489 // removes node from the list but doesn't delete it (returns pointer
490 // to the node or NULL if it wasn't found in the list)
491 wxNodeBase
*DetachNode(wxNodeBase
*node
);
492 // delete element from list, returns FALSE if node not found
493 bool DeleteNode(wxNodeBase
*node
);
494 // finds object pointer and deletes node (and object if DeleteContents
495 // is on), returns FALSE if object not found
496 bool DeleteObject(void *object
);
498 // search (all return NULL if item not found)
500 wxNodeBase
*Find(const void *object
) const;
503 wxNodeBase
*Find(const wxListKey
& key
) const;
505 // get 0-based index of object or wxNOT_FOUND
506 int IndexOf( void *object
) const;
508 // this function allows the sorting of arbitrary lists by giving
509 // a function to compare two list elements. The list is sorted in place.
510 void Sort(const wxSortCompareFunction compfunc
);
512 // functions for iterating over the list
513 void *FirstThat(wxListIterateFunction func
);
514 void ForEach(wxListIterateFunction func
);
515 void *LastThat(wxListIterateFunction func
);
517 // for STL interface, "last" points to one after the last node
518 // of the controlled sequence (NULL for the end of the list)
520 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
523 // common part of copy ctor and assignment operator
524 void DoCopy(const wxListBase
& list
);
525 // common part of all Append()s
526 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
527 // free node's data and node itself
528 void DoDeleteNode(wxNodeBase
*node
);
530 size_t m_count
; // number of elements in the list
531 bool m_destroy
; // destroy user data when deleting list items?
532 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
535 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
538 // -----------------------------------------------------------------------------
539 // macros for definition of "template" list type
540 // -----------------------------------------------------------------------------
542 // and now some heavy magic...
544 // declare a list type named 'name' and containing elements of type 'T *'
545 // (as a by product of macro expansion you also get wx##name##Node
546 // wxNode-derived type)
548 // implementation details:
549 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
550 // for the list of given type - this allows us to pass only the list name
551 // to WX_DEFINE_LIST() even if it needs both the name and the type
553 // 2. We redefine all non-type-safe wxList functions with type-safe versions
554 // which don't take any space (everything is inline), but bring compile
555 // time error checking.
557 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
558 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
559 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
560 // interesting capability to store polymorphic objects in the list and is
561 // particularly useful with, for example, "wxWindow *" list where the
562 // wxWindowBase pointers are put into the list, but wxWindow pointers are
563 // retrieved from it.
565 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
566 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
567 // it results in compiler warnings when this operator doesn't make sense
568 // (i.e. stored elements are not pointers)
570 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
571 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
572 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
574 classexp nodetype : public wxNodeBase \
577 nodetype(wxListBase *list = (wxListBase *)NULL, \
578 nodetype *previous = (nodetype *)NULL, \
579 nodetype *next = (nodetype *)NULL, \
580 T *data = (T *)NULL, \
581 const wxListKey& key = wxDefaultListKey) \
582 : wxNodeBase(list, previous, next, data, key) { } \
584 nodetype *GetNext() const \
585 { return (nodetype *)wxNodeBase::GetNext(); } \
586 nodetype *GetPrevious() const \
587 { return (nodetype *)wxNodeBase::GetPrevious(); } \
590 { return (T *)wxNodeBase::GetData(); } \
591 void SetData(T *data) \
592 { wxNodeBase::SetData(data); } \
594 virtual void DeleteData(); \
596 DECLARE_NO_COPY_CLASS(nodetype) \
599 classexp name : public wxListBase \
602 typedef nodetype Node; \
603 typedef Node* compatibility_iterator; \
605 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
607 name(size_t count, T *elements[]) \
608 : wxListBase(count, (void **)elements) { } \
610 name& operator=(const name& list) \
611 { (void) wxListBase::operator=(list); return *this; } \
613 nodetype *GetFirst() const \
614 { return (nodetype *)wxListBase::GetFirst(); } \
615 nodetype *GetLast() const \
616 { return (nodetype *)wxListBase::GetLast(); } \
618 nodetype *Item(size_t index) const \
619 { return (nodetype *)wxListBase::Item(index); } \
621 T *operator[](size_t index) const \
623 nodetype *node = Item(index); \
624 return node ? (T*)(node->GetData()) : (T*)NULL; \
627 nodetype *Append(Tbase *object) \
628 { return (nodetype *)wxListBase::Append(object); } \
629 nodetype *Insert(Tbase *object) \
630 { return (nodetype *)Insert((nodetype*)NULL, object); } \
631 nodetype *Insert(size_t pos, Tbase *object) \
632 { return (nodetype *)wxListBase::Insert(pos, object); } \
633 nodetype *Insert(nodetype *prev, Tbase *object) \
634 { return (nodetype *)wxListBase::Insert(prev, object); } \
636 nodetype *Append(long key, void *object) \
637 { return (nodetype *)wxListBase::Append(key, object); } \
638 nodetype *Append(const wxChar *key, void *object) \
639 { return (nodetype *)wxListBase::Append(key, object); } \
641 nodetype *DetachNode(nodetype *node) \
642 { return (nodetype *)wxListBase::DetachNode(node); } \
643 bool DeleteNode(nodetype *node) \
644 { return wxListBase::DeleteNode(node); } \
645 bool DeleteObject(Tbase *object) \
646 { return wxListBase::DeleteObject(object); } \
647 void Erase(compatibility_iterator it) \
648 { DeleteNode(it); } \
650 nodetype *Find(const Tbase *object) const \
651 { return (nodetype *)wxListBase::Find(object); } \
653 virtual nodetype *Find(const wxListKey& key) const \
654 { return (nodetype *)wxListBase::Find(key); } \
656 int IndexOf(Tbase *object) const \
657 { return wxListBase::IndexOf(object); } \
659 void Sort(wxSortFuncFor_##name func) \
660 { wxListBase::Sort((wxSortCompareFunction)func); } \
663 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
665 const wxListKey& key = wxDefaultListKey) \
667 return new nodetype(this, \
668 (nodetype *)prev, (nodetype *)next, \
671 /* STL interface */ \
673 typedef size_t size_type; \
674 typedef int difference_type; \
675 typedef T* value_type; \
676 typedef Tbase* base_value_type; \
677 typedef value_type& reference; \
678 typedef const value_type& const_reference; \
679 typedef base_value_type& base_reference; \
680 typedef const base_value_type& const_base_reference; \
686 typedef nodetype Node; \
687 typedef iterator itor; \
688 typedef T* value_type; \
689 typedef value_type* ptr_type; \
690 typedef value_type& reference; \
695 typedef reference reference_type; \
696 typedef ptr_type pointer_type; \
698 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
699 iterator() : m_node(NULL), m_init(NULL) { } \
700 reference_type operator*() const \
701 { return *(pointer_type)m_node->GetDataPtr(); } \
703 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
704 itor operator++(int) \
705 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
708 m_node = m_node ? m_node->GetPrevious() : m_init; \
711 itor operator--(int) \
714 m_node = m_node ? m_node->GetPrevious() : m_init; \
717 bool operator!=(const itor& it) const \
718 { return it.m_node != m_node; } \
719 bool operator==(const itor& it) const \
720 { return it.m_node == m_node; } \
722 class const_iterator \
726 typedef nodetype Node; \
727 typedef T* value_type; \
728 typedef const value_type& const_reference; \
729 typedef const_iterator itor; \
730 typedef value_type* ptr_type; \
735 typedef const_reference reference_type; \
736 typedef const ptr_type pointer_type; \
738 const_iterator(Node* node, Node* init) \
739 : m_node(node), m_init(init) { } \
740 const_iterator() : m_node(NULL), m_init(NULL) { } \
741 const_iterator(const iterator& it) \
742 : m_node(it.m_node), m_init(it.m_init) { } \
743 reference_type operator*() const \
744 { return *(pointer_type)m_node->GetDataPtr(); } \
746 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
747 itor operator++(int) \
748 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
751 m_node = m_node ? m_node->GetPrevious() : m_init; \
754 itor operator--(int) \
757 m_node = m_node ? m_node->GetPrevious() : m_init; \
760 bool operator!=(const itor& it) const \
761 { return it.m_node != m_node; } \
762 bool operator==(const itor& it) const \
763 { return it.m_node == m_node; } \
765 class reverse_iterator \
769 typedef nodetype Node; \
770 typedef T* value_type; \
771 typedef reverse_iterator itor; \
772 typedef value_type* ptr_type; \
773 typedef value_type& reference; \
778 typedef reference reference_type; \
779 typedef ptr_type pointer_type; \
781 reverse_iterator(Node* node, Node* init) \
782 : m_node(node), m_init(init) { } \
783 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
784 reference_type operator*() const \
785 { return *(pointer_type)m_node->GetDataPtr(); } \
788 { m_node = m_node->GetPrevious(); return *this; } \
789 itor operator++(int) \
790 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
792 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
793 itor operator--(int) \
796 m_node = m_node ? m_node->GetNext() : m_init; \
799 bool operator!=(const itor& it) const \
800 { return it.m_node != m_node; } \
801 bool operator==(const itor& it) const \
802 { return it.m_node == m_node; } \
804 class const_reverse_iterator \
808 typedef nodetype Node; \
809 typedef T* value_type; \
810 typedef const_reverse_iterator itor; \
811 typedef value_type* ptr_type; \
812 typedef const value_type& const_reference; \
817 typedef const_reference reference_type; \
818 typedef const ptr_type pointer_type; \
820 const_reverse_iterator(Node* node, Node* init) \
821 : m_node(node), m_init(init) { } \
822 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
823 const_reverse_iterator(const reverse_iterator& it) \
824 : m_node(it.m_node), m_init(it.m_init) { } \
825 reference_type operator*() const \
826 { return *(pointer_type)m_node->GetDataPtr(); } \
829 { m_node = m_node->GetPrevious(); return *this; } \
830 itor operator++(int) \
831 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
833 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
834 itor operator--(int) \
837 m_node = m_node ? m_node->GetNext() : m_init; \
840 bool operator!=(const itor& it) const \
841 { return it.m_node != m_node; } \
842 bool operator==(const itor& it) const \
843 { return it.m_node == m_node; } \
846 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
848 name(const_iterator first, const_iterator last) \
849 { assign(first, last); } \
850 iterator begin() { return iterator(GetFirst(), GetLast()); } \
851 const_iterator begin() const \
852 { return const_iterator(GetFirst(), GetLast()); } \
853 iterator end() { return iterator(NULL, GetLast()); } \
854 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
855 reverse_iterator rbegin() \
856 { return reverse_iterator(GetLast(), GetFirst()); } \
857 const_reverse_iterator rbegin() const \
858 { return const_reverse_iterator(GetLast(), GetFirst()); } \
859 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
860 const_reverse_iterator rend() const \
861 { return const_reverse_iterator(NULL, GetFirst()); } \
862 void resize(size_type n, value_type v = value_type()) \
869 size_type size() const { return GetCount(); } \
870 size_type max_size() const { return INT_MAX; } \
871 bool empty() const { return IsEmpty(); } \
872 reference front() { return *begin(); } \
873 const_reference front() const { return *begin(); } \
874 reference back() { return *--end(); } \
875 const_reference back() const { return *--end(); } \
876 void push_front(const_reference v = value_type()) \
877 { Insert(GetFirst(), (const_base_reference)v); } \
878 void pop_front() { DeleteNode(GetFirst()); } \
879 void push_back(const_reference v = value_type()) \
880 { Append((const_base_reference)v); } \
881 void pop_back() { DeleteNode(GetLast()); } \
882 void assign(const_iterator first, const_iterator last) \
885 for(; first != last; ++first) \
886 Append((const_base_reference)*first); \
888 void assign(size_type n, const_reference v = value_type()) \
891 for(size_type i = 0; i < n; ++i) \
892 Append((const_base_reference)v); \
894 iterator insert(iterator it, const_reference v = value_type()) \
896 Insert(it.m_node, (const_base_reference)v); \
897 return iterator(it.m_node->GetPrevious(), GetLast()); \
899 void insert(iterator it, size_type n, const_reference v = value_type())\
901 for(size_type i = 0; i < n; ++i) \
902 Insert(it.m_node, (const_base_reference)v); \
904 void insert(iterator it, const_iterator first, const_iterator last) \
906 for(; first != last; ++first) \
907 Insert(it.m_node, (const_base_reference)*first); \
909 iterator erase(iterator it) \
911 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
912 DeleteNode(it.m_node); return next; \
914 iterator erase(iterator first, iterator last) \
916 iterator next = last; ++next; \
917 DeleteNodes(first.m_node, last.m_node); \
920 void clear() { Clear(); } \
921 void splice(iterator it, name& l, iterator first, iterator last) \
922 { insert(it, first, last); l.erase(first, last); } \
923 void splice(iterator it, name& l) \
924 { splice(it, l, l.begin(), l.end() ); } \
925 void splice(iterator it, name& l, iterator first) \
927 iterator tmp = first; ++tmp; \
928 if(it == first || it == tmp) return; \
929 insert(it, *first); \
932 void remove(const_reference v) \
933 { DeleteObject((const_base_reference)v); } \
936 /* void swap(name& l) \
938 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
939 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
940 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
941 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
942 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
946 #define WX_LIST_PTROP \
947 pointer_type operator->() const \
948 { return (pointer_type)m_node->GetDataPtr(); }
949 #define WX_LIST_PTROP_NONE
951 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
952 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
953 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
954 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
956 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
957 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
958 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
959 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
961 #define WX_DECLARE_LIST(elementtype, listname) \
962 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
963 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
964 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
965 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
966 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
968 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
969 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
970 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
972 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
973 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
975 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
976 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
977 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
979 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
980 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
981 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
982 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
983 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
984 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
986 // this macro must be inserted in your program after
987 // #include <wx/listimpl.cpp>
988 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
990 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
991 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
995 // ============================================================================
996 // now we can define classes 100% compatible with the old ones
997 // ============================================================================
999 // ----------------------------------------------------------------------------
1000 // commonly used list classes
1001 // ----------------------------------------------------------------------------
1003 #if defined(wxLIST_COMPATIBILITY)
1005 // inline compatibility functions
1009 // ----------------------------------------------------------------------------
1010 // wxNodeBase deprecated methods
1011 // ----------------------------------------------------------------------------
1013 inline wxNode
*wxNodeBase::Next() const { return (wxNode
*)GetNext(); }
1014 inline wxNode
*wxNodeBase::Previous() const { return (wxNode
*)GetPrevious(); }
1015 inline wxObject
*wxNodeBase::Data() const { return (wxObject
*)GetData(); }
1017 // ----------------------------------------------------------------------------
1018 // wxListBase deprecated methods
1019 // ----------------------------------------------------------------------------
1021 inline int wxListBase::Number() const { return (int)GetCount(); }
1022 inline wxNode
*wxListBase::First() const { return (wxNode
*)GetFirst(); }
1023 inline wxNode
*wxListBase::Last() const { return (wxNode
*)GetLast(); }
1024 inline wxNode
*wxListBase::Nth(size_t n
) const { return (wxNode
*)Item(n
); }
1025 inline wxListBase::operator wxList
&() const { return *(wxList
*)this; }
1029 // define this to make a lot of noise about use of the old wxList classes.
1030 //#define wxWARN_COMPAT_LIST_USE
1032 // ----------------------------------------------------------------------------
1033 // wxList compatibility class: in fact, it's a list of wxObjects
1034 // ----------------------------------------------------------------------------
1036 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1037 class WXDLLIMPEXP_BASE
);
1039 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1042 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1044 wxDEPRECATED( wxList(int key_type
) );
1046 wxList(int key_type
= wxKEY_NONE
);
1049 // this destructor is required for Darwin
1053 wxList
& operator=(const wxList
& list
)
1054 { (void) wxListBase::operator=(list
); return *this; }
1056 // compatibility methods
1057 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
1062 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1067 DECLARE_DYNAMIC_CLASS(wxList
)
1073 // -----------------------------------------------------------------------------
1074 // wxStringList class for compatibility with the old code
1075 // -----------------------------------------------------------------------------
1076 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1078 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1083 #ifdef wxWARN_COMPAT_LIST_USE
1085 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1088 wxStringList(const wxChar
*first
...);
1091 // copying the string list: the strings are copied, too (extremely
1093 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(TRUE
); DoCopy(other
); }
1094 wxStringList
& operator=(const wxStringList
& other
)
1095 { Clear(); DoCopy(other
); return *this; }
1098 // makes a copy of the string
1099 wxNode
*Add(const wxChar
*s
);
1101 // Append to beginning of list
1102 wxNode
*Prepend(const wxChar
*s
);
1104 bool Delete(const wxChar
*s
);
1106 wxChar
**ListToArray(bool new_copies
= FALSE
) const;
1107 bool Member(const wxChar
*s
) const;
1113 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1115 DECLARE_DYNAMIC_CLASS(wxStringList
)
1118 #else // if wxUSE_STL
1120 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLEXPORT
);
1122 class WXDLLEXPORT wxStringList
: public wxStringListBase
1125 compatibility_iterator
Append(wxChar
* s
)
1126 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Append(tmp
); }
1127 compatibility_iterator
Insert(wxChar
* s
)
1128 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Insert(tmp
); }
1129 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1133 return wxStringListBase::Insert(pos
, tmp
);
1135 compatibility_iterator
Add(const wxChar
* s
)
1136 { push_back(s
); return GetLast(); }
1137 compatibility_iterator
Prepend(const wxChar
* s
)
1138 { push_front(s
); return GetFirst(); }
1143 #endif // wxLIST_COMPATIBILITY
1145 // delete all list elements
1147 // NB: the class declaration of the list elements must be visible from the
1148 // place where you use this macro, otherwise the proper destructor may not
1149 // be called (a decent compiler should give a warning about it, but don't
1151 #define WX_CLEAR_LIST(type, list) \
1153 type::iterator it, en; \
1154 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \