Try again to fix hash<fbstring> namespacing
authorPeter Griess <pgriess@fb.com>
Sat, 1 Feb 2014 04:08:02 +0000 (20:08 -0800)
committerDave Watson <davejwatson@fb.com>
Fri, 28 Feb 2014 21:59:14 +0000 (13:59 -0800)
Summary:
- Unfortunately when D1152140 broke the Android build, which uses the
Bionic C++ standard library, and which Boost doesn't auto-detect. Deal
with this by manually picking namespaces for template specialization
based on #defines.

Test Plan:
- fbconfig -r folly/ unicorn/utils/ && fbmake runtests
- Build Liger on iOS and Android

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D1154569

Blame Revision: D1152140

folly/FBString.h
folly/String.h

index 143a006ca74cf10cba6a5d2f65e9e875bc36a86d..30fcb4ab2faea97ace74ac332f64cd428428b0d8 100644 (file)
 #include <bits/c++config.h>
 #endif
 
 #include <bits/c++config.h>
 #endif
 
+#ifdef _GLIBCXX_SYMVER
+#include <ext/hash_set>
+#include <ext/hash_map>
+#endif
+
 #ifdef _LIBSTDCXX_FBSTRING
 
 #pragma GCC system_header
 #ifdef _LIBSTDCXX_FBSTRING
 
 #pragma GCC system_header
@@ -2439,21 +2444,53 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 } // namespace folly
 
 
 } // namespace folly
 
-#pragma GCC diagnostic pop
-
 #ifndef _LIBSTDCXX_FBSTRING
 
 #ifndef _LIBSTDCXX_FBSTRING
 
+// Hash functions to make fbstring usable with e.g. hash_map
+//
+// Handle interaction with different C++ standard libraries, which
+// expect these types to be in different namespaces.
 namespace std {
 namespace std {
+
+template <class C>
+struct hash<folly::basic_fbstring<C> > : private hash<const C*> {
+  size_t operator()(const folly::basic_fbstring<C> & s) const {
+    return hash<const C*>::operator()(s.c_str());
+  }
+};
+
 template <>
 struct hash< ::folly::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());
   }
 };
+
 }
 
 }
 
+#if defined(_GLIBCXX_SYMVER) && !defined(__BIONIC__)
+namespace __gnu_cxx {
+
+template <class C>
+struct hash<folly::basic_fbstring<C> > : private hash<const C*> {
+  size_t operator()(const folly::basic_fbstring<C> & s) const {
+    return hash<const C*>::operator()(s.c_str());
+  }
+};
+
+template <>
+struct hash< ::folly::fbstring> {
+  size_t operator()(const ::folly::fbstring& s) const {
+    return ::folly::hash::fnv32_buf(s.data(), s.size());
+  }
+};
+
+}
+#endif // _GLIBCXX_SYMVER && !__BIONIC__
 #endif // _LIBSTDCXX_FBSTRING
 
 #endif // _LIBSTDCXX_FBSTRING
 
+#pragma GCC diagnostic pop
+
 #undef FBSTRING_DISABLE_ADDRESS_SANITIZER
 #undef throw
 #undef FBSTRING_LIKELY
 #undef FBSTRING_DISABLE_ADDRESS_SANITIZER
 #undef throw
 #undef FBSTRING_LIKELY
index bea17b7261953ba91a15648ba4ba183273281a5b..90f9c7393857a13bc7dde1dea85f2eaa9ecf3f60 100644 (file)
@@ -495,19 +495,24 @@ std::string join(const Delim& delimiter,
 
 } // namespace folly
 
 
 } // namespace folly
 
-// Hash functions for string and fbstring usable with e.g. hash_map
+// Hash functions to make std::string usable with e.g. hash_map
 //
 //
-// We let Boost pick the namespace here for us, since it has logic to do the
-// right thing based on the C++ standard library implementation being used.
-namespace BOOST_STD_EXTENSION_NAMESPACE {
+// Handle interaction with different C++ standard libraries, which
+// expect these types to be in different namespaces.
+namespace std {
 
 template <class C>
 
 template <class C>
-struct hash<folly::basic_fbstring<C> > : private hash<const C*> {
-  size_t operator()(const folly::basic_fbstring<C> & s) const {
+struct hash<std::basic_string<C> > : private hash<const C*> {
+  size_t operator()(const std::basic_string<C> & s) const {
     return hash<const C*>::operator()(s.c_str());
   }
 };
 
     return hash<const C*>::operator()(s.c_str());
   }
 };
 
+}
+
+#if defined(_GLIBCXX_SYMVER) && !defined(__BIONIC__)
+namespace __gnu_cxx {
+
 template <class C>
 struct hash<std::basic_string<C> > : private hash<const C*> {
   size_t operator()(const std::basic_string<C> & s) const {
 template <class C>
 struct hash<std::basic_string<C> > : private hash<const C*> {
   size_t operator()(const std::basic_string<C> & s) const {
@@ -516,6 +521,7 @@ struct hash<std::basic_string<C> > : private hash<const C*> {
 };
 
 }
 };
 
 }
+#endif
 
 // Hook into boost's type traits
 namespace boost {
 
 // Hook into boost's type traits
 namespace boost {