]> git.saurik.com Git - wxWidgets.git/blame_incremental - include/wx/list.h
Committing in .
[wxWidgets.git] / include / wx / list.h
... / ...
CommitLineData
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
52extern "C"
53{
54typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2);
55}
56
57class WXDLLIMPEXP_BASE wxObjectListNode;
58typedef wxObjectListNode wxNode;
59
60//
61typedef 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
70enum 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
98template<class T>
99class WXDLLIMPEXP_BASE wxList_SortFunction
100{
101public:
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; }
105private:
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// due to circular header dependencies this function has to be declared here
373// (normally it's found in utils.h which includes itself list.h...)
374#if WXWIN_COMPATIBILITY_2_4
375extern WXDLLIMPEXP_BASE wxChar* copystring(const wxChar *s);
376#endif
377
378// undef it to get rid of old, deprecated functions
379#define wxLIST_COMPATIBILITY
380
381// -----------------------------------------------------------------------------
382// key stuff: a list may be optionally keyed on integer or string key
383// -----------------------------------------------------------------------------
384
385union wxListKeyValue
386{
387 long integer;
388 wxChar *string;
389};
390
391// a struct which may contain both types of keys
392//
393// implementation note: on one hand, this class allows to have only one function
394// for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
395// resolve ambiguity which we would otherwise have with wxStringList::Find() and
396// wxList::Find(const char *).
397class WXDLLIMPEXP_BASE wxListKey
398{
399public:
400 // implicit ctors
401 wxListKey() : m_keyType(wxKEY_NONE)
402 { }
403 wxListKey(long i) : m_keyType(wxKEY_INTEGER)
404 { m_key.integer = i; }
405 wxListKey(const wxChar *s) : m_keyType(wxKEY_STRING)
406 { m_key.string = wxStrdup(s); }
407 wxListKey(const wxString& s) : m_keyType(wxKEY_STRING)
408 { m_key.string = wxStrdup(s.c_str()); }
409
410 // accessors
411 wxKeyType GetKeyType() const { return m_keyType; }
412 const wxChar *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 free(m_key.string);
427 }
428
429private:
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
438extern WXDLLIMPEXP_DATA_BASE(wxListKey) wxDefaultListKey;
439
440class WXDLLIMPEXP_BASE wxListBase;
441
442class WXDLLIMPEXP_BASE wxNodeBase
443{
444friend class wxListBase;
445public:
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 const wxChar *GetKeyString() const { return m_key.string; }
457 long GetKeyInteger() const { return m_key.integer; }
458
459 // Necessary for some existing code
460 void SetKeyString(wxChar* s) { m_key.string = 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
470protected:
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() { }
482public:
483 // for wxList::iterator
484 void** GetDataPtr() const { return &(((wxNodeBase*)this)->m_data); }
485private:
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
502class WXDLLIMPEXP_BASE wxList;
503
504class WXDLLIMPEXP_BASE wxListBase : public wxObject
505{
506friend class WXDLLIMPEXP_BASE wxNodeBase; // should be able to call DetachNode()
507friend class wxHashTableBase; // should be able to call untyped Find()
508
509public:
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
553protected:
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__
565public:
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
574protected:
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 wxChar *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);
644private:
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
1155inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
1156inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
1157inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1158
1159// ----------------------------------------------------------------------------
1160// wxListBase deprecated methods
1161// ----------------------------------------------------------------------------
1162
1163inline int wxListBase::Number() const { return (int)GetCount(); }
1164inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
1165inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
1166inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1167inline 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
1178WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1179 class WXDLLIMPEXP_BASE);
1180
1181class WXDLLIMPEXP_BASE wxList : public wxObjectList
1182{
1183public:
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
1207private:
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// -----------------------------------------------------------------------------
1218WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
1219
1220class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1221{
1222public:
1223 // ctors and such
1224 // default
1225#ifdef wxWARN_COMPAT_LIST_USE
1226 wxStringList();
1227 wxDEPRECATED( wxStringList(const wxChar *first ...) );
1228#else
1229 wxStringList();
1230 wxStringList(const wxChar *first ...);
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
1254private:
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
1262WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLIMPEXP_BASE);
1263
1264class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1265{
1266public:
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__