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