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