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)
89 #define WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
90 WX_DECLARE_LIST_X(elT, liT, decl)
92 #define WX_DECLARE_LIST_X(elT, liT, decl) \
93 WX_DECLARE_LIST_XO(elT*, liT, decl)
95 #define WX_DECLARE_LIST_XO(elT, liT, decl) \
96 decl liT : public std::list<elT> \
101 struct compatibility_iterator \
103 typedef std::list<elT>::iterator iterator; \
107 operator bool() const \
108 { return m_list && m_iter != m_list->end(); } \
109 bool operator !() const \
110 { return !m_list || m_iter == m_list->end(); } \
111 compatibility_iterator( const liT* li, iterator it ) \
112 : m_iter( it ), m_list( (liT*)li ) {} \
113 compatibility_iterator( liT* li, iterator it ) \
114 : m_iter( it ), m_list( li ) {} \
115 compatibility_iterator() : m_list( NULL ) { } \
116 dummy* operator->() { return (dummy*)this; } \
117 const dummy* operator->() const { return (const dummy*)this; } \
119 typedef struct compatibility_iterator citer; \
123 typedef std::list<elT>::iterator it; \
124 typedef compatibility_iterator citer; \
126 elT GetData() const \
128 citer* i = (citer*)this; \
129 return *(i->m_iter); \
131 citer GetNext() const \
133 citer* i = (citer*)this; \
134 it lit = i->m_iter; \
135 return citer( i->m_list, ++lit ); \
137 citer GetPrevious() const \
139 citer* i = (citer*)this; \
140 it lit = i->m_iter; \
141 return citer( i->m_list, ++lit ); \
143 void SetData( elT e ) \
145 citer* i = (citer*)this; \
152 iterator find( elT e ) \
155 for( it = begin(), en = end(); it != en; ++it ) \
163 citer Append( elT e ) { push_back( e ); return GetLast(); } \
164 void Clear() { clear(); } \
165 size_t GetCount() const { return size(); } \
166 citer GetFirst() const { return citer( this, ((liT*)this)->begin() ); } \
167 citer GetLast() const { return citer( this, --(((liT*)this)->end()) ); } \
168 bool IsEmpty() const { return empty(); } \
169 bool DeleteObject( elT e ) \
171 iterator it = find( e ); \
179 void Erase( const compatibility_iterator& it ) \
181 erase( it.m_iter ); \
183 citer Find( elT e ) const { return citer( this, ((liT*)this)->find( e ) ); } \
184 citer Member( elT e ) const { return Find( e ); } \
185 citer Insert( elT e ) \
186 { push_front( e ); return citer( this, begin() ); } \
187 citer Insert( size_t idx, elT e ) \
188 { return Insert( Item( idx ), e ); } \
189 citer Insert( citer idx, elT e ) \
190 { return citer( this, insert( idx.m_iter, e ) ); } \
191 citer Item( size_t idx ) const \
194 for( it = ((liT*)this)->begin(); idx; --idx ) \
196 return citer( this, it ); \
198 int IndexOf( elT e ) const \
200 const_iterator it, en; \
202 for( idx = 0, it = begin(), en = end(); it != en; ++it, ++idx ) \
205 return wxNOT_FOUND; \
209 #define WX_DECLARE_LIST(elementtype, listname) \
210 WX_DECLARE_LIST_X(elementtype, listname, class)
212 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
213 WX_DECLARE_LIST_X(elementtype, listname, class WXDLLEXPORT)
215 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
216 WX_DECLARE_LIST_X(elementtype, listname, class usergoo)
218 // this macro must be inserted in your program after
219 // #include <wx/listimpl.cpp>
220 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
222 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
223 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
225 #else // if !wxUSE_STL
227 // due to circular header dependencies this function has to be declared here
228 // (normally it's found in utils.h which includes itself list.h...)
229 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
231 class WXDLLEXPORT wxObjectListNode
;
232 typedef wxObjectListNode wxNode
;
234 // undef it to get rid of old, deprecated functions
235 #define wxLIST_COMPATIBILITY
237 // -----------------------------------------------------------------------------
238 // key stuff: a list may be optionally keyed on integer or string key
239 // -----------------------------------------------------------------------------
247 // a struct which may contain both types of keys
249 // implementation note: on one hand, this class allows to have only one function
250 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
251 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
252 // wxList::Find(const char *).
253 class WXDLLIMPEXP_BASE wxListKey
257 wxListKey() : m_keyType(wxKEY_NONE
)
259 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
260 { m_key
.integer
= i
; }
261 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
262 { m_key
.string
= wxStrdup(s
); }
263 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
264 { m_key
.string
= wxStrdup(s
.c_str()); }
267 wxKeyType
GetKeyType() const { return m_keyType
; }
268 const wxChar
*GetString() const
269 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
270 long GetNumber() const
271 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
274 // Note: implementation moved to list.cpp to prevent BC++ inline
275 // expansion warning.
276 bool operator==(wxListKeyValue value
) const ;
281 if ( m_keyType
== wxKEY_STRING
)
287 wxListKeyValue m_key
;
290 // -----------------------------------------------------------------------------
291 // wxNodeBase class is a (base for) node in a double linked list
292 // -----------------------------------------------------------------------------
294 WXDLLIMPEXP_DATA_BASE(extern wxListKey
) wxDefaultListKey
;
296 class WXDLLIMPEXP_BASE wxListBase
;
298 class WXDLLIMPEXP_BASE wxNodeBase
300 friend class wxListBase
;
303 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
304 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
305 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
307 const wxListKey
& key
= wxDefaultListKey
);
309 virtual ~wxNodeBase();
311 // FIXME no check is done that the list is really keyed on strings
312 const wxChar
*GetKeyString() const { return m_key
.string
; }
313 long GetKeyInteger() const { return m_key
.integer
; }
315 // Necessary for some existing code
316 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
317 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
319 #ifdef wxLIST_COMPATIBILITY
320 // compatibility methods, use Get* instead.
321 wxDEPRECATED( wxNode
*Next() const );
322 wxDEPRECATED( wxNode
*Previous() const );
323 wxDEPRECATED( wxObject
*Data() const );
324 #endif // wxLIST_COMPATIBILITY
327 // all these are going to be "overloaded" in the derived classes
328 wxNodeBase
*GetNext() const { return m_next
; }
329 wxNodeBase
*GetPrevious() const { return m_previous
; }
331 void *GetData() const { return m_data
; }
332 void SetData(void *data
) { m_data
= data
; }
334 // get 0-based index of this node within the list or wxNOT_FOUND
337 virtual void DeleteData() { }
339 // for wxList::iterator
340 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
342 // optional key stuff
343 wxListKeyValue m_key
;
345 void *m_data
; // user data
346 wxNodeBase
*m_next
, // next and previous nodes in the list
349 wxListBase
*m_list
; // list we belong to
351 DECLARE_NO_COPY_CLASS(wxNodeBase
)
354 // -----------------------------------------------------------------------------
355 // a double-linked list class
356 // -----------------------------------------------------------------------------
360 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
362 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
363 friend class wxHashTableBase
; // should be able to call untyped Find()
365 // common part of all ctors
366 void Init(wxKeyType keyType
= wxKEY_NONE
); // Must be declared before it's used (for VC++ 1.5)
368 // default ctor & dtor
369 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
371 virtual ~wxListBase();
374 // count of items in the list
375 size_t GetCount() const { return m_count
; }
377 // return TRUE if this list is empty
378 bool IsEmpty() const { return m_count
== 0; }
385 // instruct it to destroy user data when deleting nodes
386 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
388 // query if to delete
389 bool GetDeleteContents() const
390 { return m_destroy
; }
393 wxKeyType
GetKeyType() const
394 { return m_keyType
; }
396 // set the keytype (required by the serial code)
397 void SetKeyType(wxKeyType keyType
)
398 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
400 #ifdef wxLIST_COMPATIBILITY
401 // compatibility methods from old wxList
402 wxDEPRECATED( int Number() const ); // use GetCount instead.
403 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
404 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
405 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
407 // kludge for typesafe list migration in core classes.
408 wxDEPRECATED( operator wxList
&() const );
409 #endif // wxLIST_COMPATIBILITY
413 // all methods here are "overloaded" in derived classes to provide compile
414 // time type checking
416 // create a node for the list of this type
417 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
419 const wxListKey
& key
= wxDefaultListKey
) = 0;
421 // Can't access these from derived classes otherwise (bug in Salford C++?)
428 wxListBase(size_t count
, void *elements
[]);
429 // from a sequence of objects
430 wxListBase(void *object
, ... /* terminate with NULL */);
433 // copy ctor and assignment operator
434 wxListBase(const wxListBase
& list
) : wxObject()
435 { Init(); DoCopy(list
); }
436 wxListBase
& operator=(const wxListBase
& list
)
437 { Clear(); DoCopy(list
); return *this; }
439 // get list head/tail
440 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
441 wxNodeBase
*GetLast() const { return m_nodeLast
; }
443 // by (0-based) index
444 wxNodeBase
*Item(size_t index
) const;
446 // get the list item's data
447 void *operator[](size_t n
) const
449 wxNodeBase
*node
= Item(n
);
451 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
455 // append to end of list
456 wxNodeBase
*Prepend(void *object
)
457 { return (wxNodeBase
*)wxListBase::Insert(object
); }
458 // append to beginning of list
459 wxNodeBase
*Append(void *object
);
460 // insert a new item at the beginning of the list
461 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
462 // insert a new item at the given position
463 wxNodeBase
*Insert(size_t pos
, void *object
)
464 { return pos
== GetCount() ? Append(object
)
465 : Insert(Item(pos
), object
); }
466 // insert before given node or at front of list if prev == NULL
467 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
470 wxNodeBase
*Append(long key
, void *object
);
471 wxNodeBase
*Append(const wxChar
*key
, void *object
);
473 // removes node from the list but doesn't delete it (returns pointer
474 // to the node or NULL if it wasn't found in the list)
475 wxNodeBase
*DetachNode(wxNodeBase
*node
);
476 // delete element from list, returns FALSE if node not found
477 bool DeleteNode(wxNodeBase
*node
);
478 // finds object pointer and deletes node (and object if DeleteContents
479 // is on), returns FALSE if object not found
480 bool DeleteObject(void *object
);
482 // search (all return NULL if item not found)
484 wxNodeBase
*Find(void *object
) const;
487 wxNodeBase
*Find(const wxListKey
& key
) const;
489 // get 0-based index of object or wxNOT_FOUND
490 int IndexOf( void *object
) const;
492 // this function allows the sorting of arbitrary lists by giving
493 // a function to compare two list elements. The list is sorted in place.
494 void Sort(const wxSortCompareFunction compfunc
);
496 // functions for iterating over the list
497 void *FirstThat(wxListIterateFunction func
);
498 void ForEach(wxListIterateFunction func
);
499 void *LastThat(wxListIterateFunction func
);
501 // for STL interface, "last" points to one after the last node
502 // of the controlled sequence (NULL for the end of the list)
504 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
507 // common part of copy ctor and assignment operator
508 void DoCopy(const wxListBase
& list
);
509 // common part of all Append()s
510 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
511 // free node's data and node itself
512 void DoDeleteNode(wxNodeBase
*node
);
514 size_t m_count
; // number of elements in the list
515 bool m_destroy
; // destroy user data when deleting list items?
516 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
519 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
522 // -----------------------------------------------------------------------------
523 // macros for definition of "template" list type
524 // -----------------------------------------------------------------------------
526 // and now some heavy magic...
528 // declare a list type named 'name' and containing elements of type 'T *'
529 // (as a by product of macro expansion you also get wx##name##Node
530 // wxNode-derived type)
532 // implementation details:
533 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
534 // for the list of given type - this allows us to pass only the list name
535 // to WX_DEFINE_LIST() even if it needs both the name and the type
537 // 2. We redefine all non-type-safe wxList functions with type-safe versions
538 // which don't take any space (everything is inline), but bring compile
539 // time error checking.
541 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
542 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
543 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
544 // interesting capability to store polymorphic objects in the list and is
545 // particularly useful with, for example, "wxWindow *" list where the
546 // wxWindowBase pointers are put into the list, but wxWindow pointers are
547 // retrieved from it.
549 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
550 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
552 classexp nodetype : public wxNodeBase \
555 nodetype(wxListBase *list = (wxListBase *)NULL, \
556 nodetype *previous = (nodetype *)NULL, \
557 nodetype *next = (nodetype *)NULL, \
558 T *data = (T *)NULL, \
559 const wxListKey& key = wxDefaultListKey) \
560 : wxNodeBase(list, previous, next, data, key) { } \
562 nodetype *GetNext() const \
563 { return (nodetype *)wxNodeBase::GetNext(); } \
564 nodetype *GetPrevious() const \
565 { return (nodetype *)wxNodeBase::GetPrevious(); } \
568 { return (T *)wxNodeBase::GetData(); } \
569 void SetData(T *data) \
570 { wxNodeBase::SetData(data); } \
572 virtual void DeleteData(); \
575 classexp name : public wxListBase \
578 typedef nodetype Node; \
579 typedef Node* compatibility_iterator; \
581 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
583 name(size_t count, T *elements[]) \
584 : wxListBase(count, (void **)elements) { } \
586 name& operator=(const name& list) \
587 { (void) wxListBase::operator=(list); return *this; } \
589 nodetype *GetFirst() const \
590 { return (nodetype *)wxListBase::GetFirst(); } \
591 nodetype *GetLast() const \
592 { return (nodetype *)wxListBase::GetLast(); } \
594 nodetype *Item(size_t index) const \
595 { return (nodetype *)wxListBase::Item(index); } \
597 T *operator[](size_t index) const \
599 nodetype *node = Item(index); \
600 return node ? (T*)(node->GetData()) : (T*)NULL; \
603 nodetype *Append(Tbase *object) \
604 { return (nodetype *)wxListBase::Append(object); } \
605 nodetype *Insert(Tbase *object) \
606 { return (nodetype *)Insert((nodetype*)NULL, object); } \
607 nodetype *Insert(size_t pos, Tbase *object) \
608 { return (nodetype *)wxListBase::Insert(pos, object); } \
609 nodetype *Insert(nodetype *prev, Tbase *object) \
610 { return (nodetype *)wxListBase::Insert(prev, object); } \
612 nodetype *Append(long key, void *object) \
613 { return (nodetype *)wxListBase::Append(key, object); } \
614 nodetype *Append(const wxChar *key, void *object) \
615 { return (nodetype *)wxListBase::Append(key, object); } \
617 nodetype *DetachNode(nodetype *node) \
618 { return (nodetype *)wxListBase::DetachNode(node); } \
619 bool DeleteNode(nodetype *node) \
620 { return wxListBase::DeleteNode(node); } \
621 bool DeleteObject(Tbase *object) \
622 { return wxListBase::DeleteObject(object); } \
623 void Erase(compatibility_iterator it) \
624 { DeleteNode(it); } \
626 nodetype *Find(Tbase *object) const \
627 { return (nodetype *)wxListBase::Find(object); } \
629 virtual nodetype *Find(const wxListKey& key) const \
630 { return (nodetype *)wxListBase::Find(key); } \
632 int IndexOf(Tbase *object) const \
633 { return wxListBase::IndexOf(object); } \
635 void Sort(wxSortFuncFor_##name func) \
636 { wxListBase::Sort((wxSortCompareFunction)func); } \
639 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
641 const wxListKey& key = wxDefaultListKey) \
643 return new nodetype(this, \
644 (nodetype *)prev, (nodetype *)next, \
647 /* STL interface */ \
649 typedef size_t size_type; \
650 typedef int difference_type; \
651 typedef T* value_type; \
652 typedef Tbase* base_value_type; \
653 typedef value_type& reference; \
654 typedef const value_type& const_reference; \
655 typedef base_value_type& base_reference; \
656 typedef const base_value_type& const_base_reference; \
662 typedef nodetype Node; \
663 typedef iterator itor; \
664 typedef T* value_type; \
665 typedef value_type* ptr_type; \
666 typedef value_type& reference; \
671 typedef reference reference_type; \
672 typedef ptr_type pointer_type; \
674 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
675 iterator() : m_node(NULL), m_init(NULL) { } \
676 reference_type operator*() const \
677 { return *(pointer_type)m_node->GetDataPtr(); } \
678 pointer_type operator->() const \
679 { return (pointer_type)m_node->GetDataPtr(); } \
680 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
681 itor operator++(int) \
682 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
685 m_node = m_node ? m_node->GetPrevious() : m_init; \
688 itor operator--(int) \
691 m_node = m_node ? m_node->GetPrevious() : m_init; \
694 bool operator!=(const itor& it) const \
695 { return it.m_node != m_node; } \
696 bool operator==(const itor& it) const \
697 { return it.m_node == m_node; } \
699 class const_iterator \
703 typedef nodetype Node; \
704 typedef T* value_type; \
705 typedef const value_type& const_reference; \
706 typedef const_iterator itor; \
707 typedef value_type* ptr_type; \
712 typedef const_reference reference_type; \
713 typedef const ptr_type pointer_type; \
715 const_iterator(Node* node, Node* init) \
716 : m_node(node), m_init(init) { } \
717 const_iterator() : m_node(NULL), m_init(NULL) { } \
718 const_iterator(const iterator& it) \
719 : m_node(it.m_node), m_init(it.m_init) { } \
720 reference_type operator*() const \
721 { return *(pointer_type)m_node->GetDataPtr(); } \
722 pointer_type operator->() const \
723 { return (pointer_type)m_node->GetDataPtr(); } \
724 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
725 itor operator++(int) \
726 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
729 m_node = m_node ? m_node->GetPrevious() : m_init; \
732 itor operator--(int) \
735 m_node = m_node ? m_node->GetPrevious() : m_init; \
738 bool operator!=(const itor& it) const \
739 { return it.m_node != m_node; } \
740 bool operator==(const itor& it) const \
741 { return it.m_node == m_node; } \
743 class reverse_iterator \
747 typedef nodetype Node; \
748 typedef T* value_type; \
749 typedef reverse_iterator itor; \
750 typedef value_type* ptr_type; \
751 typedef value_type& reference; \
756 typedef reference reference_type; \
757 typedef ptr_type pointer_type; \
759 reverse_iterator(Node* node, Node* init) \
760 : m_node(node), m_init(init) { } \
761 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
762 reference_type operator*() const \
763 { return *(pointer_type)m_node->GetDataPtr(); } \
764 pointer_type operator->() const \
765 { return (pointer_type)m_node->GetDataPtr(); } \
767 { m_node = m_node->GetPrevious(); return *this; } \
768 itor operator++(int) \
769 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
771 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
772 itor operator--(int) \
775 m_node = m_node ? m_node->GetNext() : m_init; \
778 bool operator!=(const itor& it) const \
779 { return it.m_node != m_node; } \
780 bool operator==(const itor& it) const \
781 { return it.m_node == m_node; } \
783 class const_reverse_iterator \
787 typedef nodetype Node; \
788 typedef T* value_type; \
789 typedef const_reverse_iterator itor; \
790 typedef value_type* ptr_type; \
791 typedef const value_type& const_reference; \
796 typedef const_reference reference_type; \
797 typedef const ptr_type pointer_type; \
799 const_reverse_iterator(Node* node, Node* init) \
800 : m_node(node), m_init(init) { } \
801 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
802 const_reverse_iterator(const reverse_iterator& it) \
803 : m_node(it.m_node), m_init(it.m_init) { } \
804 reference_type operator*() const \
805 { return *(pointer_type)m_node->GetDataPtr(); } \
806 pointer_type operator->() const \
807 { return (pointer_type)m_node->GetDataPtr(); } \
809 { m_node = m_node->GetPrevious(); return *this; } \
810 itor operator++(int) \
811 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
813 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
814 itor operator--(int) \
817 m_node = m_node ? m_node->GetNext() : m_init; \
820 bool operator!=(const itor& it) const \
821 { return it.m_node != m_node; } \
822 bool operator==(const itor& it) const \
823 { return it.m_node == m_node; } \
826 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
828 name(const_iterator first, const_iterator last) \
829 { assign(first, last); } \
830 iterator begin() { return iterator(GetFirst(), GetLast()); } \
831 const_iterator begin() const \
832 { return const_iterator(GetFirst(), GetLast()); } \
833 iterator end() { return iterator(NULL, GetLast()); } \
834 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
835 reverse_iterator rbegin() \
836 { return reverse_iterator(GetLast(), GetFirst()); } \
837 const_reverse_iterator rbegin() const \
838 { return const_reverse_iterator(GetLast(), GetFirst()); } \
839 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
840 const_reverse_iterator rend() const \
841 { return const_reverse_iterator(NULL, GetFirst()); } \
842 void resize(size_type n, value_type v = value_type()) \
845 for(; n < size(); pop_back()); \
846 else if(n > size()) \
847 for(; n > size(); push_back(v)); \
849 size_type size() const { return GetCount(); } \
850 size_type max_size() const { return INT_MAX; } \
851 bool empty() const { return IsEmpty(); } \
852 reference front() { return *begin(); } \
853 const_reference front() const { return *begin(); } \
854 reference back() { return *--end(); } \
855 const_reference back() const { return *--end(); } \
856 void push_front(const_reference v = value_type()) \
857 { Insert(GetFirst(), (const_base_reference)v); } \
858 void pop_front() { DeleteNode(GetFirst()); } \
859 void push_back(const_reference v = value_type()) \
860 { Append((const_base_reference)v); } \
861 void pop_back() { DeleteNode(GetLast()); } \
862 void assign(const_iterator first, const_iterator last) \
865 for(; first != last; ++first) \
866 Append((const_base_reference)*first); \
868 void assign(size_type n, const_reference v = value_type()) \
871 for(size_type i = 0; i < n; ++i) \
872 Append((const_base_reference)v); \
874 iterator insert(iterator it, const_reference v = value_type()) \
876 Insert(it.m_node, (const_base_reference)v); \
877 return iterator(it.m_node->GetPrevious(), GetLast()); \
879 void insert(iterator it, size_type n, const_reference v = value_type())\
881 for(size_type i = 0; i < n; ++i) \
882 Insert(it.m_node, (const_base_reference)v); \
884 void insert(iterator it, const_iterator first, const_iterator last) \
886 for(; first != last; ++first) \
887 Insert(it.m_node, (const_base_reference)*first); \
889 iterator erase(iterator it) \
891 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
892 DeleteNode(it.m_node); return next; \
894 iterator erase(iterator first, iterator last) \
896 iterator next = last; ++next; \
897 DeleteNodes(first.m_node, last.m_node); \
900 void clear() { Clear(); } \
901 void splice(iterator it, name& l, iterator first, iterator last) \
902 { insert(it, first, last); l.erase(first, last); } \
903 void splice(iterator it, name& l) \
904 { splice(it, l, l.begin(), l.end() ); } \
905 void splice(iterator it, name& l, iterator first) \
907 iterator tmp = first; ++tmp; \
908 if(it == first || it == tmp) return; \
909 insert(it, *first); \
912 void remove(const_reference v) \
913 { DeleteObject((const_base_reference)v); } \
916 /* void swap(name& l) \
918 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
919 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
920 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
921 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
922 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
926 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
927 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
929 #define WX_DECLARE_LIST(elementtype, listname) \
930 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
931 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
933 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
934 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
935 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
937 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
938 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
939 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
941 // this macro must be inserted in your program after
942 // #include <wx/listimpl.cpp>
943 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
945 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
946 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
950 // =============================================================================
951 // now we can define classes 100% compatible with the old ones
952 // =============================================================================
954 // ----------------------------------------------------------------------------
955 // commonly used list classes
956 // ----------------------------------------------------------------------------
958 #ifdef wxLIST_COMPATIBILITY
960 // define this to make a lot of noise about use of the old wxList classes.
961 //#define wxWARN_COMPAT_LIST_USE
963 // -----------------------------------------------------------------------------
964 // wxList compatibility class: in fact, it's a list of wxObjects
965 // -----------------------------------------------------------------------------
966 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
, class WXDLLIMPEXP_BASE
);
968 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
971 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
972 wxDEPRECATED( wxList(int key_type
= wxKEY_NONE
) );
974 wxList(int key_type
= wxKEY_NONE
);
977 // this destructor is required for Darwin
981 wxList
& operator=(const wxList
& list
)
982 { (void) wxListBase::operator=(list
); return *this; }
984 // compatibility methods
985 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
990 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
995 DECLARE_DYNAMIC_CLASS(wxList
)
1001 // -----------------------------------------------------------------------------
1002 // wxStringList class for compatibility with the old code
1003 // -----------------------------------------------------------------------------
1004 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1006 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1011 #ifdef wxWARN_COMPAT_LIST_USE
1012 wxDEPRECATED( wxStringList() );
1013 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1016 wxStringList(const wxChar
*first
...);
1019 // copying the string list: the strings are copied, too (extremely
1021 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(TRUE
); DoCopy(other
); }
1022 wxStringList
& operator=(const wxStringList
& other
)
1023 { Clear(); DoCopy(other
); return *this; }
1026 // makes a copy of the string
1027 wxNode
*Add(const wxChar
*s
);
1029 // Append to beginning of list
1030 wxNode
*Prepend(const wxChar
*s
);
1032 bool Delete(const wxChar
*s
);
1034 wxChar
**ListToArray(bool new_copies
= FALSE
) const;
1035 bool Member(const wxChar
*s
) const;
1041 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1043 DECLARE_DYNAMIC_CLASS(wxStringList
)
1046 #else // if wxUSE_STL
1048 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLEXPORT
);
1050 class WXDLLEXPORT wxStringList
: public wxStringListBase
1053 compatibility_iterator
Append(wxChar
* s
)
1054 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Append(tmp
); }
1055 compatibility_iterator
Insert(wxChar
* s
)
1056 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Insert(tmp
); }
1057 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1061 return wxStringListBase::Insert(pos
, tmp
);
1063 compatibility_iterator
Add(const wxChar
* s
)
1064 { push_back(s
); return GetLast(); }
1065 compatibility_iterator
Prepend(const wxChar
* s
)
1066 { push_front(s
); return GetFirst(); }
1071 #endif // wxLIST_COMPATIBILITY
1073 // delete all list elements
1075 // NB: the class declaration of the list elements must be visible from the
1076 // place where you use this macro, otherwise the proper destructor may not
1077 // be called (a decent compiler should give a warning about it, but don't
1079 #define WX_CLEAR_LIST(type, list) \
1081 type::iterator it, en; \
1082 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \