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) \
102 decl liT : public std::list<elT> \
107 class SortCompareFunction \
110 wxSortCompareFunction m_CompFunc; \
112 SortCompareFunction( wxSortCompareFunction compfunc ) \
113 : m_CompFunc( compfunc ) {} \
114 bool operator()( const elT X, const elT Y ) const \
115 { return ( m_CompFunc( X, Y ) < 0 ); } \
118 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
119 static void DeleteFunction( const _WX_LIST_ITEM_TYPE_##liT X ); \
121 class compatibility_iterator \
124 typedef liT::iterator iterator; \
130 compatibility_iterator() \
131 : m_iter(), m_list( NULL ) {} \
132 compatibility_iterator( liT* li, iterator i ) \
133 : m_iter( i ), m_list( li ) {} \
134 compatibility_iterator( const liT* li, iterator i ) \
135 : m_iter( i ), m_list( const_cast< liT* >( li ) ) {} \
137 compatibility_iterator* operator->() { return this; } \
138 const compatibility_iterator* operator->() const { return this; } \
140 bool operator==(const compatibility_iterator& i) \
141 { return (m_list == i.m_list) && (m_iter == i.m_iter); } \
142 bool operator!=(const compatibility_iterator& i) \
143 { return !( operator==( i ) ); } \
144 operator bool() const \
145 { return m_list ? m_iter != m_list->end() : false; } \
146 bool operator !() const \
147 { return !( operator bool() ); } \
149 elT GetData() const \
150 { return *m_iter; } \
151 void SetData( elT e ) \
154 compatibility_iterator GetNext() const \
156 iterator i = m_iter; \
157 return compatibility_iterator( m_list, ++i ); \
159 compatibility_iterator GetPrevious() const \
161 iterator i = m_iter; \
162 return compatibility_iterator( m_list, --i ); \
164 int IndexOf() const \
167 m_iter != m_list->end() ? \
168 std::distance( m_list->begin(), m_iter ) : \
174 liT() : m_destroy( false ) {} \
176 compatibility_iterator Find( const elT e ) const \
178 liT* _this = const_cast< liT* >( this ); \
179 return compatibility_iterator( _this, \
180 std::find( _this->begin(), _this->end(), e ) ); \
183 bool IsEmpty() const \
184 { return empty(); } \
185 size_t GetCount() const \
188 { return static_cast< int >( GetCount() ); } \
190 compatibility_iterator Item( size_t idx ) const \
192 iterator i = const_cast< liT* >(this)->begin(); \
193 std::advance( i, idx ); \
194 return compatibility_iterator( this, i ); \
196 compatibility_iterator GetFirst() const \
198 return compatibility_iterator( this, \
199 const_cast< liT* >(this)->begin() ); \
201 compatibility_iterator GetLast() const \
203 iterator i = const_cast< liT* >(this)->end(); \
204 return compatibility_iterator( this, !empty() ? --i : i ); \
206 compatibility_iterator Member( elT e ) const \
207 { return Find( e ); } \
208 compatibility_iterator Nth( int n ) const \
209 { return Item( n ); } \
210 int IndexOf( elT e ) const \
211 { return Find( e ).IndexOf(); } \
213 compatibility_iterator Append( elT e ) \
218 compatibility_iterator Insert( elT e ) \
221 return compatibility_iterator( this, begin() ); \
223 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
225 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
227 compatibility_iterator Insert( size_t idx, elT e ) \
229 return compatibility_iterator( this, \
230 insert( Item( idx ).m_iter, e ) ); \
233 void DeleteContents( bool destroy ) \
234 { m_destroy = destroy; } \
235 bool GetDeleteContents() const \
236 { return m_destroy; } \
237 void Erase( const compatibility_iterator& i ) \
240 DeleteFunction( i->GetData() ); \
243 bool DeleteNode( const compatibility_iterator& i ) \
252 bool DeleteObject( elT e ) \
254 return DeleteNode( Find( e ) ); \
259 std::for_each( begin(), end(), DeleteFunction ); \
263 void Sort( wxSortCompareFunction compfunc ) \
264 { sort( SortCompareFunction( compfunc ) ); } \
266 ~liT() { Clear(); } \
269 #define WX_DECLARE_LIST(elementtype, listname) \
270 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
271 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
272 WX_DECLARE_LIST(elementtype, listname)
274 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
275 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
276 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
277 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
279 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
280 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
281 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
282 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
284 // this macro must be inserted in your program after
285 // #include <wx/listimpl.cpp>
286 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
288 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
289 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
291 #else // if !wxUSE_STL
293 // due to circular header dependencies this function has to be declared here
294 // (normally it's found in utils.h which includes itself list.h...)
295 #if WXWIN_COMPATIBILITY_2_4
296 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
299 class WXDLLEXPORT wxObjectListNode
;
300 typedef wxObjectListNode wxNode
;
302 // undef it to get rid of old, deprecated functions
303 #define wxLIST_COMPATIBILITY
305 // -----------------------------------------------------------------------------
306 // key stuff: a list may be optionally keyed on integer or string key
307 // -----------------------------------------------------------------------------
315 // a struct which may contain both types of keys
317 // implementation note: on one hand, this class allows to have only one function
318 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
319 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
320 // wxList::Find(const char *).
321 class WXDLLIMPEXP_BASE wxListKey
325 wxListKey() : m_keyType(wxKEY_NONE
)
327 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
328 { m_key
.integer
= i
; }
329 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
330 { m_key
.string
= wxStrdup(s
); }
331 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
332 { m_key
.string
= wxStrdup(s
.c_str()); }
335 wxKeyType
GetKeyType() const { return m_keyType
; }
336 const wxChar
*GetString() const
337 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
338 long GetNumber() const
339 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
342 // Note: implementation moved to list.cpp to prevent BC++ inline
343 // expansion warning.
344 bool operator==(wxListKeyValue value
) const ;
349 if ( m_keyType
== wxKEY_STRING
)
355 wxListKeyValue m_key
;
358 // -----------------------------------------------------------------------------
359 // wxNodeBase class is a (base for) node in a double linked list
360 // -----------------------------------------------------------------------------
362 extern WXDLLIMPEXP_DATA_BASE(wxListKey
) wxDefaultListKey
;
364 class WXDLLIMPEXP_BASE wxListBase
;
366 class WXDLLIMPEXP_BASE wxNodeBase
368 friend class wxListBase
;
371 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
372 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
373 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
375 const wxListKey
& key
= wxDefaultListKey
);
377 virtual ~wxNodeBase();
379 // FIXME no check is done that the list is really keyed on strings
380 const wxChar
*GetKeyString() const { return m_key
.string
; }
381 long GetKeyInteger() const { return m_key
.integer
; }
383 // Necessary for some existing code
384 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
385 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
387 #ifdef wxLIST_COMPATIBILITY
388 // compatibility methods, use Get* instead.
389 wxDEPRECATED( wxNode
*Next() const );
390 wxDEPRECATED( wxNode
*Previous() const );
391 wxDEPRECATED( wxObject
*Data() const );
392 #endif // wxLIST_COMPATIBILITY
395 // all these are going to be "overloaded" in the derived classes
396 wxNodeBase
*GetNext() const { return m_next
; }
397 wxNodeBase
*GetPrevious() const { return m_previous
; }
399 void *GetData() const { return m_data
; }
400 void SetData(void *data
) { m_data
= data
; }
402 // get 0-based index of this node within the list or wxNOT_FOUND
405 virtual void DeleteData() { }
407 // for wxList::iterator
408 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
410 // optional key stuff
411 wxListKeyValue m_key
;
413 void *m_data
; // user data
414 wxNodeBase
*m_next
, // next and previous nodes in the list
417 wxListBase
*m_list
; // list we belong to
419 DECLARE_NO_COPY_CLASS(wxNodeBase
)
422 // -----------------------------------------------------------------------------
423 // a double-linked list class
424 // -----------------------------------------------------------------------------
426 class WXDLLIMPEXP_BASE wxList
;
428 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
430 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
431 friend class wxHashTableBase
; // should be able to call untyped Find()
433 // common part of all ctors
434 void Init(wxKeyType keyType
= wxKEY_NONE
); // Must be declared before it's used (for VC++ 1.5)
436 // default ctor & dtor
437 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
439 virtual ~wxListBase();
442 // count of items in the list
443 size_t GetCount() const { return m_count
; }
445 // return true if this list is empty
446 bool IsEmpty() const { return m_count
== 0; }
453 // instruct it to destroy user data when deleting nodes
454 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
456 // query if to delete
457 bool GetDeleteContents() const
458 { return m_destroy
; }
461 wxKeyType
GetKeyType() const
462 { return m_keyType
; }
464 // set the keytype (required by the serial code)
465 void SetKeyType(wxKeyType keyType
)
466 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
468 #ifdef wxLIST_COMPATIBILITY
469 // compatibility methods from old wxList
470 wxDEPRECATED( int Number() const ); // use GetCount instead.
471 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
472 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
473 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
475 // kludge for typesafe list migration in core classes.
476 wxDEPRECATED( operator wxList
&() const );
477 #endif // wxLIST_COMPATIBILITY
481 // all methods here are "overloaded" in derived classes to provide compile
482 // time type checking
484 // create a node for the list of this type
485 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
487 const wxListKey
& key
= wxDefaultListKey
) = 0;
489 // Can't access these from derived classes otherwise (bug in Salford C++?)
496 wxListBase(size_t count
, void *elements
[]);
497 // from a sequence of objects
498 wxListBase(void *object
, ... /* terminate with NULL */);
501 void Assign(const wxListBase
& list
)
502 { Clear(); DoCopy(list
); }
504 // get list head/tail
505 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
506 wxNodeBase
*GetLast() const { return m_nodeLast
; }
508 // by (0-based) index
509 wxNodeBase
*Item(size_t index
) const;
511 // get the list item's data
512 void *operator[](size_t n
) const
514 wxNodeBase
*node
= Item(n
);
516 return node
? node
->GetData() : (wxNodeBase
*)NULL
;
520 // append to end of list
521 wxNodeBase
*Prepend(void *object
)
522 { return (wxNodeBase
*)wxListBase::Insert(object
); }
523 // append to beginning of list
524 wxNodeBase
*Append(void *object
);
525 // insert a new item at the beginning of the list
526 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
527 // insert a new item at the given position
528 wxNodeBase
*Insert(size_t pos
, void *object
)
529 { return pos
== GetCount() ? Append(object
)
530 : Insert(Item(pos
), object
); }
531 // insert before given node or at front of list if prev == NULL
532 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
535 wxNodeBase
*Append(long key
, void *object
);
536 wxNodeBase
*Append(const wxChar
*key
, void *object
);
538 // removes node from the list but doesn't delete it (returns pointer
539 // to the node or NULL if it wasn't found in the list)
540 wxNodeBase
*DetachNode(wxNodeBase
*node
);
541 // delete element from list, returns false if node not found
542 bool DeleteNode(wxNodeBase
*node
);
543 // finds object pointer and deletes node (and object if DeleteContents
544 // is on), returns false if object not found
545 bool DeleteObject(void *object
);
547 // search (all return NULL if item not found)
549 wxNodeBase
*Find(const void *object
) const;
552 wxNodeBase
*Find(const wxListKey
& key
) const;
554 // get 0-based index of object or wxNOT_FOUND
555 int IndexOf( void *object
) const;
557 // this function allows the sorting of arbitrary lists by giving
558 // a function to compare two list elements. The list is sorted in place.
559 void Sort(const wxSortCompareFunction compfunc
);
561 // functions for iterating over the list
562 void *FirstThat(wxListIterateFunction func
);
563 void ForEach(wxListIterateFunction func
);
564 void *LastThat(wxListIterateFunction func
);
566 // for STL interface, "last" points to one after the last node
567 // of the controlled sequence (NULL for the end of the list)
569 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
572 // common part of copy ctor and assignment operator
573 void DoCopy(const wxListBase
& list
);
574 // common part of all Append()s
575 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
576 // free node's data and node itself
577 void DoDeleteNode(wxNodeBase
*node
);
579 size_t m_count
; // number of elements in the list
580 bool m_destroy
; // destroy user data when deleting list items?
581 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
584 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
587 // -----------------------------------------------------------------------------
588 // macros for definition of "template" list type
589 // -----------------------------------------------------------------------------
591 // and now some heavy magic...
593 // declare a list type named 'name' and containing elements of type 'T *'
594 // (as a by product of macro expansion you also get wx##name##Node
595 // wxNode-derived type)
597 // implementation details:
598 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
599 // for the list of given type - this allows us to pass only the list name
600 // to WX_DEFINE_LIST() even if it needs both the name and the type
602 // 2. We redefine all non-type-safe wxList functions with type-safe versions
603 // which don't take any space (everything is inline), but bring compile
604 // time error checking.
606 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
607 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
608 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
609 // interesting capability to store polymorphic objects in the list and is
610 // particularly useful with, for example, "wxWindow *" list where the
611 // wxWindowBase pointers are put into the list, but wxWindow pointers are
612 // retrieved from it.
614 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
615 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
616 // it results in compiler warnings when this operator doesn't make sense
617 // (i.e. stored elements are not pointers)
619 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
620 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
621 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
623 classexp nodetype : public wxNodeBase \
626 nodetype(wxListBase *list = (wxListBase *)NULL, \
627 nodetype *previous = (nodetype *)NULL, \
628 nodetype *next = (nodetype *)NULL, \
629 T *data = (T *)NULL, \
630 const wxListKey& key = wxDefaultListKey) \
631 : wxNodeBase(list, previous, next, data, key) { } \
633 nodetype *GetNext() const \
634 { return (nodetype *)wxNodeBase::GetNext(); } \
635 nodetype *GetPrevious() const \
636 { return (nodetype *)wxNodeBase::GetPrevious(); } \
639 { return (T *)wxNodeBase::GetData(); } \
640 void SetData(T *data) \
641 { wxNodeBase::SetData(data); } \
643 virtual void DeleteData(); \
645 DECLARE_NO_COPY_CLASS(nodetype) \
648 classexp name : public wxListBase \
651 typedef nodetype Node; \
652 typedef Node* compatibility_iterator; \
654 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
656 name(const name& list) : wxListBase(list.GetKeyType()) \
658 name(size_t count, T *elements[]) \
659 : wxListBase(count, (void **)elements) { } \
661 name& operator=(const name& list) \
662 { Assign(list); return *this; } \
664 nodetype *GetFirst() const \
665 { return (nodetype *)wxListBase::GetFirst(); } \
666 nodetype *GetLast() const \
667 { return (nodetype *)wxListBase::GetLast(); } \
669 nodetype *Item(size_t index) const \
670 { return (nodetype *)wxListBase::Item(index); } \
672 T *operator[](size_t index) const \
674 nodetype *node = Item(index); \
675 return node ? (T*)(node->GetData()) : (T*)NULL; \
678 nodetype *Append(Tbase *object) \
679 { return (nodetype *)wxListBase::Append(object); } \
680 nodetype *Insert(Tbase *object) \
681 { return (nodetype *)Insert((nodetype*)NULL, object); } \
682 nodetype *Insert(size_t pos, Tbase *object) \
683 { return (nodetype *)wxListBase::Insert(pos, object); } \
684 nodetype *Insert(nodetype *prev, Tbase *object) \
685 { return (nodetype *)wxListBase::Insert(prev, object); } \
687 nodetype *Append(long key, void *object) \
688 { return (nodetype *)wxListBase::Append(key, object); } \
689 nodetype *Append(const wxChar *key, void *object) \
690 { return (nodetype *)wxListBase::Append(key, object); } \
692 nodetype *DetachNode(nodetype *node) \
693 { return (nodetype *)wxListBase::DetachNode(node); } \
694 bool DeleteNode(nodetype *node) \
695 { return wxListBase::DeleteNode(node); } \
696 bool DeleteObject(Tbase *object) \
697 { return wxListBase::DeleteObject(object); } \
698 void Erase(compatibility_iterator it) \
699 { DeleteNode(it); } \
701 nodetype *Find(const Tbase *object) const \
702 { return (nodetype *)wxListBase::Find(object); } \
704 virtual nodetype *Find(const wxListKey& key) const \
705 { return (nodetype *)wxListBase::Find(key); } \
707 int IndexOf(Tbase *object) const \
708 { return wxListBase::IndexOf(object); } \
710 void Sort(wxSortCompareFunction func) \
711 { wxListBase::Sort(func); } \
712 void Sort(wxSortFuncFor_##name func) \
713 { Sort((wxSortCompareFunction)func); } \
716 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
718 const wxListKey& key = wxDefaultListKey) \
720 return new nodetype(this, \
721 (nodetype *)prev, (nodetype *)next, \
724 /* STL interface */ \
726 typedef size_t size_type; \
727 typedef int difference_type; \
728 typedef T* value_type; \
729 typedef Tbase* base_value_type; \
730 typedef value_type& reference; \
731 typedef const value_type& const_reference; \
732 typedef base_value_type& base_reference; \
733 typedef const base_value_type& const_base_reference; \
739 typedef nodetype Node; \
740 typedef iterator itor; \
741 typedef T* value_type; \
742 typedef value_type* ptr_type; \
743 typedef value_type& reference; \
748 typedef reference reference_type; \
749 typedef ptr_type pointer_type; \
751 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
752 iterator() : m_node(NULL), m_init(NULL) { } \
753 reference_type operator*() const \
754 { return *(pointer_type)m_node->GetDataPtr(); } \
756 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
757 itor operator++(int) \
758 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
761 m_node = m_node ? m_node->GetPrevious() : m_init; \
764 itor operator--(int) \
767 m_node = m_node ? m_node->GetPrevious() : m_init; \
770 bool operator!=(const itor& it) const \
771 { return it.m_node != m_node; } \
772 bool operator==(const itor& it) const \
773 { return it.m_node == m_node; } \
775 class const_iterator \
779 typedef nodetype Node; \
780 typedef T* value_type; \
781 typedef const value_type& const_reference; \
782 typedef const_iterator itor; \
783 typedef value_type* ptr_type; \
788 typedef const_reference reference_type; \
789 typedef const ptr_type pointer_type; \
791 const_iterator(Node* node, Node* init) \
792 : m_node(node), m_init(init) { } \
793 const_iterator() : m_node(NULL), m_init(NULL) { } \
794 const_iterator(const iterator& it) \
795 : m_node(it.m_node), m_init(it.m_init) { } \
796 reference_type operator*() const \
797 { return *(pointer_type)m_node->GetDataPtr(); } \
799 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
800 itor operator++(int) \
801 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
804 m_node = m_node ? m_node->GetPrevious() : m_init; \
807 itor operator--(int) \
810 m_node = m_node ? m_node->GetPrevious() : m_init; \
813 bool operator!=(const itor& it) const \
814 { return it.m_node != m_node; } \
815 bool operator==(const itor& it) const \
816 { return it.m_node == m_node; } \
818 class reverse_iterator \
822 typedef nodetype Node; \
823 typedef T* value_type; \
824 typedef reverse_iterator itor; \
825 typedef value_type* ptr_type; \
826 typedef value_type& reference; \
831 typedef reference reference_type; \
832 typedef ptr_type pointer_type; \
834 reverse_iterator(Node* node, Node* init) \
835 : m_node(node), m_init(init) { } \
836 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
837 reference_type operator*() const \
838 { return *(pointer_type)m_node->GetDataPtr(); } \
841 { m_node = m_node->GetPrevious(); return *this; } \
842 itor operator++(int) \
843 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
845 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
846 itor operator--(int) \
849 m_node = m_node ? m_node->GetNext() : m_init; \
852 bool operator!=(const itor& it) const \
853 { return it.m_node != m_node; } \
854 bool operator==(const itor& it) const \
855 { return it.m_node == m_node; } \
857 class const_reverse_iterator \
861 typedef nodetype Node; \
862 typedef T* value_type; \
863 typedef const_reverse_iterator itor; \
864 typedef value_type* ptr_type; \
865 typedef const value_type& const_reference; \
870 typedef const_reference reference_type; \
871 typedef const ptr_type pointer_type; \
873 const_reverse_iterator(Node* node, Node* init) \
874 : m_node(node), m_init(init) { } \
875 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
876 const_reverse_iterator(const reverse_iterator& it) \
877 : m_node(it.m_node), m_init(it.m_init) { } \
878 reference_type operator*() const \
879 { return *(pointer_type)m_node->GetDataPtr(); } \
882 { m_node = m_node->GetPrevious(); return *this; } \
883 itor operator++(int) \
884 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
886 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
887 itor operator--(int) \
890 m_node = m_node ? m_node->GetNext() : m_init; \
893 bool operator!=(const itor& it) const \
894 { return it.m_node != m_node; } \
895 bool operator==(const itor& it) const \
896 { return it.m_node == m_node; } \
899 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
901 name(const_iterator first, const_iterator last) \
902 { assign(first, last); } \
903 iterator begin() { return iterator(GetFirst(), GetLast()); } \
904 const_iterator begin() const \
905 { return const_iterator(GetFirst(), GetLast()); } \
906 iterator end() { return iterator(NULL, GetLast()); } \
907 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
908 reverse_iterator rbegin() \
909 { return reverse_iterator(GetLast(), GetFirst()); } \
910 const_reverse_iterator rbegin() const \
911 { return const_reverse_iterator(GetLast(), GetFirst()); } \
912 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
913 const_reverse_iterator rend() const \
914 { return const_reverse_iterator(NULL, GetFirst()); } \
915 void resize(size_type n, value_type v = value_type()) \
922 size_type size() const { return GetCount(); } \
923 size_type max_size() const { return INT_MAX; } \
924 bool empty() const { return IsEmpty(); } \
925 reference front() { return *begin(); } \
926 const_reference front() const { return *begin(); } \
927 reference back() { return *--end(); } \
928 const_reference back() const { return *--end(); } \
929 void push_front(const_reference v = value_type()) \
930 { Insert(GetFirst(), (const_base_reference)v); } \
931 void pop_front() { DeleteNode(GetFirst()); } \
932 void push_back(const_reference v = value_type()) \
933 { Append((const_base_reference)v); } \
934 void pop_back() { DeleteNode(GetLast()); } \
935 void assign(const_iterator first, const_iterator last) \
938 for(; first != last; ++first) \
939 Append((const_base_reference)*first); \
941 void assign(size_type n, const_reference v = value_type()) \
944 for(size_type i = 0; i < n; ++i) \
945 Append((const_base_reference)v); \
947 iterator insert(iterator it, const_reference v = value_type()) \
949 Insert(it.m_node, (const_base_reference)v); \
950 return iterator(it.m_node->GetPrevious(), GetLast()); \
952 void insert(iterator it, size_type n, const_reference v = value_type())\
954 for(size_type i = 0; i < n; ++i) \
955 Insert(it.m_node, (const_base_reference)v); \
957 void insert(iterator it, const_iterator first, const_iterator last) \
959 for(; first != last; ++first) \
960 Insert(it.m_node, (const_base_reference)*first); \
962 iterator erase(iterator it) \
964 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
965 DeleteNode(it.m_node); return next; \
967 iterator erase(iterator first, iterator last) \
969 iterator next = last; ++next; \
970 DeleteNodes(first.m_node, last.m_node); \
973 void clear() { Clear(); } \
974 void splice(iterator it, name& l, iterator first, iterator last) \
975 { insert(it, first, last); l.erase(first, last); } \
976 void splice(iterator it, name& l) \
977 { splice(it, l, l.begin(), l.end() ); } \
978 void splice(iterator it, name& l, iterator first) \
980 iterator tmp = first; ++tmp; \
981 if(it == first || it == tmp) return; \
982 insert(it, *first); \
985 void remove(const_reference v) \
986 { DeleteObject((const_base_reference)v); } \
989 /* void swap(name& l) \
991 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
992 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
993 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
994 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
995 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
999 #define WX_LIST_PTROP \
1000 pointer_type operator->() const \
1001 { return (pointer_type)m_node->GetDataPtr(); }
1002 #define WX_LIST_PTROP_NONE
1004 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1005 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1006 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1007 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1009 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1010 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
1011 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1012 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
1014 #define WX_DECLARE_LIST(elementtype, listname) \
1015 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1016 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
1017 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
1018 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1019 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
1021 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
1022 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1023 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
1025 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1026 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1028 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1029 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1030 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
1032 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1033 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1034 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
1035 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1036 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1037 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
1039 // this macro must be inserted in your program after
1040 // #include <wx/listimpl.cpp>
1041 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1043 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1044 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1046 #endif // !wxUSE_STL
1048 // ============================================================================
1049 // now we can define classes 100% compatible with the old ones
1050 // ============================================================================
1052 // ----------------------------------------------------------------------------
1053 // commonly used list classes
1054 // ----------------------------------------------------------------------------
1056 #if defined(wxLIST_COMPATIBILITY)
1058 // inline compatibility functions
1062 // ----------------------------------------------------------------------------
1063 // wxNodeBase deprecated methods
1064 // ----------------------------------------------------------------------------
1066 inline wxNode
*wxNodeBase::Next() const { return (wxNode
*)GetNext(); }
1067 inline wxNode
*wxNodeBase::Previous() const { return (wxNode
*)GetPrevious(); }
1068 inline wxObject
*wxNodeBase::Data() const { return (wxObject
*)GetData(); }
1070 // ----------------------------------------------------------------------------
1071 // wxListBase deprecated methods
1072 // ----------------------------------------------------------------------------
1074 inline int wxListBase::Number() const { return (int)GetCount(); }
1075 inline wxNode
*wxListBase::First() const { return (wxNode
*)GetFirst(); }
1076 inline wxNode
*wxListBase::Last() const { return (wxNode
*)GetLast(); }
1077 inline wxNode
*wxListBase::Nth(size_t n
) const { return (wxNode
*)Item(n
); }
1078 inline wxListBase::operator wxList
&() const { return *(wxList
*)this; }
1082 // define this to make a lot of noise about use of the old wxList classes.
1083 //#define wxWARN_COMPAT_LIST_USE
1085 // ----------------------------------------------------------------------------
1086 // wxList compatibility class: in fact, it's a list of wxObjects
1087 // ----------------------------------------------------------------------------
1089 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1090 class WXDLLIMPEXP_BASE
);
1092 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1095 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1097 wxDEPRECATED( wxList(int key_type
) );
1099 wxList(int key_type
= wxKEY_NONE
);
1102 // this destructor is required for Darwin
1106 wxList
& operator=(const wxList
& list
)
1107 { (void) wxListBase::operator=(list
); return *this; }
1109 // compatibility methods
1110 void Sort(wxSortCompareFunction compfunc
) { wxListBase::Sort(compfunc
); }
1115 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1120 DECLARE_DYNAMIC_CLASS(wxList
)
1126 // -----------------------------------------------------------------------------
1127 // wxStringList class for compatibility with the old code
1128 // -----------------------------------------------------------------------------
1129 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1131 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1136 #ifdef wxWARN_COMPAT_LIST_USE
1138 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1141 wxStringList(const wxChar
*first
...);
1144 // copying the string list: the strings are copied, too (extremely
1146 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(true); DoCopy(other
); }
1147 wxStringList
& operator=(const wxStringList
& other
)
1148 { Clear(); DoCopy(other
); return *this; }
1151 // makes a copy of the string
1152 wxNode
*Add(const wxChar
*s
);
1154 // Append to beginning of list
1155 wxNode
*Prepend(const wxChar
*s
);
1157 bool Delete(const wxChar
*s
);
1159 wxChar
**ListToArray(bool new_copies
= false) const;
1160 bool Member(const wxChar
*s
) const;
1166 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1168 DECLARE_DYNAMIC_CLASS(wxStringList
)
1171 #else // if wxUSE_STL
1173 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLIMPEXP_BASE
);
1175 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1178 compatibility_iterator
Append(wxChar
* s
)
1179 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Append(tmp
); }
1180 compatibility_iterator
Insert(wxChar
* s
)
1181 { wxString tmp
= s
; delete[] s
; return wxStringListBase::Insert(tmp
); }
1182 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1186 return wxStringListBase::Insert(pos
, tmp
);
1188 compatibility_iterator
Add(const wxChar
* s
)
1189 { push_back(s
); return GetLast(); }
1190 compatibility_iterator
Prepend(const wxChar
* s
)
1191 { push_front(s
); return GetFirst(); }
1196 #endif // wxLIST_COMPATIBILITY
1198 // delete all list elements
1200 // NB: the class declaration of the list elements must be visible from the
1201 // place where you use this macro, otherwise the proper destructor may not
1202 // be called (a decent compiler should give a warning about it, but don't
1204 #define WX_CLEAR_LIST(type, list) \
1206 type::iterator it, en; \
1207 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \