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(__APPLE__) && \
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_X(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_X(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_X(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; } \
123 typedef struct compatibility_iterator citer; \
127 typedef std::list<elT>::iterator it; \
128 typedef compatibility_iterator citer; \
130 elT GetData() const \
132 citer* i = (citer*)this; \
133 return *(i->m_iter); \
135 citer GetNext() const \
137 citer* i = (citer*)this; \
138 it lit = i->m_iter; \
139 return citer( i->m_list, ++lit ); \
141 citer GetPrevious() const \
143 citer* i = (citer*)this; \
144 it lit = i->m_iter; \
145 return citer( i->m_list, ++lit ); \
147 void SetData( elT e ) \
149 citer* i = (citer*)this; \
156 iterator find( elT e ) \
159 for( it = begin(), en = end(); it != en; ++it ) \
167 citer Append( elT e ) { push_back( e ); return GetLast(); } \
168 void Clear() { clear(); } \
169 size_t GetCount() const { return size(); } \
170 citer GetFirst() const { return citer( this, ((liT*)this)->begin() ); } \
171 citer GetLast() const { return citer( this, --(((liT*)this)->end()) ); } \
172 bool IsEmpty() const { return empty(); } \
173 bool DeleteObject( elT e ) \
175 iterator it = find( e ); \
183 void Erase( const compatibility_iterator& it ) \
185 erase( it.m_iter ); \
187 citer Find( elT e ) const { return citer( this, ((liT*)this)->find( e ) ); } \
188 citer Member( elT e ) const { return Find( e ); } \
189 citer Insert( elT e ) \
190 { push_front( e ); return citer( this, begin() ); } \
191 citer Insert( size_t idx, elT e ) \
192 { return Insert( Item( idx ), e ); } \
193 citer Insert( citer idx, elT e ) \
194 { return citer( this, insert( idx.m_iter, e ) ); } \
195 citer Item( size_t idx ) const \
198 for( it = ((liT*)this)->begin(); idx; --idx ) \
200 return citer( this, it ); \
202 int IndexOf( elT e ) const \
204 const_iterator it, en; \
206 for( idx = 0, it = begin(), en = end(); it != en; ++it, ++idx ) \
209 return wxNOT_FOUND; \
213 #define WX_DECLARE_LIST(elementtype, listname) \
214 WX_DECLARE_LIST_X(elementtype, listname, class)
215 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
216 WX_DECLARE_LIST(elementtype, listname)
218 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
219 WX_DECLARE_LIST_X(elementtype, listname, class WXDLLEXPORT)
220 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
221 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
223 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
224 WX_DECLARE_LIST_X(elementtype, listname, class usergoo)
225 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
226 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
228 // this macro must be inserted in your program after
229 // #include <wx/listimpl.cpp>
230 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
232 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
233 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
235 #else // if !wxUSE_STL
237 // due to circular header dependencies this function has to be declared here
238 // (normally it's found in utils.h which includes itself list.h...)
239 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
241 class WXDLLEXPORT wxObjectListNode
;
242 typedef wxObjectListNode wxNode
;
244 // undef it to get rid of old, deprecated functions
245 #define wxLIST_COMPATIBILITY
247 // -----------------------------------------------------------------------------
248 // key stuff: a list may be optionally keyed on integer or string key
249 // -----------------------------------------------------------------------------
257 // a struct which may contain both types of keys
259 // implementation note: on one hand, this class allows to have only one function
260 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
261 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
262 // wxList::Find(const char *).
263 class WXDLLIMPEXP_BASE wxListKey
267 wxListKey() : m_keyType(wxKEY_NONE
)
269 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
270 { m_key
.integer
= i
; }
271 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
272 { m_key
.string
= wxStrdup(s
); }
273 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
274 { m_key
.string
= wxStrdup(s
.c_str()); }
277 wxKeyType
GetKeyType() const { return m_keyType
; }
278 const wxChar
*GetString() const
279 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
280 long GetNumber() const
281 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
284 // Note: implementation moved to list.cpp to prevent BC++ inline
285 // expansion warning.
286 bool operator==(wxListKeyValue value
) const ;
291 if ( m_keyType
== wxKEY_STRING
)
297 wxListKeyValue m_key
;
300 // -----------------------------------------------------------------------------
301 // wxNodeBase class is a (base for) node in a double linked list
302 // -----------------------------------------------------------------------------
304 WXDLLIMPEXP_DATA_BASE(extern wxListKey
) wxDefaultListKey
;
306 class WXDLLIMPEXP_BASE wxListBase
;
308 class WXDLLIMPEXP_BASE wxNodeBase
310 friend class wxListBase
;
313 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
314 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
315 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
317 const wxListKey
& key
= wxDefaultListKey
);
319 virtual ~wxNodeBase();
321 // FIXME no check is done that the list is really keyed on strings
322 const wxChar
*GetKeyString() const { return m_key
.string
; }
323 long GetKeyInteger() const { return m_key
.integer
; }
325 // Necessary for some existing code
326 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
327 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
329 #ifdef wxLIST_COMPATIBILITY
330 // compatibility methods, use Get* instead.
331 wxDEPRECATED( wxNode
*Next() const );
332 wxDEPRECATED( wxNode
*Previous() const );
333 wxDEPRECATED( wxObject
*Data() const );
334 #endif // wxLIST_COMPATIBILITY
337 // all these are going to be "overloaded" in the derived classes
338 wxNodeBase
*GetNext() const { return m_next
; }
339 wxNodeBase
*GetPrevious() const { return m_previous
; }
341 void *GetData() const { return m_data
; }
342 void SetData(void *data
) { m_data
= data
; }
344 // get 0-based index of this node within the list or wxNOT_FOUND
347 virtual void DeleteData() { }
349 // for wxList::iterator
350 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
352 // optional key stuff
353 wxListKeyValue m_key
;
355 void *m_data
; // user data
356 wxNodeBase
*m_next
, // next and previous nodes in the list
359 wxListBase
*m_list
; // list we belong to
361 DECLARE_NO_COPY_CLASS(wxNodeBase
)
364 // -----------------------------------------------------------------------------
365 // a double-linked list class
366 // -----------------------------------------------------------------------------
370 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
372 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
373 friend class wxHashTableBase
; // should be able to call untyped Find()
375 // common part of all ctors
376 void Init(wxKeyType keyType
= wxKEY_NONE
); // Must be declared before it's used (for VC++ 1.5)
378 // default ctor & dtor
379 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
381 virtual ~wxListBase();
384 // count of items in the list
385 size_t GetCount() const { return m_count
; }
387 // return TRUE if this list is empty
388 bool IsEmpty() const { return m_count
== 0; }
395 // instruct it to destroy user data when deleting nodes
396 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
398 // query if to delete
399 bool GetDeleteContents() const
400 { return m_destroy
; }
403 wxKeyType
GetKeyType() const
404 { return m_keyType
; }
406 // set the keytype (required by the serial code)
407 void SetKeyType(wxKeyType keyType
)
408 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
410 #ifdef wxLIST_COMPATIBILITY
411 // compatibility methods from old wxList
412 wxDEPRECATED( int Number() const ); // use GetCount instead.
413 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
414 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
415 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
417 // kludge for typesafe list migration in core classes.
418 wxDEPRECATED( operator wxList
&() const );
419 #endif // wxLIST_COMPATIBILITY
423 // all methods here are "overloaded" in derived classes to provide compile
424 // time type checking
426 // create a node for the list of this type
427 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
429 const wxListKey
& key
= wxDefaultListKey
) = 0;
431 // Can't access these from derived classes otherwise (bug in Salford C++?)
438 wxListBase(size_t count
, void *elements
[]);
439 // from a sequence of objects
440 wxListBase(void *object
, ... /* terminate with NULL */);
443 // copy ctor and assignment operator
444 wxListBase(const wxListBase
& list
) : wxObject()
445 { Init(); DoCopy(list
); }
446 wxListBase
& operator=(const wxListBase
& list
)
447 { Clear(); DoCopy(list
); return *this; }
449 // get list head/tail
450 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
451 wxNodeBase
*GetLast() const { return m_nodeLast
; }
453 // by (0-based) index
454 wxNodeBase
*Item(size_t index
) const;
456 // get the list item's data
457 void *operator[](size_t n
) const
459 wxNodeBase
*node
= Item(n
);
461 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
465 // append to end of list
466 wxNodeBase
*Prepend(void *object
)
467 { return (wxNodeBase
*)wxListBase::Insert(object
); }
468 // append to beginning of list
469 wxNodeBase
*Append(void *object
);
470 // insert a new item at the beginning of the list
471 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
472 // insert a new item at the given position
473 wxNodeBase
*Insert(size_t pos
, void *object
)
474 { return pos
== GetCount() ? Append(object
)
475 : Insert(Item(pos
), object
); }
476 // insert before given node or at front of list if prev == NULL
477 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
480 wxNodeBase
*Append(long key
, void *object
);
481 wxNodeBase
*Append(const wxChar
*key
, void *object
);
483 // removes node from the list but doesn't delete it (returns pointer
484 // to the node or NULL if it wasn't found in the list)
485 wxNodeBase
*DetachNode(wxNodeBase
*node
);
486 // delete element from list, returns FALSE if node not found
487 bool DeleteNode(wxNodeBase
*node
);
488 // finds object pointer and deletes node (and object if DeleteContents
489 // is on), returns FALSE if object not found
490 bool DeleteObject(void *object
);
492 // search (all return NULL if item not found)
494 wxNodeBase
*Find(void *object
) const;
497 wxNodeBase
*Find(const wxListKey
& key
) const;
499 // get 0-based index of object or wxNOT_FOUND
500 int IndexOf( void *object
) const;
502 // this function allows the sorting of arbitrary lists by giving
503 // a function to compare two list elements. The list is sorted in place.
504 void Sort(const wxSortCompareFunction compfunc
);
506 // functions for iterating over the list
507 void *FirstThat(wxListIterateFunction func
);
508 void ForEach(wxListIterateFunction func
);
509 void *LastThat(wxListIterateFunction func
);
511 // for STL interface, "last" points to one after the last node
512 // of the controlled sequence (NULL for the end of the list)
514 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
517 // common part of copy ctor and assignment operator
518 void DoCopy(const wxListBase
& list
);
519 // common part of all Append()s
520 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
521 // free node's data and node itself
522 void DoDeleteNode(wxNodeBase
*node
);
524 size_t m_count
; // number of elements in the list
525 bool m_destroy
; // destroy user data when deleting list items?
526 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
529 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
532 // -----------------------------------------------------------------------------
533 // macros for definition of "template" list type
534 // -----------------------------------------------------------------------------
536 // and now some heavy magic...
538 // declare a list type named 'name' and containing elements of type 'T *'
539 // (as a by product of macro expansion you also get wx##name##Node
540 // wxNode-derived type)
542 // implementation details:
543 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
544 // for the list of given type - this allows us to pass only the list name
545 // to WX_DEFINE_LIST() even if it needs both the name and the type
547 // 2. We redefine all non-type-safe wxList functions with type-safe versions
548 // which don't take any space (everything is inline), but bring compile
549 // time error checking.
551 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
552 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
553 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
554 // interesting capability to store polymorphic objects in the list and is
555 // particularly useful with, for example, "wxWindow *" list where the
556 // wxWindowBase pointers are put into the list, but wxWindow pointers are
557 // retrieved from it.
559 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
560 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
561 // it results in compiler warnings when this operator doesn't make sense
562 // (i.e. stored elements are not pointers)
564 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
565 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
566 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
568 classexp nodetype : public wxNodeBase \
571 nodetype(wxListBase *list = (wxListBase *)NULL, \
572 nodetype *previous = (nodetype *)NULL, \
573 nodetype *next = (nodetype *)NULL, \
574 T *data = (T *)NULL, \
575 const wxListKey& key = wxDefaultListKey) \
576 : wxNodeBase(list, previous, next, data, key) { } \
578 nodetype *GetNext() const \
579 { return (nodetype *)wxNodeBase::GetNext(); } \
580 nodetype *GetPrevious() const \
581 { return (nodetype *)wxNodeBase::GetPrevious(); } \
584 { return (T *)wxNodeBase::GetData(); } \
585 void SetData(T *data) \
586 { wxNodeBase::SetData(data); } \
588 virtual void DeleteData(); \
590 DECLARE_NO_COPY_CLASS(nodetype) \
593 classexp name : public wxListBase \
596 typedef nodetype Node; \
597 typedef Node* compatibility_iterator; \
599 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
601 name(size_t count, T *elements[]) \
602 : wxListBase(count, (void **)elements) { } \
604 name& operator=(const name& list) \
605 { (void) wxListBase::operator=(list); return *this; } \
607 nodetype *GetFirst() const \
608 { return (nodetype *)wxListBase::GetFirst(); } \
609 nodetype *GetLast() const \
610 { return (nodetype *)wxListBase::GetLast(); } \
612 nodetype *Item(size_t index) const \
613 { return (nodetype *)wxListBase::Item(index); } \
615 T *operator[](size_t index) const \
617 nodetype *node = Item(index); \
618 return node ? (T*)(node->GetData()) : (T*)NULL; \
621 nodetype *Append(Tbase *object) \
622 { return (nodetype *)wxListBase::Append(object); } \
623 nodetype *Insert(Tbase *object) \
624 { return (nodetype *)Insert((nodetype*)NULL, object); } \
625 nodetype *Insert(size_t pos, Tbase *object) \
626 { return (nodetype *)wxListBase::Insert(pos, object); } \
627 nodetype *Insert(nodetype *prev, Tbase *object) \
628 { return (nodetype *)wxListBase::Insert(prev, object); } \
630 nodetype *Append(long key, void *object) \
631 { return (nodetype *)wxListBase::Append(key, object); } \
632 nodetype *Append(const wxChar *key, void *object) \
633 { return (nodetype *)wxListBase::Append(key, object); } \
635 nodetype *DetachNode(nodetype *node) \
636 { return (nodetype *)wxListBase::DetachNode(node); } \
637 bool DeleteNode(nodetype *node) \
638 { return wxListBase::DeleteNode(node); } \
639 bool DeleteObject(Tbase *object) \
640 { return wxListBase::DeleteObject(object); } \
641 void Erase(compatibility_iterator it) \
642 { DeleteNode(it); } \
644 nodetype *Find(Tbase *object) const \
645 { return (nodetype *)wxListBase::Find(object); } \
647 virtual nodetype *Find(const wxListKey& key) const \
648 { return (nodetype *)wxListBase::Find(key); } \
650 int IndexOf(Tbase *object) const \
651 { return wxListBase::IndexOf(object); } \
653 void Sort(wxSortFuncFor_##name func) \
654 { wxListBase::Sort((wxSortCompareFunction)func); } \
657 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
659 const wxListKey& key = wxDefaultListKey) \
661 return new nodetype(this, \
662 (nodetype *)prev, (nodetype *)next, \
665 /* STL interface */ \
667 typedef size_t size_type; \
668 typedef int difference_type; \
669 typedef T* value_type; \
670 typedef Tbase* base_value_type; \
671 typedef value_type& reference; \
672 typedef const value_type& const_reference; \
673 typedef base_value_type& base_reference; \
674 typedef const base_value_type& const_base_reference; \
680 typedef nodetype Node; \
681 typedef iterator itor; \
682 typedef T* value_type; \
683 typedef value_type* ptr_type; \
684 typedef value_type& reference; \
689 typedef reference reference_type; \
690 typedef ptr_type pointer_type; \
692 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
693 iterator() : m_node(NULL), m_init(NULL) { } \
694 reference_type operator*() const \
695 { return *(pointer_type)m_node->GetDataPtr(); } \
697 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
698 itor operator++(int) \
699 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
702 m_node = m_node ? m_node->GetPrevious() : m_init; \
705 itor operator--(int) \
708 m_node = m_node ? m_node->GetPrevious() : m_init; \
711 bool operator!=(const itor& it) const \
712 { return it.m_node != m_node; } \
713 bool operator==(const itor& it) const \
714 { return it.m_node == m_node; } \
716 class const_iterator \
720 typedef nodetype Node; \
721 typedef T* value_type; \
722 typedef const value_type& const_reference; \
723 typedef const_iterator itor; \
724 typedef value_type* ptr_type; \
729 typedef const_reference reference_type; \
730 typedef const ptr_type pointer_type; \
732 const_iterator(Node* node, Node* init) \
733 : m_node(node), m_init(init) { } \
734 const_iterator() : m_node(NULL), m_init(NULL) { } \
735 const_iterator(const iterator& it) \
736 : m_node(it.m_node), m_init(it.m_init) { } \
737 reference_type operator*() const \
738 { return *(pointer_type)m_node->GetDataPtr(); } \
740 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
741 itor operator++(int) \
742 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
745 m_node = m_node ? m_node->GetPrevious() : m_init; \
748 itor operator--(int) \
751 m_node = m_node ? m_node->GetPrevious() : m_init; \
754 bool operator!=(const itor& it) const \
755 { return it.m_node != m_node; } \
756 bool operator==(const itor& it) const \
757 { return it.m_node == m_node; } \
759 class reverse_iterator \
763 typedef nodetype Node; \
764 typedef T* value_type; \
765 typedef reverse_iterator itor; \
766 typedef value_type* ptr_type; \
767 typedef value_type& reference; \
772 typedef reference reference_type; \
773 typedef ptr_type pointer_type; \
775 reverse_iterator(Node* node, Node* init) \
776 : m_node(node), m_init(init) { } \
777 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
778 reference_type operator*() const \
779 { return *(pointer_type)m_node->GetDataPtr(); } \
782 { m_node = m_node->GetPrevious(); return *this; } \
783 itor operator++(int) \
784 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
786 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
787 itor operator--(int) \
790 m_node = m_node ? m_node->GetNext() : m_init; \
793 bool operator!=(const itor& it) const \
794 { return it.m_node != m_node; } \
795 bool operator==(const itor& it) const \
796 { return it.m_node == m_node; } \
798 class const_reverse_iterator \
802 typedef nodetype Node; \
803 typedef T* value_type; \
804 typedef const_reverse_iterator itor; \
805 typedef value_type* ptr_type; \
806 typedef const value_type& const_reference; \
811 typedef const_reference reference_type; \
812 typedef const ptr_type pointer_type; \
814 const_reverse_iterator(Node* node, Node* init) \
815 : m_node(node), m_init(init) { } \
816 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
817 const_reverse_iterator(const reverse_iterator& it) \
818 : m_node(it.m_node), m_init(it.m_init) { } \
819 reference_type operator*() const \
820 { return *(pointer_type)m_node->GetDataPtr(); } \
823 { m_node = m_node->GetPrevious(); return *this; } \
824 itor operator++(int) \
825 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
827 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
828 itor operator--(int) \
831 m_node = m_node ? m_node->GetNext() : m_init; \
834 bool operator!=(const itor& it) const \
835 { return it.m_node != m_node; } \
836 bool operator==(const itor& it) const \
837 { return it.m_node == m_node; } \
840 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
842 name(const_iterator first, const_iterator last) \
843 { assign(first, last); } \
844 iterator begin() { return iterator(GetFirst(), GetLast()); } \
845 const_iterator begin() const \
846 { return const_iterator(GetFirst(), GetLast()); } \
847 iterator end() { return iterator(NULL, GetLast()); } \
848 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
849 reverse_iterator rbegin() \
850 { return reverse_iterator(GetLast(), GetFirst()); } \
851 const_reverse_iterator rbegin() const \
852 { return const_reverse_iterator(GetLast(), GetFirst()); } \
853 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
854 const_reverse_iterator rend() const \
855 { return const_reverse_iterator(NULL, GetFirst()); } \
856 void resize(size_type n, value_type v = value_type()) \
859 for(; n < size(); pop_back()); \
860 else if(n > size()) \
861 for(; n > size(); push_back(v)); \
863 size_type size() const { return GetCount(); } \
864 size_type max_size() const { return INT_MAX; } \
865 bool empty() const { return IsEmpty(); } \
866 reference front() { return *begin(); } \
867 const_reference front() const { return *begin(); } \
868 reference back() { return *--end(); } \
869 const_reference back() const { return *--end(); } \
870 void push_front(const_reference v = value_type()) \
871 { Insert(GetFirst(), (const_base_reference)v); } \
872 void pop_front() { DeleteNode(GetFirst()); } \
873 void push_back(const_reference v = value_type()) \
874 { Append((const_base_reference)v); } \
875 void pop_back() { DeleteNode(GetLast()); } \
876 void assign(const_iterator first, const_iterator last) \
879 for(; first != last; ++first) \
880 Append((const_base_reference)*first); \
882 void assign(size_type n, const_reference v = value_type()) \
885 for(size_type i = 0; i < n; ++i) \
886 Append((const_base_reference)v); \
888 iterator insert(iterator it, const_reference v = value_type()) \
890 Insert(it.m_node, (const_base_reference)v); \
891 return iterator(it.m_node->GetPrevious(), GetLast()); \
893 void insert(iterator it, size_type n, const_reference v = value_type())\
895 for(size_type i = 0; i < n; ++i) \
896 Insert(it.m_node, (const_base_reference)v); \
898 void insert(iterator it, const_iterator first, const_iterator last) \
900 for(; first != last; ++first) \
901 Insert(it.m_node, (const_base_reference)*first); \
903 iterator erase(iterator it) \
905 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
906 DeleteNode(it.m_node); return next; \
908 iterator erase(iterator first, iterator last) \
910 iterator next = last; ++next; \
911 DeleteNodes(first.m_node, last.m_node); \
914 void clear() { Clear(); } \
915 void splice(iterator it, name& l, iterator first, iterator last) \
916 { insert(it, first, last); l.erase(first, last); } \
917 void splice(iterator it, name& l) \
918 { splice(it, l, l.begin(), l.end() ); } \
919 void splice(iterator it, name& l, iterator first) \
921 iterator tmp = first; ++tmp; \
922 if(it == first || it == tmp) return; \
923 insert(it, *first); \
926 void remove(const_reference v) \
927 { DeleteObject((const_base_reference)v); } \
930 /* void swap(name& l) \
932 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
933 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
934 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
935 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
936 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
940 #define WX_LIST_PTROP \
941 pointer_type operator->() const \
942 { return (pointer_type)m_node->GetDataPtr(); }
943 #define WX_LIST_PTROP_NONE
945 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
946 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
947 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
948 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
950 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
951 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
952 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
953 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
955 #define WX_DECLARE_LIST(elementtype, listname) \
956 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
957 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
958 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
959 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
960 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
962 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
963 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
964 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
965 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
966 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
967 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
969 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
970 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
971 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
972 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
973 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
974 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
976 // this macro must be inserted in your program after
977 // #include <wx/listimpl.cpp>
978 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
980 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
981 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
985 // ============================================================================
986 // now we can define classes 100% compatible with the old ones
987 // ============================================================================
989 // ----------------------------------------------------------------------------
990 // commonly used list classes
991 // ----------------------------------------------------------------------------
993 #if defined(wxLIST_COMPATIBILITY)
995 // inline compatibility functions
999 // ----------------------------------------------------------------------------
1000 // wxNodeBase deprecated methods
1001 // ----------------------------------------------------------------------------
1003 inline wxNode
*wxNodeBase::Next() const { return (wxNode
*)GetNext(); }
1004 inline wxNode
*wxNodeBase::Previous() const { return (wxNode
*)GetPrevious(); }
1005 inline wxObject
*wxNodeBase::Data() const { return (wxObject
*)GetData(); }
1007 // ----------------------------------------------------------------------------
1008 // wxListBase deprecated methods
1009 // ----------------------------------------------------------------------------
1011 inline int wxListBase::Number() const { return (int)GetCount(); }
1012 inline wxNode
*wxListBase::First() const { return (wxNode
*)GetFirst(); }
1013 inline wxNode
*wxListBase::Last() const { return (wxNode
*)GetLast(); }
1014 inline wxNode
*wxListBase::Nth(size_t n
) const { return (wxNode
*)Item(n
); }
1015 inline wxListBase::operator wxList
&() const { return *(wxList
*)this; }
1019 // define this to make a lot of noise about use of the old wxList classes.
1020 //#define wxWARN_COMPAT_LIST_USE
1022 // ----------------------------------------------------------------------------
1023 // wxList compatibility class: in fact, it's a list of wxObjects
1024 // ----------------------------------------------------------------------------
1026 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1027 class WXDLLIMPEXP_BASE
);
1029 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1032 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1033 wxDEPRECATED( wxList(int key_type
= wxKEY_NONE
) );
1035 wxList(int key_type
= wxKEY_NONE
);
1038 // this destructor is required for Darwin
1042 wxList
& operator=(const wxList
& list
)
1043 { (void) wxListBase::operator=(list
); return *this; }
1045 // compatibility methods
1046 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
1051 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1056 DECLARE_DYNAMIC_CLASS(wxList
)
1062 // -----------------------------------------------------------------------------
1063 // wxStringList class for compatibility with the old code
1064 // -----------------------------------------------------------------------------
1065 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1067 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1072 #ifdef wxWARN_COMPAT_LIST_USE
1073 wxDEPRECATED( wxStringList() );
1074 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1077 wxStringList(const wxChar
*first
...);
1080 // copying the string list: the strings are copied, too (extremely
1082 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(TRUE
); DoCopy(other
); }
1083 wxStringList
& operator=(const wxStringList
& other
)
1084 { Clear(); DoCopy(other
); return *this; }
1087 // makes a copy of the string
1088 wxNode
*Add(const wxChar
*s
);
1090 // Append to beginning of list
1091 wxNode
*Prepend(const wxChar
*s
);
1093 bool Delete(const wxChar
*s
);
1095 wxChar
**ListToArray(bool new_copies
= FALSE
) const;
1096 bool Member(const wxChar
*s
) const;
1102 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1104 DECLARE_DYNAMIC_CLASS(wxStringList
)
1107 #else // if wxUSE_STL
1109 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLEXPORT
);
1111 class WXDLLEXPORT wxStringList
: public wxStringListBase
1114 compatibility_iterator
Append(wxChar
* s
)
1115 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Append(tmp
); }
1116 compatibility_iterator
Insert(wxChar
* s
)
1117 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Insert(tmp
); }
1118 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1122 return wxStringListBase::Insert(pos
, tmp
);
1124 compatibility_iterator
Add(const wxChar
* s
)
1125 { push_back(s
); return GetLast(); }
1126 compatibility_iterator
Prepend(const wxChar
* s
)
1127 { push_front(s
); return GetFirst(); }
1132 #endif // wxLIST_COMPATIBILITY
1134 // delete all list elements
1136 // NB: the class declaration of the list elements must be visible from the
1137 // place where you use this macro, otherwise the proper destructor may not
1138 // be called (a decent compiler should give a warning about it, but don't
1140 #define WX_CLEAR_LIST(type, list) \
1142 type::iterator it, en; \
1143 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \