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: list.h 61872 2009-09-09 22:37:05Z VZ $
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_FWD_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:
wxList_SortFunction(wxSortCompareFunction f)102     wxList_SortFunction(wxSortCompareFunction f) : m_f(f) { }
operator()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                               wxT("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(const 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
375 extern 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 
385 union 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 *).
397 class WXDLLIMPEXP_BASE wxListKey
398 {
399 public:
400     // implicit ctors
wxListKey()401     wxListKey() : m_keyType(wxKEY_NONE)
402         { }
wxListKey(long i)403     wxListKey(long i) : m_keyType(wxKEY_INTEGER)
404         { m_key.integer = i; }
wxListKey(const wxChar * s)405     wxListKey(const wxChar *s) : m_keyType(wxKEY_STRING)
406         { m_key.string = wxStrdup(s); }
wxListKey(const wxString & s)407     wxListKey(const wxString& s) : m_keyType(wxKEY_STRING)
408         { m_key.string = wxStrdup(s.c_str()); }
409 
410     // accessors
GetKeyType()411     wxKeyType GetKeyType() const { return m_keyType; }
GetString()412     const wxChar *GetString() const
413         { wxASSERT( m_keyType == wxKEY_STRING ); return m_key.string; }
GetNumber()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
~wxListKey()423     ~wxListKey()
424     {
425         if ( m_keyType == wxKEY_STRING )
426             free(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_FWD_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
GetKeyString()456     const wxChar *GetKeyString() const { return m_key.string; }
GetKeyInteger()457     long GetKeyInteger() const { return m_key.integer; }
458 
459     // Necessary for some existing code
SetKeyString(wxChar * s)460     void SetKeyString(wxChar* s) { m_key.string = s; }
SetKeyInteger(long i)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
GetNext()472     wxNodeBase *GetNext() const { return m_next; }
GetPrevious()473     wxNodeBase *GetPrevious() const { return m_previous; }
474 
GetData()475     void *GetData() const { return m_data; }
SetData(void * 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 
DeleteData()481     virtual void DeleteData() { }
482 public:
483     // for wxList::iterator
GetDataPtr()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_FWD_BASE wxList;
503 
504 class WXDLLIMPEXP_BASE wxListBase : public wxObject
505 {
506 friend class WXDLLIMPEXP_FWD_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
GetCount()517     size_t GetCount() const { return m_count; }
518 
519         // return true if this list is empty
IsEmpty()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
DeleteContents(bool destroy)528     void DeleteContents(bool destroy) { m_destroy = destroy; }
529 
530        // query if to delete
GetDeleteContents()531     bool GetDeleteContents() const
532         { return m_destroy; }
533 
534       // get the keytype
GetKeyType()535     wxKeyType GetKeyType() const
536         { return m_keyType; }
537 
538       // set the keytype (required by the serial code)
SetKeyType(wxKeyType keyType)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:
Assign(const wxListBase & list)575     void Assign(const wxListBase& list)
576         { Clear(); DoCopy(list); }
577 
578         // get list head/tail
GetFirst()579     wxNodeBase *GetFirst() const { return m_nodeFirst; }
GetLast()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
Prepend(void * object)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
Insert(void * object)600     wxNodeBase *Insert(void *object) { return Insert( (wxNodeBase*)NULL, object); }
601         // insert a new item at the given position
Insert(size_t pos,void * object)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);
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             if ( it == end() )                                              \
1039                 Append((const_base_reference)v);                            \
1040             else                                                            \
1041                 Insert(it.m_node, (const_base_reference)v);                 \
1042             iterator itprev(it);                                            \
1043             return itprev--;                                                \
1044         }                                                                   \
1045         void insert(const iterator& it, size_type n, const_reference v = value_type())\
1046         {                                                                   \
1047             for(size_type i = 0; i < n; ++i)                                \
1048                 insert(it, v);                                              \
1049         }                                                                   \
1050         void insert(const iterator& it, const_iterator first, const const_iterator& last)\
1051         {                                                                   \
1052             for(; first != last; ++first)                                   \
1053                 insert(it, *first);                                         \
1054         }                                                                   \
1055         iterator erase(const iterator& it)                                  \
1056         {                                                                   \
1057             iterator next = iterator(it.m_node->GetNext(), GetLast());      \
1058             DeleteNode(it.m_node); return next;                             \
1059         }                                                                   \
1060         iterator erase(const iterator& first, const iterator& last)         \
1061         {                                                                   \
1062             iterator next = last;                                           \
1063             if ( next != end() )                                            \
1064                 ++next;                                                     \
1065             DeleteNodes(first.m_node, last.m_node);                         \
1066             return next;                                                    \
1067         }                                                                   \
1068         void clear() { Clear(); }                                           \
1069         void splice(const iterator& it, name& l, const iterator& first, const iterator& last)\
1070             { insert(it, first, last); l.erase(first, last); }              \
1071         void splice(const iterator& it, name& l)                            \
1072             { splice(it, l, l.begin(), l.end() ); }                         \
1073         void splice(const iterator& it, name& l, const iterator& first)     \
1074         {                                                                   \
1075             if ( it != first )                                              \
1076             {                                                               \
1077                 insert(it, *first);                                         \
1078                 l.erase(first);                                             \
1079             }                                                               \
1080         }                                                                   \
1081         void remove(const_reference v)                                      \
1082             { DeleteObject((const_base_reference)v); }                      \
1083         void reverse()                                                      \
1084             { Reverse(); }                                                  \
1085      /* void swap(name& l)                                                  \
1086         {                                                                   \
1087             { size_t t = m_count; m_count = l.m_count; l.m_count = t; }     \
1088             { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
1089             { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
1090             { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
1091             { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
1092         } */                                                                \
1093     }
1094 
1095 #define WX_LIST_PTROP                                                       \
1096             pointer_type operator->() const                                 \
1097                 { return (pointer_type)m_node->GetDataPtr(); }
1098 #define WX_LIST_PTROP_NONE
1099 
1100 #define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp)               \
1101     WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1102 #define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp)        \
1103     WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1104 
1105 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp)        \
1106     WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
1107 #define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp)        \
1108     WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
1109 
1110 #define WX_DECLARE_LIST(elementtype, listname)                              \
1111     typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
1112     WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
1113 #define WX_DECLARE_LIST_PTR(elementtype, listname)                              \
1114     typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
1115     WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
1116 
1117 #define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
1118     typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
1119     WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
1120 
1121 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname)                     \
1122     WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1123 
1124 #define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname)                     \
1125     typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
1126     WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
1127 
1128 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)       \
1129     typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
1130     WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
1131 #define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo)       \
1132     typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
1133     WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
1134 
1135 // this macro must be inserted in your program after
1136 //      #include "wx/listimpl.cpp"
1137 #define WX_DEFINE_LIST(name)    "don't forget to include listimpl.cpp!"
1138 
1139 #define WX_DEFINE_EXPORTED_LIST(name)      WX_DEFINE_LIST(name)
1140 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1141 
1142 #endif // !wxUSE_STL
1143 
1144 // ============================================================================
1145 // now we can define classes 100% compatible with the old ones
1146 // ============================================================================
1147 
1148 // ----------------------------------------------------------------------------
1149 // commonly used list classes
1150 // ----------------------------------------------------------------------------
1151 
1152 #if defined(wxLIST_COMPATIBILITY)
1153 
1154 // inline compatibility functions
1155 
1156 #if !wxUSE_STL
1157 
1158 // ----------------------------------------------------------------------------
1159 // wxNodeBase deprecated methods
1160 // ----------------------------------------------------------------------------
1161 
Next()1162 inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
Previous()1163 inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
Data()1164 inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1165 
1166 // ----------------------------------------------------------------------------
1167 // wxListBase deprecated methods
1168 // ----------------------------------------------------------------------------
1169 
Number()1170 inline int wxListBase::Number() const { return (int)GetCount(); }
First()1171 inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
Last()1172 inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
Nth(size_t n)1173 inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1174 inline wxListBase::operator wxList&() const { return *(wxList*)this; }
1175 
1176 #endif
1177 
1178 // define this to make a lot of noise about use of the old wxList classes.
1179 //#define wxWARN_COMPAT_LIST_USE
1180 
1181 // ----------------------------------------------------------------------------
1182 // wxList compatibility class: in fact, it's a list of wxObjects
1183 // ----------------------------------------------------------------------------
1184 
1185 WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1186                         class WXDLLIMPEXP_BASE);
1187 
1188 class WXDLLIMPEXP_BASE wxList : public wxObjectList
1189 {
1190 public:
1191 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
wxList()1192     wxList() { };
1193     wxDEPRECATED( wxList(int key_type) );
1194 #elif !wxUSE_STL
1195     wxList(int key_type = wxKEY_NONE);
1196 #endif
1197 
1198     // this destructor is required for Darwin
~wxList()1199    ~wxList() { }
1200 
1201 #if !wxUSE_STL
1202     wxList& operator=(const wxList& list)
1203         { (void) wxListBase::operator=(list); return *this; }
1204 
1205     // compatibility methods
Sort(wxSortCompareFunction compfunc)1206     void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
1207 #endif
1208 
1209 #if wxUSE_STL
1210 #else
Member(wxObject * object)1211     wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
1212 #endif
1213 
1214 private:
1215 #if !wxUSE_STL
1216     DECLARE_DYNAMIC_CLASS(wxList)
1217 #endif
1218 };
1219 
1220 #if !wxUSE_STL
1221 
1222 // -----------------------------------------------------------------------------
1223 // wxStringList class for compatibility with the old code
1224 // -----------------------------------------------------------------------------
1225 WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
1226 
1227 class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1228 {
1229 public:
1230     // ctors and such
1231         // default
1232 #ifdef wxWARN_COMPAT_LIST_USE
1233     wxStringList();
1234     wxDEPRECATED( wxStringList(const wxChar *first ...) );
1235 #else
1236     wxStringList();
1237     wxStringList(const wxChar *first ...);
1238 #endif
1239 
1240         // copying the string list: the strings are copied, too (extremely
1241         // inefficient!)
wxStringList(const wxStringList & other)1242     wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(true); DoCopy(other); }
1243     wxStringList& operator=(const wxStringList& other)
1244         { Clear(); DoCopy(other); return *this; }
1245 
1246     // operations
1247         // makes a copy of the string
1248     wxNode *Add(const wxChar *s);
1249 
1250         // Append to beginning of list
1251     wxNode *Prepend(const wxChar *s);
1252 
1253     bool Delete(const wxChar *s);
1254 
1255     wxChar **ListToArray(bool new_copies = false) const;
1256     bool Member(const wxChar *s) const;
1257 
1258     // alphabetic sort
1259     void Sort();
1260 
1261 private:
1262     void DoCopy(const wxStringList&); // common part of copy ctor and operator=
1263 
1264     DECLARE_DYNAMIC_CLASS(wxStringList)
1265 };
1266 
1267 #else // if wxUSE_STL
1268 
1269 WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLIMPEXP_BASE);
1270 
1271 class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1272 {
1273 public:
Append(wxChar * s)1274     compatibility_iterator Append(wxChar* s)
1275         { wxString tmp = s; delete[] s; return wxStringListBase::Append(tmp); }
Insert(wxChar * s)1276     compatibility_iterator Insert(wxChar* s)
1277         { wxString tmp = s; delete[] s; return wxStringListBase::Insert(tmp); }
Insert(size_t pos,wxChar * s)1278     compatibility_iterator Insert(size_t pos, wxChar* s)
1279     {
1280         wxString tmp = s;
1281         delete[] s;
1282         return wxStringListBase::Insert(pos, tmp);
1283     }
Add(const wxChar * s)1284     compatibility_iterator Add(const wxChar* s)
1285         { push_back(s); return GetLast(); }
Prepend(const wxChar * s)1286     compatibility_iterator Prepend(const wxChar* s)
1287         { push_front(s); return GetFirst(); }
1288 };
1289 
1290 #endif // wxUSE_STL
1291 
1292 #endif // wxLIST_COMPATIBILITY
1293 
1294 // delete all list elements
1295 //
1296 // NB: the class declaration of the list elements must be visible from the
1297 //     place where you use this macro, otherwise the proper destructor may not
1298 //     be called (a decent compiler should give a warning about it, but don't
1299 //     count on it)!
1300 #define WX_CLEAR_LIST(type, list)                                            \
1301     {                                                                        \
1302         type::iterator it, en;                                               \
1303         for( it = (list).begin(), en = (list).end(); it != en; ++it )        \
1304             delete *it;                                                      \
1305         (list).clear();                                                      \
1306     }
1307 
1308 #endif // _WX_LISTH__
1309