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