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 // -----------------------------------------------------------------------------
30 // -----------------------------------------------------------------------------
33 #include "wx/object.h"
34 #include "wx/string.h"
37 #include "wx/beforestd.h"
41 #include "wx/afterstd.h"
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 // type of compare function for list sort operation (as in 'qsort'): it should
49 // return a negative value, 0 or positive value if the first element is less
50 // than, equal or greater than the second
54 typedef int (* LINKAGEMODE wxSortCompareFunction
)(const void *elem1
, const void *elem2
);
57 class WXDLLIMPEXP_BASE wxObjectListNode
;
58 typedef wxObjectListNode wxNode
;
61 typedef int (* LINKAGEMODE wxListIterateFunction
)(void *current
);
63 // ----------------------------------------------------------------------------
65 // ----------------------------------------------------------------------------
67 #if !defined(wxENUM_KEY_TYPE_DEFINED)
68 #define wxENUM_KEY_TYPE_DEFINED
81 #define wxLIST_COMPATIBILITY
83 #define WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl) \
84 WX_DECLARE_LIST_WITH_DECL(elT, liT, decl)
85 #define WX_DECLARE_LIST_PTR_3(elT, dummy1, liT, dummy2, decl) \
86 WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl)
88 #define WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
89 WX_DECLARE_LIST_WITH_DECL(elT, liT, decl)
90 #define WX_DECLARE_LIST_PTR_2(elT, liT, dummy, decl) \
91 WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
93 #define WX_DECLARE_LIST_WITH_DECL(elT, liT, decl) \
94 WX_DECLARE_LIST_XO(elT*, liT, decl)
96 #if !defined( __VISUALC__ )
99 class WXDLLIMPEXP_BASE wxList_SortFunction
102 wxList_SortFunction(wxSortCompareFunction f
) : m_f(f
) { }
103 bool operator()(const T
& i1
, const T
& i2
)
104 { return m_f((T
*)&i1
, (T
*)&i2
) < 0; }
106 wxSortCompareFunction m_f
;
109 #define WX_LIST_SORTFUNCTION( elT, f ) wxList_SortFunction<elT>(f)
110 #define VC6_WORKAROUND(elT, liT, decl)
112 #else // if defined( __VISUALC__ )
114 #define WX_LIST_SORTFUNCTION( elT, f ) std::greater<elT>( f )
115 #define VC6_WORKAROUND(elT, liT, decl) \
118 /* Workaround for broken VC6 STL incorrectly requires a std::greater<> */ \
119 /* to be passed into std::list::sort() */ \
121 struct std::greater<elT> \
124 wxSortCompareFunction m_CompFunc; \
126 greater( wxSortCompareFunction compfunc = NULL ) \
127 : m_CompFunc( compfunc ) {} \
128 bool operator()(const elT X, const elT Y) const \
130 return m_CompFunc ? \
131 ( m_CompFunc( X, Y ) < 0 ) : \
136 #endif // defined( __VISUALC__ )
138 #define WX_DECLARE_LIST_XO(elT, liT, decl) \
139 VC6_WORKAROUND(elT, liT, decl) \
140 decl liT : public std::list<elT> \
145 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
146 static void DeleteFunction( const _WX_LIST_ITEM_TYPE_##liT X ); \
148 class compatibility_iterator \
151 /* Workaround for broken VC6 nested class name resolution */ \
152 typedef std::list<elT>::iterator iterator; \
158 compatibility_iterator() \
159 : m_iter(), m_list( NULL ) {} \
160 compatibility_iterator( liT* li, iterator i ) \
161 : m_iter( i ), m_list( li ) {} \
162 compatibility_iterator( const liT* li, iterator i ) \
163 : m_iter( i ), m_list( const_cast< liT* >( li ) ) {} \
165 compatibility_iterator* operator->() { return this; } \
166 const compatibility_iterator* operator->() const { return this; } \
168 bool operator==(const compatibility_iterator& i) const \
169 { return (m_list == i.m_list) && (m_iter == i.m_iter); } \
170 bool operator!=(const compatibility_iterator& i) const \
171 { return !( operator==( i ) ); } \
172 operator bool() const \
173 { return m_list ? m_iter != m_list->end() : false; } \
174 bool operator !() const \
175 { return !( operator bool() ); } \
177 elT GetData() const \
178 { return *m_iter; } \
179 void SetData( elT e ) \
182 compatibility_iterator GetNext() const \
184 iterator i = m_iter; \
185 return compatibility_iterator( m_list, ++i ); \
187 compatibility_iterator GetPrevious() const \
189 iterator i = m_iter; \
190 return compatibility_iterator( m_list, --i ); \
192 int IndexOf() const \
195 m_iter != m_list->end() ? \
196 std::distance( m_list->begin(), m_iter ) : \
202 liT() : m_destroy( false ) {} \
204 compatibility_iterator Find( const elT e ) const \
206 liT* _this = const_cast< liT* >( this ); \
207 return compatibility_iterator( _this, \
208 std::find( _this->begin(), _this->end(), e ) ); \
211 bool IsEmpty() const \
212 { return empty(); } \
213 size_t GetCount() const \
216 { return static_cast< int >( GetCount() ); } \
218 compatibility_iterator Item( size_t idx ) const \
220 iterator i = const_cast< liT* >(this)->begin(); \
221 std::advance( i, idx ); \
222 return compatibility_iterator( this, i ); \
224 compatibility_iterator GetFirst() const \
226 return compatibility_iterator( this, \
227 const_cast< liT* >(this)->begin() ); \
229 compatibility_iterator GetLast() const \
231 iterator i = const_cast< liT* >(this)->end(); \
232 return compatibility_iterator( this, !empty() ? --i : i ); \
234 compatibility_iterator Member( elT e ) const \
235 { return Find( e ); } \
236 compatibility_iterator Nth( int n ) const \
237 { return Item( n ); } \
238 int IndexOf( elT e ) const \
239 { return Find( e ).IndexOf(); } \
241 compatibility_iterator Append( elT e ) \
246 compatibility_iterator Insert( elT e ) \
249 return compatibility_iterator( this, begin() ); \
251 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
253 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
255 compatibility_iterator Insert( size_t idx, elT e ) \
257 return compatibility_iterator( this, \
258 insert( Item( idx ).m_iter, e ) ); \
261 void DeleteContents( bool destroy ) \
262 { m_destroy = destroy; } \
263 bool GetDeleteContents() const \
264 { return m_destroy; } \
265 void Erase( const compatibility_iterator& i ) \
268 DeleteFunction( i->GetData() ); \
271 bool DeleteNode( const compatibility_iterator& i ) \
280 bool DeleteObject( elT e ) \
282 return DeleteNode( Find( e ) ); \
287 std::for_each( begin(), end(), DeleteFunction ); \
290 /* Workaround for broken VC6 std::list::sort() see above */ \
291 void Sort( wxSortCompareFunction compfunc ) \
292 { sort( WX_LIST_SORTFUNCTION( elT, compfunc ) ); } \
293 ~liT() { Clear(); } \
296 #define WX_DECLARE_LIST(elementtype, listname) \
297 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
298 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
299 WX_DECLARE_LIST(elementtype, listname)
301 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
302 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
303 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
304 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
306 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
307 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
308 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
309 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
311 // this macro must be inserted in your program after
312 // #include <wx/listimpl.cpp>
313 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
315 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
316 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
318 #else // if !wxUSE_STL
320 // due to circular header dependencies this function has to be declared here
321 // (normally it's found in utils.h which includes itself list.h...)
322 #if WXWIN_COMPATIBILITY_2_4
323 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
326 // undef it to get rid of old, deprecated functions
327 #define wxLIST_COMPATIBILITY
329 // -----------------------------------------------------------------------------
330 // key stuff: a list may be optionally keyed on integer or string key
331 // -----------------------------------------------------------------------------
339 // a struct which may contain both types of keys
341 // implementation note: on one hand, this class allows to have only one function
342 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
343 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
344 // wxList::Find(const char *).
345 class WXDLLIMPEXP_BASE wxListKey
349 wxListKey() : m_keyType(wxKEY_NONE
)
351 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
352 { m_key
.integer
= i
; }
353 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
354 { m_key
.string
= wxStrdup(s
); }
355 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
356 { m_key
.string
= wxStrdup(s
.c_str()); }
359 wxKeyType
GetKeyType() const { return m_keyType
; }
360 const wxChar
*GetString() const
361 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
362 long GetNumber() const
363 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
366 // Note: implementation moved to list.cpp to prevent BC++ inline
367 // expansion warning.
368 bool operator==(wxListKeyValue value
) const ;
373 if ( m_keyType
== wxKEY_STRING
)
379 wxListKeyValue m_key
;
382 // -----------------------------------------------------------------------------
383 // wxNodeBase class is a (base for) node in a double linked list
384 // -----------------------------------------------------------------------------
386 extern WXDLLIMPEXP_DATA_BASE(wxListKey
) wxDefaultListKey
;
388 class WXDLLIMPEXP_BASE wxListBase
;
390 class WXDLLIMPEXP_BASE wxNodeBase
392 friend class wxListBase
;
395 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
396 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
397 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
399 const wxListKey
& key
= wxDefaultListKey
);
401 virtual ~wxNodeBase();
403 // FIXME no check is done that the list is really keyed on strings
404 const wxChar
*GetKeyString() const { return m_key
.string
; }
405 long GetKeyInteger() const { return m_key
.integer
; }
407 // Necessary for some existing code
408 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
409 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
411 #ifdef wxLIST_COMPATIBILITY
412 // compatibility methods, use Get* instead.
413 wxDEPRECATED( wxNode
*Next() const );
414 wxDEPRECATED( wxNode
*Previous() const );
415 wxDEPRECATED( wxObject
*Data() const );
416 #endif // wxLIST_COMPATIBILITY
419 // all these are going to be "overloaded" in the derived classes
420 wxNodeBase
*GetNext() const { return m_next
; }
421 wxNodeBase
*GetPrevious() const { return m_previous
; }
423 void *GetData() const { return m_data
; }
424 void SetData(void *data
) { m_data
= data
; }
426 // get 0-based index of this node within the list or wxNOT_FOUND
429 virtual void DeleteData() { }
431 // for wxList::iterator
432 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
434 // optional key stuff
435 wxListKeyValue m_key
;
437 void *m_data
; // user data
438 wxNodeBase
*m_next
, // next and previous nodes in the list
441 wxListBase
*m_list
; // list we belong to
443 DECLARE_NO_COPY_CLASS(wxNodeBase
)
446 // -----------------------------------------------------------------------------
447 // a double-linked list class
448 // -----------------------------------------------------------------------------
450 class WXDLLIMPEXP_BASE wxList
;
452 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
454 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
455 friend class wxHashTableBase
; // should be able to call untyped Find()
458 // default ctor & dtor
459 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
461 virtual ~wxListBase();
464 // count of items in the list
465 size_t GetCount() const { return m_count
; }
467 // return true if this list is empty
468 bool IsEmpty() const { return m_count
== 0; }
475 // instruct it to destroy user data when deleting nodes
476 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
478 // query if to delete
479 bool GetDeleteContents() const
480 { return m_destroy
; }
483 wxKeyType
GetKeyType() const
484 { return m_keyType
; }
486 // set the keytype (required by the serial code)
487 void SetKeyType(wxKeyType keyType
)
488 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
490 #ifdef wxLIST_COMPATIBILITY
491 // compatibility methods from old wxList
492 wxDEPRECATED( int Number() const ); // use GetCount instead.
493 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
494 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
495 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
497 // kludge for typesafe list migration in core classes.
498 wxDEPRECATED( operator wxList
&() const );
499 #endif // wxLIST_COMPATIBILITY
503 // all methods here are "overloaded" in derived classes to provide compile
504 // time type checking
506 // create a node for the list of this type
507 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
509 const wxListKey
& key
= wxDefaultListKey
) = 0;
511 // Can't access these from derived classes otherwise (bug in Salford C++?)
518 wxListBase(size_t count
, void *elements
[]);
519 // from a sequence of objects
520 wxListBase(void *object
, ... /* terminate with NULL */);
523 void Assign(const wxListBase
& list
)
524 { Clear(); DoCopy(list
); }
526 // get list head/tail
527 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
528 wxNodeBase
*GetLast() const { return m_nodeLast
; }
530 // by (0-based) index
531 wxNodeBase
*Item(size_t index
) const;
533 // get the list item's data
534 void *operator[](size_t n
) const
536 wxNodeBase
*node
= Item(n
);
538 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
542 // append to end of list
543 wxNodeBase
*Prepend(void *object
)
544 { return (wxNodeBase
*)wxListBase::Insert(object
); }
545 // append to beginning of list
546 wxNodeBase
*Append(void *object
);
547 // insert a new item at the beginning of the list
548 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
549 // insert a new item at the given position
550 wxNodeBase
*Insert(size_t pos
, void *object
)
551 { return pos
== GetCount() ? Append(object
)
552 : Insert(Item(pos
), object
); }
553 // insert before given node or at front of list if prev == NULL
554 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
557 wxNodeBase
*Append(long key
, void *object
);
558 wxNodeBase
*Append(const wxChar
*key
, void *object
);
560 // removes node from the list but doesn't delete it (returns pointer
561 // to the node or NULL if it wasn't found in the list)
562 wxNodeBase
*DetachNode(wxNodeBase
*node
);
563 // delete element from list, returns false if node not found
564 bool DeleteNode(wxNodeBase
*node
);
565 // finds object pointer and deletes node (and object if DeleteContents
566 // is on), returns false if object not found
567 bool DeleteObject(void *object
);
569 // search (all return NULL if item not found)
571 wxNodeBase
*Find(const void *object
) const;
574 wxNodeBase
*Find(const wxListKey
& key
) const;
576 // get 0-based index of object or wxNOT_FOUND
577 int IndexOf( void *object
) const;
579 // this function allows the sorting of arbitrary lists by giving
580 // a function to compare two list elements. The list is sorted in place.
581 void Sort(const wxSortCompareFunction compfunc
);
583 // functions for iterating over the list
584 void *FirstThat(wxListIterateFunction func
);
585 void ForEach(wxListIterateFunction func
);
586 void *LastThat(wxListIterateFunction func
);
588 // for STL interface, "last" points to one after the last node
589 // of the controlled sequence (NULL for the end of the list)
591 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
594 // common part of all ctors
595 void Init(wxKeyType keyType
= wxKEY_NONE
);
598 // common part of copy ctor and assignment operator
599 void DoCopy(const wxListBase
& list
);
600 // common part of all Append()s
601 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
602 // free node's data and node itself
603 void DoDeleteNode(wxNodeBase
*node
);
605 size_t m_count
; // number of elements in the list
606 bool m_destroy
; // destroy user data when deleting list items?
607 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
610 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
613 // -----------------------------------------------------------------------------
614 // macros for definition of "template" list type
615 // -----------------------------------------------------------------------------
617 // and now some heavy magic...
619 // declare a list type named 'name' and containing elements of type 'T *'
620 // (as a by product of macro expansion you also get wx##name##Node
621 // wxNode-derived type)
623 // implementation details:
624 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
625 // for the list of given type - this allows us to pass only the list name
626 // to WX_DEFINE_LIST() even if it needs both the name and the type
628 // 2. We redefine all non-type-safe wxList functions with type-safe versions
629 // which don't take any space (everything is inline), but bring compile
630 // time error checking.
632 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
633 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
634 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
635 // interesting capability to store polymorphic objects in the list and is
636 // particularly useful with, for example, "wxWindow *" list where the
637 // wxWindowBase pointers are put into the list, but wxWindow pointers are
638 // retrieved from it.
640 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
641 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
642 // it results in compiler warnings when this operator doesn't make sense
643 // (i.e. stored elements are not pointers)
645 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
646 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
647 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
649 classexp nodetype : public wxNodeBase \
652 nodetype(wxListBase *list = (wxListBase *)NULL, \
653 nodetype *previous = (nodetype *)NULL, \
654 nodetype *next = (nodetype *)NULL, \
655 T *data = (T *)NULL, \
656 const wxListKey& key = wxDefaultListKey) \
657 : wxNodeBase(list, previous, next, data, key) { } \
659 nodetype *GetNext() const \
660 { return (nodetype *)wxNodeBase::GetNext(); } \
661 nodetype *GetPrevious() const \
662 { return (nodetype *)wxNodeBase::GetPrevious(); } \
665 { return (T *)wxNodeBase::GetData(); } \
666 void SetData(T *data) \
667 { wxNodeBase::SetData(data); } \
670 virtual void DeleteData(); \
672 DECLARE_NO_COPY_CLASS(nodetype) \
675 classexp name : public wxListBase \
678 typedef nodetype Node; \
679 typedef Node* compatibility_iterator; \
681 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
683 name(const name& list) : wxListBase(list.GetKeyType()) \
685 name(size_t count, T *elements[]) \
686 : wxListBase(count, (void **)elements) { } \
688 name& operator=(const name& list) \
689 { Assign(list); return *this; } \
691 nodetype *GetFirst() const \
692 { return (nodetype *)wxListBase::GetFirst(); } \
693 nodetype *GetLast() const \
694 { return (nodetype *)wxListBase::GetLast(); } \
696 nodetype *Item(size_t index) const \
697 { return (nodetype *)wxListBase::Item(index); } \
699 T *operator[](size_t index) const \
701 nodetype *node = Item(index); \
702 return node ? (T*)(node->GetData()) : (T*)NULL; \
705 nodetype *Append(Tbase *object) \
706 { return (nodetype *)wxListBase::Append(object); } \
707 nodetype *Insert(Tbase *object) \
708 { return (nodetype *)Insert((nodetype*)NULL, object); } \
709 nodetype *Insert(size_t pos, Tbase *object) \
710 { return (nodetype *)wxListBase::Insert(pos, object); } \
711 nodetype *Insert(nodetype *prev, Tbase *object) \
712 { return (nodetype *)wxListBase::Insert(prev, object); } \
714 nodetype *Append(long key, void *object) \
715 { return (nodetype *)wxListBase::Append(key, object); } \
716 nodetype *Append(const wxChar *key, void *object) \
717 { return (nodetype *)wxListBase::Append(key, object); } \
719 nodetype *DetachNode(nodetype *node) \
720 { return (nodetype *)wxListBase::DetachNode(node); } \
721 bool DeleteNode(nodetype *node) \
722 { return wxListBase::DeleteNode(node); } \
723 bool DeleteObject(Tbase *object) \
724 { return wxListBase::DeleteObject(object); } \
725 void Erase(compatibility_iterator it) \
726 { DeleteNode(it); } \
728 nodetype *Find(const Tbase *object) const \
729 { return (nodetype *)wxListBase::Find(object); } \
731 virtual nodetype *Find(const wxListKey& key) const \
732 { return (nodetype *)wxListBase::Find(key); } \
734 int IndexOf(Tbase *object) const \
735 { return wxListBase::IndexOf(object); } \
737 void Sort(wxSortCompareFunction func) \
738 { wxListBase::Sort(func); } \
739 void Sort(wxSortFuncFor_##name func) \
740 { Sort((wxSortCompareFunction)func); } \
743 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
745 const wxListKey& key = wxDefaultListKey) \
747 return new nodetype(this, \
748 (nodetype *)prev, (nodetype *)next, \
751 /* STL interface */ \
753 typedef size_t size_type; \
754 typedef int difference_type; \
755 typedef T* value_type; \
756 typedef Tbase* base_value_type; \
757 typedef value_type& reference; \
758 typedef const value_type& const_reference; \
759 typedef base_value_type& base_reference; \
760 typedef const base_value_type& const_base_reference; \
766 typedef nodetype Node; \
767 typedef iterator itor; \
768 typedef T* value_type; \
769 typedef value_type* ptr_type; \
770 typedef value_type& reference; \
775 typedef reference reference_type; \
776 typedef ptr_type pointer_type; \
778 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
779 iterator() : m_node(NULL), m_init(NULL) { } \
780 reference_type operator*() const \
781 { return *(pointer_type)m_node->GetDataPtr(); } \
783 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
784 const itor operator++(int) \
785 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
788 m_node = m_node ? m_node->GetPrevious() : m_init; \
791 const itor operator--(int) \
794 m_node = m_node ? m_node->GetPrevious() : m_init; \
797 bool operator!=(const itor& it) const \
798 { return it.m_node != m_node; } \
799 bool operator==(const itor& it) const \
800 { return it.m_node == m_node; } \
802 class const_iterator \
806 typedef nodetype Node; \
807 typedef T* value_type; \
808 typedef const value_type& const_reference; \
809 typedef const_iterator itor; \
810 typedef value_type* ptr_type; \
815 typedef const_reference reference_type; \
816 typedef const ptr_type pointer_type; \
818 const_iterator(Node* node, Node* init) \
819 : m_node(node), m_init(init) { } \
820 const_iterator() : m_node(NULL), m_init(NULL) { } \
821 const_iterator(const iterator& it) \
822 : m_node(it.m_node), m_init(it.m_init) { } \
823 reference_type operator*() const \
824 { return *(pointer_type)m_node->GetDataPtr(); } \
826 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
827 const itor operator++(int) \
828 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
831 m_node = m_node ? m_node->GetPrevious() : m_init; \
834 const itor operator--(int) \
837 m_node = m_node ? m_node->GetPrevious() : m_init; \
840 bool operator!=(const itor& it) const \
841 { return it.m_node != m_node; } \
842 bool operator==(const itor& it) const \
843 { return it.m_node == m_node; } \
845 class reverse_iterator \
849 typedef nodetype Node; \
850 typedef T* value_type; \
851 typedef reverse_iterator itor; \
852 typedef value_type* ptr_type; \
853 typedef value_type& reference; \
858 typedef reference reference_type; \
859 typedef ptr_type pointer_type; \
861 reverse_iterator(Node* node, Node* init) \
862 : m_node(node), m_init(init) { } \
863 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
864 reference_type operator*() const \
865 { return *(pointer_type)m_node->GetDataPtr(); } \
868 { m_node = m_node->GetPrevious(); return *this; } \
869 const itor operator++(int) \
870 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
872 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
873 const itor operator--(int) \
876 m_node = m_node ? m_node->GetNext() : m_init; \
879 bool operator!=(const itor& it) const \
880 { return it.m_node != m_node; } \
881 bool operator==(const itor& it) const \
882 { return it.m_node == m_node; } \
884 class const_reverse_iterator \
888 typedef nodetype Node; \
889 typedef T* value_type; \
890 typedef const_reverse_iterator itor; \
891 typedef value_type* ptr_type; \
892 typedef const value_type& const_reference; \
897 typedef const_reference reference_type; \
898 typedef const ptr_type pointer_type; \
900 const_reverse_iterator(Node* node, Node* init) \
901 : m_node(node), m_init(init) { } \
902 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
903 const_reverse_iterator(const reverse_iterator& it) \
904 : m_node(it.m_node), m_init(it.m_init) { } \
905 reference_type operator*() const \
906 { return *(pointer_type)m_node->GetDataPtr(); } \
909 { m_node = m_node->GetPrevious(); return *this; } \
910 const itor operator++(int) \
911 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
913 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
914 const itor operator--(int) \
917 m_node = m_node ? m_node->GetNext() : m_init; \
920 bool operator!=(const itor& it) const \
921 { return it.m_node != m_node; } \
922 bool operator==(const itor& it) const \
923 { return it.m_node == m_node; } \
926 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
928 name(const const_iterator& first, const const_iterator& last) \
929 { assign(first, last); } \
930 iterator begin() { return iterator(GetFirst(), GetLast()); } \
931 const_iterator begin() const \
932 { return const_iterator(GetFirst(), GetLast()); } \
933 iterator end() { return iterator(NULL, GetLast()); } \
934 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
935 reverse_iterator rbegin() \
936 { return reverse_iterator(GetLast(), GetFirst()); } \
937 const_reverse_iterator rbegin() const \
938 { return const_reverse_iterator(GetLast(), GetFirst()); } \
939 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
940 const_reverse_iterator rend() const \
941 { return const_reverse_iterator(NULL, GetFirst()); } \
942 void resize(size_type n, value_type v = value_type()) \
949 size_type size() const { return GetCount(); } \
950 size_type max_size() const { return INT_MAX; } \
951 bool empty() const { return IsEmpty(); } \
952 reference front() { return *begin(); } \
953 const_reference front() const { return *begin(); } \
954 reference back() { iterator tmp = end(); return *--tmp; } \
955 const_reference back() const { const_iterator tmp = end(); return *--tmp; }\
956 void push_front(const_reference v = value_type()) \
957 { Insert(GetFirst(), (const_base_reference)v); } \
958 void pop_front() { DeleteNode(GetFirst()); } \
959 void push_back(const_reference v = value_type()) \
960 { Append((const_base_reference)v); } \
961 void pop_back() { DeleteNode(GetLast()); } \
962 void assign(const_iterator first, const const_iterator& last) \
965 for(; first != last; ++first) \
966 Append((const_base_reference)*first); \
968 void assign(size_type n, const_reference v = value_type()) \
971 for(size_type i = 0; i < n; ++i) \
972 Append((const_base_reference)v); \
974 iterator insert(const iterator& it, const_reference v = value_type())\
976 Insert(it.m_node, (const_base_reference)v); \
977 return iterator(it.m_node->GetPrevious(), GetLast()); \
979 void insert(const iterator& it, size_type n, const_reference v = value_type())\
981 for(size_type i = 0; i < n; ++i) \
982 Insert(it.m_node, (const_base_reference)v); \
984 void insert(const iterator& it, const_iterator first, const const_iterator& last)\
986 for(; first != last; ++first) \
987 Insert(it.m_node, (const_base_reference)*first); \
989 iterator erase(const iterator& it) \
991 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
992 DeleteNode(it.m_node); return next; \
994 iterator erase(const iterator& first, const iterator& last) \
996 iterator next = last; ++next; \
997 DeleteNodes(first.m_node, last.m_node); \
1000 void clear() { Clear(); } \
1001 void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
1002 { insert(it, first, last); l.erase(first, last); } \
1003 void splice(const iterator& it, name& l) \
1004 { splice(it, l, l.begin(), l.end() ); } \
1005 void splice(const iterator& it, name& l, const iterator& first) \
1007 iterator tmp = first; ++tmp; \
1008 if(it == first || it == tmp) return; \
1009 insert(it, *first); \
1012 void remove(const_reference v) \
1013 { DeleteObject((const_base_reference)v); } \
1016 /* void swap(name& l) \
1018 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
1019 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1020 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1021 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1022 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1026 #define WX_LIST_PTROP \
1027 pointer_type operator->() const \
1028 { return (pointer_type)m_node->GetDataPtr(); }
1029 #define WX_LIST_PTROP_NONE
1031 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1032 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1033 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1034 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1036 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1037 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
1038 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1039 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
1041 #define WX_DECLARE_LIST(elementtype, listname) \
1042 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1043 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
1044 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
1045 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1046 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
1048 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
1049 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1050 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
1052 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1053 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1055 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1056 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1057 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
1059 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1060 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1061 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
1062 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1063 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1064 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
1066 // this macro must be inserted in your program after
1067 // #include <wx/listimpl.cpp>
1068 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1070 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1071 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1073 #endif // !wxUSE_STL
1075 // ============================================================================
1076 // now we can define classes 100% compatible with the old ones
1077 // ============================================================================
1079 // ----------------------------------------------------------------------------
1080 // commonly used list classes
1081 // ----------------------------------------------------------------------------
1083 #if defined(wxLIST_COMPATIBILITY)
1085 // inline compatibility functions
1089 // ----------------------------------------------------------------------------
1090 // wxNodeBase deprecated methods
1091 // ----------------------------------------------------------------------------
1093 inline wxNode
*wxNodeBase::Next() const { return (wxNode
*)GetNext(); }
1094 inline wxNode
*wxNodeBase::Previous() const { return (wxNode
*)GetPrevious(); }
1095 inline wxObject
*wxNodeBase::Data() const { return (wxObject
*)GetData(); }
1097 // ----------------------------------------------------------------------------
1098 // wxListBase deprecated methods
1099 // ----------------------------------------------------------------------------
1101 inline int wxListBase::Number() const { return (int)GetCount(); }
1102 inline wxNode
*wxListBase::First() const { return (wxNode
*)GetFirst(); }
1103 inline wxNode
*wxListBase::Last() const { return (wxNode
*)GetLast(); }
1104 inline wxNode
*wxListBase::Nth(size_t n
) const { return (wxNode
*)Item(n
); }
1105 inline wxListBase::operator wxList
&() const { return *(wxList
*)this; }
1109 // define this to make a lot of noise about use of the old wxList classes.
1110 //#define wxWARN_COMPAT_LIST_USE
1112 // ----------------------------------------------------------------------------
1113 // wxList compatibility class: in fact, it's a list of wxObjects
1114 // ----------------------------------------------------------------------------
1116 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1117 class WXDLLIMPEXP_BASE
);
1119 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1122 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1124 wxDEPRECATED( wxList(int key_type
) );
1126 wxList(int key_type
= wxKEY_NONE
);
1129 // this destructor is required for Darwin
1133 wxList
& operator=(const wxList
& list
)
1134 { (void) wxListBase::operator=(list
); return *this; }
1136 // compatibility methods
1137 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
1142 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1147 DECLARE_DYNAMIC_CLASS(wxList
)
1153 // -----------------------------------------------------------------------------
1154 // wxStringList class for compatibility with the old code
1155 // -----------------------------------------------------------------------------
1156 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1158 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1163 #ifdef wxWARN_COMPAT_LIST_USE
1165 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1168 wxStringList(const wxChar
*first
...);
1171 // copying the string list: the strings are copied, too (extremely
1173 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(true); DoCopy(other
); }
1174 wxStringList
& operator=(const wxStringList
& other
)
1175 { Clear(); DoCopy(other
); return *this; }
1178 // makes a copy of the string
1179 wxNode
*Add(const wxChar
*s
);
1181 // Append to beginning of list
1182 wxNode
*Prepend(const wxChar
*s
);
1184 bool Delete(const wxChar
*s
);
1186 wxChar
**ListToArray(bool new_copies
= false) const;
1187 bool Member(const wxChar
*s
) const;
1193 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1195 DECLARE_DYNAMIC_CLASS(wxStringList
)
1198 #else // if wxUSE_STL
1200 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLIMPEXP_BASE
);
1202 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1205 compatibility_iterator
Append(wxChar
* s
)
1206 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Append(tmp
); }
1207 compatibility_iterator
Insert(wxChar
* s
)
1208 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Insert(tmp
); }
1209 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1213 return wxStringListBase::Insert(pos
, tmp
);
1215 compatibility_iterator
Add(const wxChar
* s
)
1216 { push_back(s
); return GetLast(); }
1217 compatibility_iterator
Prepend(const wxChar
* s
)
1218 { push_front(s
); return GetFirst(); }
1223 #endif // wxLIST_COMPATIBILITY
1225 // delete all list elements
1227 // NB: the class declaration of the list elements must be visible from the
1228 // place where you use this macro, otherwise the proper destructor may not
1229 // be called (a decent compiler should give a warning about it, but don't
1231 #define WX_CLEAR_LIST(type, list) \
1233 type::iterator it, en; \
1234 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \