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
52extern "C"
53{
54typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2);
55}
56
57class WXDLLIMPEXP_FWD_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                              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
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_FWD_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_FWD_BASE wxList;
503
504class WXDLLIMPEXP_BASE wxListBase : public wxObject
505{
506friend class WXDLLIMPEXP_FWD_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            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
1162inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
1163inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
1164inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1165
1166// ----------------------------------------------------------------------------
1167// wxListBase deprecated methods
1168// ----------------------------------------------------------------------------
1169
1170inline int wxListBase::Number() const { return (int)GetCount(); }
1171inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
1172inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
1173inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1174inline 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
1185WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1186                        class WXDLLIMPEXP_BASE);
1187
1188class WXDLLIMPEXP_BASE wxList : public wxObjectList
1189{
1190public:
1191#if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
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
1199   ~wxList() { }
1200
1201#if !wxUSE_STL
1202    wxList& operator=(const wxList& list)
1203        { (void) wxListBase::operator=(list); return *this; }
1204
1205    // compatibility methods
1206    void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
1207#endif
1208
1209#if wxUSE_STL
1210#else
1211    wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
1212#endif
1213
1214private:
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// -----------------------------------------------------------------------------
1225WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
1226
1227class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1228{
1229public:
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!)
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
1261private:
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
1269WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLIMPEXP_BASE);
1270
1271class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1272{
1273public:
1274    compatibility_iterator Append(wxChar* s)
1275        { wxString tmp = s; delete[] s; return wxStringListBase::Append(tmp); }
1276    compatibility_iterator Insert(wxChar* s)
1277        { wxString tmp = s; delete[] s; return wxStringListBase::Insert(tmp); }
1278    compatibility_iterator Insert(size_t pos, wxChar* s)
1279    {
1280        wxString tmp = s;
1281        delete[] s;
1282        return wxStringListBase::Insert(pos, tmp);
1283    }
1284    compatibility_iterator Add(const wxChar* s)
1285        { push_back(s); return GetLast(); }
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