Coverage Report

Created: 2026-04-01 06:14

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