1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxHashTable class
4 // Author: Julian Smart
5 // Modified by: VZ at 25.02.00: type safe hashes with WX_DECLARE_HASH()
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
16 #include "wx/string.h"
19 #include "wx/object.h"
21 class WXDLLIMPEXP_FWD_BASE wxObject
;
24 // the default size of the hash
25 #define wxHASH_SIZE_DEFAULT (1000)
28 * A hash table is an array of user-definable size with lists
29 * of data items hanging off the array positions. Usually there'll
30 * be a hit, so no search is required; otherwise we'll have to run down
31 * the list to find the desired item.
40 // for some compilers (AIX xlC), defining it as friend inside the class is not
41 // enough, so provide a real forward declaration
42 class WXDLLIMPEXP_FWD_BASE wxHashTableBase
;
44 class WXDLLIMPEXP_BASE wxHashTableBase_Node
46 friend class WXDLLIMPEXP_FWD_BASE wxHashTableBase
;
47 typedef class WXDLLIMPEXP_FWD_BASE wxHashTableBase_Node _Node
;
49 wxHashTableBase_Node( long key
, void* value
,
50 wxHashTableBase
* table
);
51 wxHashTableBase_Node( const wxString
& key
, void* value
,
52 wxHashTableBase
* table
);
53 ~wxHashTableBase_Node();
55 long GetKeyInteger() const { return m_key
.integer
; }
56 const wxString
& GetKeyString() const { return *m_key
.string
; }
58 void* GetData() const { return m_value
; }
59 void SetData( void* data
) { m_value
= data
; }
62 _Node
* GetNext() const { return m_next
; }
65 // next node in the chain
66 wxHashTableBase_Node
* m_next
;
74 // pointer to the hash containing the node, used to remove the
75 // node from the hash when the user deletes the node iterating
77 // TODO: move it to wxHashTable_Node (only wxHashTable supports
79 wxHashTableBase
* m_hashPtr
;
82 class WXDLLIMPEXP_BASE wxHashTableBase
87 friend class WXDLLIMPEXP_FWD_BASE wxHashTableBase_Node
;
89 typedef wxHashTableBase_Node Node
;
92 virtual ~wxHashTableBase() { }
94 void Create( wxKeyType keyType
= wxKEY_INTEGER
,
95 size_t size
= wxHASH_SIZE_DEFAULT
);
99 size_t GetSize() const { return m_size
; }
100 size_t GetCount() const { return m_count
; }
102 void DeleteContents( bool flag
) { m_deleteContents
= flag
; }
104 static long MakeKey(const wxString
& string
);
107 void DoPut( long key
, long hash
, void* data
);
108 void DoPut( const wxString
& key
, long hash
, void* data
);
109 void* DoGet( long key
, long hash
) const;
110 void* DoGet( const wxString
& key
, long hash
) const;
111 void* DoDelete( long key
, long hash
);
112 void* DoDelete( const wxString
& key
, long hash
);
115 // Remove the node from the hash, *only called from
116 // ~wxHashTable*_Node destructor
117 void DoRemoveNode( wxHashTableBase_Node
* node
);
119 // destroys data contained in the node if appropriate:
120 // deletes the key if it is a string and destrys
121 // the value if m_deleteContents is true
122 void DoDestroyNode( wxHashTableBase_Node
* node
);
124 // inserts a node in the table (at the end of the chain)
125 void DoInsertNode( size_t bucket
, wxHashTableBase_Node
* node
);
127 // removes a node from the table (fiven a pointer to the previous
128 // but does not delete it (only deletes its contents)
129 void DoUnlinkNode( size_t bucket
, wxHashTableBase_Node
* node
,
130 wxHashTableBase_Node
* prev
);
132 // unconditionally deletes node value (invoking the
133 // correct destructor)
134 virtual void DoDeleteContents( wxHashTableBase_Node
* node
) = 0;
140 // number of nodes (key/value pairs)
146 // key typ (INTEGER/STRING)
149 // delete contents when hash is cleared
150 bool m_deleteContents
;
153 wxDECLARE_NO_COPY_CLASS(wxHashTableBase
);
156 // ----------------------------------------------------------------------------
157 // for compatibility only
158 // ----------------------------------------------------------------------------
160 class WXDLLIMPEXP_BASE wxHashTable_Node
: public wxHashTableBase_Node
162 friend class WXDLLIMPEXP_FWD_BASE wxHashTable
;
164 wxHashTable_Node( long key
, void* value
,
165 wxHashTableBase
* table
)
166 : wxHashTableBase_Node( key
, value
, table
) { }
167 wxHashTable_Node( const wxString
& key
, void* value
,
168 wxHashTableBase
* table
)
169 : wxHashTableBase_Node( key
, value
, table
) { }
171 wxObject
* GetData() const
172 { return (wxObject
*)wxHashTableBase_Node::GetData(); }
173 void SetData( wxObject
* data
)
174 { wxHashTableBase_Node::SetData( data
); }
176 wxHashTable_Node
* GetNext() const
177 { return (wxHashTable_Node
*)wxHashTableBase_Node::GetNext(); }
180 // should inherit protectedly, but it is public for compatibility in
181 // order to publicly inherit from wxObject
182 class WXDLLIMPEXP_BASE wxHashTable
: public wxHashTableBase
184 typedef wxHashTableBase hash
;
186 typedef wxHashTable_Node Node
;
187 typedef wxHashTable_Node
* compatibility_iterator
;
189 wxHashTable( wxKeyType keyType
= wxKEY_INTEGER
,
190 size_t size
= wxHASH_SIZE_DEFAULT
)
191 : wxHashTableBase() { Create( keyType
, size
); BeginFind(); }
192 wxHashTable( const wxHashTable
& table
);
194 virtual ~wxHashTable() { Destroy(); }
196 const wxHashTable
& operator=( const wxHashTable
& );
198 // key and value are the same
199 void Put(long value
, wxObject
*object
)
200 { DoPut( value
, value
, object
); }
201 void Put(long lhash
, long value
, wxObject
*object
)
202 { DoPut( value
, lhash
, object
); }
203 void Put(const wxString
& value
, wxObject
*object
)
204 { DoPut( value
, MakeKey( value
), object
); }
205 void Put(long lhash
, const wxString
& value
, wxObject
*object
)
206 { DoPut( value
, lhash
, object
); }
208 // key and value are the same
209 wxObject
*Get(long value
) const
210 { return (wxObject
*)DoGet( value
, value
); }
211 wxObject
*Get(long lhash
, long value
) const
212 { return (wxObject
*)DoGet( value
, lhash
); }
213 wxObject
*Get(const wxString
& value
) const
214 { return (wxObject
*)DoGet( value
, MakeKey( value
) ); }
215 wxObject
*Get(long lhash
, const wxString
& value
) const
216 { return (wxObject
*)DoGet( value
, lhash
); }
218 // Deletes entry and returns data if found
219 wxObject
*Delete(long key
)
220 { return (wxObject
*)DoDelete( key
, key
); }
221 wxObject
*Delete(long lhash
, long key
)
222 { return (wxObject
*)DoDelete( key
, lhash
); }
223 wxObject
*Delete(const wxString
& key
)
224 { return (wxObject
*)DoDelete( key
, MakeKey( key
) ); }
225 wxObject
*Delete(long lhash
, const wxString
& key
)
226 { return (wxObject
*)DoDelete( key
, lhash
); }
228 // Way of iterating through whole hash table (e.g. to delete everything)
229 // Not necessary, of course, if you're only storing pointers to
230 // objects maintained separately
231 void BeginFind() { m_curr
= NULL
; m_currBucket
= 0; }
234 void Clear() { wxHashTableBase::Clear(); }
236 size_t GetCount() const { return wxHashTableBase::GetCount(); }
239 void DoCopy( const wxHashTable
& copy
);
241 // searches the next node starting from bucket bucketStart and sets
242 // m_curr to it and m_currBucket to its bucket
243 void GetNextNode( size_t bucketStart
);
245 virtual void DoDeleteContents( wxHashTableBase_Node
* node
);
250 // bucket the current node belongs to
254 // defines a new type safe hash table which stores the elements of type eltype
255 // in lists of class listclass
256 #define _WX_DECLARE_HASH(eltype, dummy, hashclass, classexp) \
257 classexp hashclass : public wxHashTableBase \
260 hashclass(wxKeyType keyType = wxKEY_INTEGER, \
261 size_t size = wxHASH_SIZE_DEFAULT) \
262 : wxHashTableBase() { Create(keyType, size); } \
264 virtual ~hashclass() { Destroy(); } \
266 void Put(long key, eltype *data) { DoPut(key, key, (void*)data); } \
267 void Put(long lhash, long key, eltype *data) \
268 { DoPut(key, lhash, (void*)data); } \
269 eltype *Get(long key) const { return (eltype*)DoGet(key, key); } \
270 eltype *Get(long lhash, long key) const \
271 { return (eltype*)DoGet(key, lhash); } \
272 eltype *Delete(long key) { return (eltype*)DoDelete(key, key); } \
273 eltype *Delete(long lhash, long key) \
274 { return (eltype*)DoDelete(key, lhash); } \
276 virtual void DoDeleteContents( wxHashTableBase_Node* node ) \
277 { delete (eltype*)node->GetData(); } \
279 DECLARE_NO_COPY_CLASS(hashclass) \
283 // this macro is to be used in the user code
284 #define WX_DECLARE_HASH(el, list, hash) \
285 _WX_DECLARE_HASH(el, list, hash, class)
287 // and this one does exactly the same thing but should be used inside the
289 #define WX_DECLARE_EXPORTED_HASH(el, list, hash) \
290 _WX_DECLARE_HASH(el, list, hash, class WXDLLIMPEXP_CORE)
292 #define WX_DECLARE_USER_EXPORTED_HASH(el, list, hash, usergoo) \
293 _WX_DECLARE_HASH(el, list, hash, class usergoo)
295 // delete all hash elements
297 // NB: the class declaration of the hash elements must be visible from the
298 // place where you use this macro, otherwise the proper destructor may not
299 // be called (a decent compiler should give a warning about it, but don't
301 #define WX_CLEAR_HASH_TABLE(hash) \
303 (hash).BeginFind(); \
304 wxHashTable::compatibility_iterator it = (hash).Next(); \
307 delete it->GetData(); \
308 it = (hash).Next(); \
313 #endif // _WX_HASH_H__