Statistics
| Revision:

root / trunk / install / launcher / izpack-launcher-1.3_linux / src / wx / include / wx / list.h @ 6834

History | View | Annotate | Download (23.9 KB)

1
/////////////////////////////////////////////////////////////////////////////
2
// Name:        list.h
3
// Purpose:     wxList, wxStringList classes
4
// Author:      Julian Smart
5
// Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added
6
// Created:     29/01/98
7
// RCS-ID:      $Id: list.h 6834 2006-08-24 08:23:24Z jmvivo $
8
// Copyright:   (c) 1998 Julian Smart
9
// Licence:     wxWindows license
10
/////////////////////////////////////////////////////////////////////////////
11

    
12
/*
13
  All this is quite ugly but serves two purposes:
14
    1. Be almost 100% compatible with old, untyped, wxList class
15
    2. Ensure compile-time type checking for the linked lists
16

17
  The idea is to have one base class (wxListBase) working with "void *" data,
18
  but to hide these untyped functions - i.e. make them protected, so they
19
  can only be used from derived classes which have inline member functions
20
  working with right types. This achieves the 2nd goal. As for the first one,
21
  we provide a special derivation of wxListBase called wxList which looks just
22
  like the old class.
23
*/
24

    
25
#ifndef _WX_LISTH__
26
#define _WX_LISTH__
27

    
28
// -----------------------------------------------------------------------------
29
// headers
30
// -----------------------------------------------------------------------------
31

    
32
#include "wx/defs.h"
33
#include "wx/object.h"
34
#include "wx/string.h"
35

    
36
// due to circular header dependencies this function has to be declared here
37
// (normally it's found in utils.h which includes itself list.h...)
38
extern WXDLLEXPORT wxChar* copystring(const wxChar *s);
39

    
40
class WXDLLEXPORT wxObjectListNode;
41
typedef wxObjectListNode wxNode;
42

    
43
// undef it to get rid of old, deprecated functions
44
#define wxLIST_COMPATIBILITY
45

    
46
// -----------------------------------------------------------------------------
47
// constants
48
// -----------------------------------------------------------------------------
49
enum wxKeyType
50
{
51
    wxKEY_NONE,
52
    wxKEY_INTEGER,
53
    wxKEY_STRING
54
};
55

    
56
// -----------------------------------------------------------------------------
57
// types
58
// -----------------------------------------------------------------------------
59

    
60
// type of compare function for list sort operation (as in 'qsort'): it should
61
// return a negative value, 0 or positive value if the first element is less
62
// than, equal or greater than the second
63
extern "C"
64
{
65
typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2);
66
}
67

    
68
//
69
typedef int (* LINKAGEMODE wxListIterateFunction)(void *current);
70

    
71
// -----------------------------------------------------------------------------
72
// key stuff: a list may be optionally keyed on integer or string key
73
// -----------------------------------------------------------------------------
74

    
75
union wxListKeyValue
76
{
77
    long integer;
78
    wxChar *string;
79
};
80

    
81
// a struct which may contain both types of keys
82
//
83
// implementation note: on one hand, this class allows to have only one function
84
// for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
85
// resolve ambiguity which we would otherwise have with wxStringList::Find() and
86
// wxList::Find(const char *).
87
class WXDLLEXPORT wxListKey
88
{
89
public:
90
    // implicit ctors
91
    wxListKey() : m_keyType(wxKEY_NONE)
92
        { }
93
    wxListKey(long i) : m_keyType(wxKEY_INTEGER)
94
        { m_key.integer = i; }
95
    wxListKey(const wxChar *s) : m_keyType(wxKEY_STRING)
96
        { m_key.string = wxStrdup(s); }
97
    wxListKey(const wxString& s) : m_keyType(wxKEY_STRING)
98
        { m_key.string = wxStrdup(s.c_str()); }
99

    
100
    // accessors
101
    wxKeyType GetKeyType() const { return m_keyType; }
102
    const wxChar *GetString() const
103
        { wxASSERT( m_keyType == wxKEY_STRING ); return m_key.string; }
104
    long GetNumber() const
105
        { wxASSERT( m_keyType == wxKEY_INTEGER ); return m_key.integer; }
106

    
107
    // comparison
108
    // Note: implementation moved to list.cpp to prevent BC++ inline
109
    // expansion warning.
110
    bool operator==(wxListKeyValue value) const ;
111

    
112
    // dtor
113
    ~wxListKey()
114
    {
115
        if ( m_keyType == wxKEY_STRING )
116
            free(m_key.string);
117
    }
118

    
119
private:
120
    wxKeyType m_keyType;
121
    wxListKeyValue m_key;
122
};
123

    
124
// -----------------------------------------------------------------------------
125
// wxNodeBase class is a (base for) node in a double linked list
126
// -----------------------------------------------------------------------------
127

    
128
WXDLLEXPORT_DATA(extern wxListKey) wxDefaultListKey;
129

    
130
class WXDLLEXPORT wxListBase;
131

    
132
class WXDLLEXPORT wxNodeBase
133
{
134
friend class wxListBase;
135
public:
136
    // ctor
137
    wxNodeBase(wxListBase *list = (wxListBase *)NULL,
138
               wxNodeBase *previous = (wxNodeBase *)NULL,
139
               wxNodeBase *next = (wxNodeBase *)NULL,
140
               void *data = NULL,
141
               const wxListKey& key = wxDefaultListKey);
142

    
143
    virtual ~wxNodeBase();
144

    
145
    // FIXME no check is done that the list is really keyed on strings
146
    const wxChar *GetKeyString() const { return m_key.string; }
147
    long GetKeyInteger() const { return m_key.integer; }
148

    
149
    // Necessary for some existing code
150
    void SetKeyString(wxChar* s) { m_key.string = s; }
151
    void SetKeyInteger(long i) { m_key.integer = i; }
152

    
153
#ifdef wxLIST_COMPATIBILITY
154
    // compatibility methods
155
    wxNode *Next() const { return (wxNode *)GetNext(); }
156
    wxNode *Previous() const { return (wxNode *)GetPrevious(); }
157
    wxObject *Data() const { return (wxObject *)GetData(); }
158
#endif // wxLIST_COMPATIBILITY
159

    
160
protected:
161
    // all these are going to be "overloaded" in the derived classes
162
    wxNodeBase *GetNext() const { return m_next; }
163
    wxNodeBase *GetPrevious() const { return m_previous; }
164

    
165
    void *GetData() const { return m_data; }
166
    void SetData(void *data) { m_data = data; }
167

    
168
    // get 0-based index of this node within the list or wxNOT_FOUND
169
    int IndexOf() const;
170

    
171
    virtual void DeleteData() { }
172

    
173
private:
174
    // optional key stuff
175
    wxListKeyValue m_key;
176

    
177
    void        *m_data;        // user data
178
    wxNodeBase  *m_next,        // next and previous nodes in the list
179
                *m_previous;
180

    
181
    wxListBase  *m_list;        // list we belong to
182

    
183
    DECLARE_NO_COPY_CLASS(wxNodeBase)
184
};
185

    
186
// -----------------------------------------------------------------------------
187
// a double-linked list class
188
// -----------------------------------------------------------------------------
189

    
190
class WXDLLEXPORT wxListBase : public wxObject
191
{
192
friend class WXDLLEXPORT wxNodeBase; // should be able to call DetachNode()
193
friend class wxHashTableBase;   // should be able to call untyped Find()
194
private:
195
        // common part of all ctors
196
    void Init(wxKeyType keyType = wxKEY_NONE); // Must be declared before it's used (for VC++ 1.5)
197
public:
198
    // default ctor & dtor
199
    wxListBase(wxKeyType keyType = wxKEY_NONE)
200
        { Init(keyType); }
201
    virtual ~wxListBase();
202

    
203
    // accessors
204
        // count of items in the list
205
    size_t GetCount() const { return m_count; }
206

    
207
        // return TRUE if this list is empty
208
    bool IsEmpty() const { return m_count == 0; }
209

    
210
    // operations
211

    
212
        // delete all nodes
213
    void Clear();
214

    
215
        // instruct it to destroy user data when deleting nodes
216
    void DeleteContents(bool destroy) { m_destroy = destroy; }
217

    
218
       // query if to delete
219
    bool GetDeleteContents() const
220
        { return m_destroy; }
221

    
222
      // get the keytype
223
    wxKeyType GetKeyType() const
224
        { return m_keyType; }
225

    
226
      // set the keytype (required by the serial code)
227
    void SetKeyType(wxKeyType keyType)
228
        { wxASSERT( m_count==0 ); m_keyType = keyType; }
229

    
230
#ifdef wxLIST_COMPATIBILITY
231
    int Number() const { return GetCount(); }
232
    wxNode *First() const { return (wxNode *)GetFirst(); }
233
    wxNode *Last() const { return (wxNode *)GetLast(); }
234
    wxNode *Nth(size_t n) const { return (wxNode *)Item(n); }
235
#endif // wxLIST_COMPATIBILITY
236

    
237
protected:
238

    
239
    // all methods here are "overloaded" in derived classes to provide compile
240
    // time type checking
241

    
242
    // create a node for the list of this type
243
    virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next,
244
                                   void *data,
245
                                   const wxListKey& key = wxDefaultListKey) = 0;
246

    
247
// Can't access these from derived classes otherwise (bug in Salford C++?)
248
#ifdef __SALFORDC__
249
public:
250
#endif
251

    
252
    // ctors
253
        // from an array
254
    wxListBase(size_t count, void *elements[]);
255
        // from a sequence of objects
256
    wxListBase(void *object, ... /* terminate with NULL */);
257

    
258
protected:
259
        // copy ctor and assignment operator
260
    wxListBase(const wxListBase& list) : wxObject()
261
        { Init(); DoCopy(list); }
262
    wxListBase& operator=(const wxListBase& list)
263
        { Clear(); DoCopy(list); return *this; }
264

    
265
        // get list head/tail
266
    wxNodeBase *GetFirst() const { return m_nodeFirst; }
267
    wxNodeBase *GetLast() const { return m_nodeLast; }
268

    
269
        // by (0-based) index
270
    wxNodeBase *Item(size_t index) const;
271

    
272
        // get the list item's data
273
    void *operator[](size_t n) const
274
    {
275
        wxNodeBase *node = Item(n);
276

    
277
        return node ? node->GetData() : (wxNodeBase *)NULL;
278
    }
279

    
280
    // operations
281
        // append to end of list
282
    wxNodeBase *Prepend(void *object)
283
        { return (wxNodeBase *)wxListBase::Insert(object); }
284
        // append to beginning of list
285
    wxNodeBase *Append(void *object);
286
        // insert a new item at the beginning of the list
287
    wxNodeBase *Insert(void *object) { return Insert( (wxNodeBase*)NULL, object); }
288
        // insert a new item at the given position
289
    wxNodeBase *Insert(size_t pos, void *object)
290
        { return pos == GetCount() ? Append(object)
291
                                   : Insert(Item(pos), object); }
292
        // insert before given node or at front of list if prev == NULL
293
    wxNodeBase *Insert(wxNodeBase *prev, void *object);
294

    
295
        // keyed append
296
    wxNodeBase *Append(long key, void *object);
297
    wxNodeBase *Append(const wxChar *key, void *object);
298

    
299
        // removes node from the list but doesn't delete it (returns pointer
300
        // to the node or NULL if it wasn't found in the list)
301
    wxNodeBase *DetachNode(wxNodeBase *node);
302
        // delete element from list, returns FALSE if node not found
303
    bool DeleteNode(wxNodeBase *node);
304
        // finds object pointer and deletes node (and object if DeleteContents
305
        // is on), returns FALSE if object not found
306
    bool DeleteObject(void *object);
307

    
308
    // search (all return NULL if item not found)
309
        // by data
310
    wxNodeBase *Find(void *object) const;
311

    
312
        // by key
313
    wxNodeBase *Find(const wxListKey& key) const;
314

    
315
    // get 0-based index of object or wxNOT_FOUND
316
    int IndexOf( void *object ) const;
317

    
318
    // this function allows the sorting of arbitrary lists by giving
319
    // a function to compare two list elements. The list is sorted in place.
320
    void Sort(const wxSortCompareFunction compfunc);
321

    
322
    // functions for iterating over the list
323
    void *FirstThat(wxListIterateFunction func);
324
    void ForEach(wxListIterateFunction func);
325
    void *LastThat(wxListIterateFunction func);
326

    
327
private:
328
    // helpers
329
        // common part of copy ctor and assignment operator
330
    void DoCopy(const wxListBase& list);
331
        // common part of all Append()s
332
    wxNodeBase *AppendCommon(wxNodeBase *node);
333
        // free node's data and node itself
334
    void DoDeleteNode(wxNodeBase *node);
335

    
336
    size_t m_count;             // number of elements in the list
337
    bool m_destroy;             // destroy user data when deleting list items?
338
    wxNodeBase *m_nodeFirst,    // pointers to the head and tail of the list
339
               *m_nodeLast;
340

    
341
    wxKeyType m_keyType;        // type of our keys (may be wxKEY_NONE)
342
};
343

    
344
// -----------------------------------------------------------------------------
345
// macros for definition of "template" list type
346
// -----------------------------------------------------------------------------
347

    
348
// and now some heavy magic...
349

    
350
// declare a list type named 'name' and containing elements of type 'T *'
351
// (as a by product of macro expansion you also get wx##name##Node
352
// wxNode-derived type)
353
//
354
// implementation details:
355
//  1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
356
//     for the list of given type - this allows us to pass only the list name
357
//     to WX_DEFINE_LIST() even if it needs both the name and the type
358
//
359
//  2. We redefine all non-type-safe wxList functions with type-safe versions
360
//     which don't take any space (everything is inline), but bring compile
361
//     time error checking.
362
//
363
//  3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
364
//     a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
365
//     generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
366
//     interesting capability to store polymorphic objects in the list and is
367
//     particularly useful with, for example, "wxWindow *" list where the
368
//     wxWindowBase pointers are put into the list, but wxWindow pointers are
369
//     retrieved from it.
370

    
371
#define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp)               \
372
    typedef int (*wxSortFuncFor_##name)(const T **, const T **);            \
373
                                                                            \
374
    classexp nodetype : public wxNodeBase                                   \
375
    {                                                                       \
376
    public:                                                                 \
377
        nodetype(wxListBase *list = (wxListBase *)NULL,                     \
378
                 nodetype *previous = (nodetype *)NULL,                     \
379
                 nodetype *next = (nodetype *)NULL,                         \
380
                 T *data = (T *)NULL,                                       \
381
                 const wxListKey& key = wxDefaultListKey)                   \
382
            : wxNodeBase(list, previous, next, data, key) { }               \
383
                                                                            \
384
        nodetype *GetNext() const                                           \
385
            { return (nodetype *)wxNodeBase::GetNext(); }                   \
386
        nodetype *GetPrevious() const                                       \
387
            { return (nodetype *)wxNodeBase::GetPrevious(); }               \
388
                                                                            \
389
        T *GetData() const                                                  \
390
            { return (T *)wxNodeBase::GetData(); }                          \
391
        void SetData(T *data)                                               \
392
            { wxNodeBase::SetData(data); }                                  \
393
                                                                            \
394
        virtual void DeleteData();                                          \
395
    };                                                                      \
396
                                                                            \
397
    classexp name : public wxListBase                                       \
398
    {                                                                       \
399
    public:                                                                 \
400
        typedef nodetype Node;                                              \
401
        typedef Node* compatibility_iterator;                               \
402
                                                                            \
403
        name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType)          \
404
            { }                                                             \
405
        name(size_t count, T *elements[])                                   \
406
            : wxListBase(count, (void **)elements) { }                      \
407
                                                                            \
408
        name& operator=(const name& list)                                   \
409
            { (void) wxListBase::operator=(list); return *this; }           \
410
                                                                            \
411
        nodetype *GetFirst() const                                          \
412
            { return (nodetype *)wxListBase::GetFirst(); }                  \
413
        nodetype *GetLast() const                                           \
414
            { return (nodetype *)wxListBase::GetLast(); }                   \
415
                                                                            \
416
        nodetype *Item(size_t index) const                                  \
417
            { return (nodetype *)wxListBase::Item(index); }                 \
418
                                                                            \
419
        T *operator[](size_t index) const                                   \
420
        {                                                                   \
421
            nodetype *node = Item(index);                                   \
422
            return node ? (T*)(node->GetData()) : (T*)NULL;                 \
423
        }                                                                   \
424
                                                                            \
425
        nodetype *Append(Tbase *object)                                     \
426
            { return (nodetype *)wxListBase::Append(object); }              \
427
        nodetype *Insert(Tbase *object)                                     \
428
            { return (nodetype *)Insert((nodetype*)NULL, object); }         \
429
        nodetype *Insert(size_t pos, Tbase *object)                         \
430
            { return (nodetype *)wxListBase::Insert(pos, object); }         \
431
        nodetype *Insert(nodetype *prev, Tbase *object)                     \
432
            { return (nodetype *)wxListBase::Insert(prev, object); }        \
433
                                                                            \
434
        nodetype *Append(long key, void *object)                            \
435
            { return (nodetype *)wxListBase::Append(key, object); }         \
436
        nodetype *Append(const wxChar *key, void *object)                   \
437
            { return (nodetype *)wxListBase::Append(key, object); }         \
438
                                                                            \
439
        nodetype *DetachNode(nodetype *node)                                \
440
            { return (nodetype *)wxListBase::DetachNode(node); }            \
441
        bool DeleteNode(nodetype *node)                                     \
442
            { return wxListBase::DeleteNode(node); }                        \
443
        bool DeleteObject(Tbase *object)                                    \
444
            { return wxListBase::DeleteObject(object); }                    \
445
                                                                            \
446
        nodetype *Find(Tbase *object) const                                 \
447
            { return (nodetype *)wxListBase::Find(object); }                \
448
                                                                            \
449
        virtual nodetype *Find(const wxListKey& key) const                  \
450
            { return (nodetype *)wxListBase::Find(key); }                   \
451
                                                                            \
452
        int IndexOf(Tbase *object) const                                    \
453
            { return wxListBase::IndexOf(object); }                         \
454
                                                                            \
455
        void Sort(wxSortFuncFor_##name func)                                \
456
            { wxListBase::Sort((wxSortCompareFunction)func); }              \
457
                                                                            \
458
    protected:                                                              \
459
        virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next,  \
460
                               void *data,                                  \
461
                               const wxListKey& key = wxDefaultListKey)     \
462
            {                                                               \
463
                return new nodetype(this,                                   \
464
                                    (nodetype *)prev, (nodetype *)next,     \
465
                                    (T *)data, key);                        \
466
            }                                                               \
467
    }
468

    
469
#define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp)        \
470
    WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
471

    
472
#define WX_DECLARE_LIST(elementtype, listname)                              \
473
    typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
474
    WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
475

    
476
#define WX_DECLARE_EXPORTED_LIST(elementtype, listname)                     \
477
    typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
478
    WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
479

    
480
#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)       \
481
    typedef elementtype _WX_LIST_ITEM_TYPE_##listname;                      \
482
    WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
483

    
484
// this macro must be inserted in your program after
485
//      #include <wx/listimpl.cpp>
486
#define WX_DEFINE_LIST(name)    "don't forget to include listimpl.cpp!"
487

    
488
#define WX_DEFINE_EXPORTED_LIST(name)      WX_DEFINE_LIST(name)
489
#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
490

    
491

    
492
// =============================================================================
493
// now we can define classes 100% compatible with the old ones
494
// =============================================================================
495

    
496
// ----------------------------------------------------------------------------
497
// commonly used list classes
498
// ----------------------------------------------------------------------------
499

    
500
#ifdef wxLIST_COMPATIBILITY
501

    
502
// -----------------------------------------------------------------------------
503
// wxList compatibility class: in fact, it's a list of wxObjects
504
// -----------------------------------------------------------------------------
505

    
506
WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode, class WXDLLEXPORT);
507

    
508
class WXDLLEXPORT wxList : public wxObjectList
509
{
510
public:
511
    wxList(int key_type = wxKEY_NONE) : wxObjectList((wxKeyType)key_type) { }
512
    // this destructor is required for Darwin
513
   ~wxList() { }
514

    
515
    wxList& operator=(const wxList& list)
516
        { (void) wxListBase::operator=(list); return *this; }
517

    
518
    // compatibility methods
519
    void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
520

    
521
    wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
522

    
523
private:
524
    DECLARE_DYNAMIC_CLASS(wxList)
525
};
526

    
527
// -----------------------------------------------------------------------------
528
// wxStringList class for compatibility with the old code
529
// -----------------------------------------------------------------------------
530

    
531
WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLEXPORT);
532

    
533
class WXDLLEXPORT wxStringList : public wxStringListBase
534
{
535
public:
536
    // ctors and such
537
        // default
538
    wxStringList() { DeleteContents(TRUE); }
539
    wxStringList(const wxChar *first ...);
540

    
541
        // copying the string list: the strings are copied, too (extremely
542
        // inefficient!)
543
    wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(TRUE); DoCopy(other); }
544
    wxStringList& operator=(const wxStringList& other)
545
        { Clear(); DoCopy(other); return *this; }
546

    
547
    // operations
548
        // makes a copy of the string
549
    wxNode *Add(const wxChar *s)
550
        { return (wxNode *)wxStringListBase::Append(copystring(s)); }
551
        
552
        // Append to beginning of list
553
    wxNode *Prepend(const wxChar *s)
554
        { return (wxNode *)wxStringListBase::Insert(copystring(s)); }
555

    
556
    bool Delete(const wxChar *s);
557

    
558
    wxChar **ListToArray(bool new_copies = FALSE) const;
559
    bool Member(const wxChar *s) const;
560

    
561
    // alphabetic sort
562
    void Sort();
563

    
564
private:
565
    void DoCopy(const wxStringList&); // common part of copy ctor and operator=
566

    
567
    DECLARE_DYNAMIC_CLASS(wxStringList)
568
};
569

    
570
#endif // wxLIST_COMPATIBILITY
571

    
572
#endif
573
    // _WX_LISTH__