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 // Visual C++ 2005 complains about the const
139 #if (defined(__VISUALC__) && __VISUALC__ >= 1400) || defined(__MWERKS__)
140 #define _WX_DELETEFUNCTIONCONST
142 #define _WX_DELETEFUNCTIONCONST const
145 #define WX_DECLARE_LIST_XO(elT, liT, decl) \
146 VC6_WORKAROUND(elT, liT, decl) \
147 decl liT : public std::list<elT> \
152 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
153 static void DeleteFunction( _WX_DELETEFUNCTIONCONST _WX_LIST_ITEM_TYPE_##liT X ); \
155 class compatibility_iterator \
158 /* Workaround for broken VC6 nested class name resolution */ \
159 typedef std::list<elT>::iterator iterator; \
165 compatibility_iterator() \
166 : m_iter(), m_list( NULL ) {} \
167 compatibility_iterator( liT* li, iterator i ) \
168 : m_iter( i ), m_list( li ) {} \
169 compatibility_iterator( const liT* li, iterator i ) \
170 : m_iter( i ), m_list( const_cast< liT* >( li ) ) {} \
172 compatibility_iterator* operator->() { return this; } \
173 const compatibility_iterator* operator->() const { return this; } \
175 bool operator==(const compatibility_iterator& i) const \
176 { return (m_list == i.m_list) && (m_iter == i.m_iter); } \
177 bool operator!=(const compatibility_iterator& i) const \
178 { return !( operator==( i ) ); } \
179 operator bool() const \
180 { return m_list ? m_iter != m_list->end() : false; } \
181 bool operator !() const \
182 { return !( operator bool() ); } \
184 elT GetData() const \
185 { return *m_iter; } \
186 void SetData( elT e ) \
189 compatibility_iterator GetNext() const \
191 iterator i = m_iter; \
192 return compatibility_iterator( m_list, ++i ); \
194 compatibility_iterator GetPrevious() const \
196 iterator i = m_iter; \
197 return compatibility_iterator( m_list, --i ); \
199 int IndexOf() const \
202 m_iter != m_list->end() ? \
203 std::distance( m_list->begin(), m_iter ) : \
209 liT() : m_destroy( false ) {} \
211 compatibility_iterator Find( const elT e ) const \
213 liT* _this = const_cast< liT* >( this ); \
214 return compatibility_iterator( _this, \
215 std::find( _this->begin(), _this->end(), e ) ); \
218 bool IsEmpty() const \
219 { return empty(); } \
220 size_t GetCount() const \
223 { return static_cast< int >( GetCount() ); } \
225 compatibility_iterator Item( size_t idx ) const \
227 iterator i = const_cast< liT* >(this)->begin(); \
228 std::advance( i, idx ); \
229 return compatibility_iterator( this, i ); \
231 compatibility_iterator GetFirst() const \
233 return compatibility_iterator( this, \
234 const_cast< liT* >(this)->begin() ); \
236 compatibility_iterator GetLast() const \
238 iterator i = const_cast< liT* >(this)->end(); \
239 return compatibility_iterator( this, !empty() ? --i : i ); \
241 compatibility_iterator Member( elT e ) const \
242 { return Find( e ); } \
243 compatibility_iterator Nth( int n ) const \
244 { return Item( n ); } \
245 int IndexOf( elT e ) const \
246 { return Find( e ).IndexOf(); } \
248 compatibility_iterator Append( elT e ) \
253 compatibility_iterator Insert( elT e ) \
256 return compatibility_iterator( this, begin() ); \
258 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
260 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
262 compatibility_iterator Insert( size_t idx, elT e ) \
264 return compatibility_iterator( this, \
265 insert( Item( idx ).m_iter, e ) ); \
268 void DeleteContents( bool destroy ) \
269 { m_destroy = destroy; } \
270 bool GetDeleteContents() const \
271 { return m_destroy; } \
272 void Erase( const compatibility_iterator& i ) \
275 DeleteFunction( i->GetData() ); \
278 bool DeleteNode( const compatibility_iterator& i ) \
287 bool DeleteObject( elT e ) \
289 return DeleteNode( Find( e ) ); \
294 std::for_each( begin(), end(), DeleteFunction ); \
297 /* Workaround for broken VC6 std::list::sort() see above */ \
298 void Sort( wxSortCompareFunction compfunc ) \
299 { sort( WX_LIST_SORTFUNCTION( elT, compfunc ) ); } \
300 ~liT() { Clear(); } \
303 #define WX_DECLARE_LIST(elementtype, listname) \
304 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
305 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
306 WX_DECLARE_LIST(elementtype, listname)
308 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
309 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
310 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
311 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
313 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
314 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
315 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
316 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
318 // this macro must be inserted in your program after
319 // #include "wx/listimpl.cpp"
320 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
322 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
323 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
325 #else // if !wxUSE_STL
327 // due to circular header dependencies this function has to be declared here
328 // (normally it's found in utils.h which includes itself list.h...)
329 #if WXWIN_COMPATIBILITY_2_4
330 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
333 // undef it to get rid of old, deprecated functions
334 #define wxLIST_COMPATIBILITY
336 // -----------------------------------------------------------------------------
337 // key stuff: a list may be optionally keyed on integer or string key
338 // -----------------------------------------------------------------------------
346 // a struct which may contain both types of keys
348 // implementation note: on one hand, this class allows to have only one function
349 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
350 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
351 // wxList::Find(const char *).
352 class WXDLLIMPEXP_BASE wxListKey
356 wxListKey() : m_keyType(wxKEY_NONE
)
358 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
359 { m_key
.integer
= i
; }
360 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
361 { m_key
.string
= wxStrdup(s
); }
362 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
363 { m_key
.string
= wxStrdup(s
.c_str()); }
366 wxKeyType
GetKeyType() const { return m_keyType
; }
367 const wxChar
*GetString() const
368 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
369 long GetNumber() const
370 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
373 // Note: implementation moved to list.cpp to prevent BC++ inline
374 // expansion warning.
375 bool operator==(wxListKeyValue value
) const ;
380 if ( m_keyType
== wxKEY_STRING
)
386 wxListKeyValue m_key
;
389 // -----------------------------------------------------------------------------
390 // wxNodeBase class is a (base for) node in a double linked list
391 // -----------------------------------------------------------------------------
393 extern WXDLLIMPEXP_DATA_BASE(wxListKey
) wxDefaultListKey
;
395 class WXDLLIMPEXP_BASE wxListBase
;
397 class WXDLLIMPEXP_BASE wxNodeBase
399 friend class wxListBase
;
402 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
403 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
404 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
406 const wxListKey
& key
= wxDefaultListKey
);
408 virtual ~wxNodeBase();
410 // FIXME no check is done that the list is really keyed on strings
411 const wxChar
*GetKeyString() const { return m_key
.string
; }
412 long GetKeyInteger() const { return m_key
.integer
; }
414 // Necessary for some existing code
415 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
416 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
418 #ifdef wxLIST_COMPATIBILITY
419 // compatibility methods, use Get* instead.
420 wxDEPRECATED( wxNode
*Next() const );
421 wxDEPRECATED( wxNode
*Previous() const );
422 wxDEPRECATED( wxObject
*Data() const );
423 #endif // wxLIST_COMPATIBILITY
426 // all these are going to be "overloaded" in the derived classes
427 wxNodeBase
*GetNext() const { return m_next
; }
428 wxNodeBase
*GetPrevious() const { return m_previous
; }
430 void *GetData() const { return m_data
; }
431 void SetData(void *data
) { m_data
= data
; }
433 // get 0-based index of this node within the list or wxNOT_FOUND
436 virtual void DeleteData() { }
438 // for wxList::iterator
439 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
441 // optional key stuff
442 wxListKeyValue m_key
;
444 void *m_data
; // user data
445 wxNodeBase
*m_next
, // next and previous nodes in the list
448 wxListBase
*m_list
; // list we belong to
450 DECLARE_NO_COPY_CLASS(wxNodeBase
)
453 // -----------------------------------------------------------------------------
454 // a double-linked list class
455 // -----------------------------------------------------------------------------
457 class WXDLLIMPEXP_BASE wxList
;
459 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
461 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
462 friend class wxHashTableBase
; // should be able to call untyped Find()
465 // default ctor & dtor
466 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
468 virtual ~wxListBase();
471 // count of items in the list
472 size_t GetCount() const { return m_count
; }
474 // return true if this list is empty
475 bool IsEmpty() const { return m_count
== 0; }
482 // instruct it to destroy user data when deleting nodes
483 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
485 // query if to delete
486 bool GetDeleteContents() const
487 { return m_destroy
; }
490 wxKeyType
GetKeyType() const
491 { return m_keyType
; }
493 // set the keytype (required by the serial code)
494 void SetKeyType(wxKeyType keyType
)
495 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
497 #ifdef wxLIST_COMPATIBILITY
498 // compatibility methods from old wxList
499 wxDEPRECATED( int Number() const ); // use GetCount instead.
500 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
501 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
502 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
504 // kludge for typesafe list migration in core classes.
505 wxDEPRECATED( operator wxList
&() const );
506 #endif // wxLIST_COMPATIBILITY
510 // all methods here are "overloaded" in derived classes to provide compile
511 // time type checking
513 // create a node for the list of this type
514 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
516 const wxListKey
& key
= wxDefaultListKey
) = 0;
518 // Can't access these from derived classes otherwise (bug in Salford C++?)
525 wxListBase(size_t count
, void *elements
[]);
526 // from a sequence of objects
527 wxListBase(void *object
, ... /* terminate with NULL */);
530 void Assign(const wxListBase
& list
)
531 { Clear(); DoCopy(list
); }
533 // get list head/tail
534 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
535 wxNodeBase
*GetLast() const { return m_nodeLast
; }
537 // by (0-based) index
538 wxNodeBase
*Item(size_t index
) const;
540 // get the list item's data
541 void *operator[](size_t n
) const
543 wxNodeBase
*node
= Item(n
);
545 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
549 // append to end of list
550 wxNodeBase
*Prepend(void *object
)
551 { return (wxNodeBase
*)wxListBase::Insert(object
); }
552 // append to beginning of list
553 wxNodeBase
*Append(void *object
);
554 // insert a new item at the beginning of the list
555 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
556 // insert a new item at the given position
557 wxNodeBase
*Insert(size_t pos
, void *object
)
558 { return pos
== GetCount() ? Append(object
)
559 : Insert(Item(pos
), object
); }
560 // insert before given node or at front of list if prev == NULL
561 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
564 wxNodeBase
*Append(long key
, void *object
);
565 wxNodeBase
*Append(const wxChar
*key
, void *object
);
567 // removes node from the list but doesn't delete it (returns pointer
568 // to the node or NULL if it wasn't found in the list)
569 wxNodeBase
*DetachNode(wxNodeBase
*node
);
570 // delete element from list, returns false if node not found
571 bool DeleteNode(wxNodeBase
*node
);
572 // finds object pointer and deletes node (and object if DeleteContents
573 // is on), returns false if object not found
574 bool DeleteObject(void *object
);
576 // search (all return NULL if item not found)
578 wxNodeBase
*Find(const void *object
) const;
581 wxNodeBase
*Find(const wxListKey
& key
) const;
583 // get 0-based index of object or wxNOT_FOUND
584 int IndexOf( void *object
) const;
586 // this function allows the sorting of arbitrary lists by giving
587 // a function to compare two list elements. The list is sorted in place.
588 void Sort(const wxSortCompareFunction compfunc
);
590 // functions for iterating over the list
591 void *FirstThat(wxListIterateFunction func
);
592 void ForEach(wxListIterateFunction func
);
593 void *LastThat(wxListIterateFunction func
);
595 // for STL interface, "last" points to one after the last node
596 // of the controlled sequence (NULL for the end of the list)
598 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
601 // common part of all ctors
602 void Init(wxKeyType keyType
= wxKEY_NONE
);
605 // common part of copy ctor and assignment operator
606 void DoCopy(const wxListBase
& list
);
607 // common part of all Append()s
608 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
609 // free node's data and node itself
610 void DoDeleteNode(wxNodeBase
*node
);
612 size_t m_count
; // number of elements in the list
613 bool m_destroy
; // destroy user data when deleting list items?
614 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
617 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
620 // -----------------------------------------------------------------------------
621 // macros for definition of "template" list type
622 // -----------------------------------------------------------------------------
624 // and now some heavy magic...
626 // declare a list type named 'name' and containing elements of type 'T *'
627 // (as a by product of macro expansion you also get wx##name##Node
628 // wxNode-derived type)
630 // implementation details:
631 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
632 // for the list of given type - this allows us to pass only the list name
633 // to WX_DEFINE_LIST() even if it needs both the name and the type
635 // 2. We redefine all non-type-safe wxList functions with type-safe versions
636 // which don't take any space (everything is inline), but bring compile
637 // time error checking.
639 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
640 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
641 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
642 // interesting capability to store polymorphic objects in the list and is
643 // particularly useful with, for example, "wxWindow *" list where the
644 // wxWindowBase pointers are put into the list, but wxWindow pointers are
645 // retrieved from it.
647 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
648 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
649 // it results in compiler warnings when this operator doesn't make sense
650 // (i.e. stored elements are not pointers)
652 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
653 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
654 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
656 classexp nodetype : public wxNodeBase \
659 nodetype(wxListBase *list = (wxListBase *)NULL, \
660 nodetype *previous = (nodetype *)NULL, \
661 nodetype *next = (nodetype *)NULL, \
662 T *data = (T *)NULL, \
663 const wxListKey& key = wxDefaultListKey) \
664 : wxNodeBase(list, previous, next, data, key) { } \
666 nodetype *GetNext() const \
667 { return (nodetype *)wxNodeBase::GetNext(); } \
668 nodetype *GetPrevious() const \
669 { return (nodetype *)wxNodeBase::GetPrevious(); } \
672 { return (T *)wxNodeBase::GetData(); } \
673 void SetData(T *data) \
674 { wxNodeBase::SetData(data); } \
677 virtual void DeleteData(); \
679 DECLARE_NO_COPY_CLASS(nodetype) \
682 classexp name : public wxListBase \
685 typedef nodetype Node; \
686 typedef Node* compatibility_iterator; \
688 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
690 name(const name& list) : wxListBase(list.GetKeyType()) \
692 name(size_t count, T *elements[]) \
693 : wxListBase(count, (void **)elements) { } \
695 name& operator=(const name& list) \
696 { Assign(list); return *this; } \
698 nodetype *GetFirst() const \
699 { return (nodetype *)wxListBase::GetFirst(); } \
700 nodetype *GetLast() const \
701 { return (nodetype *)wxListBase::GetLast(); } \
703 nodetype *Item(size_t index) const \
704 { return (nodetype *)wxListBase::Item(index); } \
706 T *operator[](size_t index) const \
708 nodetype *node = Item(index); \
709 return node ? (T*)(node->GetData()) : (T*)NULL; \
712 nodetype *Append(Tbase *object) \
713 { return (nodetype *)wxListBase::Append(object); } \
714 nodetype *Insert(Tbase *object) \
715 { return (nodetype *)Insert((nodetype*)NULL, object); } \
716 nodetype *Insert(size_t pos, Tbase *object) \
717 { return (nodetype *)wxListBase::Insert(pos, object); } \
718 nodetype *Insert(nodetype *prev, Tbase *object) \
719 { return (nodetype *)wxListBase::Insert(prev, object); } \
721 nodetype *Append(long key, void *object) \
722 { return (nodetype *)wxListBase::Append(key, object); } \
723 nodetype *Append(const wxChar *key, void *object) \
724 { return (nodetype *)wxListBase::Append(key, object); } \
726 nodetype *DetachNode(nodetype *node) \
727 { return (nodetype *)wxListBase::DetachNode(node); } \
728 bool DeleteNode(nodetype *node) \
729 { return wxListBase::DeleteNode(node); } \
730 bool DeleteObject(Tbase *object) \
731 { return wxListBase::DeleteObject(object); } \
732 void Erase(compatibility_iterator it) \
733 { DeleteNode(it); } \
735 nodetype *Find(const Tbase *object) const \
736 { return (nodetype *)wxListBase::Find(object); } \
738 virtual nodetype *Find(const wxListKey& key) const \
739 { return (nodetype *)wxListBase::Find(key); } \
741 int IndexOf(Tbase *object) const \
742 { return wxListBase::IndexOf(object); } \
744 void Sort(wxSortCompareFunction func) \
745 { wxListBase::Sort(func); } \
746 void Sort(wxSortFuncFor_##name func) \
747 { Sort((wxSortCompareFunction)func); } \
750 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
752 const wxListKey& key = wxDefaultListKey) \
754 return new nodetype(this, \
755 (nodetype *)prev, (nodetype *)next, \
758 /* STL interface */ \
760 typedef size_t size_type; \
761 typedef int difference_type; \
762 typedef T* value_type; \
763 typedef Tbase* base_value_type; \
764 typedef value_type& reference; \
765 typedef const value_type& const_reference; \
766 typedef base_value_type& base_reference; \
767 typedef const base_value_type& const_base_reference; \
773 typedef nodetype Node; \
774 typedef iterator itor; \
775 typedef T* value_type; \
776 typedef value_type* ptr_type; \
777 typedef value_type& reference; \
782 typedef reference reference_type; \
783 typedef ptr_type pointer_type; \
785 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
786 iterator() : m_node(NULL), m_init(NULL) { } \
787 reference_type operator*() const \
788 { return *(pointer_type)m_node->GetDataPtr(); } \
790 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
791 const itor operator++(int) \
792 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
795 m_node = m_node ? m_node->GetPrevious() : m_init; \
798 const itor operator--(int) \
801 m_node = m_node ? m_node->GetPrevious() : m_init; \
804 bool operator!=(const itor& it) const \
805 { return it.m_node != m_node; } \
806 bool operator==(const itor& it) const \
807 { return it.m_node == m_node; } \
809 class const_iterator \
813 typedef nodetype Node; \
814 typedef T* value_type; \
815 typedef const value_type& const_reference; \
816 typedef const_iterator itor; \
817 typedef value_type* ptr_type; \
822 typedef const_reference reference_type; \
823 typedef const ptr_type pointer_type; \
825 const_iterator(Node* node, Node* init) \
826 : m_node(node), m_init(init) { } \
827 const_iterator() : m_node(NULL), m_init(NULL) { } \
828 const_iterator(const iterator& it) \
829 : m_node(it.m_node), m_init(it.m_init) { } \
830 reference_type operator*() const \
831 { return *(pointer_type)m_node->GetDataPtr(); } \
833 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
834 const itor operator++(int) \
835 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
838 m_node = m_node ? m_node->GetPrevious() : m_init; \
841 const itor operator--(int) \
844 m_node = m_node ? m_node->GetPrevious() : m_init; \
847 bool operator!=(const itor& it) const \
848 { return it.m_node != m_node; } \
849 bool operator==(const itor& it) const \
850 { return it.m_node == m_node; } \
852 class reverse_iterator \
856 typedef nodetype Node; \
857 typedef T* value_type; \
858 typedef reverse_iterator itor; \
859 typedef value_type* ptr_type; \
860 typedef value_type& reference; \
865 typedef reference reference_type; \
866 typedef ptr_type pointer_type; \
868 reverse_iterator(Node* node, Node* init) \
869 : m_node(node), m_init(init) { } \
870 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
871 reference_type operator*() const \
872 { return *(pointer_type)m_node->GetDataPtr(); } \
875 { m_node = m_node->GetPrevious(); return *this; } \
876 const itor operator++(int) \
877 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
879 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
880 const itor operator--(int) \
883 m_node = m_node ? m_node->GetNext() : m_init; \
886 bool operator!=(const itor& it) const \
887 { return it.m_node != m_node; } \
888 bool operator==(const itor& it) const \
889 { return it.m_node == m_node; } \
891 class const_reverse_iterator \
895 typedef nodetype Node; \
896 typedef T* value_type; \
897 typedef const_reverse_iterator itor; \
898 typedef value_type* ptr_type; \
899 typedef const value_type& const_reference; \
904 typedef const_reference reference_type; \
905 typedef const ptr_type pointer_type; \
907 const_reverse_iterator(Node* node, Node* init) \
908 : m_node(node), m_init(init) { } \
909 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
910 const_reverse_iterator(const reverse_iterator& it) \
911 : m_node(it.m_node), m_init(it.m_init) { } \
912 reference_type operator*() const \
913 { return *(pointer_type)m_node->GetDataPtr(); } \
916 { m_node = m_node->GetPrevious(); return *this; } \
917 const itor operator++(int) \
918 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
920 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
921 const itor operator--(int) \
924 m_node = m_node ? m_node->GetNext() : m_init; \
927 bool operator!=(const itor& it) const \
928 { return it.m_node != m_node; } \
929 bool operator==(const itor& it) const \
930 { return it.m_node == m_node; } \
933 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
935 name(const const_iterator& first, const const_iterator& last) \
936 { assign(first, last); } \
937 iterator begin() { return iterator(GetFirst(), GetLast()); } \
938 const_iterator begin() const \
939 { return const_iterator(GetFirst(), GetLast()); } \
940 iterator end() { return iterator(NULL, GetLast()); } \
941 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
942 reverse_iterator rbegin() \
943 { return reverse_iterator(GetLast(), GetFirst()); } \
944 const_reverse_iterator rbegin() const \
945 { return const_reverse_iterator(GetLast(), GetFirst()); } \
946 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
947 const_reverse_iterator rend() const \
948 { return const_reverse_iterator(NULL, GetFirst()); } \
949 void resize(size_type n, value_type v = value_type()) \
956 size_type size() const { return GetCount(); } \
957 size_type max_size() const { return INT_MAX; } \
958 bool empty() const { return IsEmpty(); } \
959 reference front() { return *begin(); } \
960 const_reference front() const { return *begin(); } \
961 reference back() { iterator tmp = end(); return *--tmp; } \
962 const_reference back() const { const_iterator tmp = end(); return *--tmp; }\
963 void push_front(const_reference v = value_type()) \
964 { Insert(GetFirst(), (const_base_reference)v); } \
965 void pop_front() { DeleteNode(GetFirst()); } \
966 void push_back(const_reference v = value_type()) \
967 { Append((const_base_reference)v); } \
968 void pop_back() { DeleteNode(GetLast()); } \
969 void assign(const_iterator first, const const_iterator& last) \
972 for(; first != last; ++first) \
973 Append((const_base_reference)*first); \
975 void assign(size_type n, const_reference v = value_type()) \
978 for(size_type i = 0; i < n; ++i) \
979 Append((const_base_reference)v); \
981 iterator insert(const iterator& it, const_reference v = value_type())\
983 Insert(it.m_node, (const_base_reference)v); \
984 return iterator(it.m_node->GetPrevious(), GetLast()); \
986 void insert(const iterator& it, size_type n, const_reference v = value_type())\
988 for(size_type i = 0; i < n; ++i) \
989 Insert(it.m_node, (const_base_reference)v); \
991 void insert(const iterator& it, const_iterator first, const const_iterator& last)\
993 for(; first != last; ++first) \
994 Insert(it.m_node, (const_base_reference)*first); \
996 iterator erase(const iterator& it) \
998 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
999 DeleteNode(it.m_node); return next; \
1001 iterator erase(const iterator& first, const iterator& last) \
1003 iterator next = last; ++next; \
1004 DeleteNodes(first.m_node, last.m_node); \
1007 void clear() { Clear(); } \
1008 void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
1009 { insert(it, first, last); l.erase(first, last); } \
1010 void splice(const iterator& it, name& l) \
1011 { splice(it, l, l.begin(), l.end() ); } \
1012 void splice(const iterator& it, name& l, const iterator& first) \
1014 iterator tmp = first; ++tmp; \
1015 if(it == first || it == tmp) return; \
1016 insert(it, *first); \
1019 void remove(const_reference v) \
1020 { DeleteObject((const_base_reference)v); } \
1023 /* void swap(name& l) \
1025 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
1026 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1027 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1028 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1029 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1033 #define WX_LIST_PTROP \
1034 pointer_type operator->() const \
1035 { return (pointer_type)m_node->GetDataPtr(); }
1036 #define WX_LIST_PTROP_NONE
1038 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1039 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1040 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1041 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1043 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1044 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
1045 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1046 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
1048 #define WX_DECLARE_LIST(elementtype, listname) \
1049 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1050 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
1051 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
1052 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1053 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
1055 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
1056 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1057 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
1059 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1060 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1062 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1063 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1064 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
1066 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1067 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1068 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
1069 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1070 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1071 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
1073 // this macro must be inserted in your program after
1074 // #include "wx/listimpl.cpp"
1075 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1077 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1078 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1080 #endif // !wxUSE_STL
1082 // ============================================================================
1083 // now we can define classes 100% compatible with the old ones
1084 // ============================================================================
1086 // ----------------------------------------------------------------------------
1087 // commonly used list classes
1088 // ----------------------------------------------------------------------------
1090 #if defined(wxLIST_COMPATIBILITY)
1092 // inline compatibility functions
1096 // ----------------------------------------------------------------------------
1097 // wxNodeBase deprecated methods
1098 // ----------------------------------------------------------------------------
1100 inline wxNode
*wxNodeBase::Next() const { return (wxNode
*)GetNext(); }
1101 inline wxNode
*wxNodeBase::Previous() const { return (wxNode
*)GetPrevious(); }
1102 inline wxObject
*wxNodeBase::Data() const { return (wxObject
*)GetData(); }
1104 // ----------------------------------------------------------------------------
1105 // wxListBase deprecated methods
1106 // ----------------------------------------------------------------------------
1108 inline int wxListBase::Number() const { return (int)GetCount(); }
1109 inline wxNode
*wxListBase::First() const { return (wxNode
*)GetFirst(); }
1110 inline wxNode
*wxListBase::Last() const { return (wxNode
*)GetLast(); }
1111 inline wxNode
*wxListBase::Nth(size_t n
) const { return (wxNode
*)Item(n
); }
1112 inline wxListBase::operator wxList
&() const { return *(wxList
*)this; }
1116 // define this to make a lot of noise about use of the old wxList classes.
1117 //#define wxWARN_COMPAT_LIST_USE
1119 // ----------------------------------------------------------------------------
1120 // wxList compatibility class: in fact, it's a list of wxObjects
1121 // ----------------------------------------------------------------------------
1123 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1124 class WXDLLIMPEXP_BASE
);
1126 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1129 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1131 wxDEPRECATED( wxList(int key_type
) );
1133 wxList(int key_type
= wxKEY_NONE
);
1136 // this destructor is required for Darwin
1140 wxList
& operator=(const wxList
& list
)
1141 { (void) wxListBase::operator=(list
); return *this; }
1143 // compatibility methods
1144 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
1149 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1154 DECLARE_DYNAMIC_CLASS(wxList
)
1160 // -----------------------------------------------------------------------------
1161 // wxStringList class for compatibility with the old code
1162 // -----------------------------------------------------------------------------
1163 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1165 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1170 #ifdef wxWARN_COMPAT_LIST_USE
1172 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1175 wxStringList(const wxChar
*first
...);
1178 // copying the string list: the strings are copied, too (extremely
1180 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(true); DoCopy(other
); }
1181 wxStringList
& operator=(const wxStringList
& other
)
1182 { Clear(); DoCopy(other
); return *this; }
1185 // makes a copy of the string
1186 wxNode
*Add(const wxChar
*s
);
1188 // Append to beginning of list
1189 wxNode
*Prepend(const wxChar
*s
);
1191 bool Delete(const wxChar
*s
);
1193 wxChar
**ListToArray(bool new_copies
= false) const;
1194 bool Member(const wxChar
*s
) const;
1200 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1202 DECLARE_DYNAMIC_CLASS(wxStringList
)
1205 #else // if wxUSE_STL
1207 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLIMPEXP_BASE
);
1209 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1212 compatibility_iterator
Append(wxChar
* s
)
1213 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Append(tmp
); }
1214 compatibility_iterator
Insert(wxChar
* s
)
1215 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Insert(tmp
); }
1216 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1220 return wxStringListBase::Insert(pos
, tmp
);
1222 compatibility_iterator
Add(const wxChar
* s
)
1223 { push_back(s
); return GetLast(); }
1224 compatibility_iterator
Prepend(const wxChar
* s
)
1225 { push_front(s
); return GetFirst(); }
1230 #endif // wxLIST_COMPATIBILITY
1232 // delete all list elements
1234 // NB: the class declaration of the list elements must be visible from the
1235 // place where you use this macro, otherwise the proper destructor may not
1236 // be called (a decent compiler should give a warning about it, but don't
1238 #define WX_CLEAR_LIST(type, list) \
1240 type::iterator it, en; \
1241 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1246 #endif // _WX_LISTH__