1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxHashTable class
4 // Author: Julian Smart
5 // Modified by: VZ at 25.02.00: type safe hashes with WX_DECLARE_HASH()
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
15 #include "wx/string.h"
17 #if !wxUSE_STD_CONTAINERS
18 #include "wx/object.h"
20 class WXDLLIMPEXP_FWD_BASE wxObject
;
23 // the default size of the hash
24 #define wxHASH_SIZE_DEFAULT (1000)
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.
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
;
43 class WXDLLIMPEXP_BASE wxHashTableBase_Node
45 friend class WXDLLIMPEXP_FWD_BASE wxHashTableBase
;
46 typedef class WXDLLIMPEXP_FWD_BASE wxHashTableBase_Node _Node
;
48 wxHashTableBase_Node( long key
, void* value
,
49 wxHashTableBase
* table
);
50 wxHashTableBase_Node( const wxString
& key
, void* value
,
51 wxHashTableBase
* table
);
52 ~wxHashTableBase_Node();
54 long GetKeyInteger() const { return m_key
.integer
; }
55 const wxString
& GetKeyString() const { return *m_key
.string
; }
57 void* GetData() const { return m_value
; }
58 void SetData( void* data
) { m_value
= data
; }
61 _Node
* GetNext() const { return m_next
; }
64 // next node in the chain
65 wxHashTableBase_Node
* m_next
;
73 // pointer to the hash containing the node, used to remove the
74 // node from the hash when the user deletes the node iterating
76 // TODO: move it to wxHashTable_Node (only wxHashTable supports
78 wxHashTableBase
* m_hashPtr
;
81 class WXDLLIMPEXP_BASE wxHashTableBase
82 #if !wxUSE_STD_CONTAINERS
86 friend class WXDLLIMPEXP_FWD_BASE wxHashTableBase_Node
;
88 typedef wxHashTableBase_Node Node
;
91 virtual ~wxHashTableBase() { }
93 void Create( wxKeyType keyType
= wxKEY_INTEGER
,
94 size_t size
= wxHASH_SIZE_DEFAULT
);
98 size_t GetSize() const { return m_size
; }
99 size_t GetCount() const { return m_count
; }
101 void DeleteContents( bool flag
) { m_deleteContents
= flag
; }
103 static long MakeKey(const wxString
& string
);
106 void DoPut( long key
, long hash
, void* data
);
107 void DoPut( const wxString
& key
, long hash
, void* data
);
108 void* DoGet( long key
, long hash
) const;
109 void* DoGet( const wxString
& key
, long hash
) const;
110 void* DoDelete( long key
, long hash
);
111 void* DoDelete( const wxString
& key
, long hash
);
114 // Remove the node from the hash, *only called from
115 // ~wxHashTable*_Node destructor
116 void DoRemoveNode( wxHashTableBase_Node
* node
);
118 // destroys data contained in the node if appropriate:
119 // deletes the key if it is a string and destrys
120 // the value if m_deleteContents is true
121 void DoDestroyNode( wxHashTableBase_Node
* node
);
123 // inserts a node in the table (at the end of the chain)
124 void DoInsertNode( size_t bucket
, wxHashTableBase_Node
* node
);
126 // removes a node from the table (fiven a pointer to the previous
127 // but does not delete it (only deletes its contents)
128 void DoUnlinkNode( size_t bucket
, wxHashTableBase_Node
* node
,
129 wxHashTableBase_Node
* prev
);
131 // unconditionally deletes node value (invoking the
132 // correct destructor)
133 virtual void DoDeleteContents( wxHashTableBase_Node
* node
) = 0;
139 // number of nodes (key/value pairs)
145 // key typ (INTEGER/STRING)
148 // delete contents when hash is cleared
149 bool m_deleteContents
;
152 wxDECLARE_NO_COPY_CLASS(wxHashTableBase
);
155 // ----------------------------------------------------------------------------
156 // for compatibility only
157 // ----------------------------------------------------------------------------
159 class WXDLLIMPEXP_BASE wxHashTable_Node
: public wxHashTableBase_Node
161 friend class WXDLLIMPEXP_FWD_BASE wxHashTable
;
163 wxHashTable_Node( long key
, void* value
,
164 wxHashTableBase
* table
)
165 : wxHashTableBase_Node( key
, value
, table
) { }
166 wxHashTable_Node( const wxString
& key
, void* value
,
167 wxHashTableBase
* table
)
168 : wxHashTableBase_Node( key
, value
, table
) { }
170 wxObject
* GetData() const
171 { return (wxObject
*)wxHashTableBase_Node::GetData(); }
172 void SetData( wxObject
* data
)
173 { wxHashTableBase_Node::SetData( data
); }
175 wxHashTable_Node
* GetNext() const
176 { return (wxHashTable_Node
*)wxHashTableBase_Node::GetNext(); }
179 // should inherit protectedly, but it is public for compatibility in
180 // order to publicly inherit from wxObject
181 class WXDLLIMPEXP_BASE wxHashTable
: public wxHashTableBase
183 typedef wxHashTableBase hash
;
185 typedef wxHashTable_Node Node
;
186 typedef wxHashTable_Node
* compatibility_iterator
;
188 wxHashTable( wxKeyType keyType
= wxKEY_INTEGER
,
189 size_t size
= wxHASH_SIZE_DEFAULT
)
190 : wxHashTableBase() { Create( keyType
, size
); BeginFind(); }
191 wxHashTable( const wxHashTable
& table
);
193 virtual ~wxHashTable() { Destroy(); }
195 const wxHashTable
& operator=( const wxHashTable
& );
197 // key and value are the same
198 void Put(long value
, wxObject
*object
)
199 { DoPut( value
, value
, object
); }
200 void Put(long lhash
, long value
, wxObject
*object
)
201 { DoPut( value
, lhash
, object
); }
202 void Put(const wxString
& value
, wxObject
*object
)
203 { DoPut( value
, MakeKey( value
), object
); }
204 void Put(long lhash
, const wxString
& value
, wxObject
*object
)
205 { DoPut( value
, lhash
, object
); }
207 // key and value are the same
208 wxObject
*Get(long value
) const
209 { return (wxObject
*)DoGet( value
, value
); }
210 wxObject
*Get(long lhash
, long value
) const
211 { return (wxObject
*)DoGet( value
, lhash
); }
212 wxObject
*Get(const wxString
& value
) const
213 { return (wxObject
*)DoGet( value
, MakeKey( value
) ); }
214 wxObject
*Get(long lhash
, const wxString
& value
) const
215 { return (wxObject
*)DoGet( value
, lhash
); }
217 // Deletes entry and returns data if found
218 wxObject
*Delete(long key
)
219 { return (wxObject
*)DoDelete( key
, key
); }
220 wxObject
*Delete(long lhash
, long key
)
221 { return (wxObject
*)DoDelete( key
, lhash
); }
222 wxObject
*Delete(const wxString
& key
)
223 { return (wxObject
*)DoDelete( key
, MakeKey( key
) ); }
224 wxObject
*Delete(long lhash
, const wxString
& key
)
225 { return (wxObject
*)DoDelete( key
, lhash
); }
227 // Way of iterating through whole hash table (e.g. to delete everything)
228 // Not necessary, of course, if you're only storing pointers to
229 // objects maintained separately
230 void BeginFind() { m_curr
= NULL
; m_currBucket
= 0; }
233 void Clear() { wxHashTableBase::Clear(); }
235 size_t GetCount() const { return wxHashTableBase::GetCount(); }
238 void DoCopy( const wxHashTable
& copy
);
240 // searches the next node starting from bucket bucketStart and sets
241 // m_curr to it and m_currBucket to its bucket
242 void GetNextNode( size_t bucketStart
);
244 virtual void DoDeleteContents( wxHashTableBase_Node
* node
);
249 // bucket the current node belongs to
253 // defines a new type safe hash table which stores the elements of type eltype
254 // in lists of class listclass
255 #define _WX_DECLARE_HASH(eltype, dummy, hashclass, classexp) \
256 classexp hashclass : public wxHashTableBase \
259 hashclass(wxKeyType keyType = wxKEY_INTEGER, \
260 size_t size = wxHASH_SIZE_DEFAULT) \
261 : wxHashTableBase() { Create(keyType, size); } \
263 virtual ~hashclass() { Destroy(); } \
265 void Put(long key, eltype *data) { DoPut(key, key, (void*)data); } \
266 void Put(long lhash, long key, eltype *data) \
267 { DoPut(key, lhash, (void*)data); } \
268 eltype *Get(long key) const { return (eltype*)DoGet(key, key); } \
269 eltype *Get(long lhash, long key) const \
270 { return (eltype*)DoGet(key, lhash); } \
271 eltype *Delete(long key) { return (eltype*)DoDelete(key, key); } \
272 eltype *Delete(long lhash, long key) \
273 { return (eltype*)DoDelete(key, lhash); } \
275 virtual void DoDeleteContents( wxHashTableBase_Node* node ) \
276 { delete (eltype*)node->GetData(); } \
278 DECLARE_NO_COPY_CLASS(hashclass) \
282 // this macro is to be used in the user code
283 #define WX_DECLARE_HASH(el, list, hash) \
284 _WX_DECLARE_HASH(el, list, hash, class)
286 // and this one does exactly the same thing but should be used inside the
288 #define WX_DECLARE_EXPORTED_HASH(el, list, hash) \
289 _WX_DECLARE_HASH(el, list, hash, class WXDLLIMPEXP_CORE)
291 #define WX_DECLARE_USER_EXPORTED_HASH(el, list, hash, usergoo) \
292 _WX_DECLARE_HASH(el, list, hash, class usergoo)
294 // delete all hash elements
296 // NB: the class declaration of the hash elements must be visible from the
297 // place where you use this macro, otherwise the proper destructor may not
298 // be called (a decent compiler should give a warning about it, but don't
300 #define WX_CLEAR_HASH_TABLE(hash) \
302 (hash).BeginFind(); \
303 wxHashTable::compatibility_iterator it = (hash).Next(); \
306 delete it->GetData(); \
307 it = (hash).Next(); \
312 #endif // _WX_HASH_H__