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