/////////////////////////////////////////////////////////////////////////////
-// Name: hashmap.h
+// Name: wx/hashmap.h
// Purpose: wxHashMap class
// Author: Mattia Barbon
// Modified by:
#define _WX_HASHMAP_H_
#include "wx/string.h"
+#include "wx/wxcrt.h"
#if (defined(HAVE_EXT_HASH_MAP) || defined(HAVE_HASH_MAP)) \
&& (defined(HAVE_GNU_CXX_HASH_MAP) || defined(HAVE_STD_HASH_MAP))
#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)
value_type m_value; \
}; \
\
- CLASSEXP Iterator; \
- friend CLASSEXP Iterator; \
protected: \
static void DeleteNode( _wxHashTable_NodeBase* node ) \
{ \
m_node = next ? next : GetNextNode(); \
} \
}; \
+ friend class Iterator; \
\
public: \
CLASSEXP 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; } \
const_iterator end() const { return const_iterator( 0, this ); } \
iterator end() { return iterator( 0, this ); } \
const_iterator begin() const \
- { return const_iterator( (Node*)GetFirstNode( m_tableBuckets, (_wxHashTable_NodeBase**)m_table ), this ); }; \
+ { return const_iterator( (Node*)GetFirstNode( m_tableBuckets, (_wxHashTable_NodeBase**)m_table ), this ); } \
iterator begin() \
- { return iterator( (Node*)GetFirstNode( m_tableBuckets, (_wxHashTable_NodeBase**)m_table ), this ); }; \
+ { return iterator( (Node*)GetFirstNode( m_tableBuckets, (_wxHashTable_NodeBase**)m_table ), this ); } \
\
size_type erase( const const_key_type& key ) \
{ \
/* returns NULL if not found */ \
Node** GetNodePtr( const const_key_type& key ) const \
{ \
- unsigned long hash = wx_static_cast(unsigned long, 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 = wx_static_cast(unsigned long, 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 ) \
{ \
WX_HASH_MAP_NAMESPACE::hash<unsigned int> uintHash;
WX_HASH_MAP_NAMESPACE::hash<short> shortHash;
WX_HASH_MAP_NAMESPACE::hash<unsigned short> ushortHash;
+
+#if defined wxLongLong_t && !defined wxLongLongIsLong
+ // hash<wxLongLong_t> 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<long> longlongHash;
+ #else
+ WX_HASH_MAP_NAMESPACE::hash<wxLongLong_t> longlongHash;
+ #endif
+#endif
+
public:
wxIntegerHash() { }
size_t operator()( long x ) const { return longHash( x ); }
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; }
};
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; }
};
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; }
};
wxPointerEqual& operator=(const wxPointerEqual&) { return *this; }
};
-// wxString, char*, wxChar*
+// wxString, char*, wchar_t*
class WXDLLIMPEXP_BASE wxStringHash
{
public:
wxStringHash() {}
unsigned long operator()( const wxString& x ) const
- { return wxCharStringHash( x.c_str() ); }
- unsigned long operator()( const wxChar* x ) const
- { return wxCharStringHash( x ); }
- static unsigned long wxCharStringHash( const wxChar* );
-#if wxUSE_UNICODE
+ { return stringHash( x.wx_str() ); }
+ unsigned long operator()( const wchar_t* x ) const
+ { return stringHash( x ); }
unsigned long operator()( const char* x ) const
- { return charStringHash( x ); }
- static unsigned long charStringHash( const char* );
-#endif // wxUSE_UNICODE
+ { return stringHash( x ); }
+
+#if WXWIN_COMPATIBILITY_2_8
+ static unsigned long wxCharStringHash( const wxChar* x )
+ { return stringHash(x); }
+ #if wxUSE_UNICODE
+ static unsigned long charStringHash( const char* x )
+ { return stringHash(x); }
+ #endif
+#endif // WXWIN_COMPATIBILITY_2_8
+
+ static unsigned long stringHash( const wchar_t* );
+ static unsigned long stringHash( const char* );
wxStringHash& operator=(const wxStringHash&) { return *this; }
};
\
/* 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)
#endif // _WX_HASHMAP_H_
-