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"
45 #if defined(__WXMSW__) && defined(__MINGW32__)
46 #include "wx/msw/winundef.h"
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 // type of compare function for list sort operation (as in 'qsort'): it should
55 // return a negative value, 0 or positive value if the first element is less
56 // than, equal or greater than the second
59 typedef int (* LINKAGEMODE wxSortCompareFunction
)(const void *elem1
, const void *elem2
);
62 class WXDLLIMPEXP_BASE wxObjectListNode
;
63 typedef wxObjectListNode wxNode
;
66 typedef int (* LINKAGEMODE wxListIterateFunction
)(void *current
);
68 // ----------------------------------------------------------------------------
70 // ----------------------------------------------------------------------------
72 #if !defined(wxENUM_KEY_TYPE_DEFINED)
73 #define wxENUM_KEY_TYPE_DEFINED
86 #define wxLIST_COMPATIBILITY
88 #define WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl) \
89 WX_DECLARE_LIST_X(elT, liT, decl)
91 #define WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
92 WX_DECLARE_LIST_X(elT, liT, decl)
94 #define WX_DECLARE_LIST_X(elT, liT, decl) \
95 WX_DECLARE_LIST_XO(elT*, liT, decl)
97 #define WX_DECLARE_LIST_XO(elT, liT, decl) \
98 decl liT : public std::list<elT> \
103 struct compatibility_iterator \
105 typedef std::list<elT>::iterator iterator; \
109 operator bool() const \
110 { return m_list && m_iter != m_list->end(); } \
111 bool operator !() const \
112 { return !m_list || m_iter == m_list->end(); } \
113 compatibility_iterator( const liT* li, iterator it ) \
114 : m_iter( it ), m_list( (liT*)li ) {} \
115 compatibility_iterator( liT* li, iterator it ) \
116 : m_iter( it ), m_list( li ) {} \
117 compatibility_iterator() : m_list( NULL ) { } \
118 dummy* operator->() { return (dummy*)this; } \
119 const dummy* operator->() const { return (const dummy*)this; } \
121 typedef struct compatibility_iterator citer; \
125 typedef std::list<elT>::iterator it; \
126 typedef compatibility_iterator citer; \
128 elT GetData() const \
130 citer* i = (citer*)this; \
131 return *(i->m_iter); \
133 citer GetNext() const \
135 citer* i = (citer*)this; \
136 it lit = i->m_iter; \
137 return citer( i->m_list, ++lit ); \
139 citer GetPrevious() const \
141 citer* i = (citer*)this; \
142 it lit = i->m_iter; \
143 return citer( i->m_list, ++lit ); \
145 void SetData( elT e ) \
147 citer* i = (citer*)this; \
154 iterator find( elT e ) \
157 for( it = begin(), en = end(); it != en; ++it ) \
165 citer Append( elT e ) { push_back( e ); return GetLast(); } \
166 void Clear() { clear(); } \
167 size_t GetCount() const { return size(); } \
168 citer GetFirst() const { return citer( this, ((liT*)this)->begin() ); } \
169 citer GetLast() const { return citer( this, --(((liT*)this)->end()) ); } \
170 bool IsEmpty() const { return empty(); } \
171 bool DeleteObject( elT e ) \
173 iterator it = find( e ); \
181 void Erase( const compatibility_iterator& it ) \
183 erase( it.m_iter ); \
185 citer Find( elT e ) const { return citer( this, ((liT*)this)->find( e ) ); } \
186 citer Member( elT e ) const { return Find( e ); } \
187 citer Insert( elT e ) \
188 { push_front( e ); return citer( this, begin() ); } \
189 citer Insert( size_t idx, elT e ) \
190 { return Insert( Item( idx ), e ); } \
191 citer Insert( citer idx, elT e ) \
192 { return citer( this, insert( idx.m_iter, e ) ); } \
193 citer Item( size_t idx ) const \
196 for( it = ((liT*)this)->begin(); idx; --idx ) \
198 return citer( this, it ); \
200 int IndexOf( elT e ) const \
202 const_iterator it, en; \
204 for( idx = 0, it = begin(), en = end(); it != en; ++it, ++idx ) \
207 return wxNOT_FOUND; \
211 #define WX_DECLARE_LIST(elementtype, listname) \
212 WX_DECLARE_LIST_X(elementtype, listname, class)
214 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
215 WX_DECLARE_LIST_X(elementtype, listname, class WXDLLEXPORT)
217 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
218 WX_DECLARE_LIST_X(elementtype, listname, class usergoo)
220 // this macro must be inserted in your program after
221 // #include <wx/listimpl.cpp>
222 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
224 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
225 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
227 #else // if !wxUSE_STL
229 // due to circular header dependencies this function has to be declared here
230 // (normally it's found in utils.h which includes itself list.h...)
231 extern WXDLLEXPORT wxChar
* copystring(const wxChar
*s
);
233 class WXDLLEXPORT wxObjectListNode
;
234 typedef wxObjectListNode wxNode
;
236 // undef it to get rid of old, deprecated functions
237 #define wxLIST_COMPATIBILITY
239 // -----------------------------------------------------------------------------
240 // key stuff: a list may be optionally keyed on integer or string key
241 // -----------------------------------------------------------------------------
249 // a struct which may contain both types of keys
251 // implementation note: on one hand, this class allows to have only one function
252 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
253 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
254 // wxList::Find(const char *).
255 class WXDLLIMPEXP_BASE wxListKey
259 wxListKey() : m_keyType(wxKEY_NONE
)
261 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
262 { m_key
.integer
= i
; }
263 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
264 { m_key
.string
= wxStrdup(s
); }
265 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
266 { m_key
.string
= wxStrdup(s
.c_str()); }
269 wxKeyType
GetKeyType() const { return m_keyType
; }
270 const wxChar
*GetString() const
271 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
272 long GetNumber() const
273 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
276 // Note: implementation moved to list.cpp to prevent BC++ inline
277 // expansion warning.
278 bool operator==(wxListKeyValue value
) const ;
283 if ( m_keyType
== wxKEY_STRING
)
289 wxListKeyValue m_key
;
292 // -----------------------------------------------------------------------------
293 // wxNodeBase class is a (base for) node in a double linked list
294 // -----------------------------------------------------------------------------
296 WXDLLIMPEXP_DATA_BASE(extern wxListKey
) wxDefaultListKey
;
298 class WXDLLIMPEXP_BASE wxListBase
;
300 class WXDLLIMPEXP_BASE wxNodeBase
302 friend class wxListBase
;
305 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
306 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
307 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
309 const wxListKey
& key
= wxDefaultListKey
);
311 virtual ~wxNodeBase();
313 // FIXME no check is done that the list is really keyed on strings
314 const wxChar
*GetKeyString() const { return m_key
.string
; }
315 long GetKeyInteger() const { return m_key
.integer
; }
317 // Necessary for some existing code
318 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
319 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
321 #ifdef wxLIST_COMPATIBILITY
322 // compatibility methods, use Get* instead.
323 wxDEPRECATED( wxNode
*Next() const );
324 wxDEPRECATED( wxNode
*Previous() const );
325 wxDEPRECATED( wxObject
*Data() const );
326 #endif // wxLIST_COMPATIBILITY
329 // all these are going to be "overloaded" in the derived classes
330 wxNodeBase
*GetNext() const { return m_next
; }
331 wxNodeBase
*GetPrevious() const { return m_previous
; }
333 void *GetData() const { return m_data
; }
334 void SetData(void *data
) { m_data
= data
; }
336 // get 0-based index of this node within the list or wxNOT_FOUND
339 virtual void DeleteData() { }
341 // for wxList::iterator
342 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
344 // optional key stuff
345 wxListKeyValue m_key
;
347 void *m_data
; // user data
348 wxNodeBase
*m_next
, // next and previous nodes in the list
351 wxListBase
*m_list
; // list we belong to
353 DECLARE_NO_COPY_CLASS(wxNodeBase
)
356 // -----------------------------------------------------------------------------
357 // a double-linked list class
358 // -----------------------------------------------------------------------------
362 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
364 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
365 friend class wxHashTableBase
; // should be able to call untyped Find()
367 // common part of all ctors
368 void Init(wxKeyType keyType
= wxKEY_NONE
); // Must be declared before it's used (for VC++ 1.5)
370 // default ctor & dtor
371 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
373 virtual ~wxListBase();
376 // count of items in the list
377 size_t GetCount() const { return m_count
; }
379 // return TRUE if this list is empty
380 bool IsEmpty() const { return m_count
== 0; }
387 // instruct it to destroy user data when deleting nodes
388 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
390 // query if to delete
391 bool GetDeleteContents() const
392 { return m_destroy
; }
395 wxKeyType
GetKeyType() const
396 { return m_keyType
; }
398 // set the keytype (required by the serial code)
399 void SetKeyType(wxKeyType keyType
)
400 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
402 #ifdef wxLIST_COMPATIBILITY
403 // compatibility methods from old wxList
404 wxDEPRECATED( int Number() const ); // use GetCount instead.
405 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
406 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
407 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
409 // kludge for typesafe list migration in core classes.
410 wxDEPRECATED( operator wxList
&() const );
411 #endif // wxLIST_COMPATIBILITY
415 // all methods here are "overloaded" in derived classes to provide compile
416 // time type checking
418 // create a node for the list of this type
419 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
421 const wxListKey
& key
= wxDefaultListKey
) = 0;
423 // Can't access these from derived classes otherwise (bug in Salford C++?)
430 wxListBase(size_t count
, void *elements
[]);
431 // from a sequence of objects
432 wxListBase(void *object
, ... /* terminate with NULL */);
435 // copy ctor and assignment operator
436 wxListBase(const wxListBase
& list
) : wxObject()
437 { Init(); DoCopy(list
); }
438 wxListBase
& operator=(const wxListBase
& list
)
439 { Clear(); DoCopy(list
); return *this; }
441 // get list head/tail
442 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
443 wxNodeBase
*GetLast() const { return m_nodeLast
; }
445 // by (0-based) index
446 wxNodeBase
*Item(size_t index
) const;
448 // get the list item's data
449 void *operator[](size_t n
) const
451 wxNodeBase
*node
= Item(n
);
453 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
457 // append to end of list
458 wxNodeBase
*Prepend(void *object
)
459 { return (wxNodeBase
*)wxListBase::Insert(object
); }
460 // append to beginning of list
461 wxNodeBase
*Append(void *object
);
462 // insert a new item at the beginning of the list
463 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
464 // insert a new item at the given position
465 wxNodeBase
*Insert(size_t pos
, void *object
)
466 { return pos
== GetCount() ? Append(object
)
467 : Insert(Item(pos
), object
); }
468 // insert before given node or at front of list if prev == NULL
469 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
472 wxNodeBase
*Append(long key
, void *object
);
473 wxNodeBase
*Append(const wxChar
*key
, void *object
);
475 // removes node from the list but doesn't delete it (returns pointer
476 // to the node or NULL if it wasn't found in the list)
477 wxNodeBase
*DetachNode(wxNodeBase
*node
);
478 // delete element from list, returns FALSE if node not found
479 bool DeleteNode(wxNodeBase
*node
);
480 // finds object pointer and deletes node (and object if DeleteContents
481 // is on), returns FALSE if object not found
482 bool DeleteObject(void *object
);
484 // search (all return NULL if item not found)
486 wxNodeBase
*Find(void *object
) const;
489 wxNodeBase
*Find(const wxListKey
& key
) const;
491 // get 0-based index of object or wxNOT_FOUND
492 int IndexOf( void *object
) const;
494 // this function allows the sorting of arbitrary lists by giving
495 // a function to compare two list elements. The list is sorted in place.
496 void Sort(const wxSortCompareFunction compfunc
);
498 // functions for iterating over the list
499 void *FirstThat(wxListIterateFunction func
);
500 void ForEach(wxListIterateFunction func
);
501 void *LastThat(wxListIterateFunction func
);
503 // for STL interface, "last" points to one after the last node
504 // of the controlled sequence (NULL for the end of the list)
506 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
509 // common part of copy ctor and assignment operator
510 void DoCopy(const wxListBase
& list
);
511 // common part of all Append()s
512 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
513 // free node's data and node itself
514 void DoDeleteNode(wxNodeBase
*node
);
516 size_t m_count
; // number of elements in the list
517 bool m_destroy
; // destroy user data when deleting list items?
518 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
521 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
524 // -----------------------------------------------------------------------------
525 // macros for definition of "template" list type
526 // -----------------------------------------------------------------------------
528 // and now some heavy magic...
530 // declare a list type named 'name' and containing elements of type 'T *'
531 // (as a by product of macro expansion you also get wx##name##Node
532 // wxNode-derived type)
534 // implementation details:
535 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
536 // for the list of given type - this allows us to pass only the list name
537 // to WX_DEFINE_LIST() even if it needs both the name and the type
539 // 2. We redefine all non-type-safe wxList functions with type-safe versions
540 // which don't take any space (everything is inline), but bring compile
541 // time error checking.
543 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
544 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
545 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
546 // interesting capability to store polymorphic objects in the list and is
547 // particularly useful with, for example, "wxWindow *" list where the
548 // wxWindowBase pointers are put into the list, but wxWindow pointers are
549 // retrieved from it.
551 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
552 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
554 classexp nodetype : public wxNodeBase \
557 nodetype(wxListBase *list = (wxListBase *)NULL, \
558 nodetype *previous = (nodetype *)NULL, \
559 nodetype *next = (nodetype *)NULL, \
560 T *data = (T *)NULL, \
561 const wxListKey& key = wxDefaultListKey) \
562 : wxNodeBase(list, previous, next, data, key) { } \
564 nodetype *GetNext() const \
565 { return (nodetype *)wxNodeBase::GetNext(); } \
566 nodetype *GetPrevious() const \
567 { return (nodetype *)wxNodeBase::GetPrevious(); } \
570 { return (T *)wxNodeBase::GetData(); } \
571 void SetData(T *data) \
572 { wxNodeBase::SetData(data); } \
574 virtual void DeleteData(); \
577 classexp name : public wxListBase \
580 typedef nodetype Node; \
581 typedef Node* compatibility_iterator; \
583 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
585 name(size_t count, T *elements[]) \
586 : wxListBase(count, (void **)elements) { } \
588 name& operator=(const name& list) \
589 { (void) wxListBase::operator=(list); return *this; } \
591 nodetype *GetFirst() const \
592 { return (nodetype *)wxListBase::GetFirst(); } \
593 nodetype *GetLast() const \
594 { return (nodetype *)wxListBase::GetLast(); } \
596 nodetype *Item(size_t index) const \
597 { return (nodetype *)wxListBase::Item(index); } \
599 T *operator[](size_t index) const \
601 nodetype *node = Item(index); \
602 return node ? (T*)(node->GetData()) : (T*)NULL; \
605 nodetype *Append(Tbase *object) \
606 { return (nodetype *)wxListBase::Append(object); } \
607 nodetype *Insert(Tbase *object) \
608 { return (nodetype *)Insert((nodetype*)NULL, object); } \
609 nodetype *Insert(size_t pos, Tbase *object) \
610 { return (nodetype *)wxListBase::Insert(pos, object); } \
611 nodetype *Insert(nodetype *prev, Tbase *object) \
612 { return (nodetype *)wxListBase::Insert(prev, object); } \
614 nodetype *Append(long key, void *object) \
615 { return (nodetype *)wxListBase::Append(key, object); } \
616 nodetype *Append(const wxChar *key, void *object) \
617 { return (nodetype *)wxListBase::Append(key, object); } \
619 nodetype *DetachNode(nodetype *node) \
620 { return (nodetype *)wxListBase::DetachNode(node); } \
621 bool DeleteNode(nodetype *node) \
622 { return wxListBase::DeleteNode(node); } \
623 bool DeleteObject(Tbase *object) \
624 { return wxListBase::DeleteObject(object); } \
625 void Erase(compatibility_iterator it) \
626 { DeleteNode(it); } \
628 nodetype *Find(Tbase *object) const \
629 { return (nodetype *)wxListBase::Find(object); } \
631 virtual nodetype *Find(const wxListKey& key) const \
632 { return (nodetype *)wxListBase::Find(key); } \
634 int IndexOf(Tbase *object) const \
635 { return wxListBase::IndexOf(object); } \
637 void Sort(wxSortFuncFor_##name func) \
638 { wxListBase::Sort((wxSortCompareFunction)func); } \
641 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
643 const wxListKey& key = wxDefaultListKey) \
645 return new nodetype(this, \
646 (nodetype *)prev, (nodetype *)next, \
649 /* STL interface */ \
651 typedef size_t size_type; \
652 typedef int difference_type; \
653 typedef T* value_type; \
654 typedef Tbase* base_value_type; \
655 typedef value_type& reference; \
656 typedef const value_type& const_reference; \
657 typedef base_value_type& base_reference; \
658 typedef const base_value_type& const_base_reference; \
664 typedef list::Node Node; \
665 typedef iterator itor; \
666 typedef list::value_type* ptr_type; \
671 typedef list::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 list::Node Node; \
704 typedef const_iterator itor; \
705 typedef list::value_type* ptr_type; \
710 typedef list::const_reference reference_type; \
711 typedef const ptr_type pointer_type; \
713 const_iterator(Node* node, Node* init) \
714 : m_node(node), m_init(init) { } \
715 const_iterator() : m_node(NULL), m_init(NULL) { } \
716 const_iterator(const iterator& it) \
717 : m_node(it.m_node), m_init(it.m_init) { } \
718 reference_type operator*() const \
719 { return *(pointer_type)m_node->GetDataPtr(); } \
720 pointer_type operator->() const \
721 { return (pointer_type)m_node->GetDataPtr(); } \
722 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
723 itor operator++(int) \
724 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
727 m_node = m_node ? m_node->GetPrevious() : m_init; \
730 itor operator--(int) \
733 m_node = m_node ? m_node->GetPrevious() : m_init; \
736 bool operator!=(const itor& it) const \
737 { return it.m_node != m_node; } \
738 bool operator==(const itor& it) const \
739 { return it.m_node == m_node; } \
741 class reverse_iterator \
745 typedef list::Node Node; \
746 typedef reverse_iterator itor; \
747 typedef list::value_type* ptr_type; \
752 typedef list::reference reference_type; \
753 typedef ptr_type pointer_type; \
755 reverse_iterator(Node* node, Node* init) \
756 : m_node(node), m_init(init) { } \
757 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
758 reference_type operator*() const \
759 { return *(pointer_type)m_node->GetDataPtr(); } \
760 pointer_type operator->() const \
761 { return (pointer_type)m_node->GetDataPtr(); } \
763 { m_node = m_node->GetPrevious(); return *this; } \
764 itor operator++(int) \
765 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
767 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
768 itor operator--(int) \
771 m_node = m_node ? m_node->GetNext() : m_init; \
774 bool operator!=(const itor& it) const \
775 { return it.m_node != m_node; } \
776 bool operator==(const itor& it) const \
777 { return it.m_node == m_node; } \
779 class const_reverse_iterator \
783 typedef list::Node Node; \
784 typedef const_reverse_iterator itor; \
785 typedef list::value_type* ptr_type; \
790 typedef list::const_reference reference_type; \
791 typedef const ptr_type pointer_type; \
793 const_reverse_iterator(Node* node, Node* init) \
794 : m_node(node), m_init(init) { } \
795 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
796 const_reverse_iterator(const reverse_iterator& it) \
797 : m_node(it.m_node), m_init(it.m_init) { } \
798 reference_type operator*() const \
799 { return *(pointer_type)m_node->GetDataPtr(); } \
800 pointer_type operator->() const \
801 { return (pointer_type)m_node->GetDataPtr(); } \
803 { m_node = m_node->GetPrevious(); return *this; } \
804 itor operator++(int) \
805 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
807 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
808 itor operator--(int) \
811 m_node = m_node ? m_node->GetNext() : m_init; \
814 bool operator!=(const itor& it) const \
815 { return it.m_node != m_node; } \
816 bool operator==(const itor& it) const \
817 { return it.m_node == m_node; } \
820 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
822 name(const_iterator first, const_iterator last) \
823 { assign(first, last); } \
824 iterator begin() { return iterator(GetFirst(), GetLast()); } \
825 const_iterator begin() const \
826 { return const_iterator(GetFirst(), GetLast()); } \
827 iterator end() { return iterator(NULL, GetLast()); } \
828 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
829 reverse_iterator rbegin() \
830 { return reverse_iterator(GetLast(), GetFirst()); } \
831 const_reverse_iterator rbegin() const \
832 { return const_reverse_iterator(GetLast(), GetFirst()); } \
833 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
834 const_reverse_iterator rend() const \
835 { return const_reverse_iterator(NULL, GetFirst()); } \
836 void resize(size_type n, value_type v = value_type()) \
839 for(; n < size(); pop_back()); \
840 else if(n > size()) \
841 for(; n > size(); push_back(v)); \
843 size_type size() const { return GetCount(); } \
844 size_type max_size() const { return INT_MAX; } \
845 bool empty() const { return IsEmpty(); } \
846 reference front() { return *begin(); } \
847 const_reference front() const { return *begin(); } \
848 reference back() { return *--end(); } \
849 const_reference back() const { return *--end(); } \
850 void push_front(const_reference v = value_type()) \
851 { Insert(GetFirst(), (const_base_reference)v); } \
852 void pop_front() { DeleteNode(GetFirst()); } \
853 void push_back(const_reference v = value_type()) \
854 { Append((const_base_reference)v); } \
855 void pop_back() { DeleteNode(GetLast()); } \
856 void assign(const_iterator first, const_iterator last) \
859 for(; first != last; ++first) \
860 Append((const_base_reference)*first); \
862 void assign(size_type n, const_reference v = value_type()) \
865 for(size_type i = 0; i < n; ++i) \
866 Append((const_base_reference)v); \
868 iterator insert(iterator it, const_reference v = value_type()) \
870 Insert(it.m_node, (const_base_reference)v); \
871 return iterator(it.m_node->GetPrevious(), GetLast()); \
873 void insert(iterator it, size_type n, const_reference v = value_type())\
875 for(size_type i = 0; i < n; ++i) \
876 Insert(it.m_node, (const_base_reference)v); \
878 void insert(iterator it, const_iterator first, const_iterator last) \
880 for(; first != last; ++first) \
881 Insert(it.m_node, (const_base_reference)*first); \
883 iterator erase(iterator it) \
885 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
886 DeleteNode(it.m_node); return next; \
888 iterator erase(iterator first, iterator last) \
890 iterator next = last; ++next; \
891 DeleteNodes(first.m_node, last.m_node); \
894 void clear() { Clear(); } \
895 void splice(iterator it, name& l, iterator first, iterator last) \
896 { insert(it, first, last); l.erase(first, last); } \
897 void splice(iterator it, name& l) \
898 { splice(it, l, l.begin(), l.end() ); } \
899 void splice(iterator it, name& l, iterator first) \
901 iterator tmp = first; ++tmp; \
902 if(it == first || it == tmp) return; \
903 insert(it, *first); \
906 void remove(const_reference v) \
907 { DeleteObject((const_base_reference)v); } \
910 /* void swap(name& l) \
912 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
913 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
914 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
915 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
916 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
920 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
921 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
923 #define WX_DECLARE_LIST(elementtype, listname) \
924 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
925 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
927 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
928 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
929 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
931 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
932 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
933 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
935 // this macro must be inserted in your program after
936 // #include <wx/listimpl.cpp>
937 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
939 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
940 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
944 // =============================================================================
945 // now we can define classes 100% compatible with the old ones
946 // =============================================================================
948 // ----------------------------------------------------------------------------
949 // commonly used list classes
950 // ----------------------------------------------------------------------------
952 #ifdef wxLIST_COMPATIBILITY
954 // define this to make a lot of noise about use of the old wxList classes.
955 //#define wxWARN_COMPAT_LIST_USE
957 // -----------------------------------------------------------------------------
958 // wxList compatibility class: in fact, it's a list of wxObjects
959 // -----------------------------------------------------------------------------
960 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
, class WXDLLIMPEXP_BASE
);
962 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
965 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
966 wxDEPRECATED( wxList(int key_type
= wxKEY_NONE
) );
968 wxList(int key_type
= wxKEY_NONE
);
971 // this destructor is required for Darwin
975 wxList
& operator=(const wxList
& list
)
976 { (void) wxListBase::operator=(list
); return *this; }
978 // compatibility methods
979 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
984 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
989 DECLARE_DYNAMIC_CLASS(wxList
)
995 // -----------------------------------------------------------------------------
996 // wxStringList class for compatibility with the old code
997 // -----------------------------------------------------------------------------
998 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1000 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1005 #ifdef wxWARN_COMPAT_LIST_USE
1006 wxDEPRECATED( wxStringList() );
1007 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1010 wxStringList(const wxChar
*first
...);
1013 // copying the string list: the strings are copied, too (extremely
1015 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(TRUE
); DoCopy(other
); }
1016 wxStringList
& operator=(const wxStringList
& other
)
1017 { Clear(); DoCopy(other
); return *this; }
1020 // makes a copy of the string
1021 wxNode
*Add(const wxChar
*s
);
1023 // Append to beginning of list
1024 wxNode
*Prepend(const wxChar
*s
);
1026 bool Delete(const wxChar
*s
);
1028 wxChar
**ListToArray(bool new_copies
= FALSE
) const;
1029 bool Member(const wxChar
*s
) const;
1035 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1037 DECLARE_DYNAMIC_CLASS(wxStringList
)
1040 #else // if wxUSE_STL
1042 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLEXPORT
);
1044 class WXDLLEXPORT wxStringList
: public wxStringListBase
1051 #endif // wxLIST_COMPATIBILITY
1053 // delete all list elements
1055 // NB: the class declaration of the list elements must be visible from the
1056 // place where you use this macro, otherwise the proper destructor may not
1057 // be called (a decent compiler should give a warning about it, but don't
1059 #define WX_CLEAR_LIST(type, list) \
1061 type::iterator it, en; \
1062 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \