Coverage Report

Created: 2026-04-01 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wxwidgets/include/wx/hash.h
Line
Count
Source
1
/////////////////////////////////////////////////////////////////////////////
2
// Name:        wx/hash.h
3
// Purpose:     wxHashTable class
4
// Author:      Julian Smart
5
// Modified by: VZ at 25.02.00: type safe hashes with WX_DECLARE_HASH()
6
// Created:     01/02/97
7
// Copyright:   (c) Julian Smart
8
// Licence:     wxWindows licence
9
/////////////////////////////////////////////////////////////////////////////
10
11
#ifndef _WX_HASH_H__
12
#define _WX_HASH_H__
13
14
#include "wx/defs.h"
15
#include "wx/string.h"
16
17
#if !wxUSE_STD_CONTAINERS
18
    #include "wx/object.h"
19
#else
20
    class WXDLLIMPEXP_FWD_BASE wxObject;
21
#endif
22
23
// the default size of the hash
24
#define wxHASH_SIZE_DEFAULT     (1000)
25
26
/*
27
 * A hash table is an array of user-definable size with lists
28
 * of data items hanging off the array positions.  Usually there'll
29
 * be a hit, so no search is required; otherwise we'll have to run down
30
 * the list to find the desired item.
31
*/
32
33
union wxHashKeyValue
34
{
35
    long integer;
36
    wxString *string;
37
};
38
39
// for some compilers (AIX xlC), defining it as friend inside the class is not
40
// enough, so provide a real forward declaration
41
class WXDLLIMPEXP_FWD_BASE wxHashTableBase;
42
43
// and clang doesn't like using WXDLLIMPEXP_FWD_BASE inside a typedef.
44
class WXDLLIMPEXP_FWD_BASE wxHashTableBase_Node;
45
46
class WXDLLIMPEXP_BASE wxHashTableBase_Node
47
{
48
    friend class wxHashTableBase;
49
    typedef class wxHashTableBase_Node _Node;
50
public:
51
    wxHashTableBase_Node( long key, void* value,
52
                          wxHashTableBase* table );
53
    wxHashTableBase_Node( const wxString&  key, void* value,
54
                          wxHashTableBase* table );
55
    ~wxHashTableBase_Node();
56
57
0
    long GetKeyInteger() const { return m_key.integer; }
58
0
    const wxString& GetKeyString() const { return *m_key.string; }
59
60
0
    void* GetData() const { return m_value; }
61
0
    void SetData( void* data ) { m_value = data; }
62
63
protected:
64
4
    _Node* GetNext() const { return m_next; }
65
66
protected:
67
    // next node in the chain
68
    wxHashTableBase_Node* m_next;
69
70
    // key
71
    wxHashKeyValue m_key;
72
73
    // value
74
    void* m_value;
75
76
    // pointer to the hash containing the node, used to remove the
77
    // node from the hash when the user deletes the node iterating
78
    // through it
79
    // TODO: move it to wxHashTable_Node (only wxHashTable supports
80
    //       iteration)
81
    wxHashTableBase* m_hashPtr;
82
};
83
84
class WXDLLIMPEXP_BASE wxHashTableBase
85
#if !wxUSE_STD_CONTAINERS
86
    : public wxObject
87
#endif
88
{
89
    friend class WXDLLIMPEXP_FWD_BASE wxHashTableBase_Node;
90
public:
91
    typedef wxHashTableBase_Node Node;
92
93
    wxHashTableBase();
94
0
    virtual ~wxHashTableBase() = default;
95
96
    void Create( wxKeyType keyType = wxKEY_INTEGER,
97
                 size_t size = wxHASH_SIZE_DEFAULT );
98
    void Clear();
99
    void Destroy();
100
101
0
    size_t GetSize() const { return m_size; }
102
0
    size_t GetCount() const { return m_count; }
103
104
0
    void DeleteContents( bool flag ) { m_deleteContents = flag; }
105
106
    static long MakeKey(const wxString& string);
107
108
protected:
109
    void DoPut( long key, long hash, void* data );
110
    void DoPut( const wxString&  key, long hash, void* data );
111
    void* DoGet( long key, long hash ) const;
112
    void* DoGet( const wxString&  key, long hash ) const;
113
    void* DoDelete( long key, long hash );
114
    void* DoDelete( const wxString&  key, long hash );
115
116
private:
117
    // Remove the node from the hash, *only called from
118
    // ~wxHashTable*_Node destructor
119
    void DoRemoveNode( wxHashTableBase_Node* node );
120
121
    // destroys data contained in the node if appropriate:
122
    // deletes the key if it is a string and destroys
123
    // the value if m_deleteContents is true
124
    void DoDestroyNode( wxHashTableBase_Node* node );
125
126
    // inserts a node in the table (at the end of the chain)
127
    void DoInsertNode( size_t bucket, wxHashTableBase_Node* node );
128
129
    // removes a node from the table (fiven a pointer to the previous
130
    // but does not delete it (only deletes its contents)
131
    void DoUnlinkNode( size_t bucket, wxHashTableBase_Node* node,
132
                       wxHashTableBase_Node* prev );
133
134
    // unconditionally deletes node value (invoking the
135
    // correct destructor)
136
    virtual void DoDeleteContents( wxHashTableBase_Node* node ) = 0;
137
138
protected:
139
    // number of buckets
140
    size_t m_size;
141
142
    // number of nodes (key/value pairs)
143
    size_t m_count;
144
145
    // table
146
    Node** m_table;
147
148
    // key typ (INTEGER/STRING)
149
    wxKeyType m_keyType;
150
151
    // delete contents when hash is cleared
152
    bool m_deleteContents;
153
154
private:
155
    wxDECLARE_NO_COPY_CLASS(wxHashTableBase);
156
};
157
158
// ----------------------------------------------------------------------------
159
// for compatibility only
160
// ----------------------------------------------------------------------------
161
162
class WXDLLIMPEXP_BASE wxHashTable_Node : public wxHashTableBase_Node
163
{
164
    friend class WXDLLIMPEXP_FWD_BASE wxHashTable;
165
public:
166
    wxHashTable_Node( long key, void* value,
167
                      wxHashTableBase* table )
168
0
        : wxHashTableBase_Node( key, value, table ) { }
169
    wxHashTable_Node( const wxString&  key, void* value,
170
                      wxHashTableBase* table )
171
0
        : wxHashTableBase_Node( key, value, table ) { }
172
173
    wxObject* GetData() const
174
0
        { return (wxObject*)wxHashTableBase_Node::GetData(); }
175
    void SetData( wxObject* data )
176
0
        { wxHashTableBase_Node::SetData( data ); }
177
178
    wxHashTable_Node* GetNext() const
179
0
        { return (wxHashTable_Node*)wxHashTableBase_Node::GetNext(); }
180
};
181
182
// should inherit protectedly, but it is public for compatibility in
183
// order to publicly inherit from wxObject
184
class WXDLLIMPEXP_BASE wxHashTable : public wxHashTableBase
185
{
186
    typedef wxHashTableBase hash;
187
public:
188
    typedef wxHashTable_Node Node;
189
    typedef wxHashTable_Node* compatibility_iterator;
190
public:
191
    wxHashTable( wxKeyType keyType = wxKEY_INTEGER,
192
                 size_t size = wxHASH_SIZE_DEFAULT )
193
2
        : wxHashTableBase() { Create( keyType, size ); BeginFind(); }
194
    wxHashTable( const wxHashTable& table );
195
196
0
    virtual ~wxHashTable() { Destroy(); }
197
198
    const wxHashTable& operator=( const wxHashTable& );
199
200
    // key and value are the same
201
    void Put(long value, wxObject *object)
202
0
        { DoPut( value, value, object ); }
203
    void Put(long lhash, long value, wxObject *object)
204
0
        { DoPut( value, lhash, object ); }
205
    void Put(const wxString& value, wxObject *object)
206
76
        { DoPut( value, MakeKey( value ), object ); }
207
    void Put(long lhash, const wxString& value, wxObject *object)
208
0
        { DoPut( value, lhash, object ); }
209
210
    // key and value are the same
211
    wxObject *Get(long value) const
212
0
        { return (wxObject*)DoGet( value, value ); }
213
    wxObject *Get(long lhash, long value) const
214
0
        { return (wxObject*)DoGet( value, lhash ); }
215
    wxObject *Get(const wxString& value) const
216
76
        { return (wxObject*)DoGet( value, MakeKey( value ) ); }
217
    wxObject *Get(long lhash, const wxString& value) const
218
0
        { return (wxObject*)DoGet( value, lhash ); }
219
220
    // Deletes entry and returns data if found
221
    wxObject *Delete(long key)
222
0
        { return (wxObject*)DoDelete( key, key ); }
223
    wxObject *Delete(long lhash, long key)
224
0
        { return (wxObject*)DoDelete( key, lhash ); }
225
    wxObject *Delete(const wxString& key)
226
0
        { return (wxObject*)DoDelete( key, MakeKey( key ) ); }
227
    wxObject *Delete(long lhash, const wxString& key)
228
0
        { return (wxObject*)DoDelete( key, lhash ); }
229
230
    // Way of iterating through whole hash table (e.g. to delete everything)
231
    // Not necessary, of course, if you're only storing pointers to
232
    // objects maintained separately
233
2
    void BeginFind() { m_curr = nullptr; m_currBucket = 0; }
234
    Node* Next();
235
236
0
    void Clear() { wxHashTableBase::Clear(); }
237
238
0
    size_t GetCount() const { return wxHashTableBase::GetCount(); }
239
protected:
240
    // copy helper
241
    void DoCopy( const wxHashTable& copy );
242
243
    // searches the next node starting from bucket bucketStart and sets
244
    // m_curr to it and m_currBucket to its bucket
245
    void GetNextNode( size_t bucketStart );
246
private:
247
    virtual void DoDeleteContents( wxHashTableBase_Node* node ) override;
248
249
    // current node
250
    Node* m_curr;
251
252
    // bucket the current node belongs to
253
    size_t m_currBucket;
254
};
255
256
// defines a new type safe hash table which stores the elements of type eltype
257
// in lists of class listclass
258
#define _WX_DECLARE_HASH(eltype, dummy, hashclass, classexp)                  \
259
    classexp hashclass : public wxHashTableBase                               \
260
    {                                                                         \
261
    public:                                                                   \
262
        hashclass(wxKeyType keyType = wxKEY_INTEGER,                          \
263
                  size_t size = wxHASH_SIZE_DEFAULT)                          \
264
            : wxHashTableBase() { Create(keyType, size); }                    \
265
                                                                              \
266
        virtual ~hashclass() { Destroy(); }                                   \
267
                                                                              \
268
        void Put(long key, eltype *data) { DoPut(key, key, (void*)data); }    \
269
        void Put(long lhash, long key, eltype *data)                          \
270
            { DoPut(key, lhash, (void*)data); }                               \
271
        eltype *Get(long key) const { return (eltype*)DoGet(key, key); }      \
272
        eltype *Get(long lhash, long key) const                               \
273
            { return (eltype*)DoGet(key, lhash); }                            \
274
        eltype *Delete(long key) { return (eltype*)DoDelete(key, key); }      \
275
        eltype *Delete(long lhash, long key)                                  \
276
            { return (eltype*)DoDelete(key, lhash); }                         \
277
    private:                                                                  \
278
        virtual void DoDeleteContents( wxHashTableBase_Node* node ) override\
279
            { delete (eltype*)node->GetData(); }                              \
280
                                                                              \
281
        wxDECLARE_NO_COPY_CLASS(hashclass);                                   \
282
    }
283
284
285
// this macro is to be used in the user code
286
#define WX_DECLARE_HASH(el, list, hash) \
287
    _WX_DECLARE_HASH(el, list, hash, class)
288
289
// and this one does exactly the same thing but should be used inside the
290
// library
291
#define WX_DECLARE_EXPORTED_HASH(el, list, hash)  \
292
    _WX_DECLARE_HASH(el, list, hash, class WXDLLIMPEXP_CORE)
293
294
#define WX_DECLARE_USER_EXPORTED_HASH(el, list, hash, usergoo)  \
295
    _WX_DECLARE_HASH(el, list, hash, class usergoo)
296
297
// delete all hash elements
298
//
299
// NB: the class declaration of the hash elements must be visible from the
300
//     place where you use this macro, otherwise the proper destructor may not
301
//     be called (a decent compiler should give a warning about it, but don't
302
//     count on it)!
303
#define WX_CLEAR_HASH_TABLE(hash)                                            \
304
    {                                                                        \
305
        (hash).BeginFind();                                                  \
306
        wxHashTable::compatibility_iterator it = (hash).Next();              \
307
        while( it )                                                          \
308
        {                                                                    \
309
            delete it->GetData();                                            \
310
            it = (hash).Next();                                              \
311
        }                                                                    \
312
        (hash).Clear();                                                      \
313
    }
314
315
#endif // _WX_HASH_H__