void*,
wxHashTableHash,
wxHashTableEqual,
- wxHashTableBaseBase );
+ wxHashTableBaseBaseBase );
+
+// hack: we should really have HASH_MULTI(MAP|SET), but this requires
+// less work
+
+class WXDLLIMPEXP_BASE wxHashTableBaseBase : public wxHashTableBaseBaseBase
+{
+public:
+ wxHashTableBaseBase(size_t size, const wxHashTableHash& hash,
+ const wxHashTableEqual& equal)
+ : wxHashTableBaseBaseBase(size, hash, equal)
+ { }
+
+ void multi_insert(const wxHashKeyValue& key, void* value)
+ {
+ CreateNodeLast(value_type(key, value));
+ }
+};
class WXDLLIMPEXP_BASE wxHashTableBase
{
wxASSERT( m_keyType == wxKEY_INTEGER );
wxHashKeyValue k; k.integer = key;
- m_map[k] = data;
+ m_map.multi_insert(k, data);
}
void DoPut( const wxChar* key, void* data )
wxASSERT( m_keyType == wxKEY_STRING );
wxHashKeyValue k;
- k.string = (wxChar*)key;
- wxHashTableBaseBase::iterator it = m_map.find(k);
-
- if( it == m_map.end() )
- {
- k.string = new wxChar[wxStrlen(key) + 1];
- wxStrcpy(k.string, key);
- m_map[k] = data;
- }
- else
- it->second = data;
+ k.string = wxStrcpy(new wxChar[wxStrlen(key) + 1], key);
+ m_map.multi_insert(k, data);
}
void* DoGet( long key ) const
wxObject *Get(const wxChar *value) const { return (wxObject*)DoGet( value ); }
// Deletes entry and returns data if found
- wxObject *Delete(long key) { return (wxObject*)DoGet( key ); }
- wxObject *Delete(const wxChar *key) { return (wxObject*)DoGet( key ); }
+ wxObject *Delete(long key) { return (wxObject*)DoDelete( key ); }
+ wxObject *Delete(const wxChar *key) { return (wxObject*)DoDelete( key ); }
#if 0
// Construct your own integer key from a string, e.g. in case
\
return node; \
} \
+ void CreateNodeLast( const value_type& value ) \
+ { \
+ size_t bucket = m_hasher( m_getKey(value) ) % m_tableBuckets; \
+ Node* curr = m_table[bucket], \
+ * next = m_table[bucket]; \
+ while( next ) { curr = next; next = next->m_next(); } \
+ Node** ptr = curr ? (Node**)&curr->m_nxt : &m_table[bucket]; \
+ *ptr = new Node( value ); \
+ /* must be after the node is inserted */ \
+ ++m_items; \
+ if( SHOULD_GROW( m_tableBuckets, m_items ) ) \
+ ResizeTable( m_tableBuckets ); \
+ } \
void CreateNode( const value_type& value ) \
{\
CreateNode(value, m_hasher( m_getKey(value) ) % m_tableBuckets ); \
{
wxHashTable hash(wxKEY_INTEGER), hash2(wxKEY_STRING);
+ wxObject o;
int i;
for ( i = 0; i < 100; ++i )
- hash.Put(i, (wxObject*)&i + i);
+ hash.Put(i, &o + i);
hash.BeginFind();
wxHashTable::compatibility_iterator it = hash.Next();
wxPuts(_T("Error in wxHashTable::compatibility_iterator\n"));
for ( i = 99; i >= 0; --i )
- if( hash.Get(i) != (wxObject*)&i + i )
+ if( hash.Get(i) != &o + i )
wxPuts(_T("Error in wxHashTable::Get/Put\n"));
- hash2.Put("foo", (wxObject*)&i + 1);
- hash2.Put("bar", (wxObject*)&i + 2);
- hash2.Put("baz", (wxObject*)&i + 3);
+ for ( i = 0; i < 100; ++i )
+ hash.Put(i, &o + i + 20);
+
+ for ( i = 99; i >= 0; --i )
+ if( hash.Get(i) != &o + i)
+ wxPuts(_T("Error (2) in wxHashTable::Get/Put\n"));
+
+ for ( i = 0; i < 50; ++i )
+ if( hash.Delete(i) != &o + i)
+ wxPuts(_T("Error in wxHashTable::Delete\n"));
+
+ for ( i = 50; i < 100; ++i )
+ if( hash.Get(i) != &o + i)
+ wxPuts(_T("Error (3) in wxHashTable::Get/Put\n"));
+
+ for ( i = 0; i < 50; ++i )
+ if( hash.Get(i) != &o + i + 20)
+ wxPuts(_T("Error (4) in wxHashTable::Put/Delete\n"));
- if (hash2.Get("moo") != NULL)
+ for ( i = 0; i < 50; ++i )
+ if( hash.Delete(i) != &o + i + 20)
+ wxPuts(_T("Error (2) in wxHashTable::Delete\n"));
+
+ for ( i = 0; i < 50; ++i )
+ if( hash.Get(i) != NULL)
+ wxPuts(_T("Error (5) in wxHashTable::Put/Delete\n"));
+
+ hash2.Put(_T("foo"), &o + 1);
+ hash2.Put(_T("bar"), &o + 2);
+ hash2.Put(_T("baz"), &o + 3);
+
+ if (hash2.Get(_T("moo")) != NULL)
wxPuts(_T("Error in wxHashTable::Get\n"));
- if (hash2.Get("bar") != (wxObject*)&i + 2)
+ if (hash2.Get(_T("bar")) != &o + 2)
wxPuts(_T("Error in wxHashTable::Get/Put\n"));
+
+ hash2.Put(_T("bar"), &o + 0);
+
+ if (hash2.Get(_T("bar")) != &o + 2)
+ wxPuts(_T("Error (2) in wxHashTable::Get/Put\n"));
}
#if !wxUSE_STL
{