1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxList, wxStringList classes
4 // Author: Julian Smart
5 // Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 All this is quite ugly but serves two purposes:
14 1. Be almost 100% compatible with old, untyped, wxList class
15 2. Ensure compile-time type checking for the linked lists
17 The idea is to have one base class (wxListBase) working with "void *" data,
18 but to hide these untyped functions - i.e. make them protected, so they
19 can only be used from derived classes which have inline member functions
20 working with right types. This achieves the 2nd goal. As for the first one,
21 we provide a special derivation of wxListBase called wxList which looks just
28 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) && \
29 !(defined(__MINGW32__) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
30 #pragma interface "list.h"
33 // -----------------------------------------------------------------------------
35 // -----------------------------------------------------------------------------
38 #include "wx/object.h"
39 #include "wx/string.h"
42 #include "wx/beforestd.h"
46 #include "wx/afterstd.h"
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 // type of compare function for list sort operation (as in 'qsort'): it should
54 // return a negative value, 0 or positive value if the first element is less
55 // 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_WITH_DECL(elT, liT, decl)
90 #define WX_DECLARE_LIST_PTR_3(elT, dummy1, liT, dummy2, decl) \
91 WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl)
93 #define WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
94 WX_DECLARE_LIST_WITH_DECL(elT, liT, decl)
95 #define WX_DECLARE_LIST_PTR_2(elT, liT, dummy, decl) \
96 WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
98 #define WX_DECLARE_LIST_WITH_DECL(elT, liT, decl) \
99 WX_DECLARE_LIST_XO(elT*, liT, decl)
101 #define WX_DECLARE_LIST_XO(elT, liT, decl) \
104 /* Workaround for broken VC6 STL incorrectly requires a std::greater<> */ \
105 /* to be passed into std::list::sort() */ \
107 struct std::greater<elT> \
110 wxSortCompareFunction m_CompFunc; \
112 greater( wxSortCompareFunction compfunc = NULL ) \
113 : m_CompFunc( compfunc ) {} \
114 bool operator()(const elT X, const elT Y) const \
116 return m_CompFunc ? \
117 ( m_CompFunc( X, Y ) < 0 ) : \
122 decl liT : public std::list<elT> \
127 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
128 static void DeleteFunction( const _WX_LIST_ITEM_TYPE_##liT X ); \
130 class compatibility_iterator \
133 /* Workaround for broken VC6 nested class name resolution */ \
134 typedef std::list<elT>::iterator iterator; \
140 compatibility_iterator() \
141 : m_iter(), m_list( NULL ) {} \
142 compatibility_iterator( liT* li, iterator i ) \
143 : m_iter( i ), m_list( li ) {} \
144 compatibility_iterator( const liT* li, iterator i ) \
145 : m_iter( i ), m_list( const_cast< liT* >( li ) ) {} \
147 compatibility_iterator* operator->() { return this; } \
148 const compatibility_iterator* operator->() const { return this; } \
150 bool operator==(const compatibility_iterator& i) \
151 { return (m_list == i.m_list) && (m_iter == i.m_iter); } \
152 bool operator!=(const compatibility_iterator& i) \
153 { return !( operator==( i ) ); } \
154 operator bool() const \
155 { return m_list ? m_iter != m_list->end() : false; } \
156 bool operator !() const \
157 { return !( operator bool() ); } \
159 elT GetData() const \
160 { return *m_iter; } \
161 void SetData( elT e ) \
164 compatibility_iterator GetNext() const \
166 iterator i = m_iter; \
167 return compatibility_iterator( m_list, ++i ); \
169 compatibility_iterator GetPrevious() const \
171 iterator i = m_iter; \
172 return compatibility_iterator( m_list, --i ); \
174 int IndexOf() const \
177 m_iter != m_list->end() ? \
178 std::distance( m_list->begin(), m_iter ) : \
184 liT() : m_destroy( false ) {} \
186 compatibility_iterator Find( const elT e ) const \
188 liT* _this = const_cast< liT* >( this ); \
189 return compatibility_iterator( _this, \
190 std::find( _this->begin(), _this->end(), e ) ); \
193 bool IsEmpty() const \
194 { return empty(); } \
195 size_t GetCount() const \
198 { return static_cast< int >( GetCount() ); } \
200 compatibility_iterator Item( size_t idx ) const \
202 iterator i = const_cast< liT* >(this)->begin(); \
203 std::advance( i, idx ); \
204 return compatibility_iterator( this, i ); \
206 compatibility_iterator GetFirst() const \
208 return compatibility_iterator( this, \
209 const_cast< liT* >(this)->begin() ); \
211 compatibility_iterator GetLast() const \
213 iterator i = const_cast< liT* >(this)->end(); \
214 return compatibility_iterator( this, !empty() ? --i : i ); \
216 compatibility_iterator Member( elT e ) const \
217 { return Find( e ); } \
218 compatibility_iterator Nth( int n ) const \
219 { return Item( n ); } \
220 int IndexOf( elT e ) const \
221 { return Find( e ).IndexOf(); } \
223 compatibility_iterator Append( elT e ) \
228 compatibility_iterator Insert( elT e ) \
231 return compatibility_iterator( this, begin() ); \
233 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
235 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
237 compatibility_iterator Insert( size_t idx, elT e ) \
239 return compatibility_iterator( this, \
240 insert( Item( idx ).m_iter, e ) ); \
243 void DeleteContents( bool destroy ) \
244 { m_destroy = destroy; } \
245 bool GetDeleteContents() const \
246 { return m_destroy; } \
247 void Erase( const compatibility_iterator& i ) \
250 DeleteFunction( i->GetData() ); \
253 bool DeleteNode( const compatibility_iterator& i ) \
262 bool DeleteObject( elT e ) \
264 return DeleteNode( Find( e ) ); \
269 std::for_each( begin(), end(), DeleteFunction ); \
273 /* Workaround for broken VC6 std::list::sort() see above */ \
274 void Sort( wxSortCompareFunction compfunc ) \
275 { sort( std::greater<elT>( compfunc ) ); } \
277 ~liT() { Clear(); } \
280 #define WX_DECLARE_LIST(elementtype, listname) \
281 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
282 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
283 WX_DECLARE_LIST(elementtype, listname)
285 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
286 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
287 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
288 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
290 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
291 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
292 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
293 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
295 // this macro must be inserted in your program after
296 // #include <wx/listimpl.cpp>
297 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
299 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
300 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
302 #else // if !wxUSE_STL
304 // due to circular header dependencies this function has to be declared here
305 // (normally it's found in utils.h which includes itself list.h...)
306 #if WXWIN_COMPATIBILITY_2_4
307 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
310 class WXDLLEXPORT wxObjectListNode
;
311 typedef wxObjectListNode wxNode
;
313 // undef it to get rid of old, deprecated functions
314 #define wxLIST_COMPATIBILITY
316 // -----------------------------------------------------------------------------
317 // key stuff: a list may be optionally keyed on integer or string key
318 // -----------------------------------------------------------------------------
326 // a struct which may contain both types of keys
328 // implementation note: on one hand, this class allows to have only one function
329 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
330 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
331 // wxList::Find(const char *).
332 class WXDLLIMPEXP_BASE wxListKey
336 wxListKey() : m_keyType(wxKEY_NONE
)
338 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
339 { m_key
.integer
= i
; }
340 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
341 { m_key
.string
= wxStrdup(s
); }
342 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
343 { m_key
.string
= wxStrdup(s
.c_str()); }
346 wxKeyType
GetKeyType() const { return m_keyType
; }
347 const wxChar
*GetString() const
348 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
349 long GetNumber() const
350 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
353 // Note: implementation moved to list.cpp to prevent BC++ inline
354 // expansion warning.
355 bool operator==(wxListKeyValue value
) const ;
360 if ( m_keyType
== wxKEY_STRING
)
366 wxListKeyValue m_key
;
369 // -----------------------------------------------------------------------------
370 // wxNodeBase class is a (base for) node in a double linked list
371 // -----------------------------------------------------------------------------
373 extern WXDLLIMPEXP_DATA_BASE(wxListKey
) wxDefaultListKey
;
375 class WXDLLIMPEXP_BASE wxListBase
;
377 class WXDLLIMPEXP_BASE wxNodeBase
379 friend class wxListBase
;
382 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
383 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
384 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
386 const wxListKey
& key
= wxDefaultListKey
);
388 virtual ~wxNodeBase();
390 // FIXME no check is done that the list is really keyed on strings
391 const wxChar
*GetKeyString() const { return m_key
.string
; }
392 long GetKeyInteger() const { return m_key
.integer
; }
394 // Necessary for some existing code
395 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
396 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
398 #ifdef wxLIST_COMPATIBILITY
399 // compatibility methods, use Get* instead.
400 wxDEPRECATED( wxNode
*Next() const );
401 wxDEPRECATED( wxNode
*Previous() const );
402 wxDEPRECATED( wxObject
*Data() const );
403 #endif // wxLIST_COMPATIBILITY
406 // all these are going to be "overloaded" in the derived classes
407 wxNodeBase
*GetNext() const { return m_next
; }
408 wxNodeBase
*GetPrevious() const { return m_previous
; }
410 void *GetData() const { return m_data
; }
411 void SetData(void *data
) { m_data
= data
; }
413 // get 0-based index of this node within the list or wxNOT_FOUND
416 virtual void DeleteData() { }
418 // for wxList::iterator
419 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
421 // optional key stuff
422 wxListKeyValue m_key
;
424 void *m_data
; // user data
425 wxNodeBase
*m_next
, // next and previous nodes in the list
428 wxListBase
*m_list
; // list we belong to
430 DECLARE_NO_COPY_CLASS(wxNodeBase
)
433 // -----------------------------------------------------------------------------
434 // a double-linked list class
435 // -----------------------------------------------------------------------------
437 class WXDLLIMPEXP_BASE wxList
;
439 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
441 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
442 friend class wxHashTableBase
; // should be able to call untyped Find()
444 // common part of all ctors
445 void Init(wxKeyType keyType
= wxKEY_NONE
); // Must be declared before it's used (for VC++ 1.5)
447 // default ctor & dtor
448 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
450 virtual ~wxListBase();
453 // count of items in the list
454 size_t GetCount() const { return m_count
; }
456 // return true if this list is empty
457 bool IsEmpty() const { return m_count
== 0; }
464 // instruct it to destroy user data when deleting nodes
465 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
467 // query if to delete
468 bool GetDeleteContents() const
469 { return m_destroy
; }
472 wxKeyType
GetKeyType() const
473 { return m_keyType
; }
475 // set the keytype (required by the serial code)
476 void SetKeyType(wxKeyType keyType
)
477 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
479 #ifdef wxLIST_COMPATIBILITY
480 // compatibility methods from old wxList
481 wxDEPRECATED( int Number() const ); // use GetCount instead.
482 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
483 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
484 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
486 // kludge for typesafe list migration in core classes.
487 wxDEPRECATED( operator wxList
&() const );
488 #endif // wxLIST_COMPATIBILITY
492 // all methods here are "overloaded" in derived classes to provide compile
493 // time type checking
495 // create a node for the list of this type
496 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
498 const wxListKey
& key
= wxDefaultListKey
) = 0;
500 // Can't access these from derived classes otherwise (bug in Salford C++?)
507 wxListBase(size_t count
, void *elements
[]);
508 // from a sequence of objects
509 wxListBase(void *object
, ... /* terminate with NULL */);
512 void Assign(const wxListBase
& list
)
513 { Clear(); DoCopy(list
); }
515 // get list head/tail
516 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
517 wxNodeBase
*GetLast() const { return m_nodeLast
; }
519 // by (0-based) index
520 wxNodeBase
*Item(size_t index
) const;
522 // get the list item's data
523 void *operator[](size_t n
) const
525 wxNodeBase
*node
= Item(n
);
527 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
531 // append to end of list
532 wxNodeBase
*Prepend(void *object
)
533 { return (wxNodeBase
*)wxListBase::Insert(object
); }
534 // append to beginning of list
535 wxNodeBase
*Append(void *object
);
536 // insert a new item at the beginning of the list
537 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
538 // insert a new item at the given position
539 wxNodeBase
*Insert(size_t pos
, void *object
)
540 { return pos
== GetCount() ? Append(object
)
541 : Insert(Item(pos
), object
); }
542 // insert before given node or at front of list if prev == NULL
543 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
546 wxNodeBase
*Append(long key
, void *object
);
547 wxNodeBase
*Append(const wxChar
*key
, void *object
);
549 // removes node from the list but doesn't delete it (returns pointer
550 // to the node or NULL if it wasn't found in the list)
551 wxNodeBase
*DetachNode(wxNodeBase
*node
);
552 // delete element from list, returns false if node not found
553 bool DeleteNode(wxNodeBase
*node
);
554 // finds object pointer and deletes node (and object if DeleteContents
555 // is on), returns false if object not found
556 bool DeleteObject(void *object
);
558 // search (all return NULL if item not found)
560 wxNodeBase
*Find(const void *object
) const;
563 wxNodeBase
*Find(const wxListKey
& key
) const;
565 // get 0-based index of object or wxNOT_FOUND
566 int IndexOf( void *object
) const;
568 // this function allows the sorting of arbitrary lists by giving
569 // a function to compare two list elements. The list is sorted in place.
570 void Sort(const wxSortCompareFunction compfunc
);
572 // functions for iterating over the list
573 void *FirstThat(wxListIterateFunction func
);
574 void ForEach(wxListIterateFunction func
);
575 void *LastThat(wxListIterateFunction func
);
577 // for STL interface, "last" points to one after the last node
578 // of the controlled sequence (NULL for the end of the list)
580 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
583 // common part of copy ctor and assignment operator
584 void DoCopy(const wxListBase
& list
);
585 // common part of all Append()s
586 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
587 // free node's data and node itself
588 void DoDeleteNode(wxNodeBase
*node
);
590 size_t m_count
; // number of elements in the list
591 bool m_destroy
; // destroy user data when deleting list items?
592 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
595 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
598 // -----------------------------------------------------------------------------
599 // macros for definition of "template" list type
600 // -----------------------------------------------------------------------------
602 // and now some heavy magic...
604 // declare a list type named 'name' and containing elements of type 'T *'
605 // (as a by product of macro expansion you also get wx##name##Node
606 // wxNode-derived type)
608 // implementation details:
609 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
610 // for the list of given type - this allows us to pass only the list name
611 // to WX_DEFINE_LIST() even if it needs both the name and the type
613 // 2. We redefine all non-type-safe wxList functions with type-safe versions
614 // which don't take any space (everything is inline), but bring compile
615 // time error checking.
617 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
618 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
619 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
620 // interesting capability to store polymorphic objects in the list and is
621 // particularly useful with, for example, "wxWindow *" list where the
622 // wxWindowBase pointers are put into the list, but wxWindow pointers are
623 // retrieved from it.
625 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
626 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
627 // it results in compiler warnings when this operator doesn't make sense
628 // (i.e. stored elements are not pointers)
630 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
631 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
632 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
634 classexp nodetype : public wxNodeBase \
637 nodetype(wxListBase *list = (wxListBase *)NULL, \
638 nodetype *previous = (nodetype *)NULL, \
639 nodetype *next = (nodetype *)NULL, \
640 T *data = (T *)NULL, \
641 const wxListKey& key = wxDefaultListKey) \
642 : wxNodeBase(list, previous, next, data, key) { } \
644 nodetype *GetNext() const \
645 { return (nodetype *)wxNodeBase::GetNext(); } \
646 nodetype *GetPrevious() const \
647 { return (nodetype *)wxNodeBase::GetPrevious(); } \
650 { return (T *)wxNodeBase::GetData(); } \
651 void SetData(T *data) \
652 { wxNodeBase::SetData(data); } \
654 virtual void DeleteData(); \
656 DECLARE_NO_COPY_CLASS(nodetype) \
659 classexp name : public wxListBase \
662 typedef nodetype Node; \
663 typedef Node* compatibility_iterator; \
665 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
667 name(const name& list) : wxListBase(list.GetKeyType()) \
669 name(size_t count, T *elements[]) \
670 : wxListBase(count, (void **)elements) { } \
672 name& operator=(const name& list) \
673 { Assign(list); return *this; } \
675 nodetype *GetFirst() const \
676 { return (nodetype *)wxListBase::GetFirst(); } \
677 nodetype *GetLast() const \
678 { return (nodetype *)wxListBase::GetLast(); } \
680 nodetype *Item(size_t index) const \
681 { return (nodetype *)wxListBase::Item(index); } \
683 T *operator[](size_t index) const \
685 nodetype *node = Item(index); \
686 return node ? (T*)(node->GetData()) : (T*)NULL; \
689 nodetype *Append(Tbase *object) \
690 { return (nodetype *)wxListBase::Append(object); } \
691 nodetype *Insert(Tbase *object) \
692 { return (nodetype *)Insert((nodetype*)NULL, object); } \
693 nodetype *Insert(size_t pos, Tbase *object) \
694 { return (nodetype *)wxListBase::Insert(pos, object); } \
695 nodetype *Insert(nodetype *prev, Tbase *object) \
696 { return (nodetype *)wxListBase::Insert(prev, object); } \
698 nodetype *Append(long key, void *object) \
699 { return (nodetype *)wxListBase::Append(key, object); } \
700 nodetype *Append(const wxChar *key, void *object) \
701 { return (nodetype *)wxListBase::Append(key, object); } \
703 nodetype *DetachNode(nodetype *node) \
704 { return (nodetype *)wxListBase::DetachNode(node); } \
705 bool DeleteNode(nodetype *node) \
706 { return wxListBase::DeleteNode(node); } \
707 bool DeleteObject(Tbase *object) \
708 { return wxListBase::DeleteObject(object); } \
709 void Erase(compatibility_iterator it) \
710 { DeleteNode(it); } \
712 nodetype *Find(const Tbase *object) const \
713 { return (nodetype *)wxListBase::Find(object); } \
715 virtual nodetype *Find(const wxListKey& key) const \
716 { return (nodetype *)wxListBase::Find(key); } \
718 int IndexOf(Tbase *object) const \
719 { return wxListBase::IndexOf(object); } \
721 void Sort(wxSortCompareFunction func) \
722 { wxListBase::Sort(func); } \
723 void Sort(wxSortFuncFor_##name func) \
724 { Sort((wxSortCompareFunction)func); } \
727 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
729 const wxListKey& key = wxDefaultListKey) \
731 return new nodetype(this, \
732 (nodetype *)prev, (nodetype *)next, \
735 /* STL interface */ \
737 typedef size_t size_type; \
738 typedef int difference_type; \
739 typedef T* value_type; \
740 typedef Tbase* base_value_type; \
741 typedef value_type& reference; \
742 typedef const value_type& const_reference; \
743 typedef base_value_type& base_reference; \
744 typedef const base_value_type& const_base_reference; \
750 typedef nodetype Node; \
751 typedef iterator itor; \
752 typedef T* value_type; \
753 typedef value_type* ptr_type; \
754 typedef value_type& reference; \
759 typedef reference reference_type; \
760 typedef ptr_type pointer_type; \
762 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
763 iterator() : m_node(NULL), m_init(NULL) { } \
764 reference_type operator*() const \
765 { return *(pointer_type)m_node->GetDataPtr(); } \
767 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
768 itor operator++(int) \
769 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
772 m_node = m_node ? m_node->GetPrevious() : m_init; \
775 itor operator--(int) \
778 m_node = m_node ? m_node->GetPrevious() : m_init; \
781 bool operator!=(const itor& it) const \
782 { return it.m_node != m_node; } \
783 bool operator==(const itor& it) const \
784 { return it.m_node == m_node; } \
786 class const_iterator \
790 typedef nodetype Node; \
791 typedef T* value_type; \
792 typedef const value_type& const_reference; \
793 typedef const_iterator itor; \
794 typedef value_type* ptr_type; \
799 typedef const_reference reference_type; \
800 typedef const ptr_type pointer_type; \
802 const_iterator(Node* node, Node* init) \
803 : m_node(node), m_init(init) { } \
804 const_iterator() : m_node(NULL), m_init(NULL) { } \
805 const_iterator(const iterator& it) \
806 : m_node(it.m_node), m_init(it.m_init) { } \
807 reference_type operator*() const \
808 { return *(pointer_type)m_node->GetDataPtr(); } \
810 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
811 itor operator++(int) \
812 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
815 m_node = m_node ? m_node->GetPrevious() : m_init; \
818 itor operator--(int) \
821 m_node = m_node ? m_node->GetPrevious() : m_init; \
824 bool operator!=(const itor& it) const \
825 { return it.m_node != m_node; } \
826 bool operator==(const itor& it) const \
827 { return it.m_node == m_node; } \
829 class reverse_iterator \
833 typedef nodetype Node; \
834 typedef T* value_type; \
835 typedef reverse_iterator itor; \
836 typedef value_type* ptr_type; \
837 typedef value_type& reference; \
842 typedef reference reference_type; \
843 typedef ptr_type pointer_type; \
845 reverse_iterator(Node* node, Node* init) \
846 : m_node(node), m_init(init) { } \
847 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
848 reference_type operator*() const \
849 { return *(pointer_type)m_node->GetDataPtr(); } \
852 { m_node = m_node->GetPrevious(); return *this; } \
853 itor operator++(int) \
854 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
856 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
857 itor operator--(int) \
860 m_node = m_node ? m_node->GetNext() : m_init; \
863 bool operator!=(const itor& it) const \
864 { return it.m_node != m_node; } \
865 bool operator==(const itor& it) const \
866 { return it.m_node == m_node; } \
868 class const_reverse_iterator \
872 typedef nodetype Node; \
873 typedef T* value_type; \
874 typedef const_reverse_iterator itor; \
875 typedef value_type* ptr_type; \
876 typedef const value_type& const_reference; \
881 typedef const_reference reference_type; \
882 typedef const ptr_type pointer_type; \
884 const_reverse_iterator(Node* node, Node* init) \
885 : m_node(node), m_init(init) { } \
886 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
887 const_reverse_iterator(const reverse_iterator& it) \
888 : m_node(it.m_node), m_init(it.m_init) { } \
889 reference_type operator*() const \
890 { return *(pointer_type)m_node->GetDataPtr(); } \
893 { m_node = m_node->GetPrevious(); return *this; } \
894 itor operator++(int) \
895 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
897 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
898 itor operator--(int) \
901 m_node = m_node ? m_node->GetNext() : m_init; \
904 bool operator!=(const itor& it) const \
905 { return it.m_node != m_node; } \
906 bool operator==(const itor& it) const \
907 { return it.m_node == m_node; } \
910 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
912 name(const_iterator first, const_iterator last) \
913 { assign(first, last); } \
914 iterator begin() { return iterator(GetFirst(), GetLast()); } \
915 const_iterator begin() const \
916 { return const_iterator(GetFirst(), GetLast()); } \
917 iterator end() { return iterator(NULL, GetLast()); } \
918 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
919 reverse_iterator rbegin() \
920 { return reverse_iterator(GetLast(), GetFirst()); } \
921 const_reverse_iterator rbegin() const \
922 { return const_reverse_iterator(GetLast(), GetFirst()); } \
923 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
924 const_reverse_iterator rend() const \
925 { return const_reverse_iterator(NULL, GetFirst()); } \
926 void resize(size_type n, value_type v = value_type()) \
933 size_type size() const { return GetCount(); } \
934 size_type max_size() const { return INT_MAX; } \
935 bool empty() const { return IsEmpty(); } \
936 reference front() { return *begin(); } \
937 const_reference front() const { return *begin(); } \
938 reference back() { return *--end(); } \
939 const_reference back() const { return *--end(); } \
940 void push_front(const_reference v = value_type()) \
941 { Insert(GetFirst(), (const_base_reference)v); } \
942 void pop_front() { DeleteNode(GetFirst()); } \
943 void push_back(const_reference v = value_type()) \
944 { Append((const_base_reference)v); } \
945 void pop_back() { DeleteNode(GetLast()); } \
946 void assign(const_iterator first, const_iterator last) \
949 for(; first != last; ++first) \
950 Append((const_base_reference)*first); \
952 void assign(size_type n, const_reference v = value_type()) \
955 for(size_type i = 0; i < n; ++i) \
956 Append((const_base_reference)v); \
958 iterator insert(iterator it, const_reference v = value_type()) \
960 Insert(it.m_node, (const_base_reference)v); \
961 return iterator(it.m_node->GetPrevious(), GetLast()); \
963 void insert(iterator it, size_type n, const_reference v = value_type())\
965 for(size_type i = 0; i < n; ++i) \
966 Insert(it.m_node, (const_base_reference)v); \
968 void insert(iterator it, const_iterator first, const_iterator last) \
970 for(; first != last; ++first) \
971 Insert(it.m_node, (const_base_reference)*first); \
973 iterator erase(iterator it) \
975 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
976 DeleteNode(it.m_node); return next; \
978 iterator erase(iterator first, iterator last) \
980 iterator next = last; ++next; \
981 DeleteNodes(first.m_node, last.m_node); \
984 void clear() { Clear(); } \
985 void splice(iterator it, name& l, iterator first, iterator last) \
986 { insert(it, first, last); l.erase(first, last); } \
987 void splice(iterator it, name& l) \
988 { splice(it, l, l.begin(), l.end() ); } \
989 void splice(iterator it, name& l, iterator first) \
991 iterator tmp = first; ++tmp; \
992 if(it == first || it == tmp) return; \
993 insert(it, *first); \
996 void remove(const_reference v) \
997 { DeleteObject((const_base_reference)v); } \
1000 /* void swap(name& l) \
1002 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
1003 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1004 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1005 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1006 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1010 #define WX_LIST_PTROP \
1011 pointer_type operator->() const \
1012 { return (pointer_type)m_node->GetDataPtr(); }
1013 #define WX_LIST_PTROP_NONE
1015 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1016 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1017 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1018 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1020 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1021 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
1022 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1023 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
1025 #define WX_DECLARE_LIST(elementtype, listname) \
1026 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1027 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
1028 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
1029 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1030 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
1032 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
1033 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1034 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
1036 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1037 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1039 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1040 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1041 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
1043 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1044 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1045 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
1046 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1047 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1048 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
1050 // this macro must be inserted in your program after
1051 // #include <wx/listimpl.cpp>
1052 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1054 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1055 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1057 #endif // !wxUSE_STL
1059 // ============================================================================
1060 // now we can define classes 100% compatible with the old ones
1061 // ============================================================================
1063 // ----------------------------------------------------------------------------
1064 // commonly used list classes
1065 // ----------------------------------------------------------------------------
1067 #if defined(wxLIST_COMPATIBILITY)
1069 // inline compatibility functions
1073 // ----------------------------------------------------------------------------
1074 // wxNodeBase deprecated methods
1075 // ----------------------------------------------------------------------------
1077 inline wxNode
*wxNodeBase::Next() const { return (wxNode
*)GetNext(); }
1078 inline wxNode
*wxNodeBase::Previous() const { return (wxNode
*)GetPrevious(); }
1079 inline wxObject
*wxNodeBase::Data() const { return (wxObject
*)GetData(); }
1081 // ----------------------------------------------------------------------------
1082 // wxListBase deprecated methods
1083 // ----------------------------------------------------------------------------
1085 inline int wxListBase::Number() const { return (int)GetCount(); }
1086 inline wxNode
*wxListBase::First() const { return (wxNode
*)GetFirst(); }
1087 inline wxNode
*wxListBase::Last() const { return (wxNode
*)GetLast(); }
1088 inline wxNode
*wxListBase::Nth(size_t n
) const { return (wxNode
*)Item(n
); }
1089 inline wxListBase::operator wxList
&() const { return *(wxList
*)this; }
1093 // define this to make a lot of noise about use of the old wxList classes.
1094 //#define wxWARN_COMPAT_LIST_USE
1096 // ----------------------------------------------------------------------------
1097 // wxList compatibility class: in fact, it's a list of wxObjects
1098 // ----------------------------------------------------------------------------
1100 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1101 class WXDLLIMPEXP_BASE
);
1103 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1106 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1108 wxDEPRECATED( wxList(int key_type
) );
1110 wxList(int key_type
= wxKEY_NONE
);
1113 // this destructor is required for Darwin
1117 wxList
& operator=(const wxList
& list
)
1118 { (void) wxListBase::operator=(list
); return *this; }
1120 // compatibility methods
1121 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
1126 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1131 DECLARE_DYNAMIC_CLASS(wxList
)
1137 // -----------------------------------------------------------------------------
1138 // wxStringList class for compatibility with the old code
1139 // -----------------------------------------------------------------------------
1140 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1142 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1147 #ifdef wxWARN_COMPAT_LIST_USE
1149 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1152 wxStringList(const wxChar
*first
...);
1155 // copying the string list: the strings are copied, too (extremely
1157 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(true); DoCopy(other
); }
1158 wxStringList
& operator=(const wxStringList
& other
)
1159 { Clear(); DoCopy(other
); return *this; }
1162 // makes a copy of the string
1163 wxNode
*Add(const wxChar
*s
);
1165 // Append to beginning of list
1166 wxNode
*Prepend(const wxChar
*s
);
1168 bool Delete(const wxChar
*s
);
1170 wxChar
**ListToArray(bool new_copies
= false) const;
1171 bool Member(const wxChar
*s
) const;
1177 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1179 DECLARE_DYNAMIC_CLASS(wxStringList
)
1182 #else // if wxUSE_STL
1184 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLIMPEXP_BASE
);
1186 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1189 compatibility_iterator
Append(wxChar
* s
)
1190 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Append(tmp
); }
1191 compatibility_iterator
Insert(wxChar
* s
)
1192 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Insert(tmp
); }
1193 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1197 return wxStringListBase::Insert(pos
, tmp
);
1199 compatibility_iterator
Add(const wxChar
* s
)
1200 { push_back(s
); return GetLast(); }
1201 compatibility_iterator
Prepend(const wxChar
* s
)
1202 { push_front(s
); return GetFirst(); }
1207 #endif // wxLIST_COMPATIBILITY
1209 // delete all list elements
1211 // NB: the class declaration of the list elements must be visible from the
1212 // place where you use this macro, otherwise the proper destructor may not
1213 // be called (a decent compiler should give a warning about it, but don't
1215 #define WX_CLEAR_LIST(type, list) \
1217 type::iterator it, en; \
1218 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \