X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fe8604accea93f016df337a19afa7f957626dcf1..855f31ebe72bef834a32df2c274b41fb282ad265:/include/wx/hashmap.h diff --git a/include/wx/hashmap.h b/include/wx/hashmap.h index adf8035092..41aaccb230 100644 --- a/include/wx/hashmap.h +++ b/include/wx/hashmap.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: hashmap.h +// Name: wx/hashmap.h // Purpose: wxHashMap class // Author: Mattia Barbon // Modified by: @@ -12,10 +12,6 @@ #ifndef _WX_HASHMAP_H_ #define _WX_HASHMAP_H_ -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma interface "hashmap.h" -#endif - #include "wx/string.h" #if (defined(HAVE_EXT_HASH_MAP) || defined(HAVE_HASH_MAP)) \ @@ -38,7 +34,7 @@ #endif #define _WX_DECLARE_HASH_MAP( KEY_T, VALUE_T, HASH_T, KEY_EQ_T, CLASSNAME, CLASSEXP ) \ - typedef WX_HASH_MAP_NAMESPACE::hash_map< KEY_T, VALUE_T, HASH_T, KEY_EQ_T > CLASSNAME; + typedef WX_HASH_MAP_NAMESPACE::hash_map< KEY_T, VALUE_T, HASH_T, KEY_EQ_T > CLASSNAME #else // !wxUSE_STL || !defined(HAVE_STL_HASH_MAP) @@ -101,6 +97,10 @@ protected: { return (void **)calloc(sz, sizeof(void*)); } + static void FreeTable(void *table) + { + free(table); + } }; #define _WX_DECLARE_HASHTABLE( VALUE_T, KEY_T, HASH_T, KEY_EX_T, KEY_EQ_T, CLASSNAME, CLASSEXP, SHOULD_GROW, SHOULD_SHRINK ) \ @@ -143,8 +143,8 @@ public: \ value_type m_value; \ }; \ \ - struct Iterator; \ - friend struct Iterator; \ + CLASSEXP Iterator; \ + friend CLASSEXP Iterator; \ protected: \ static void DeleteNode( _wxHashTable_NodeBase* node ) \ { \ @@ -154,8 +154,9 @@ public: \ /* */ \ /* forward iterator */ \ /* */ \ - struct Iterator \ + CLASSEXP Iterator \ { \ + public: \ Node* m_node; \ Self* m_ht; \ \ @@ -186,8 +187,9 @@ public: \ }; \ \ public: \ - struct iterator:public Iterator \ + CLASSEXP iterator : public Iterator \ { \ + public: \ iterator() : Iterator() {} \ iterator( Node* node, Self* ht ) : Iterator( node, ht ) {} \ iterator& operator++() { PlusPlus(); return *this; } \ @@ -196,9 +198,11 @@ public: \ pointer operator ->() const { return &(m_node->m_value); } \ }; \ \ - struct const_iterator:public Iterator \ + CLASSEXP const_iterator : public Iterator \ { \ + public: \ const_iterator() : Iterator() {} \ + const_iterator(iterator i) : Iterator(i) {} \ const_iterator( Node* node, const Self* ht ) \ : Iterator( node, (Self*)ht ) {} \ const_iterator& operator++() { PlusPlus();return *this; } \ @@ -245,7 +249,7 @@ public: \ { \ clear(); \ \ - free(m_table); \ + FreeTable(m_table); \ } \ \ hasher hash_funct() { return m_hasher; } \ @@ -334,25 +338,26 @@ protected: \ /* returns NULL if not found */ \ Node** GetNodePtr( const const_key_type& key ) const \ { \ - unsigned long hash = m_hasher( key ); \ - Node** node = &m_table[hash % m_tableBuckets]; \ + size_t bucket = m_hasher( key ) % m_tableBuckets; \ + Node** node = &m_table[bucket]; \ \ while( *node ) \ { \ if( m_equals( m_getKey( (*node)->m_value ), key ) ) \ return node; \ + /* Tell the compiler to not do any strict-aliasing assumptions with a void cast? Can we make such a runtime guarantee? */ \ node = (Node**)&(*node)->m_nxt; \ } \ \ - return 0; \ + return NULL; \ } \ \ /* returns NULL if not found */ \ /* expressing it in terms of GetNodePtr is 5-8% slower :-( */ \ Node* GetNode( const const_key_type& key ) const \ { \ - unsigned long hash = m_hasher( key ); \ - Node* node = m_table[hash % m_tableBuckets]; \ + size_t bucket = m_hasher( key ) % m_tableBuckets; \ + Node* node = m_table[bucket]; \ \ while( node ) \ { \ @@ -376,7 +381,7 @@ protected: \ this, (_wxHashTable_NodeBase**)m_table, \ (BucketFromNode)GetBucketForNode,\ (ProcessNode)&DummyProcessNode ); \ - free(srcTable); \ + FreeTable(srcTable); \ } \ \ /* this must be called _after_ m_table has been cleaned */ \ @@ -430,8 +435,8 @@ public: \ }; // grow/shrink predicates -inline bool never_grow( size_t, size_t ) { return FALSE; } -inline bool never_shrink( size_t, size_t ) { return FALSE; } +inline bool never_grow( size_t, size_t ) { return false; } +inline bool never_shrink( size_t, size_t ) { return false; } inline bool grow_lf70( size_t buckets, size_t items ) { return float(items)/float(buckets) >= 0.85; @@ -458,6 +463,23 @@ class WXDLLIMPEXP_BASE wxIntegerHash WX_HASH_MAP_NAMESPACE::hash uintHash; WX_HASH_MAP_NAMESPACE::hash shortHash; WX_HASH_MAP_NAMESPACE::hash ushortHash; + +#if defined wxLongLong_t && !defined wxLongLongIsLong + // hash ought to work but doesn't on some compilers + #if (!defined SIZEOF_LONG_LONG && SIZEOF_LONG == 4) \ + || (defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == SIZEOF_LONG * 2) + size_t longlongHash( wxLongLong_t x ) const + { + return longHash( wx_truncate_cast(long, x) ) ^ + longHash( wx_truncate_cast(long, x >> (sizeof(long) * 8)) ); + } + #elif defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == SIZEOF_LONG + WX_HASH_MAP_NAMESPACE::hash longlongHash; + #else + WX_HASH_MAP_NAMESPACE::hash longlongHash; + #endif +#endif + public: wxIntegerHash() { } size_t operator()( long x ) const { return longHash( x ); } @@ -466,6 +488,10 @@ public: size_t operator()( unsigned int x ) const { return uintHash( x ); } size_t operator()( short x ) const { return shortHash( x ); } size_t operator()( unsigned short x ) const { return ushortHash( x ); } +#if defined wxLongLong_t && !defined wxLongLongIsLong + size_t operator()( wxLongLong_t x ) const { return longlongHash(x); } + size_t operator()( wxULongLong_t x ) const { return longlongHash(x); } +#endif wxIntegerHash& operator=(const wxIntegerHash&) { return *this; } }; @@ -483,6 +509,10 @@ public: 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; } +#if defined wxLongLong_t && !defined wxLongLongIsLong + wxULongLong_t operator()( wxLongLong_t x ) const { return wx_static_cast(wxULongLong_t, x); } + wxULongLong_t operator()( wxULongLong_t x ) const { return x; } +#endif wxIntegerHash& operator=(const wxIntegerHash&) { return *this; } }; @@ -499,6 +529,10 @@ public: bool operator()( unsigned int a, unsigned int b ) const { 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; } +#if defined wxLongLong_t && !defined wxLongLongIsLong + bool operator()( wxLongLong_t a, wxLongLong_t b ) const { return a == b; } + bool operator()( wxULongLong_t a, wxULongLong_t b ) const { return a == b; } +#endif wxIntegerEqual& operator=(const wxIntegerEqual&) { return *this; } }; @@ -509,12 +543,10 @@ class WXDLLIMPEXP_BASE wxPointerHash public: wxPointerHash() { } - // TODO: this might not work well on architectures with 64 bit pointers but - // 32 bit longs, we should use % ULONG_MAX there #if wxUSE_STL && defined(HAVE_STL_HASH_MAP) size_t operator()( const void* k ) const { return (size_t)k; } #else - unsigned long operator()( const void* k ) const { return (unsigned long)wxPtrToULong(k); } + wxUIntPtr operator()( const void* k ) const { return wxPtrToUInt(k); } #endif wxPointerHash& operator=(const wxPointerHash&) { return *this; } @@ -617,7 +649,10 @@ public: \ \ /* count() == 0 | 1 */ \ size_type count( const const_key_type& key ) \ - { return GetNode( key ) ? 1 : 0; } \ + { \ + /* explicit cast needed to suppress CodeWarrior warnings */ \ + return (size_type)(GetNode( key ) ? 1 : 0); \ + } \ } #endif // !wxUSE_STL || !defined(HAVE_STL_HASH_MAP) @@ -681,4 +716,3 @@ WX_DECLARE_HASH_MAP_WITH_DECL( long, long, wxIntegerHash, wxIntegerEqual, #endif // _WX_HASHMAP_H_ -