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