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