X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FFBString.h;h=09ab0565220e3a22ddf163faab07c725141f9603;hb=5ba3126fb76f1d81100b34e429c79cd21f8cd142;hp=45791e3fc615f068659124090d86eabe2e5d88ae;hpb=ab7561bec78a9d6999f9d4f1305cd4d23306ea82;p=folly.git diff --git a/folly/FBString.h b/folly/FBString.h index 45791e3f..09ab0565 100644 --- a/folly/FBString.h +++ b/folly/FBString.h @@ -40,6 +40,7 @@ #else // !_LIBSTDCXX_FBSTRING +#include #include // libc++ doesn't provide this header, nor does msvc @@ -56,13 +57,7 @@ #include #include #include - -#if FOLLY_HAVE_DEPRECATED_ASSOC -#ifdef _GLIBCXX_SYMVER -#include -#include -#endif -#endif +#include // When used in folly, assertions are not disabled. #define FBSTRING_ASSERT(expr) assert(expr) @@ -79,13 +74,13 @@ #define FBSTRING_UNLIKELY(x) (x) #endif -#pragma GCC diagnostic push +FOLLY_PUSH_WARNING // Ignore shadowing warnings within this file, so includers can use -Wshadow. -#pragma GCC diagnostic ignored "-Wshadow" +FOLLY_GCC_DISABLE_WARNING("-Wshadow") // GCC 4.9 has a false positive in setSmallSize (probably // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124), disable // compile-time array bound checking. -#pragma GCC diagnostic ignored "-Warray-bounds" +FOLLY_GCC_DISABLE_WARNING("-Warray-bounds") // FBString cannot use throw when replacing std::string, though it may still // use std::__throw_* @@ -499,7 +494,9 @@ public: if (RefCounted::refs(ml_.data_) > 1) { return ml_.size_; } - default: {} + break; + default: + break; } return ml_.capacity(); } @@ -753,10 +750,13 @@ inline void fbstring_core::initSmall( switch ((byteSize + wordWidth - 1) / wordWidth) { // Number of words. case 3: ml_.capacity_ = reinterpret_cast(data)[2]; + FOLLY_FALLTHROUGH; case 2: ml_.size_ = reinterpret_cast(data)[1]; + FOLLY_FALLTHROUGH; case 1: ml_.data_ = *reinterpret_cast(const_cast(data)); + FOLLY_FALLTHROUGH; case 0: break; } @@ -1147,9 +1147,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 + /* implicit */ basic_fbstring(const std::basic_string& str) + : store_(str.data(), str.size()) {} #endif basic_fbstring(const basic_fbstring& str, @@ -1211,13 +1211,14 @@ public: #ifndef _LIBSTDCXX_FBSTRING // Compatibility with std::string - basic_fbstring & operator=(const std::string & rhs) { + template + basic_fbstring& operator=(const std::basic_string& rhs) { return assign(rhs.data(), rhs.size()); } // Compatibility with std::string - std::string toStdString() const { - return std::string(data(), size()); + std::basic_string toStdString() const { + return std::basic_string(data(), size()); } #else // A lot of code in fbcode still uses this method, so keep it here for now. @@ -1230,7 +1231,24 @@ public: return assign(s); } - basic_fbstring& operator=(value_type c); + // This actually goes directly against the C++ spec, but the + // value_type overload is dangerous, so we're explicitly deleting + // any overloads of operator= that could implicitly convert to + // value_type. + // Note that we do need to explicitly specify the template types because + // otherwise MSVC 2017 will aggressively pre-resolve value_type to + // traits_type::char_type, which won't compare as equal when determining + // which overload the implementation is referring to. + // Also note that MSVC 2015 Update 3 requires us to explicitly specify the + // namespace in-which to search for basic_fbstring, otherwise it tries to + // look for basic_fbstring::basic_fbstring, which is just plain wrong. + template + typename std::enable_if< + std::is_same< + typename std::decay::type, + typename folly::basic_fbstring::value_type>::value, + basic_fbstring&>::type + operator=(TP c); basic_fbstring& operator=(std::initializer_list il) { return assign(il.begin(), il.end()); @@ -1860,8 +1878,13 @@ inline basic_fbstring& basic_fbstring::operator=( } template -inline basic_fbstring& basic_fbstring::operator=( - const value_type c) { +template +inline typename std::enable_if< + std::is_same< + typename std::decay::type, + typename basic_fbstring::value_type>::value, + basic_fbstring&>::type +basic_fbstring::operator=(TP c) { Invariant checker(*this); if (empty()) { @@ -2725,34 +2748,90 @@ constexpr typename basic_fbstring::size_type #ifndef _LIBSTDCXX_FBSTRING // basic_string compatibility routines -template -inline -bool operator==(const basic_fbstring& lhs, - const std::string& rhs) { +template +inline bool operator==( + const basic_fbstring& lhs, + const std::basic_string& rhs) { return lhs.compare(0, lhs.size(), rhs.data(), rhs.size()) == 0; } -template -inline -bool operator==(const std::string& lhs, - const basic_fbstring& rhs) { +template +inline bool operator==( + const std::basic_string& lhs, + const basic_fbstring& rhs) { return rhs == lhs; } -template -inline -bool operator!=(const basic_fbstring& lhs, - const std::string& rhs) { +template +inline bool operator!=( + const basic_fbstring& lhs, + const std::basic_string& rhs) { return !(lhs == rhs); } -template -inline -bool operator!=(const std::string& lhs, - const basic_fbstring& rhs) { +template +inline bool operator!=( + const std::basic_string& lhs, + const basic_fbstring& rhs) { return !(lhs == rhs); } +template +inline bool operator<( + const basic_fbstring& lhs, + const std::basic_string& rhs) { + return lhs.compare(0, lhs.size(), rhs.data(), rhs.size()) < 0; +} + +template +inline bool operator>( + const basic_fbstring& lhs, + const std::basic_string& rhs) { + return lhs.compare(0, lhs.size(), rhs.data(), rhs.size()) > 0; +} + +template +inline bool operator<( + const std::basic_string& lhs, + const basic_fbstring& rhs) { + return rhs > lhs; +} + +template +inline bool operator>( + const std::basic_string& lhs, + const basic_fbstring& rhs) { + return rhs < lhs; +} + +template +inline bool operator<=( + const basic_fbstring& lhs, + const std::basic_string& rhs) { + return !(lhs > rhs); +} + +template +inline bool operator>=( + const basic_fbstring& lhs, + const std::basic_string& rhs) { + return !(lhs < rhs); +} + +template +inline bool operator<=( + const std::basic_string& lhs, + const basic_fbstring& rhs) { + return !(lhs > rhs); +} + +template +inline bool operator>=( + const std::basic_string& lhs, + const basic_fbstring& rhs) { + return !(lhs < rhs); +} + #if !defined(_LIBSTDCXX_FBSTRING) typedef basic_fbstring fbstring; #endif @@ -2795,22 +2874,12 @@ FOLLY_FBSTRING_HASH } // namespace std -#if FOLLY_HAVE_DEPRECATED_ASSOC -#if defined(_GLIBCXX_SYMVER) && !defined(__BIONIC__) -namespace __gnu_cxx { - -FOLLY_FBSTRING_HASH - -} // namespace __gnu_cxx -#endif // _GLIBCXX_SYMVER && !__BIONIC__ -#endif // FOLLY_HAVE_DEPRECATED_ASSOC - #undef FOLLY_FBSTRING_HASH #undef FOLLY_FBSTRING_HASH1 #endif // _LIBSTDCXX_FBSTRING -#pragma GCC diagnostic pop +FOLLY_POP_WARNING #undef FBSTRING_DISABLE_SSO #undef FBSTRING_SANITIZE_ADDRESS