added assert to verify that operands are initialized in compatibility_iterator::opera...
[wxWidgets.git] / include / wx / list.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/list.h
3 // Purpose: wxList, wxStringList classes
4 // Author: Julian Smart
5 // Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added
6 // Created: 29/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 /*
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
16
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
22 like the old class.
23 */
24
25 #ifndef _WX_LISTH__
26 #define _WX_LISTH__
27
28 // -----------------------------------------------------------------------------
29 // headers
30 // -----------------------------------------------------------------------------
31
32 #include "wx/defs.h"
33 #include "wx/object.h"
34 #include "wx/string.h"
35
36 #if wxUSE_STL
37 #include "wx/beforestd.h"
38 #include <algorithm>
39 #include <iterator>
40 #include <list>
41 #include "wx/afterstd.h"
42 #endif
43
44 // ----------------------------------------------------------------------------
45 // types
46 // ----------------------------------------------------------------------------
47
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
51
52 extern "C"
53 {
54 typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2);
55 }
56
57 class WXDLLIMPEXP_BASE wxObjectListNode;
58 typedef wxObjectListNode wxNode;
59
60 //
61 typedef int (* LINKAGEMODE wxListIterateFunction)(void *current);
62
63 // ----------------------------------------------------------------------------
64 // constants
65 // ----------------------------------------------------------------------------
66
67 #if !defined(wxENUM_KEY_TYPE_DEFINED)
68 #define wxENUM_KEY_TYPE_DEFINED
69
70 enum wxKeyType
71 {
72 wxKEY_NONE,
73 wxKEY_INTEGER,
74 wxKEY_STRING
75 };
76
77 #endif
78
79 #if wxUSE_STL
80
81 #define wxLIST_COMPATIBILITY
82
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)
87
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) \
92
93 #define WX_DECLARE_LIST_WITH_DECL(elT, liT, decl) \
94 WX_DECLARE_LIST_XO(elT*, liT, decl)
95
96 #if !defined( __VISUALC__ )
97
98 template<class T>
99 class WXDLLIMPEXP_BASE wxList_SortFunction
100 {
101 public:
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; }
105 private:
106 wxSortCompareFunction m_f;
107 };
108
109 #define WX_LIST_SORTFUNCTION( elT, f ) wxList_SortFunction<elT>(f)
110 #define VC6_WORKAROUND(elT, liT, decl)
111
112 #else // if defined( __VISUALC__ )
113
114 #define WX_LIST_SORTFUNCTION( elT, f ) std::greater<elT>( f )
115 #define VC6_WORKAROUND(elT, liT, decl) \
116 decl liT; \
117 \
118 /* Workaround for broken VC6 STL incorrectly requires a std::greater<> */ \
119 /* to be passed into std::list::sort() */ \
120 template <> \
121 struct std::greater<elT> \
122 { \
123 private: \
124 wxSortCompareFunction m_CompFunc; \
125 public: \
126 greater( wxSortCompareFunction compfunc = NULL ) \
127 : m_CompFunc( compfunc ) {} \
128 bool operator()(const elT X, const elT Y) const \
129 { \
130 return m_CompFunc ? \
131 ( m_CompFunc( X, Y ) < 0 ) : \
132 ( X > Y ); \
133 } \
134 };
135
136 #endif // defined( __VISUALC__ )
137
138 #define WX_DECLARE_LIST_XO(elT, liT, decl) \
139 VC6_WORKAROUND(elT, liT, decl) \
140 decl liT : public std::list<elT> \
141 { \
142 private: \
143 bool m_destroy; \
144 private: \
145 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
146 static void DeleteFunction( _WX_LIST_ITEM_TYPE_##liT X ); \
147 public: \
148 class compatibility_iterator \
149 { \
150 private: \
151 /* Workaround for broken VC6 nested class name resolution */ \
152 typedef std::list<elT>::iterator iterator; \
153 friend class liT; \
154 private: \
155 iterator m_iter; \
156 liT * m_list; \
157 public: \
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 ) ) {} \
164 \
165 compatibility_iterator* operator->() { return this; } \
166 const compatibility_iterator* operator->() const { return this; } \
167 \
168 bool operator==(const compatibility_iterator& i) const \
169 { \
170 wxASSERT_MSG( m_list && i.m_list, \
171 _T("comparing invalid iterators is illegal") ); \
172 return (m_list == i.m_list) && (m_iter == i.m_iter); \
173 } \
174 bool operator!=(const compatibility_iterator& i) const \
175 { return !( operator==( i ) ); } \
176 operator bool() const \
177 { return m_list ? m_iter != m_list->end() : false; } \
178 bool operator !() const \
179 { return !( operator bool() ); } \
180 \
181 elT GetData() const \
182 { return *m_iter; } \
183 void SetData( elT e ) \
184 { *m_iter = e; } \
185 \
186 compatibility_iterator GetNext() const \
187 { \
188 iterator i = m_iter; \
189 return compatibility_iterator( m_list, ++i ); \
190 } \
191 compatibility_iterator GetPrevious() const \
192 { \
193 iterator i = m_iter; \
194 return compatibility_iterator( m_list, --i ); \
195 } \
196 int IndexOf() const \
197 { \
198 return *this ? std::distance( m_list->begin(), m_iter ) \
199 : wxNOT_FOUND; \
200 } \
201 }; \
202 public: \
203 liT() : m_destroy( false ) {} \
204 \
205 compatibility_iterator Find( const elT e ) const \
206 { \
207 liT* _this = const_cast< liT* >( this ); \
208 return compatibility_iterator( _this, \
209 std::find( _this->begin(), _this->end(), e ) ); \
210 } \
211 \
212 bool IsEmpty() const \
213 { return empty(); } \
214 size_t GetCount() const \
215 { return size(); } \
216 int Number() const \
217 { return static_cast< int >( GetCount() ); } \
218 \
219 compatibility_iterator Item( size_t idx ) const \
220 { \
221 iterator i = const_cast< liT* >(this)->begin(); \
222 std::advance( i, idx ); \
223 return compatibility_iterator( this, i ); \
224 } \
225 compatibility_iterator GetFirst() const \
226 { \
227 return compatibility_iterator( this, \
228 const_cast< liT* >(this)->begin() ); \
229 } \
230 compatibility_iterator GetLast() const \
231 { \
232 iterator i = const_cast< liT* >(this)->end(); \
233 return compatibility_iterator( this, !empty() ? --i : i ); \
234 } \
235 compatibility_iterator Member( elT e ) const \
236 { return Find( e ); } \
237 compatibility_iterator Nth( int n ) const \
238 { return Item( n ); } \
239 int IndexOf( elT e ) const \
240 { return Find( e ).IndexOf(); } \
241 \
242 compatibility_iterator Append( elT e ) \
243 { \
244 push_back( e ); \
245 return GetLast(); \
246 } \
247 compatibility_iterator Insert( elT e ) \
248 { \
249 push_front( e ); \
250 return compatibility_iterator( this, begin() ); \
251 } \
252 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
253 { \
254 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
255 } \
256 compatibility_iterator Insert( size_t idx, elT e ) \
257 { \
258 return compatibility_iterator( this, \
259 insert( Item( idx ).m_iter, e ) ); \
260 } \
261 \
262 void DeleteContents( bool destroy ) \
263 { m_destroy = destroy; } \
264 bool GetDeleteContents() const \
265 { return m_destroy; } \
266 void Erase( const compatibility_iterator& i ) \
267 { \
268 if ( m_destroy ) \
269 DeleteFunction( i->GetData() ); \
270 erase( i.m_iter ); \
271 } \
272 bool DeleteNode( const compatibility_iterator& i ) \
273 { \
274 if( i ) \
275 { \
276 Erase( i ); \
277 return true; \
278 } \
279 return false; \
280 } \
281 bool DeleteObject( elT e ) \
282 { \
283 return DeleteNode( Find( e ) ); \
284 } \
285 void Clear() \
286 { \
287 if ( m_destroy ) \
288 std::for_each( begin(), end(), DeleteFunction ); \
289 clear(); \
290 } \
291 /* Workaround for broken VC6 std::list::sort() see above */ \
292 void Sort( wxSortCompareFunction compfunc ) \
293 { sort( WX_LIST_SORTFUNCTION( elT, compfunc ) ); } \
294 ~liT() { Clear(); } \
295 }
296
297 #define WX_DECLARE_LIST(elementtype, listname) \
298 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
299 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
300 WX_DECLARE_LIST(elementtype, listname)
301
302 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
303 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
304 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
305 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
306
307 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
308 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
309 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
310 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
311
312 // this macro must be inserted in your program after
313 // #include "wx/listimpl.cpp"
314 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
315
316 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
317 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
318
319 #else // if !wxUSE_STL
320
321 // due to circular header dependencies this function has to be declared here
322 // (normally it's found in utils.h which includes itself list.h...)
323 #if WXWIN_COMPATIBILITY_2_4
324 extern WXDLLIMPEXP_BASE wxChar* copystring(const wxChar *s);
325 #endif
326
327 // undef it to get rid of old, deprecated functions
328 #define wxLIST_COMPATIBILITY
329
330 // -----------------------------------------------------------------------------
331 // key stuff: a list may be optionally keyed on integer or string key
332 // -----------------------------------------------------------------------------
333
334 union wxListKeyValue
335 {
336 long integer;
337 wxChar *string;
338 };
339
340 // a struct which may contain both types of keys
341 //
342 // implementation note: on one hand, this class allows to have only one function
343 // for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
344 // resolve ambiguity which we would otherwise have with wxStringList::Find() and
345 // wxList::Find(const char *).
346 class WXDLLIMPEXP_BASE wxListKey
347 {
348 public:
349 // implicit ctors
350 wxListKey() : m_keyType(wxKEY_NONE)
351 { }
352 wxListKey(long i) : m_keyType(wxKEY_INTEGER)
353 { m_key.integer = i; }
354 wxListKey(const wxChar *s) : m_keyType(wxKEY_STRING)
355 { m_key.string = wxStrdup(s); }
356 wxListKey(const wxString& s) : m_keyType(wxKEY_STRING)
357 { m_key.string = wxStrdup(s.c_str()); }
358
359 // accessors
360 wxKeyType GetKeyType() const { return m_keyType; }
361 const wxChar *GetString() const
362 { wxASSERT( m_keyType == wxKEY_STRING ); return m_key.string; }
363 long GetNumber() const
364 { wxASSERT( m_keyType == wxKEY_INTEGER ); return m_key.integer; }
365
366 // comparison
367 // Note: implementation moved to list.cpp to prevent BC++ inline
368 // expansion warning.
369 bool operator==(wxListKeyValue value) const ;
370
371 // dtor
372 ~wxListKey()
373 {
374 if ( m_keyType == wxKEY_STRING )
375 free(m_key.string);
376 }
377
378 private:
379 wxKeyType m_keyType;
380 wxListKeyValue m_key;
381 };
382
383 // -----------------------------------------------------------------------------
384 // wxNodeBase class is a (base for) node in a double linked list
385 // -----------------------------------------------------------------------------
386
387 extern WXDLLIMPEXP_DATA_BASE(wxListKey) wxDefaultListKey;
388
389 class WXDLLIMPEXP_BASE wxListBase;
390
391 class WXDLLIMPEXP_BASE wxNodeBase
392 {
393 friend class wxListBase;
394 public:
395 // ctor
396 wxNodeBase(wxListBase *list = (wxListBase *)NULL,
397 wxNodeBase *previous = (wxNodeBase *)NULL,
398 wxNodeBase *next = (wxNodeBase *)NULL,
399 void *data = NULL,
400 const wxListKey& key = wxDefaultListKey);
401
402 virtual ~wxNodeBase();
403
404 // FIXME no check is done that the list is really keyed on strings
405 const wxChar *GetKeyString() const { return m_key.string; }
406 long GetKeyInteger() const { return m_key.integer; }
407
408 // Necessary for some existing code
409 void SetKeyString(wxChar* s) { m_key.string = s; }
410 void SetKeyInteger(long i) { m_key.integer = i; }
411
412 #ifdef wxLIST_COMPATIBILITY
413 // compatibility methods, use Get* instead.
414 wxDEPRECATED( wxNode *Next() const );
415 wxDEPRECATED( wxNode *Previous() const );
416 wxDEPRECATED( wxObject *Data() const );
417 #endif // wxLIST_COMPATIBILITY
418
419 protected:
420 // all these are going to be "overloaded" in the derived classes
421 wxNodeBase *GetNext() const { return m_next; }
422 wxNodeBase *GetPrevious() const { return m_previous; }
423
424 void *GetData() const { return m_data; }
425 void SetData(void *data) { m_data = data; }
426
427 // get 0-based index of this node within the list or wxNOT_FOUND
428 int IndexOf() const;
429
430 virtual void DeleteData() { }
431 public:
432 // for wxList::iterator
433 void** GetDataPtr() const { return &(((wxNodeBase*)this)->m_data); }
434 private:
435 // optional key stuff
436 wxListKeyValue m_key;
437
438 void *m_data; // user data
439 wxNodeBase *m_next, // next and previous nodes in the list
440 *m_previous;
441
442 wxListBase *m_list; // list we belong to
443
444 DECLARE_NO_COPY_CLASS(wxNodeBase)
445 };
446
447 // -----------------------------------------------------------------------------
448 // a double-linked list class
449 // -----------------------------------------------------------------------------
450
451 class WXDLLIMPEXP_BASE wxList;
452
453 class WXDLLIMPEXP_BASE wxListBase : public wxObject
454 {
455 friend class WXDLLIMPEXP_BASE wxNodeBase; // should be able to call DetachNode()
456 friend class wxHashTableBase; // should be able to call untyped Find()
457
458 public:
459 // default ctor & dtor
460 wxListBase(wxKeyType keyType = wxKEY_NONE)
461 { Init(keyType); }
462 virtual ~wxListBase();
463
464 // accessors
465 // count of items in the list
466 size_t GetCount() const { return m_count; }
467
468 // return true if this list is empty
469 bool IsEmpty() const { return m_count == 0; }
470
471 // operations
472
473 // delete all nodes
474 void Clear();
475
476 // instruct it to destroy user data when deleting nodes
477 void DeleteContents(bool destroy) { m_destroy = destroy; }
478
479 // query if to delete
480 bool GetDeleteContents() const
481 { return m_destroy; }
482
483 // get the keytype
484 wxKeyType GetKeyType() const
485 { return m_keyType; }
486
487 // set the keytype (required by the serial code)
488 void SetKeyType(wxKeyType keyType)
489 { wxASSERT( m_count==0 ); m_keyType = keyType; }
490
491 #ifdef wxLIST_COMPATIBILITY
492 // compatibility methods from old wxList
493 wxDEPRECATED( int Number() const ); // use GetCount instead.
494 wxDEPRECATED( wxNode *First() const ); // use GetFirst
495 wxDEPRECATED( wxNode *Last() const ); // use GetLast
496 wxDEPRECATED( wxNode *Nth(size_t n) const ); // use Item
497
498 // kludge for typesafe list migration in core classes.
499 wxDEPRECATED( operator wxList&() const );
500 #endif // wxLIST_COMPATIBILITY
501
502 protected:
503
504 // all methods here are "overloaded" in derived classes to provide compile
505 // time type checking
506
507 // create a node for the list of this type
508 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next,
509 void *data,
510 const wxListKey& key = wxDefaultListKey) = 0;
511
512 // Can't access these from derived classes otherwise (bug in Salford C++?)
513 #ifdef __SALFORDC__
514 public:
515 #endif
516
517 // ctors
518 // from an array
519 wxListBase(size_t count, void *elements[]);
520 // from a sequence of objects
521 wxListBase(void *object, ... /* terminate with NULL */);
522
523 protected:
524 void Assign(const wxListBase& list)
525 { Clear(); DoCopy(list); }
526
527 // get list head/tail
528 wxNodeBase *GetFirst() const { return m_nodeFirst; }
529 wxNodeBase *GetLast() const { return m_nodeLast; }
530
531 // by (0-based) index
532 wxNodeBase *Item(size_t index) const;
533
534 // get the list item's data
535 void *operator[](size_t n) const
536 {
537 wxNodeBase *node = Item(n);
538
539 return node ? node->GetData() : (wxNodeBase *)NULL;
540 }
541
542 // operations
543 // append to end of list
544 wxNodeBase *Prepend(void *object)
545 { return (wxNodeBase *)wxListBase::Insert(object); }
546 // append to beginning of list
547 wxNodeBase *Append(void *object);
548 // insert a new item at the beginning of the list
549 wxNodeBase *Insert(void *object) { return Insert( (wxNodeBase*)NULL, object); }
550 // insert a new item at the given position
551 wxNodeBase *Insert(size_t pos, void *object)
552 { return pos == GetCount() ? Append(object)
553 : Insert(Item(pos), object); }
554 // insert before given node or at front of list if prev == NULL
555 wxNodeBase *Insert(wxNodeBase *prev, void *object);
556
557 // keyed append
558 wxNodeBase *Append(long key, void *object);
559 wxNodeBase *Append(const wxChar *key, void *object);
560
561 // removes node from the list but doesn't delete it (returns pointer
562 // to the node or NULL if it wasn't found in the list)
563 wxNodeBase *DetachNode(wxNodeBase *node);
564 // delete element from list, returns false if node not found
565 bool DeleteNode(wxNodeBase *node);
566 // finds object pointer and deletes node (and object if DeleteContents
567 // is on), returns false if object not found
568 bool DeleteObject(void *object);
569
570 // search (all return NULL if item not found)
571 // by data
572 wxNodeBase *Find(const void *object) const;
573
574 // by key
575 wxNodeBase *Find(const wxListKey& key) const;
576
577 // get 0-based index of object or wxNOT_FOUND
578 int IndexOf( void *object ) const;
579
580 // this function allows the sorting of arbitrary lists by giving
581 // a function to compare two list elements. The list is sorted in place.
582 void Sort(const wxSortCompareFunction compfunc);
583
584 // functions for iterating over the list
585 void *FirstThat(wxListIterateFunction func);
586 void ForEach(wxListIterateFunction func);
587 void *LastThat(wxListIterateFunction func);
588
589 // for STL interface, "last" points to one after the last node
590 // of the controlled sequence (NULL for the end of the list)
591 void Reverse();
592 void DeleteNodes(wxNodeBase* first, wxNodeBase* last);
593 private:
594
595 // common part of all ctors
596 void Init(wxKeyType keyType = wxKEY_NONE);
597
598 // helpers
599 // common part of copy ctor and assignment operator
600 void DoCopy(const wxListBase& list);
601 // common part of all Append()s
602 wxNodeBase *AppendCommon(wxNodeBase *node);
603 // free node's data and node itself
604 void DoDeleteNode(wxNodeBase *node);
605
606 size_t m_count; // number of elements in the list
607 bool m_destroy; // destroy user data when deleting list items?
608 wxNodeBase *m_nodeFirst, // pointers to the head and tail of the list
609 *m_nodeLast;
610
611 wxKeyType m_keyType; // type of our keys (may be wxKEY_NONE)
612 };
613
614 // -----------------------------------------------------------------------------
615 // macros for definition of "template" list type
616 // -----------------------------------------------------------------------------
617
618 // and now some heavy magic...
619
620 // declare a list type named 'name' and containing elements of type 'T *'
621 // (as a by product of macro expansion you also get wx##name##Node
622 // wxNode-derived type)
623 //
624 // implementation details:
625 // 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
626 // for the list of given type - this allows us to pass only the list name
627 // to WX_DEFINE_LIST() even if it needs both the name and the type
628 //
629 // 2. We redefine all non-type-safe wxList functions with type-safe versions
630 // which don't take any space (everything is inline), but bring compile
631 // time error checking.
632 //
633 // 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
634 // a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
635 // generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
636 // interesting capability to store polymorphic objects in the list and is
637 // particularly useful with, for example, "wxWindow *" list where the
638 // wxWindowBase pointers are put into the list, but wxWindow pointers are
639 // retrieved from it.
640 //
641 // 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
642 // WX_DECLARE_LIST_4 to allow defining classes without operator->() as
643 // it results in compiler warnings when this operator doesn't make sense
644 // (i.e. stored elements are not pointers)
645
646 // common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
647 #define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
648 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
649 \
650 classexp nodetype : public wxNodeBase \
651 { \
652 public: \
653 nodetype(wxListBase *list = (wxListBase *)NULL, \
654 nodetype *previous = (nodetype *)NULL, \
655 nodetype *next = (nodetype *)NULL, \
656 T *data = (T *)NULL, \
657 const wxListKey& key = wxDefaultListKey) \
658 : wxNodeBase(list, previous, next, data, key) { } \
659 \
660 nodetype *GetNext() const \
661 { return (nodetype *)wxNodeBase::GetNext(); } \
662 nodetype *GetPrevious() const \
663 { return (nodetype *)wxNodeBase::GetPrevious(); } \
664 \
665 T *GetData() const \
666 { return (T *)wxNodeBase::GetData(); } \
667 void SetData(T *data) \
668 { wxNodeBase::SetData(data); } \
669 \
670 protected: \
671 virtual void DeleteData(); \
672 \
673 DECLARE_NO_COPY_CLASS(nodetype) \
674 }; \
675 \
676 classexp name : public wxListBase \
677 { \
678 public: \
679 typedef nodetype Node; \
680 typedef Node* compatibility_iterator; \
681 \
682 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
683 { } \
684 name(const name& list) : wxListBase(list.GetKeyType()) \
685 { Assign(list); } \
686 name(size_t count, T *elements[]) \
687 : wxListBase(count, (void **)elements) { } \
688 \
689 name& operator=(const name& list) \
690 { Assign(list); return *this; } \
691 \
692 nodetype *GetFirst() const \
693 { return (nodetype *)wxListBase::GetFirst(); } \
694 nodetype *GetLast() const \
695 { return (nodetype *)wxListBase::GetLast(); } \
696 \
697 nodetype *Item(size_t index) const \
698 { return (nodetype *)wxListBase::Item(index); } \
699 \
700 T *operator[](size_t index) const \
701 { \
702 nodetype *node = Item(index); \
703 return node ? (T*)(node->GetData()) : (T*)NULL; \
704 } \
705 \
706 nodetype *Append(Tbase *object) \
707 { return (nodetype *)wxListBase::Append(object); } \
708 nodetype *Insert(Tbase *object) \
709 { return (nodetype *)Insert((nodetype*)NULL, object); } \
710 nodetype *Insert(size_t pos, Tbase *object) \
711 { return (nodetype *)wxListBase::Insert(pos, object); } \
712 nodetype *Insert(nodetype *prev, Tbase *object) \
713 { return (nodetype *)wxListBase::Insert(prev, object); } \
714 \
715 nodetype *Append(long key, void *object) \
716 { return (nodetype *)wxListBase::Append(key, object); } \
717 nodetype *Append(const wxChar *key, void *object) \
718 { return (nodetype *)wxListBase::Append(key, object); } \
719 \
720 nodetype *DetachNode(nodetype *node) \
721 { return (nodetype *)wxListBase::DetachNode(node); } \
722 bool DeleteNode(nodetype *node) \
723 { return wxListBase::DeleteNode(node); } \
724 bool DeleteObject(Tbase *object) \
725 { return wxListBase::DeleteObject(object); } \
726 void Erase(compatibility_iterator it) \
727 { DeleteNode(it); } \
728 \
729 nodetype *Find(const Tbase *object) const \
730 { return (nodetype *)wxListBase::Find(object); } \
731 \
732 virtual nodetype *Find(const wxListKey& key) const \
733 { return (nodetype *)wxListBase::Find(key); } \
734 \
735 int IndexOf(Tbase *object) const \
736 { return wxListBase::IndexOf(object); } \
737 \
738 void Sort(wxSortCompareFunction func) \
739 { wxListBase::Sort(func); } \
740 void Sort(wxSortFuncFor_##name func) \
741 { Sort((wxSortCompareFunction)func); } \
742 \
743 protected: \
744 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
745 void *data, \
746 const wxListKey& key = wxDefaultListKey) \
747 { \
748 return new nodetype(this, \
749 (nodetype *)prev, (nodetype *)next, \
750 (T *)data, key); \
751 } \
752 /* STL interface */ \
753 public: \
754 typedef size_t size_type; \
755 typedef int difference_type; \
756 typedef T* value_type; \
757 typedef Tbase* base_value_type; \
758 typedef value_type& reference; \
759 typedef const value_type& const_reference; \
760 typedef base_value_type& base_reference; \
761 typedef const base_value_type& const_base_reference; \
762 \
763 class iterator \
764 { \
765 typedef name list; \
766 public: \
767 typedef nodetype Node; \
768 typedef iterator itor; \
769 typedef T* value_type; \
770 typedef value_type* ptr_type; \
771 typedef value_type& reference; \
772 \
773 Node* m_node; \
774 Node* m_init; \
775 public: \
776 typedef reference reference_type; \
777 typedef ptr_type pointer_type; \
778 \
779 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
780 iterator() : m_node(NULL), m_init(NULL) { } \
781 reference_type operator*() const \
782 { return *(pointer_type)m_node->GetDataPtr(); } \
783 ptrop \
784 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
785 const itor operator++(int) \
786 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
787 itor& operator--() \
788 { \
789 m_node = m_node ? m_node->GetPrevious() : m_init; \
790 return *this; \
791 } \
792 const itor operator--(int) \
793 { \
794 itor tmp = *this; \
795 m_node = m_node ? m_node->GetPrevious() : m_init; \
796 return tmp; \
797 } \
798 bool operator!=(const itor& it) const \
799 { return it.m_node != m_node; } \
800 bool operator==(const itor& it) const \
801 { return it.m_node == m_node; } \
802 }; \
803 class const_iterator \
804 { \
805 typedef name list; \
806 public: \
807 typedef nodetype Node; \
808 typedef T* value_type; \
809 typedef const value_type& const_reference; \
810 typedef const_iterator itor; \
811 typedef value_type* ptr_type; \
812 \
813 Node* m_node; \
814 Node* m_init; \
815 public: \
816 typedef const_reference reference_type; \
817 typedef const ptr_type pointer_type; \
818 \
819 const_iterator(Node* node, Node* init) \
820 : m_node(node), m_init(init) { } \
821 const_iterator() : m_node(NULL), m_init(NULL) { } \
822 const_iterator(const iterator& it) \
823 : m_node(it.m_node), m_init(it.m_init) { } \
824 reference_type operator*() const \
825 { return *(pointer_type)m_node->GetDataPtr(); } \
826 ptrop \
827 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
828 const itor operator++(int) \
829 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
830 itor& operator--() \
831 { \
832 m_node = m_node ? m_node->GetPrevious() : m_init; \
833 return *this; \
834 } \
835 const itor operator--(int) \
836 { \
837 itor tmp = *this; \
838 m_node = m_node ? m_node->GetPrevious() : m_init; \
839 return tmp; \
840 } \
841 bool operator!=(const itor& it) const \
842 { return it.m_node != m_node; } \
843 bool operator==(const itor& it) const \
844 { return it.m_node == m_node; } \
845 }; \
846 class reverse_iterator \
847 { \
848 typedef name list; \
849 public: \
850 typedef nodetype Node; \
851 typedef T* value_type; \
852 typedef reverse_iterator itor; \
853 typedef value_type* ptr_type; \
854 typedef value_type& reference; \
855 \
856 Node* m_node; \
857 Node* m_init; \
858 public: \
859 typedef reference reference_type; \
860 typedef ptr_type pointer_type; \
861 \
862 reverse_iterator(Node* node, Node* init) \
863 : m_node(node), m_init(init) { } \
864 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
865 reference_type operator*() const \
866 { return *(pointer_type)m_node->GetDataPtr(); } \
867 ptrop \
868 itor& operator++() \
869 { m_node = m_node->GetPrevious(); return *this; } \
870 const itor operator++(int) \
871 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
872 itor& operator--() \
873 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
874 const itor operator--(int) \
875 { \
876 itor tmp = *this; \
877 m_node = m_node ? m_node->GetNext() : m_init; \
878 return tmp; \
879 } \
880 bool operator!=(const itor& it) const \
881 { return it.m_node != m_node; } \
882 bool operator==(const itor& it) const \
883 { return it.m_node == m_node; } \
884 }; \
885 class const_reverse_iterator \
886 { \
887 typedef name list; \
888 public: \
889 typedef nodetype Node; \
890 typedef T* value_type; \
891 typedef const_reverse_iterator itor; \
892 typedef value_type* ptr_type; \
893 typedef const value_type& const_reference; \
894 \
895 Node* m_node; \
896 Node* m_init; \
897 public: \
898 typedef const_reference reference_type; \
899 typedef const ptr_type pointer_type; \
900 \
901 const_reverse_iterator(Node* node, Node* init) \
902 : m_node(node), m_init(init) { } \
903 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
904 const_reverse_iterator(const reverse_iterator& it) \
905 : m_node(it.m_node), m_init(it.m_init) { } \
906 reference_type operator*() const \
907 { return *(pointer_type)m_node->GetDataPtr(); } \
908 ptrop \
909 itor& operator++() \
910 { m_node = m_node->GetPrevious(); return *this; } \
911 const itor operator++(int) \
912 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
913 itor& operator--() \
914 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
915 const itor operator--(int) \
916 { \
917 itor tmp = *this; \
918 m_node = m_node ? m_node->GetNext() : m_init; \
919 return tmp; \
920 } \
921 bool operator!=(const itor& it) const \
922 { return it.m_node != m_node; } \
923 bool operator==(const itor& it) const \
924 { return it.m_node == m_node; } \
925 }; \
926 \
927 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
928 { assign(n, v); } \
929 name(const const_iterator& first, const const_iterator& last) \
930 { assign(first, last); } \
931 iterator begin() { return iterator(GetFirst(), GetLast()); } \
932 const_iterator begin() const \
933 { return const_iterator(GetFirst(), GetLast()); } \
934 iterator end() { return iterator(NULL, GetLast()); } \
935 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
936 reverse_iterator rbegin() \
937 { return reverse_iterator(GetLast(), GetFirst()); } \
938 const_reverse_iterator rbegin() const \
939 { return const_reverse_iterator(GetLast(), GetFirst()); } \
940 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
941 const_reverse_iterator rend() const \
942 { return const_reverse_iterator(NULL, GetFirst()); } \
943 void resize(size_type n, value_type v = value_type()) \
944 { \
945 while (n < size()) \
946 pop_back(); \
947 while (n > size()) \
948 push_back(v); \
949 } \
950 size_type size() const { return GetCount(); } \
951 size_type max_size() const { return INT_MAX; } \
952 bool empty() const { return IsEmpty(); } \
953 reference front() { return *begin(); } \
954 const_reference front() const { return *begin(); } \
955 reference back() { iterator tmp = end(); return *--tmp; } \
956 const_reference back() const { const_iterator tmp = end(); return *--tmp; }\
957 void push_front(const_reference v = value_type()) \
958 { Insert(GetFirst(), (const_base_reference)v); } \
959 void pop_front() { DeleteNode(GetFirst()); } \
960 void push_back(const_reference v = value_type()) \
961 { Append((const_base_reference)v); } \
962 void pop_back() { DeleteNode(GetLast()); } \
963 void assign(const_iterator first, const const_iterator& last) \
964 { \
965 clear(); \
966 for(; first != last; ++first) \
967 Append((const_base_reference)*first); \
968 } \
969 void assign(size_type n, const_reference v = value_type()) \
970 { \
971 clear(); \
972 for(size_type i = 0; i < n; ++i) \
973 Append((const_base_reference)v); \
974 } \
975 iterator insert(const iterator& it, const_reference v = value_type())\
976 { \
977 Insert(it.m_node, (const_base_reference)v); \
978 return iterator(it.m_node->GetPrevious(), GetLast()); \
979 } \
980 void insert(const iterator& it, size_type n, const_reference v = value_type())\
981 { \
982 for(size_type i = 0; i < n; ++i) \
983 Insert(it.m_node, (const_base_reference)v); \
984 } \
985 void insert(const iterator& it, const_iterator first, const const_iterator& last)\
986 { \
987 for(; first != last; ++first) \
988 Insert(it.m_node, (const_base_reference)*first); \
989 } \
990 iterator erase(const iterator& it) \
991 { \
992 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
993 DeleteNode(it.m_node); return next; \
994 } \
995 iterator erase(const iterator& first, const iterator& last) \
996 { \
997 iterator next = last; ++next; \
998 DeleteNodes(first.m_node, last.m_node); \
999 return next; \
1000 } \
1001 void clear() { Clear(); } \
1002 void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
1003 { insert(it, first, last); l.erase(first, last); } \
1004 void splice(const iterator& it, name& l) \
1005 { splice(it, l, l.begin(), l.end() ); } \
1006 void splice(const iterator& it, name& l, const iterator& first) \
1007 { \
1008 iterator tmp = first; ++tmp; \
1009 if(it == first || it == tmp) return; \
1010 insert(it, *first); \
1011 l.erase(first); \
1012 } \
1013 void remove(const_reference v) \
1014 { DeleteObject((const_base_reference)v); } \
1015 void reverse() \
1016 { Reverse(); } \
1017 /* void swap(name& l) \
1018 { \
1019 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
1020 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1021 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1022 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1023 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1024 } */ \
1025 }
1026
1027 #define WX_LIST_PTROP \
1028 pointer_type operator->() const \
1029 { return (pointer_type)m_node->GetDataPtr(); }
1030 #define WX_LIST_PTROP_NONE
1031
1032 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1033 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1034 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1035 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1036
1037 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1038 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
1039 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1040 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
1041
1042 #define WX_DECLARE_LIST(elementtype, listname) \
1043 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1044 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
1045 #define WX_DECLARE_LIST_PTR(elementtype, listname) \
1046 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1047 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
1048
1049 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
1050 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1051 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
1052
1053 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1054 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1055
1056 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1057 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1058 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
1059
1060 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1061 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1062 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
1063 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1064 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1065 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
1066
1067 // this macro must be inserted in your program after
1068 // #include "wx/listimpl.cpp"
1069 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1070
1071 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1072 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1073
1074 #endif // !wxUSE_STL
1075
1076 // ============================================================================
1077 // now we can define classes 100% compatible with the old ones
1078 // ============================================================================
1079
1080 // ----------------------------------------------------------------------------
1081 // commonly used list classes
1082 // ----------------------------------------------------------------------------
1083
1084 #if defined(wxLIST_COMPATIBILITY)
1085
1086 // inline compatibility functions
1087
1088 #if !wxUSE_STL
1089
1090 // ----------------------------------------------------------------------------
1091 // wxNodeBase deprecated methods
1092 // ----------------------------------------------------------------------------
1093
1094 inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
1095 inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
1096 inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1097
1098 // ----------------------------------------------------------------------------
1099 // wxListBase deprecated methods
1100 // ----------------------------------------------------------------------------
1101
1102 inline int wxListBase::Number() const { return (int)GetCount(); }
1103 inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
1104 inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
1105 inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1106 inline wxListBase::operator wxList&() const { return *(wxList*)this; }
1107
1108 #endif
1109
1110 // define this to make a lot of noise about use of the old wxList classes.
1111 //#define wxWARN_COMPAT_LIST_USE
1112
1113 // ----------------------------------------------------------------------------
1114 // wxList compatibility class: in fact, it's a list of wxObjects
1115 // ----------------------------------------------------------------------------
1116
1117 WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1118 class WXDLLIMPEXP_BASE);
1119
1120 class WXDLLIMPEXP_BASE wxList : public wxObjectList
1121 {
1122 public:
1123 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
1124 wxList() { };
1125 wxDEPRECATED( wxList(int key_type) );
1126 #elif !wxUSE_STL
1127 wxList(int key_type = wxKEY_NONE);
1128 #endif
1129
1130 // this destructor is required for Darwin
1131 ~wxList() { }
1132
1133 #if !wxUSE_STL
1134 wxList& operator=(const wxList& list)
1135 { (void) wxListBase::operator=(list); return *this; }
1136
1137 // compatibility methods
1138 void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
1139 #endif
1140
1141 #if wxUSE_STL
1142 #else
1143 wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
1144 #endif
1145
1146 private:
1147 #if !wxUSE_STL
1148 DECLARE_DYNAMIC_CLASS(wxList)
1149 #endif
1150 };
1151
1152 #if !wxUSE_STL
1153
1154 // -----------------------------------------------------------------------------
1155 // wxStringList class for compatibility with the old code
1156 // -----------------------------------------------------------------------------
1157 WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
1158
1159 class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1160 {
1161 public:
1162 // ctors and such
1163 // default
1164 #ifdef wxWARN_COMPAT_LIST_USE
1165 wxStringList();
1166 wxDEPRECATED( wxStringList(const wxChar *first ...) );
1167 #else
1168 wxStringList();
1169 wxStringList(const wxChar *first ...);
1170 #endif
1171
1172 // copying the string list: the strings are copied, too (extremely
1173 // inefficient!)
1174 wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(true); DoCopy(other); }
1175 wxStringList& operator=(const wxStringList& other)
1176 { Clear(); DoCopy(other); return *this; }
1177
1178 // operations
1179 // makes a copy of the string
1180 wxNode *Add(const wxChar *s);
1181
1182 // Append to beginning of list
1183 wxNode *Prepend(const wxChar *s);
1184
1185 bool Delete(const wxChar *s);
1186
1187 wxChar **ListToArray(bool new_copies = false) const;
1188 bool Member(const wxChar *s) const;
1189
1190 // alphabetic sort
1191 void Sort();
1192
1193 private:
1194 void DoCopy(const wxStringList&); // common part of copy ctor and operator=
1195
1196 DECLARE_DYNAMIC_CLASS(wxStringList)
1197 };
1198
1199 #else // if wxUSE_STL
1200
1201 WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLIMPEXP_BASE);
1202
1203 class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1204 {
1205 public:
1206 compatibility_iterator Append(wxChar* s)
1207 { wxString tmp = s; delete[] s; return wxStringListBase::Append(tmp); }
1208 compatibility_iterator Insert(wxChar* s)
1209 { wxString tmp = s; delete[] s; return wxStringListBase::Insert(tmp); }
1210 compatibility_iterator Insert(size_t pos, wxChar* s)
1211 {
1212 wxString tmp = s;
1213 delete[] s;
1214 return wxStringListBase::Insert(pos, tmp);
1215 }
1216 compatibility_iterator Add(const wxChar* s)
1217 { push_back(s); return GetLast(); }
1218 compatibility_iterator Prepend(const wxChar* s)
1219 { push_front(s); return GetFirst(); }
1220 };
1221
1222 #endif // wxUSE_STL
1223
1224 #endif // wxLIST_COMPATIBILITY
1225
1226 // delete all list elements
1227 //
1228 // NB: the class declaration of the list elements must be visible from the
1229 // place where you use this macro, otherwise the proper destructor may not
1230 // be called (a decent compiler should give a warning about it, but don't
1231 // count on it)!
1232 #define WX_CLEAR_LIST(type, list) \
1233 { \
1234 type::iterator it, en; \
1235 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1236 delete *it; \
1237 (list).clear(); \
1238 }
1239
1240 #endif // _WX_LISTH__