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