From df377ed2a89f02d266468ef2a2d4ea109f741138 Mon Sep 17 00:00:00 2001 From: Tudor Bosman Date: Wed, 9 Jul 2014 08:42:15 -0700 Subject: [PATCH] Remove unnecessary and broken hash specializations Summary: No need to specialize std::hash for std::basic_string; the STL already does this. Plus, the specializations were broken in multiple ways: 1. std::hash does not treat const char* specially, so it just hashes the pointer value (contrasting the old __gnu_cxx::hash, which hashed a C-string) 2. Either way, using __gnu_cxx::hash for std::string is broken, as it won't hash anything past the first null byte. Also, make sure fbstring gets the same (full) specializations as std::string does in the standard. Test Plan: fbconfig -r folly && fbmake runtests_opt, also tests in tupperware/agent which is still using __gnu_cxx::hash_map with string keys. Reviewed By: pgriess@fb.com, andrei.alexandrescu@fb.com Subscribers: njormrod, jhj, kma, lesha FB internal diff: D1426479 --- folly/FBString.h | 53 +++++++++++++++++++++--------------------------- folly/String.h | 30 --------------------------- 2 files changed, 23 insertions(+), 60 deletions(-) diff --git a/folly/FBString.h b/folly/FBString.h index 78c04090..e80eba59 100644 --- a/folly/FBString.h +++ b/folly/FBString.h @@ -2417,47 +2417,40 @@ _GLIBCXX_END_NAMESPACE_VERSION // // Handle interaction with different C++ standard libraries, which // expect these types to be in different namespaces. -namespace std { -template -struct hash > : private hash { - size_t operator()(const folly::basic_fbstring & s) const { - return hash::operator()(s.c_str()); - } -}; +#define FOLLY_FBSTRING_HASH1(T) \ + template <> \ + struct hash< ::folly::basic_fbstring > { \ + size_t operator()(const ::folly::fbstring& s) const { \ + return ::folly::hash::fnv32_buf(s.data(), s.size()); \ + } \ + }; -template <> -struct hash< ::folly::fbstring> { - size_t operator()(const ::folly::fbstring& s) const { - return ::folly::hash::fnv32_buf(s.data(), s.size()); - } -}; +// The C++11 standard says that these four are defined +#define FOLLY_FBSTRING_HASH \ + FOLLY_FBSTRING_HASH1(char) \ + FOLLY_FBSTRING_HASH1(char16_t) \ + FOLLY_FBSTRING_HASH1(char32_t) \ + FOLLY_FBSTRING_HASH1(wchar_t) -} +namespace std { + +FOLLY_FBSTRING_HASH + +} // namespace std -#ifndef _LIBSTDCXX_FBSTRING #if FOLLY_HAVE_DEPRECATED_ASSOC #if defined(_GLIBCXX_SYMVER) && !defined(__BIONIC__) namespace __gnu_cxx { -template -struct hash > : private hash { - size_t operator()(const folly::basic_fbstring & s) const { - return hash::operator()(s.c_str()); - } -}; +FOLLY_FBSTRING_HASH -template <> -struct hash< ::folly::fbstring> { - size_t operator()(const ::folly::fbstring& s) const { - return ::folly::hash::fnv32_buf(s.data(), s.size()); - } -}; - -} +} // namespace __gnu_cxx #endif // _GLIBCXX_SYMVER && !__BIONIC__ #endif // FOLLY_HAVE_DEPRECATED_ASSOC -#endif // _LIBSTDCXX_FBSTRING + +#undef FOLLY_FBSTRING_HASH +#undef FOLLY_FBSTRING_HASH1 #endif // _LIBSTDCXX_FBSTRING diff --git a/folly/String.h b/folly/String.h index 563f5313..3df3f9c4 100644 --- a/folly/String.h +++ b/folly/String.h @@ -524,36 +524,6 @@ inline void toLowerAscii(MutableStringPiece str) { } // namespace folly -// Hash functions to make std::string usable with e.g. hash_map -// -// Handle interaction with different C++ standard libraries, which -// expect these types to be in different namespaces. -namespace std { - -template -struct hash > : private hash { - size_t operator()(const std::basic_string & s) const { - return hash::operator()(s.c_str()); - } -}; - -} - -#if FOLLY_HAVE_DEPRECATED_ASSOC -#if defined(_GLIBCXX_SYMVER) && !defined(__BIONIC__) -namespace __gnu_cxx { - -template -struct hash > : private hash { - size_t operator()(const std::basic_string & s) const { - return hash::operator()(s.c_str()); - } -}; - -} -#endif -#endif - // Hook into boost's type traits namespace boost { template -- 2.34.1