various minor fixes to wxHashMap: compilation warnings suppressed, use calloc() instead of new[]

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13954 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2002-02-01 14:58:55 +00:00
parent e05c8fa7bb
commit 376e1129f7
2 changed files with 70 additions and 47 deletions

View File

@ -2,7 +2,7 @@
// Name: hashmap.cpp // Name: hashmap.cpp
// Purpose: wxHashMap class // Purpose: wxHashMap class
// Author: Mattia Barbon // Author: Mattia Barbon
// Modified by: // Modified by:
// Created: 29/01/2002 // Created: 29/01/2002
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Mattia Barbon // Copyright: (c) Mattia Barbon
@ -31,7 +31,7 @@ class WXDLLEXPORT _wxHashTableBase2
{ {
public: public:
typedef void (*NodeDtor)(_wxHashTable_NodeBase*); typedef void (*NodeDtor)(_wxHashTable_NodeBase*);
typedef unsigned long (*BucketFromNode)(_wxHashTableBase2*,_wxHashTable_NodeBase*); typedef unsigned long (*BucketFromNode)(_wxHashTableBase2*,_wxHashTable_NodeBase*);
typedef _wxHashTable_NodeBase* (*ProcessNode)(_wxHashTable_NodeBase*); typedef _wxHashTable_NodeBase* (*ProcessNode)(_wxHashTable_NodeBase*);
protected: protected:
static _wxHashTable_NodeBase* DummyProcessNode(_wxHashTable_NodeBase* node); static _wxHashTable_NodeBase* DummyProcessNode(_wxHashTable_NodeBase* node);
@ -46,15 +46,15 @@ protected:
return 0; return 0;
} }
/* static const unsigned prime_count = 31; */ // as static const unsigned prime_count = 31 but works with all compilers
enum { prime_count = 31 }; enum { prime_count = 31 };
static const unsigned long s_primes[prime_count]; static const unsigned long ms_primes[prime_count];
/* returns the first prime in s_primes greater than n */ // returns the first prime in ms_primes greater than n
static unsigned long GetNextPrime( unsigned long n ); static unsigned long GetNextPrime( unsigned long n );
/* returns the first prime in s_primes smaller than n */ // returns the first prime in ms_primes smaller than n
/* ( or s_primes[0] if n is very small ) */ // ( or ms_primes[0] if n is very small )
static unsigned long GetPreviousPrime( unsigned long n ); static unsigned long GetPreviousPrime( unsigned long n );
static void CopyHashTable( _wxHashTable_NodeBase** srcTable, static void CopyHashTable( _wxHashTable_NodeBase** srcTable,
@ -62,19 +62,14 @@ protected:
_wxHashTable_NodeBase** dstTable, _wxHashTable_NodeBase** dstTable,
BucketFromNode func, ProcessNode proc ); BucketFromNode func, ProcessNode proc );
/* maybe just use calloc */
static void** AllocTable( size_t size ) static void** AllocTable( size_t size )
{ {
void** table = new void*[size]; return (void **)calloc(size, sizeof(void*));
memset( table, 0, size * sizeof(void*) );
return table;
} }
}; };
#define _WX_DECLARE_HASHTABLE( VALUE_T, KEY_T, HASH_T, KEY_EX_T, KEY_EQ_T, CLASSNAME, CLASSEXP, SHOULD_GROW, SHOULD_SHRINK ) \ #define _WX_DECLARE_HASHTABLE( VALUE_T, KEY_T, HASH_T, KEY_EX_T, KEY_EQ_T, CLASSNAME, CLASSEXP, SHOULD_GROW, SHOULD_SHRINK ) \
CLASSEXP CLASSNAME:protected _wxHashTableBase2 \ CLASSEXP CLASSNAME : protected _wxHashTableBase2 \
{ \ { \
public: \ public: \
typedef KEY_T key_type; \ typedef KEY_T key_type; \
@ -139,7 +134,7 @@ protected: \
protected: \ protected: \
Node* GetNextNode() \ Node* GetNextNode() \
{ \ { \
size_type bucket = GetBucketForNode(m_ht,m_node); \ size_type bucket = GetBucketForNode(m_ht,m_node); \
for( size_type i = bucket + 1; i < m_ht->m_tableBuckets; ++i ) \ for( size_type i = bucket + 1; i < m_ht->m_tableBuckets; ++i ) \
{ \ { \
if( m_ht->m_table[i] ) \ if( m_ht->m_table[i] ) \
@ -151,7 +146,7 @@ protected: \
void PlusPlus() \ void PlusPlus() \
{ \ { \
Node* next = m_node->m_next(); \ Node* next = m_node->m_next(); \
m_node = next ? next : GetNextNode(); \ m_node = next ? next : GetNextNode(); \
} \ } \
}; \ }; \
\ \
@ -208,14 +203,14 @@ public: \
m_getKey = ht.m_getKey; \ m_getKey = ht.m_getKey; \
m_items = ht.m_items; \ m_items = ht.m_items; \
HashCopy( ht ); \ HashCopy( ht ); \
return *this; \ return *this; \
} \ } \
\ \
~CLASSNAME() \ ~CLASSNAME() \
{ \ { \
clear(); \ clear(); \
\ \
delete[] m_table; \ free(m_table); \
} \ } \
\ \
hasher hash_funct() { return m_hasher; } \ hasher hash_funct() { return m_hasher; } \
@ -330,7 +325,7 @@ protected: \
this, (_wxHashTable_NodeBase**)m_table, \ this, (_wxHashTable_NodeBase**)m_table, \
(BucketFromNode)&GetBucketForNode,\ (BucketFromNode)&GetBucketForNode,\
(ProcessNode)&DummyProcessNode ); \ (ProcessNode)&DummyProcessNode ); \
delete[] srcTable; \ free(srcTable); \
} \ } \
\ \
/* this must be called _after_ m_table has been cleaned */ \ /* this must be called _after_ m_table has been cleaned */ \
@ -345,6 +340,8 @@ protected: \
} \ } \
}; };
// defines an STL-like pair class CLASSNAME storing two fields: first of type
// KEY_T and second of type VALUE_T
#define _WX_DECLARE_PAIR( KEY_T, VALUE_T, CLASSNAME, CLASSEXP ) \ #define _WX_DECLARE_PAIR( KEY_T, VALUE_T, CLASSNAME, CLASSEXP ) \
CLASSEXP CLASSNAME \ CLASSEXP CLASSNAME \
{ \ { \
@ -361,12 +358,19 @@ public: \
t2 second; \ t2 second; \
}; };
// defines the class CLASSNAME returning the key part (of type KEY_T) from a
// pair of type PAIR_T
#define _WX_DECLARE_HASH_MAP_KEY_EX( KEY_T, PAIR_T, CLASSNAME, CLASSEXP ) \ #define _WX_DECLARE_HASH_MAP_KEY_EX( KEY_T, PAIR_T, CLASSNAME, CLASSEXP ) \
CLASSEXP CLASSNAME \ CLASSEXP CLASSNAME \
{ \ { \
public: \ public: \
CLASSNAME() {}; \ CLASSNAME() { } \
KEY_T operator()( PAIR_T pair ) const { return pair.first; } \ KEY_T operator()( PAIR_T pair ) const { return pair.first; } \
\
/* the dummy assignment operator is needed to suppress compiler */ \
/* warnings from hash table class' operator=(): gcc complains about */ \
/* "statement with no effect" without it */ \
CLASSNAME& operator=(const CLASSNAME&) { return *this; } \
}; };
// grow/shrink predicates // grow/shrink predicates
@ -377,51 +381,70 @@ inline bool grow_lf70( size_t buckets, size_t items )
return float(items)/float(buckets) >= 0.85; return float(items)/float(buckets) >= 0.85;
} }
// ----------------------------------------------------------------------------
// hashing and comparison functors
// ----------------------------------------------------------------------------
// NB: implementation detail: all of these classes must have dummy assignment
// operators to suppress warnings about "statement with no effect" from gcc
// in the hash table class assignment operator (where they're assigned)
// integer types // integer types
class WXDLLEXPORT wxIntegerHash class WXDLLEXPORT wxIntegerHash
{ {
public: public:
wxIntegerHash() {}; wxIntegerHash() { }
unsigned long operator()( long x ) const { return (unsigned long)x; } unsigned long operator()( long x ) const { return (unsigned long)x; }
unsigned long operator()( unsigned long x ) const { return x; } unsigned long operator()( unsigned long x ) const { return x; }
unsigned long operator()( int x ) const { return (unsigned long)x; } unsigned long operator()( int x ) const { return (unsigned long)x; }
unsigned long operator()( unsigned int x ) const { return x; } unsigned long operator()( unsigned int x ) const { return x; }
unsigned long operator()( short x ) const { return (unsigned long)x; }
unsigned long operator()( unsigned short x ) const { return x; }
wxIntegerHash& operator=(const wxIntegerHash&) { return *this; }
}; };
class WXDLLEXPORT wxIntegerEqual class WXDLLEXPORT wxIntegerEqual
{ {
public: public:
wxIntegerEqual() {}; wxIntegerEqual() { }
bool operator()( long a, long b ) const { return a == b; } bool operator()( long a, long b ) const { return a == b; }
bool operator()( unsigned long a, unsigned long b ) const bool operator()( unsigned long a, unsigned long b ) const { return a == b; }
{ return a == b; }
bool operator()( int a, int b ) const { return a == b; } bool operator()( int a, int b ) const { return a == b; }
bool operator()( unsigned int a, unsigned int b ) const bool operator()( unsigned int a, unsigned int b ) const { return a == b; }
{ return a == b; } bool operator()( short a, short b ) const { return a == b; }
bool operator()( unsigned short a, unsigned short b ) const { return a == b; }
wxIntegerEqual& operator=(const wxIntegerEqual&) { return *this; }
}; };
// pointers // pointers
class WXDLLEXPORT wxPointerHash class WXDLLEXPORT wxPointerHash
{ {
public: public:
wxPointerHash() {}; wxPointerHash() { }
unsigned long operator()( const void* k ) const
{ return (unsigned long)k; } // TODO: this might not work well on architectures with 64 bit pointers but
// 32 bit longs, we should use % ULONG_MAX there
unsigned long operator()( const void* k ) const { return (unsigned long)k; }
wxPointerHash& operator=(const wxPointerHash&) { return *this; }
}; };
class WXDLLEXPORT wxPointerEqual class WXDLLEXPORT wxPointerEqual
{ {
public: public:
wxPointerEqual() {}; wxPointerEqual() { }
bool operator()( const void* a, const void* b ) const bool operator()( const void* a, const void* b ) const { return a == b; }
{ return a == b; }
wxPointerEqual& operator=(const wxPointerEqual&) { return *this; }
}; };
// wxString, char*, wxChar* // wxString, char*, wxChar*
class WXDLLEXPORT wxStringHash class WXDLLEXPORT wxStringHash
{ {
public: public:
wxStringHash() {}; wxStringHash() {}
unsigned long operator()( const wxString& x ) const unsigned long operator()( const wxString& x ) const
{ return wxCharStringHash( x.c_str() ); } { return wxCharStringHash( x.c_str() ); }
unsigned long operator()( const wxChar* x ) const unsigned long operator()( const wxChar* x ) const
@ -431,13 +454,15 @@ public:
unsigned long operator()( const char* x ) const unsigned long operator()( const char* x ) const
{ return charStringHash( x ); } { return charStringHash( x ); }
static unsigned long charStringHash( const char* ); static unsigned long charStringHash( const char* );
#endif #endif // wxUSE_UNICODE
wxStringHash& operator=(const wxStringHash&) { return *this; }
}; };
class WXDLLEXPORT wxStringEqual class WXDLLEXPORT wxStringEqual
{ {
public: public:
wxStringEqual() {}; wxStringEqual() {}
bool operator()( const wxString& a, const wxString& b ) const bool operator()( const wxString& a, const wxString& b ) const
{ return a == b; } { return a == b; }
bool operator()( const wxChar* a, const wxChar* b ) const bool operator()( const wxChar* a, const wxChar* b ) const
@ -445,7 +470,9 @@ public:
#if wxUSE_UNICODE #if wxUSE_UNICODE
bool operator()( const char* a, const char* b ) const bool operator()( const char* a, const char* b ) const
{ return strcmp( a, b ) == 0; } { return strcmp( a, b ) == 0; }
#endif #endif // wxUSE_UNICODE
wxStringEqual& operator=(const wxStringEqual&) { return *this; }
}; };
#define _WX_DECLARE_HASH_MAP( KEY_T, VALUE_T, HASH_T, KEY_EQ_T, CLASSNAME, CLASSEXP ) \ #define _WX_DECLARE_HASH_MAP( KEY_T, VALUE_T, HASH_T, KEY_EQ_T, CLASSNAME, CLASSEXP ) \
@ -512,8 +539,5 @@ public: \
_WX_DECLARE_HASH_MAP( void*, VALUE_T, wxPointerHash, wxPointerEqual, \ _WX_DECLARE_HASH_MAP( void*, VALUE_T, wxPointerHash, wxPointerEqual, \
CLASSNAME, class WXDLLEXPORT ); CLASSNAME, class WXDLLEXPORT );
#endif #endif // _WX_HASHMAP_H_
// Local variables:
// mode: c++
// End:

View File

@ -2,7 +2,7 @@
// Name: hashmap.cpp // Name: hashmap.cpp
// Purpose: wxHashMap implementation // Purpose: wxHashMap implementation
// Author: Mattia Barbon // Author: Mattia Barbon
// Modified by: // Modified by:
// Created: 29/01/2002 // Created: 29/01/2002
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Mattia Barbon // Copyright: (c) Mattia Barbon
@ -22,8 +22,6 @@
#include "wx/hashmap.h" #include "wx/hashmap.h"
#include <assert.h>
/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins */ /* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins */
/* from requirements by Colin Plumb. */ /* from requirements by Colin Plumb. */
/* (http://burtleburtle.net/bob/hash/doobs.html) */ /* (http://burtleburtle.net/bob/hash/doobs.html) */
@ -63,7 +61,7 @@ unsigned long wxStringHash::charStringHash( const char* k )
#endif #endif
/* from SGI STL */ /* from SGI STL */
const unsigned long _wxHashTableBase2::s_primes[prime_count] = const unsigned long _wxHashTableBase2::ms_primes[prime_count] =
{ {
7ul, 13ul, 29ul, 7ul, 13ul, 29ul,
53ul, 97ul, 193ul, 389ul, 769ul, 53ul, 97ul, 193ul, 389ul, 769ul,
@ -76,7 +74,7 @@ const unsigned long _wxHashTableBase2::s_primes[prime_count] =
unsigned long _wxHashTableBase2::GetNextPrime( unsigned long n ) unsigned long _wxHashTableBase2::GetNextPrime( unsigned long n )
{ {
const unsigned long* ptr = &s_primes[0]; const unsigned long* ptr = &ms_primes[0];
for( size_t i = 0; i < prime_count; ++i, ++ptr ) for( size_t i = 0; i < prime_count; ++i, ++ptr )
{ {
if( n < *ptr ) if( n < *ptr )
@ -84,14 +82,15 @@ unsigned long _wxHashTableBase2::GetNextPrime( unsigned long n )
} }
/* someone might try to alloc a 2^32-element hash table */ /* someone might try to alloc a 2^32-element hash table */
assert(0); wxFAIL_MSG( _T("hash table too big?") );
/* quiet warning */ /* quiet warning */
return 0; return 0;
} }
unsigned long _wxHashTableBase2::GetPreviousPrime( unsigned long n ) unsigned long _wxHashTableBase2::GetPreviousPrime( unsigned long n )
{ {
const unsigned long* ptr = &s_primes[prime_count - 1]; const unsigned long* ptr = &ms_primes[prime_count - 1];
for( size_t i = 0; i < prime_count; ++i, --ptr ) for( size_t i = 0; i < prime_count; ++i, --ptr )
{ {