Try again to fix hash<fbstring> namespacing
[folly.git] / folly / FBString.h
index 02e4d276464ffc3c68971e3fd7c3e3b5299105e5..30fcb4ab2faea97ace74ac332f64cd428428b0d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2014 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #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
@@ -2312,7 +2317,29 @@ operator<<(
   std::basic_ostream<typename basic_fbstring<E, T, A, S>::value_type,
   typename basic_fbstring<E, T, A, S>::traits_type>& os,
     const basic_fbstring<E, T, A, S>& str) {
+#if _LIBCPP_VERSION
+  typename std::basic_ostream<
+    typename basic_fbstring<E, T, A, S>::value_type,
+    typename basic_fbstring<E, T, A, S>::traits_type>::sentry __s(os);
+  if (__s) {
+    typedef std::ostreambuf_iterator<
+      typename basic_fbstring<E, T, A, S>::value_type,
+      typename basic_fbstring<E, T, A, S>::traits_type> _Ip;
+    size_t __len = str.size();
+    bool __left =
+      (os.flags() & std::ios_base::adjustfield) == std::ios_base::left;
+    if (__pad_and_output(_Ip(os),
+                         str.data(),
+                         __left ? str.data() + __len : str.data(),
+                         str.data() + __len,
+                         os,
+                         os.fill()).failed()) {
+      os.setstate(std::ios_base::badbit | std::ios_base::failbit);
+    }
+  }
+#else
   std::__ostream_insert(os, str.data(), str.size());
+#endif
   return os;
 }
 
@@ -2417,21 +2444,53 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 } // namespace folly
 
-#pragma GCC diagnostic pop
-
 #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 {
+
+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());
   }
 };
+
 }
 
+#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
 
+#pragma GCC diagnostic pop
+
 #undef FBSTRING_DISABLE_ADDRESS_SANITIZER
 #undef throw
 #undef FBSTRING_LIKELY