Tweak basic_fbstring construction from std types
authorPhil Willoughby <philwill@fb.com>
Wed, 17 May 2017 11:05:52 +0000 (04:05 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 17 May 2017 11:24:42 +0000 (04:24 -0700)
Summary:
Previously we defined an assignment from std::string on all basic_fbstring
specialisations, but we don't actually want to do that because it's nonsense to
construct a basic_fbstring<char16_t> from an std::string. Equally it's not
nonsense to construct one of those from an std::u16string but the previous code
didn't allow it.

We now permit basic_fbstring<C, T, A1, S> to be constructed or assigned-to from
std::basic_string<C, T, A2>. The character type and traits must match but the
allocator is permitted to vary.

Background on my determination that the allocator type was unimportant and
could be disregarded: In part this is because C++17 made the same choice for
basic_string_view. Another factor was C++17's std::pmr::string (it's a
std::string with a different allocator) which I thought should be convertible
to fbstring in the same way as std::string.

Reviewed By: Gownta

Differential Revision: D5060569

fbshipit-source-id: f8984c528b76356240970c67916c58995d3f228d

folly/FBString.h

index 45ba6cb5afe358b1e8e4070084c968bd357dcaca..5db1e61e19329bc2fc86c82d90d2bb0ff18036e4 100644 (file)
@@ -1141,9 +1141,9 @@ public:
 
 #ifndef _LIBSTDCXX_FBSTRING
   // This is defined for compatibility with std::string
-  /* implicit */ basic_fbstring(const std::string& str)
-      : store_(str.data(), str.size()) {
-  }
+  template <typename A2>
+  /* implicit */ basic_fbstring(const std::basic_string<E, T, A2>& str)
+      : store_(str.data(), str.size()) {}
 #endif
 
   basic_fbstring(const basic_fbstring& str,
@@ -1205,13 +1205,14 @@ public:
 
 #ifndef _LIBSTDCXX_FBSTRING
   // Compatibility with std::string
-  basic_fbstring & operator=(const std::string & rhs) {
+  template <typename A2>
+  basic_fbstring& operator=(const std::basic_string<E, T, A2>& rhs) {
     return assign(rhs.data(), rhs.size());
   }
 
   // Compatibility with std::string
-  std::string toStdString() const {
-    return std::string(data(), size());
+  std::basic_string<E, T, A> toStdString() const {
+    return std::basic_string<E, T, A>(data(), size());
   }
 #else
   // A lot of code in fbcode still uses this method, so keep it here for now.