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( _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 \
194 return *this ? std::distance( m_list->begin(), m_iter ) \
199 liT() : m_destroy( false ) {} \
201 compatibility_iterator Find( const elT e ) const \
203 liT* _this = const_cast< liT* >( this ); \
204 return compatibility_iterator( _this, \
205 std::find( _this->begin(), _this->end(), e ) ); \
208 bool IsEmpty() const \
209 { return empty(); } \
210 size_t GetCount() const \
213 { return static_cast< int >( GetCount() ); } \
215 compatibility_iterator Item( size_t idx ) const \
217 iterator i = const_cast< liT* >(this)->begin(); \
218 std::advance( i, idx ); \
219 return compatibility_iterator( this, i ); \
221 compatibility_iterator GetFirst() const \
223 return compatibility_iterator( this, \
224 const_cast< liT* >(this)->begin() ); \
226 compatibility_iterator GetLast() const \
228 iterator i = const_cast< liT* >(this)->end(); \
229 return compatibility_iterator( this, !empty() ? --i : i ); \
231 compatibility_iterator Member( elT e ) const \
232 { return Find( e ); } \
233 compatibility_iterator Nth( int n ) const \
234 { return Item( n ); } \
235 int IndexOf( elT e ) const \
236 { return Find( e ).IndexOf(); } \
238 compatibility_iterator Append( elT e ) \
243 compatibility_iterator Insert( elT e ) \
246 return compatibility_iterator( this, begin() ); \
248 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
250 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
252 compatibility_iterator Insert( size_t idx, elT e ) \
254 return compatibility_iterator( this, \
255 insert( Item( idx ).m_iter, e ) ); \
258 void DeleteContents( bool destroy ) \
259 { m_destroy = destroy; } \
260 bool GetDeleteContents() const \
261 { return m_destroy; } \
262 void Erase( const compatibility_iterator& i ) \
265 DeleteFunction( i->GetData() ); \
268 bool DeleteNode( const compatibility_iterator& i ) \
277 bool DeleteObject( elT e ) \
279 return DeleteNode( Find( e ) ); \
284 std::for_each( begin(), end(), DeleteFunction ); \
287 /* Workaround for broken VC6 std::list::sort() see above */ \
288 void Sort( wxSortCompareFunction compfunc ) \
289 { sort( WX_LIST_SORTFUNCTION( elT, compfunc ) ); } \
290 ~liT() { Clear(); } \
293 #define WX_DECLARE_LIST(elementtype, listname) \
294 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
295 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
296 WX_DECLARE_LIST(elementtype, listname)
298 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
299 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
300 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
301 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
303 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
304 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
305 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
306 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
308 // this macro must be inserted in your program after
309 // #include "wx/listimpl.cpp"
310 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
312 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
313 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
315 #else // if !wxUSE_STL
317 // due to circular header dependencies this function has to be declared here
318 // (normally it's found in utils.h which includes itself list.h...)
319 #if WXWIN_COMPATIBILITY_2_4
320 extern WXDLLIMPEXP_BASE wxChar
* copystring(const wxChar
*s
);
323 // undef it to get rid of old, deprecated functions
324 #define wxLIST_COMPATIBILITY
326 // -----------------------------------------------------------------------------
327 // key stuff: a list may be optionally keyed on integer or string key
328 // -----------------------------------------------------------------------------
336 // a struct which may contain both types of keys
338 // implementation note: on one hand, this class allows to have only one function
339 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
340 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
341 // wxList::Find(const char *).
342 class WXDLLIMPEXP_BASE wxListKey
346 wxListKey() : m_keyType(wxKEY_NONE
)
348 wxListKey(long i
) : m_keyType(wxKEY_INTEGER
)
349 { m_key
.integer
= i
; }
350 wxListKey(const wxChar
*s
) : m_keyType(wxKEY_STRING
)
351 { m_key
.string
= wxStrdup(s
); }
352 wxListKey(const wxString
& s
) : m_keyType(wxKEY_STRING
)
353 { m_key
.string
= wxStrdup(s
.c_str()); }
356 wxKeyType
GetKeyType() const { return m_keyType
; }
357 const wxChar
*GetString() const
358 { wxASSERT( m_keyType
== wxKEY_STRING
); return m_key
.string
; }
359 long GetNumber() const
360 { wxASSERT( m_keyType
== wxKEY_INTEGER
); return m_key
.integer
; }
363 // Note: implementation moved to list.cpp to prevent BC++ inline
364 // expansion warning.
365 bool operator==(wxListKeyValue value
) const ;
370 if ( m_keyType
== wxKEY_STRING
)
376 wxListKeyValue m_key
;
379 // -----------------------------------------------------------------------------
380 // wxNodeBase class is a (base for) node in a double linked list
381 // -----------------------------------------------------------------------------
383 extern WXDLLIMPEXP_DATA_BASE(wxListKey
) wxDefaultListKey
;
385 class WXDLLIMPEXP_BASE wxListBase
;
387 class WXDLLIMPEXP_BASE wxNodeBase
389 friend class wxListBase
;
392 wxNodeBase(wxListBase
*list
= (wxListBase
*)NULL
,
393 wxNodeBase
*previous
= (wxNodeBase
*)NULL
,
394 wxNodeBase
*next
= (wxNodeBase
*)NULL
,
396 const wxListKey
& key
= wxDefaultListKey
);
398 virtual ~wxNodeBase();
400 // FIXME no check is done that the list is really keyed on strings
401 const wxChar
*GetKeyString() const { return m_key
.string
; }
402 long GetKeyInteger() const { return m_key
.integer
; }
404 // Necessary for some existing code
405 void SetKeyString(wxChar
* s
) { m_key
.string
= s
; }
406 void SetKeyInteger(long i
) { m_key
.integer
= i
; }
408 #ifdef wxLIST_COMPATIBILITY
409 // compatibility methods, use Get* instead.
410 wxDEPRECATED( wxNode
*Next() const );
411 wxDEPRECATED( wxNode
*Previous() const );
412 wxDEPRECATED( wxObject
*Data() const );
413 #endif // wxLIST_COMPATIBILITY
416 // all these are going to be "overloaded" in the derived classes
417 wxNodeBase
*GetNext() const { return m_next
; }
418 wxNodeBase
*GetPrevious() const { return m_previous
; }
420 void *GetData() const { return m_data
; }
421 void SetData(void *data
) { m_data
= data
; }
423 // get 0-based index of this node within the list or wxNOT_FOUND
426 virtual void DeleteData() { }
428 // for wxList::iterator
429 void** GetDataPtr() const { return &(((wxNodeBase
*)this)->m_data
); }
431 // optional key stuff
432 wxListKeyValue m_key
;
434 void *m_data
; // user data
435 wxNodeBase
*m_next
, // next and previous nodes in the list
438 wxListBase
*m_list
; // list we belong to
440 DECLARE_NO_COPY_CLASS(wxNodeBase
)
443 // -----------------------------------------------------------------------------
444 // a double-linked list class
445 // -----------------------------------------------------------------------------
447 class WXDLLIMPEXP_BASE wxList
;
449 class WXDLLIMPEXP_BASE wxListBase
: public wxObject
451 friend class WXDLLIMPEXP_BASE wxNodeBase
; // should be able to call DetachNode()
452 friend class wxHashTableBase
; // should be able to call untyped Find()
455 // default ctor & dtor
456 wxListBase(wxKeyType keyType
= wxKEY_NONE
)
458 virtual ~wxListBase();
461 // count of items in the list
462 size_t GetCount() const { return m_count
; }
464 // return true if this list is empty
465 bool IsEmpty() const { return m_count
== 0; }
472 // instruct it to destroy user data when deleting nodes
473 void DeleteContents(bool destroy
) { m_destroy
= destroy
; }
475 // query if to delete
476 bool GetDeleteContents() const
477 { return m_destroy
; }
480 wxKeyType
GetKeyType() const
481 { return m_keyType
; }
483 // set the keytype (required by the serial code)
484 void SetKeyType(wxKeyType keyType
)
485 { wxASSERT( m_count
==0 ); m_keyType
= keyType
; }
487 #ifdef wxLIST_COMPATIBILITY
488 // compatibility methods from old wxList
489 wxDEPRECATED( int Number() const ); // use GetCount instead.
490 wxDEPRECATED( wxNode
*First() const ); // use GetFirst
491 wxDEPRECATED( wxNode
*Last() const ); // use GetLast
492 wxDEPRECATED( wxNode
*Nth(size_t n
) const ); // use Item
494 // kludge for typesafe list migration in core classes.
495 wxDEPRECATED( operator wxList
&() const );
496 #endif // wxLIST_COMPATIBILITY
500 // all methods here are "overloaded" in derived classes to provide compile
501 // time type checking
503 // create a node for the list of this type
504 virtual wxNodeBase
*CreateNode(wxNodeBase
*prev
, wxNodeBase
*next
,
506 const wxListKey
& key
= wxDefaultListKey
) = 0;
508 // Can't access these from derived classes otherwise (bug in Salford C++?)
515 wxListBase(size_t count
, void *elements
[]);
516 // from a sequence of objects
517 wxListBase(void *object
, ... /* terminate with NULL */);
520 void Assign(const wxListBase
& list
)
521 { Clear(); DoCopy(list
); }
523 // get list head/tail
524 wxNodeBase
*GetFirst() const { return m_nodeFirst
; }
525 wxNodeBase
*GetLast() const { return m_nodeLast
; }
527 // by (0-based) index
528 wxNodeBase
*Item(size_t index
) const;
530 // get the list item's data
531 void *operator[](size_t n
) const
533 wxNodeBase
*node
= Item(n
);
535 return node ? node
->GetData() : (wxNodeBase
*)NULL
;
539 // append to end of list
540 wxNodeBase
*Prepend(void *object
)
541 { return (wxNodeBase
*)wxListBase
::Insert(object
); }
542 // append to beginning of list
543 wxNodeBase
*Append(void *object
);
544 // insert a new item at the beginning of the list
545 wxNodeBase
*Insert(void *object
) { return Insert( (wxNodeBase
*)NULL
, object
); }
546 // insert a new item at the given position
547 wxNodeBase
*Insert(size_t pos
, void *object
)
548 { return pos
== GetCount() ?
Append(object
)
549 : Insert(Item(pos
), object
); }
550 // insert before given node or at front of list if prev == NULL
551 wxNodeBase
*Insert(wxNodeBase
*prev
, void *object
);
554 wxNodeBase
*Append(long key
, void *object
);
555 wxNodeBase
*Append(const wxChar
*key
, void *object
);
557 // removes node from the list but doesn't delete it (returns pointer
558 // to the node or NULL if it wasn't found in the list)
559 wxNodeBase
*DetachNode(wxNodeBase
*node
);
560 // delete element from list, returns false if node not found
561 bool DeleteNode(wxNodeBase
*node
);
562 // finds object pointer and deletes node (and object if DeleteContents
563 // is on), returns false if object not found
564 bool DeleteObject(void *object
);
566 // search (all return NULL if item not found)
568 wxNodeBase
*Find(const void *object
) const;
571 wxNodeBase
*Find(const wxListKey
& key
) const;
573 // get 0-based index of object or wxNOT_FOUND
574 int IndexOf( void *object
) const;
576 // this function allows the sorting of arbitrary lists by giving
577 // a function to compare two list elements. The list is sorted in place.
578 void Sort(const wxSortCompareFunction compfunc
);
580 // functions for iterating over the list
581 void *FirstThat(wxListIterateFunction func
);
582 void ForEach(wxListIterateFunction func
);
583 void *LastThat(wxListIterateFunction func
);
585 // for STL interface, "last" points to one after the last node
586 // of the controlled sequence (NULL for the end of the list)
588 void DeleteNodes(wxNodeBase
* first
, wxNodeBase
* last
);
591 // common part of all ctors
592 void Init(wxKeyType keyType
= wxKEY_NONE
);
595 // common part of copy ctor and assignment operator
596 void DoCopy(const wxListBase
& list
);
597 // common part of all Append()s
598 wxNodeBase
*AppendCommon(wxNodeBase
*node
);
599 // free node's data and node itself
600 void DoDeleteNode(wxNodeBase
*node
);
602 size_t m_count
; // number of elements in the list
603 bool m_destroy
; // destroy user data when deleting list items?
604 wxNodeBase
*m_nodeFirst
, // pointers to the head and tail of the list
607 wxKeyType m_keyType
; // type of our keys (may be wxKEY_NONE)
610 // -----------------------------------------------------------------------------
611 // macros for definition of "template" list type
612 // -----------------------------------------------------------------------------
614 // and now some heavy magic...
616 // declare a list type named 'name' and containing elements of type 'T *'
617 // (as a by product of macro expansion you also get wx##name##Node
618 // wxNode-derived type)
620 // implementation details:
621 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
622 // for the list of given type - this allows us to pass only the list name
623 // to WX_DEFINE_LIST() even if it needs both the name and the type
625 // 2. We redefine all non-type-safe wxList functions with type-safe versions
626 // which don't take any space (everything is inline), but bring compile
627 // time error checking.
629 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
630 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
631 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
632 // interesting capability to store polymorphic objects in the list and is
633 // particularly useful with, for example, "wxWindow *" list where the
634 // wxWindowBase pointers are put into the list, but wxWindow pointers are
635 // retrieved from it.
637 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
638 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
639 // it results in compiler warnings when this operator doesn't make sense
640 // (i.e. stored elements are not pointers)
642 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
643 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
644 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
646 classexp nodetype : public wxNodeBase \
649 nodetype(wxListBase *list = (wxListBase *)NULL, \
650 nodetype *previous = (nodetype *)NULL, \
651 nodetype *next = (nodetype *)NULL, \
652 T *data = (T *)NULL, \
653 const wxListKey& key = wxDefaultListKey) \
654 : wxNodeBase(list, previous, next, data, key) { } \
656 nodetype *GetNext() const \
657 { return (nodetype *)wxNodeBase::GetNext(); } \
658 nodetype *GetPrevious() const \
659 { return (nodetype *)wxNodeBase::GetPrevious(); } \
662 { return (T *)wxNodeBase::GetData(); } \
663 void SetData(T *data) \
664 { wxNodeBase::SetData(data); } \
667 virtual void DeleteData(); \
669 DECLARE_NO_COPY_CLASS(nodetype) \
672 classexp name : public wxListBase \
675 typedef nodetype Node; \
676 typedef Node* compatibility_iterator; \
678 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
680 name(const name& list) : wxListBase(list.GetKeyType()) \
682 name(size_t count, T *elements[]) \
683 : wxListBase(count, (void **)elements) { } \
685 name& operator=(const name& list) \
686 { Assign(list); return *this; } \
688 nodetype *GetFirst() const \
689 { return (nodetype *)wxListBase::GetFirst(); } \
690 nodetype *GetLast() const \
691 { return (nodetype *)wxListBase::GetLast(); } \
693 nodetype *Item(size_t index) const \
694 { return (nodetype *)wxListBase::Item(index); } \
696 T *operator[](size_t index) const \
698 nodetype *node = Item(index); \
699 return node ? (T*)(node->GetData()) : (T*)NULL; \
702 nodetype *Append(Tbase *object) \
703 { return (nodetype *)wxListBase::Append(object); } \
704 nodetype *Insert(Tbase *object) \
705 { return (nodetype *)Insert((nodetype*)NULL, object); } \
706 nodetype *Insert(size_t pos, Tbase *object) \
707 { return (nodetype *)wxListBase::Insert(pos, object); } \
708 nodetype *Insert(nodetype *prev, Tbase *object) \
709 { return (nodetype *)wxListBase::Insert(prev, object); } \
711 nodetype *Append(long key, void *object) \
712 { return (nodetype *)wxListBase::Append(key, object); } \
713 nodetype *Append(const wxChar *key, void *object) \
714 { return (nodetype *)wxListBase::Append(key, object); } \
716 nodetype *DetachNode(nodetype *node) \
717 { return (nodetype *)wxListBase::DetachNode(node); } \
718 bool DeleteNode(nodetype *node) \
719 { return wxListBase::DeleteNode(node); } \
720 bool DeleteObject(Tbase *object) \
721 { return wxListBase::DeleteObject(object); } \
722 void Erase(compatibility_iterator it) \
723 { DeleteNode(it); } \
725 nodetype *Find(const Tbase *object) const \
726 { return (nodetype *)wxListBase::Find(object); } \
728 virtual nodetype *Find(const wxListKey& key) const \
729 { return (nodetype *)wxListBase::Find(key); } \
731 int IndexOf(Tbase *object) const \
732 { return wxListBase::IndexOf(object); } \
734 void Sort(wxSortCompareFunction func) \
735 { wxListBase::Sort(func); } \
736 void Sort(wxSortFuncFor_##name func) \
737 { Sort((wxSortCompareFunction)func); } \
740 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
742 const wxListKey& key = wxDefaultListKey) \
744 return new nodetype(this, \
745 (nodetype *)prev, (nodetype *)next, \
748 /* STL interface */ \
750 typedef size_t size_type; \
751 typedef int difference_type; \
752 typedef T* value_type; \
753 typedef Tbase* base_value_type; \
754 typedef value_type& reference; \
755 typedef const value_type& const_reference; \
756 typedef base_value_type& base_reference; \
757 typedef const base_value_type& const_base_reference; \
763 typedef nodetype Node; \
764 typedef iterator itor; \
765 typedef T* value_type; \
766 typedef value_type* ptr_type; \
767 typedef value_type& reference; \
772 typedef reference reference_type; \
773 typedef ptr_type pointer_type; \
775 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
776 iterator() : m_node(NULL), m_init(NULL) { } \
777 reference_type operator*() const \
778 { return *(pointer_type)m_node->GetDataPtr(); } \
780 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
781 const itor operator++(int) \
782 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
785 m_node = m_node ? m_node->GetPrevious() : m_init; \
788 const itor operator--(int) \
791 m_node = m_node ? m_node->GetPrevious() : m_init; \
794 bool operator!=(const itor& it) const \
795 { return it.m_node != m_node; } \
796 bool operator==(const itor& it) const \
797 { return it.m_node == m_node; } \
799 class const_iterator \
803 typedef nodetype Node; \
804 typedef T* value_type; \
805 typedef const value_type& const_reference; \
806 typedef const_iterator itor; \
807 typedef value_type* ptr_type; \
812 typedef const_reference reference_type; \
813 typedef const ptr_type pointer_type; \
815 const_iterator(Node* node, Node* init) \
816 : m_node(node), m_init(init) { } \
817 const_iterator() : m_node(NULL), m_init(NULL) { } \
818 const_iterator(const iterator& it) \
819 : m_node(it.m_node), m_init(it.m_init) { } \
820 reference_type operator*() const \
821 { return *(pointer_type)m_node->GetDataPtr(); } \
823 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
824 const itor operator++(int) \
825 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
828 m_node = m_node ? m_node->GetPrevious() : m_init; \
831 const itor operator--(int) \
834 m_node = m_node ? m_node->GetPrevious() : m_init; \
837 bool operator!=(const itor& it) const \
838 { return it.m_node != m_node; } \
839 bool operator==(const itor& it) const \
840 { return it.m_node == m_node; } \
842 class reverse_iterator \
846 typedef nodetype Node; \
847 typedef T* value_type; \
848 typedef reverse_iterator itor; \
849 typedef value_type* ptr_type; \
850 typedef value_type& reference; \
855 typedef reference reference_type; \
856 typedef ptr_type pointer_type; \
858 reverse_iterator(Node* node, Node* init) \
859 : m_node(node), m_init(init) { } \
860 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
861 reference_type operator*() const \
862 { return *(pointer_type)m_node->GetDataPtr(); } \
865 { m_node = m_node->GetPrevious(); return *this; } \
866 const itor operator++(int) \
867 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
869 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
870 const itor operator--(int) \
873 m_node = m_node ? m_node->GetNext() : m_init; \
876 bool operator!=(const itor& it) const \
877 { return it.m_node != m_node; } \
878 bool operator==(const itor& it) const \
879 { return it.m_node == m_node; } \
881 class const_reverse_iterator \
885 typedef nodetype Node; \
886 typedef T* value_type; \
887 typedef const_reverse_iterator itor; \
888 typedef value_type* ptr_type; \
889 typedef const value_type& const_reference; \
894 typedef const_reference reference_type; \
895 typedef const ptr_type pointer_type; \
897 const_reverse_iterator(Node* node, Node* init) \
898 : m_node(node), m_init(init) { } \
899 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
900 const_reverse_iterator(const reverse_iterator& it) \
901 : m_node(it.m_node), m_init(it.m_init) { } \
902 reference_type operator*() const \
903 { return *(pointer_type)m_node->GetDataPtr(); } \
906 { m_node = m_node->GetPrevious(); return *this; } \
907 const itor operator++(int) \
908 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
910 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
911 const itor operator--(int) \
914 m_node = m_node ? m_node->GetNext() : m_init; \
917 bool operator!=(const itor& it) const \
918 { return it.m_node != m_node; } \
919 bool operator==(const itor& it) const \
920 { return it.m_node == m_node; } \
923 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
925 name(const const_iterator& first, const const_iterator& last) \
926 { assign(first, last); } \
927 iterator begin() { return iterator(GetFirst(), GetLast()); } \
928 const_iterator begin() const \
929 { return const_iterator(GetFirst(), GetLast()); } \
930 iterator end() { return iterator(NULL, GetLast()); } \
931 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
932 reverse_iterator rbegin() \
933 { return reverse_iterator(GetLast(), GetFirst()); } \
934 const_reverse_iterator rbegin() const \
935 { return const_reverse_iterator(GetLast(), GetFirst()); } \
936 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
937 const_reverse_iterator rend() const \
938 { return const_reverse_iterator(NULL, GetFirst()); } \
939 void resize(size_type n, value_type v = value_type()) \
946 size_type size() const { return GetCount(); } \
947 size_type max_size() const { return INT_MAX; } \
948 bool empty() const { return IsEmpty(); } \
949 reference front() { return *begin(); } \
950 const_reference front() const { return *begin(); } \
951 reference back() { iterator tmp = end(); return *--tmp; } \
952 const_reference back() const { const_iterator tmp = end(); return *--tmp; }\
953 void push_front(const_reference v = value_type()) \
954 { Insert(GetFirst(), (const_base_reference)v); } \
955 void pop_front() { DeleteNode(GetFirst()); } \
956 void push_back(const_reference v = value_type()) \
957 { Append((const_base_reference)v); } \
958 void pop_back() { DeleteNode(GetLast()); } \
959 void assign(const_iterator first, const const_iterator& last) \
962 for(; first != last; ++first) \
963 Append((const_base_reference)*first); \
965 void assign(size_type n, const_reference v = value_type()) \
968 for(size_type i = 0; i < n; ++i) \
969 Append((const_base_reference)v); \
971 iterator insert(const iterator& it, const_reference v = value_type())\
973 Insert(it.m_node, (const_base_reference)v); \
974 return iterator(it.m_node->GetPrevious(), GetLast()); \
976 void insert(const iterator& it, size_type n, const_reference v = value_type())\
978 for(size_type i = 0; i < n; ++i) \
979 Insert(it.m_node, (const_base_reference)v); \
981 void insert(const iterator& it, const_iterator first, const const_iterator& last)\
983 for(; first != last; ++first) \
984 Insert(it.m_node, (const_base_reference)*first); \
986 iterator erase(const iterator& it) \
988 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
989 DeleteNode(it.m_node); return next; \
991 iterator erase(const iterator& first, const iterator& last) \
993 iterator next = last; ++next; \
994 DeleteNodes(first.m_node, last.m_node); \
997 void clear() { Clear(); } \
998 void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
999 { insert(it, first, last); l.erase(first, last); } \
1000 void splice(const iterator& it, name& l) \
1001 { splice(it, l, l.begin(), l.end() ); } \
1002 void splice(const iterator& it, name& l, const iterator& first) \
1004 iterator tmp = first; ++tmp; \
1005 if(it == first || it == tmp) return; \
1006 insert(it, *first); \
1009 void remove(const_reference v) \
1010 { DeleteObject((const_base_reference)v); } \
1013 /* void swap(name& l) \
1015 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
1016 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1017 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1018 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1019 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1023 #define WX_LIST_PTROP \
1024 pointer_type operator->() const \
1025 { return (pointer_type)m_node->GetDataPtr(); }
1026 #define WX_LIST_PTROP_NONE
1028 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1029 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1030 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1031 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1033 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1034 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
1035 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1036 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
1038 #define WX_DECLARE_LIST(elementtype, listname) \
1039 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1040 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
1041 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
1042 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1043 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
1045 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
1046 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1047 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
1049 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1050 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1052 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1053 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1054 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
1056 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1057 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1058 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
1059 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1060 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1061 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
1063 // this macro must be inserted in your program after
1064 // #include "wx/listimpl.cpp"
1065 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1067 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1068 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1070 #endif // !wxUSE_STL
1072 // ============================================================================
1073 // now we can define classes 100% compatible with the old ones
1074 // ============================================================================
1076 // ----------------------------------------------------------------------------
1077 // commonly used list classes
1078 // ----------------------------------------------------------------------------
1080 #if defined(wxLIST_COMPATIBILITY)
1082 // inline compatibility functions
1086 // ----------------------------------------------------------------------------
1087 // wxNodeBase deprecated methods
1088 // ----------------------------------------------------------------------------
1090 inline wxNode
*wxNodeBase
::Next() const { return (wxNode
*)GetNext(); }
1091 inline wxNode
*wxNodeBase
::Previous() const { return (wxNode
*)GetPrevious(); }
1092 inline wxObject
*wxNodeBase
::Data() const { return (wxObject
*)GetData(); }
1094 // ----------------------------------------------------------------------------
1095 // wxListBase deprecated methods
1096 // ----------------------------------------------------------------------------
1098 inline int wxListBase
::Number() const { return (int)GetCount(); }
1099 inline wxNode
*wxListBase
::First() const { return (wxNode
*)GetFirst(); }
1100 inline wxNode
*wxListBase
::Last() const { return (wxNode
*)GetLast(); }
1101 inline wxNode
*wxListBase
::Nth(size_t n
) const { return (wxNode
*)Item(n
); }
1102 inline wxListBase
::operator wxList
&() const { return *(wxList
*)this; }
1106 // define this to make a lot of noise about use of the old wxList classes.
1107 //#define wxWARN_COMPAT_LIST_USE
1109 // ----------------------------------------------------------------------------
1110 // wxList compatibility class: in fact, it's a list of wxObjects
1111 // ----------------------------------------------------------------------------
1113 WX_DECLARE_LIST_2(wxObject
, wxObjectList
, wxObjectListNode
,
1114 class WXDLLIMPEXP_BASE
);
1116 class WXDLLIMPEXP_BASE wxList
: public wxObjectList
1119 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1121 wxDEPRECATED( wxList(int key_type
) );
1123 wxList(int key_type
= wxKEY_NONE
);
1126 // this destructor is required for Darwin
1130 wxList
& operator=(const wxList
& list
)
1131 { (void) wxListBase
::operator=(list
); return *this; }
1133 // compatibility methods
1134 void Sort(wxSortCompareFunction compfunc
) { wxListBase
::Sort(compfunc
); }
1139 wxNode
*Member(wxObject
*object
) const { return (wxNode
*)Find(object
); }
1144 DECLARE_DYNAMIC_CLASS(wxList
)
1150 // -----------------------------------------------------------------------------
1151 // wxStringList class for compatibility with the old code
1152 // -----------------------------------------------------------------------------
1153 WX_DECLARE_LIST_2(wxChar
, wxStringListBase
, wxStringListNode
, class WXDLLIMPEXP_BASE
);
1155 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1160 #ifdef wxWARN_COMPAT_LIST_USE
1162 wxDEPRECATED( wxStringList(const wxChar
*first
...) );
1165 wxStringList(const wxChar
*first
...);
1168 // copying the string list: the strings are copied, too (extremely
1170 wxStringList(const wxStringList
& other
) : wxStringListBase() { DeleteContents(true); DoCopy(other
); }
1171 wxStringList
& operator=(const wxStringList
& other
)
1172 { Clear(); DoCopy(other
); return *this; }
1175 // makes a copy of the string
1176 wxNode
*Add(const wxChar
*s
);
1178 // Append to beginning of list
1179 wxNode
*Prepend(const wxChar
*s
);
1181 bool Delete(const wxChar
*s
);
1183 wxChar
**ListToArray(bool new_copies
= false) const;
1184 bool Member(const wxChar
*s
) const;
1190 void DoCopy(const wxStringList
&); // common part of copy ctor and operator=
1192 DECLARE_DYNAMIC_CLASS(wxStringList
)
1195 #else // if wxUSE_STL
1197 WX_DECLARE_LIST_XO(wxString
, wxStringListBase
, class WXDLLIMPEXP_BASE
);
1199 class WXDLLIMPEXP_BASE wxStringList
: public wxStringListBase
1202 compatibility_iterator
Append(wxChar
* s
)
1203 { wxString tmp
= s
; delete[] s
; return wxStringListBase
::Append(tmp
); }
1204 compatibility_iterator
Insert(wxChar
* s
)
1205 { wxString tmp
= s
; delete[] s
; return wxStringListBase
::Insert(tmp
); }
1206 compatibility_iterator
Insert(size_t pos
, wxChar
* s
)
1210 return wxStringListBase
::Insert(pos
, tmp
);
1212 compatibility_iterator
Add(const wxChar
* s
)
1213 { push_back(s
); return GetLast(); }
1214 compatibility_iterator
Prepend(const wxChar
* s
)
1215 { push_front(s
); return GetFirst(); }
1220 #endif // wxLIST_COMPATIBILITY
1222 // delete all list elements
1224 // NB: the class declaration of the list elements must be visible from the
1225 // place where you use this macro, otherwise the proper destructor may not
1226 // be called (a decent compiler should give a warning about it, but don't
1228 #define WX_CLEAR_LIST(type, list) \
1230 type::iterator it, en; \
1231 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1236 #endif // _WX_LISTH__