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