Coverage Report

Created: 2025-06-13 06:30

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