diff options
author | Paolo Carlini <pcarlini@suse.de> | 2005-07-13 10:47:40 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2005-07-13 10:47:40 +0000 |
commit | 5a298377cf1bf0883f295c66e2dcd8aa87b1038d (patch) | |
tree | 9f3e68604de2a2a4e881d651ab725eac3f077fbf /libstdc++-v3 | |
parent | 2824a5c3b11d3131ee7f95938a869339aa863e57 (diff) | |
download | gcc-5a298377cf1bf0883f295c66e2dcd8aa87b1038d.tar.gz |
PR libstdc++/21193 (string & wstring)
2005-07-13 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/21193 (string & wstring)
* include/tr1/functional (hash<string>, hash<wstring>):
Reimplement using the FNV hash.
* include/tr1/functional: Trivial formatting fixes.
From-SVN: r101964
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/tr1/functional | 107 |
2 files changed, 84 insertions, 31 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7ab1fca13bb..18bd7701919 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2005-07-13 Paolo Carlini <pcarlini@suse.de> + + PR libstdc++/21193 (string & wstring) + * include/tr1/functional (hash<string>, hash<wstring>): + Reimplement using the FNV hash. + + * include/tr1/functional: Trivial formatting fixes. + 2005-07-11 Paolo Carlini <pcarlini@suse.de> * include/bits/ostream.tcc (basic_ostream<>::operator<<(long), diff --git a/libstdc++-v3/include/tr1/functional b/libstdc++-v3/include/tr1/functional index abe92e3bf23..6866357c864 100644 --- a/libstdc++-v3/include/tr1/functional +++ b/libstdc++-v3/include/tr1/functional @@ -1090,15 +1090,19 @@ namespace tr1 #undef _GLIBCXX_JOIN2 #undef _GLIBCXX_JOIN -// Definition of default hash function std::tr1::hash<>. The types for -// which std::tr1::hash<T> is defined is in clause 6.3.3. of the PDTR. - - template <typename T> struct hash; - - #define tr1_hashtable_define_trivial_hash(T) \ - template <> struct hash<T> { \ - std::size_t operator()(T val) const { return static_cast<std::size_t>(val); } \ - } \ + // Definition of default hash function std::tr1::hash<>. The types for + // which std::tr1::hash<T> is defined is in clause 6.3.3. of the PDTR. + template<typename T> + struct hash; + +#define tr1_hashtable_define_trivial_hash(T) \ + template<> \ + struct hash<T> \ + { \ + std::size_t \ + operator()(T val) const \ + { return static_cast<std::size_t>(val); } \ + } tr1_hashtable_define_trivial_hash(bool); tr1_hashtable_define_trivial_hash(char); @@ -1116,44 +1120,85 @@ namespace tr1 tr1_hashtable_define_trivial_hash(double); tr1_hashtable_define_trivial_hash(long double); - #undef tr1_hashtable_define_trivial_hash +#undef tr1_hashtable_define_trivial_hash + + template<typename T> + struct hash<T*> + { + std::size_t + operator()(T* p) const + { return reinterpret_cast<std::size_t>(p); } + }; + + // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) + // (used by the next specializations of std::tr1::hash<>) - template <typename T> - struct hash<T*> { - std::size_t operator()(T* p) const { - return reinterpret_cast<std::size_t>(p); + // Dummy generic implementation (for sizeof(size_t) != 4,8). + template<std::size_t = sizeof(std::size_t)> + struct Fnv_hash + { + static std::size_t + hash(const char* first, std::size_t length) + { + std::size_t result = 0; + for (; length > 0; --length) + result = (result * 131) + *first++; + return result; } }; - // ??? We can probably find a better hash function than this (i.e. one - // that vectorizes better and that produces a more uniform distribution). + template<> + struct Fnv_hash<4> + { + static std::size_t + hash(const char* first, std::size_t length) + { + std::size_t result = 2166136261UL; + for (; length > 0; --length) + { + result ^= (std::size_t)*first++; + result *= 16777619UL; + } + return result; + } + }; + + template<> + struct Fnv_hash<8> + { + static std::size_t + hash(const char* first, std::size_t length) + { + std::size_t result = 14695981039346656037ULL; + for (; length > 0; --length) + { + result ^= (std::size_t)*first++; + result *= 1099511628211ULL; + } + return result; + } + }; // XXX String hash probably shouldn't be an inline member function, // since it's nontrivial. Once we have the framework for TR1 .cc // files, this should go in one. - - template <> + template<> struct hash<std::string> { - std::size_t operator()(const std::string& s) const - { - std::size_t result = 0; - for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) - result = (result * 131) + *i; - return result; - } + std::size_t + operator()(const std::string& s) const + { return Fnv_hash<>::hash(s.data(), s.length()); } }; #ifdef _GLIBCXX_USE_WCHAR_T - template <> + template<> struct hash<std::wstring> { - std::size_t operator()(const std::wstring& s) const + std::size_t + operator()(const std::wstring& s) const { - std::size_t result = 0; - for (std::wstring::const_iterator i = s.begin(); i != s.end(); ++i) - result = (result * 131) + *i; - return result; + return Fnv_hash<>::hash(reinterpret_cast<const char*>(s.data()), + s.length() * sizeof(wchar_t)); } }; #endif |