Fixes for wxHashTable when wxUSE_STL=1:
wxHashTable must work like an hash_multimap, not an hash_map. wxHashTable::Delete is supposed to actually delete entries more tests in console sample. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23034 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -140,7 +140,24 @@ WX_DECLARE_EXPORTED_HASH_MAP( wxHashKeyValue,
|
|||||||
void*,
|
void*,
|
||||||
wxHashTableHash,
|
wxHashTableHash,
|
||||||
wxHashTableEqual,
|
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
|
class WXDLLIMPEXP_BASE wxHashTableBase
|
||||||
{
|
{
|
||||||
@@ -176,7 +193,7 @@ protected:
|
|||||||
wxASSERT( m_keyType == wxKEY_INTEGER );
|
wxASSERT( m_keyType == wxKEY_INTEGER );
|
||||||
|
|
||||||
wxHashKeyValue k; k.integer = key;
|
wxHashKeyValue k; k.integer = key;
|
||||||
m_map[k] = data;
|
m_map.multi_insert(k, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoPut( const wxChar* key, void* data )
|
void DoPut( const wxChar* key, void* data )
|
||||||
@@ -184,17 +201,8 @@ protected:
|
|||||||
wxASSERT( m_keyType == wxKEY_STRING );
|
wxASSERT( m_keyType == wxKEY_STRING );
|
||||||
|
|
||||||
wxHashKeyValue k;
|
wxHashKeyValue k;
|
||||||
k.string = (wxChar*)key;
|
k.string = wxStrcpy(new wxChar[wxStrlen(key) + 1], key);
|
||||||
wxHashTableBaseBase::iterator it = m_map.find(k);
|
m_map.multi_insert(k, data);
|
||||||
|
|
||||||
if( it == m_map.end() )
|
|
||||||
{
|
|
||||||
k.string = new wxChar[wxStrlen(key) + 1];
|
|
||||||
wxStrcpy(k.string, key);
|
|
||||||
m_map[k] = data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
it->second = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* DoGet( long key ) const
|
void* DoGet( long key ) const
|
||||||
@@ -407,8 +415,8 @@ public:
|
|||||||
wxObject *Get(const wxChar *value) const { return (wxObject*)DoGet( value ); }
|
wxObject *Get(const wxChar *value) const { return (wxObject*)DoGet( value ); }
|
||||||
|
|
||||||
// Deletes entry and returns data if found
|
// Deletes entry and returns data if found
|
||||||
wxObject *Delete(long key) { return (wxObject*)DoGet( key ); }
|
wxObject *Delete(long key) { return (wxObject*)DoDelete( key ); }
|
||||||
wxObject *Delete(const wxChar *key) { return (wxObject*)DoGet( key ); }
|
wxObject *Delete(const wxChar *key) { return (wxObject*)DoDelete( key ); }
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Construct your own integer key from a string, e.g. in case
|
// Construct your own integer key from a string, e.g. in case
|
||||||
|
@@ -297,6 +297,19 @@ protected: \
|
|||||||
\
|
\
|
||||||
return node; \
|
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 ) \
|
void CreateNode( const value_type& value ) \
|
||||||
{\
|
{\
|
||||||
CreateNode(value, m_hasher( m_getKey(value) ) % m_tableBuckets ); \
|
CreateNode(value, m_hasher( m_getKey(value) ) % m_tableBuckets ); \
|
||||||
|
@@ -1152,10 +1152,11 @@ static void TestHash()
|
|||||||
|
|
||||||
{
|
{
|
||||||
wxHashTable hash(wxKEY_INTEGER), hash2(wxKEY_STRING);
|
wxHashTable hash(wxKEY_INTEGER), hash2(wxKEY_STRING);
|
||||||
|
wxObject o;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for ( i = 0; i < 100; ++i )
|
for ( i = 0; i < 100; ++i )
|
||||||
hash.Put(i, (wxObject*)&i + i);
|
hash.Put(i, &o + i);
|
||||||
|
|
||||||
hash.BeginFind();
|
hash.BeginFind();
|
||||||
wxHashTable::compatibility_iterator it = hash.Next();
|
wxHashTable::compatibility_iterator it = hash.Next();
|
||||||
@@ -1171,18 +1172,50 @@ static void TestHash()
|
|||||||
wxPuts(_T("Error in wxHashTable::compatibility_iterator\n"));
|
wxPuts(_T("Error in wxHashTable::compatibility_iterator\n"));
|
||||||
|
|
||||||
for ( i = 99; i >= 0; --i )
|
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"));
|
wxPuts(_T("Error in wxHashTable::Get/Put\n"));
|
||||||
|
|
||||||
hash2.Put("foo", (wxObject*)&i + 1);
|
for ( i = 0; i < 100; ++i )
|
||||||
hash2.Put("bar", (wxObject*)&i + 2);
|
hash.Put(i, &o + i + 20);
|
||||||
hash2.Put("baz", (wxObject*)&i + 3);
|
|
||||||
|
|
||||||
if (hash2.Get("moo") != NULL)
|
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"));
|
||||||
|
|
||||||
|
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"));
|
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"));
|
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
|
#if !wxUSE_STL
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user