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