From 425811f10e098158858abd934f5aceabf17f250a Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 24 Jul 2026 11:26:48 -0700 Subject: [PATCH] Undo make string matchers work with std::wstring_view due to internal breakages Reopens: #4912 PiperOrigin-RevId: 953470061 Change-Id: Ie979aa352f0ecbfb27dec5a41aae4b668cf7541b --- googlemock/include/gmock/gmock-matchers.h | 106 +++++++++++++----- .../test/gmock-matchers-comparisons_test.cc | 18 +-- googletest/include/gtest/gtest-matchers.h | 48 ++------ 3 files changed, 95 insertions(+), 77 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 3cd0ce069..603a5029f 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -4982,68 +4982,116 @@ internal::ResultOfMatcher ResultOf( // Matches a string equal to str. template -PolymorphicMatcher>> StrEq( - const T& str) { +PolymorphicMatcher> StrEq( + const internal::StringLike& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher>( - internal::StringType(str), true, true)); + internal::StrEqualityMatcher(std::string(str), true, true)); } // Matches a string not equal to str. template -PolymorphicMatcher>> StrNe( - const T& str) { +PolymorphicMatcher> StrNe( + const internal::StringLike& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher>( - internal::StringType(str), false, true)); + internal::StrEqualityMatcher(std::string(str), false, true)); } // Matches a string equal to str, ignoring case. template -PolymorphicMatcher>> -StrCaseEq(const T& str) { +PolymorphicMatcher> StrCaseEq( + const internal::StringLike& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher>( - internal::StringType(str), true, false)); + internal::StrEqualityMatcher(std::string(str), true, false)); } // Matches a string not equal to str, ignoring case. template -PolymorphicMatcher>> -StrCaseNe(const T& str) { - return MakePolymorphicMatcher( - internal::StrEqualityMatcher>( - internal::StringType(str), false, false)); +PolymorphicMatcher> StrCaseNe( + const internal::StringLike& str) { + return MakePolymorphicMatcher(internal::StrEqualityMatcher( + std::string(str), false, false)); } // Creates a matcher that matches any string, std::string, or C string // that contains the given substring. template -PolymorphicMatcher>> -HasSubstr(const T& substring) { +PolymorphicMatcher> HasSubstr( + const internal::StringLike& substring) { return MakePolymorphicMatcher( - internal::HasSubstrMatcher>( - internal::StringType(substring))); + internal::HasSubstrMatcher(std::string(substring))); } // Matches a string that starts with 'prefix' (case-sensitive). template -PolymorphicMatcher>> -StartsWith(const T& prefix) { +PolymorphicMatcher> StartsWith( + const internal::StringLike& prefix) { return MakePolymorphicMatcher( - internal::StartsWithMatcher>( - internal::StringType(prefix))); + internal::StartsWithMatcher(std::string(prefix))); } // Matches a string that ends with 'suffix' (case-sensitive). template -PolymorphicMatcher>> EndsWith( - const T& suffix) { +PolymorphicMatcher> EndsWith( + const internal::StringLike& suffix) { return MakePolymorphicMatcher( - internal::EndsWithMatcher>( - internal::StringType(suffix))); + internal::EndsWithMatcher(std::string(suffix))); } +#if GTEST_HAS_STD_WSTRING +// Wide string matchers. + +// Matches a string equal to str. +inline PolymorphicMatcher> StrEq( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher(str, true, true)); +} + +// Matches a string not equal to str. +inline PolymorphicMatcher> StrNe( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher(str, false, true)); +} + +// Matches a string equal to str, ignoring case. +inline PolymorphicMatcher> StrCaseEq( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher(str, true, false)); +} + +// Matches a string not equal to str, ignoring case. +inline PolymorphicMatcher> StrCaseNe( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher(str, false, false)); +} + +// Creates a matcher that matches any ::wstring, std::wstring, or C wide string +// that contains the given substring. +inline PolymorphicMatcher> HasSubstr( + const std::wstring& substring) { + return MakePolymorphicMatcher( + internal::HasSubstrMatcher(substring)); +} + +// Matches a string that starts with 'prefix' (case-sensitive). +inline PolymorphicMatcher> StartsWith( + const std::wstring& prefix) { + return MakePolymorphicMatcher( + internal::StartsWithMatcher(prefix)); +} + +// Matches a string that ends with 'suffix' (case-sensitive). +inline PolymorphicMatcher> EndsWith( + const std::wstring& suffix) { + return MakePolymorphicMatcher( + internal::EndsWithMatcher(suffix)); +} + +#endif // GTEST_HAS_STD_WSTRING + // Creates a polymorphic matcher that matches a 2-tuple where the // first field == the second field. inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); } diff --git a/googlemock/test/gmock-matchers-comparisons_test.cc b/googlemock/test/gmock-matchers-comparisons_test.cc index 1403b6d40..b800f1e8b 100644 --- a/googlemock/test/gmock-matchers-comparisons_test.cc +++ b/googlemock/test/gmock-matchers-comparisons_test.cc @@ -1254,22 +1254,22 @@ TEST(RefTest, ExplainsResult) { // Tests string comparison matchers. template -internal::StringType ToString(T str) { - return internal::StringType(str); +std::string FromStringLike(internal::StringLike str) { + return std::string(str); } -TEST(StringType, TestConversions) { - EXPECT_EQ("foo", ToString("foo")); - EXPECT_EQ("foo", ToString(std::string("foo"))); +TEST(StringLike, TestConversions) { + EXPECT_EQ("foo", FromStringLike("foo")); + EXPECT_EQ("foo", FromStringLike(std::string("foo"))); #if GTEST_INTERNAL_HAS_STRING_VIEW - EXPECT_EQ("foo", ToString(internal::StringView("foo"))); + EXPECT_EQ("foo", FromStringLike(internal::StringView("foo"))); #endif // GTEST_INTERNAL_HAS_STRING_VIEW // Non deducible types. - EXPECT_EQ("", ToString({})); - EXPECT_EQ("foo", ToString({'f', 'o', 'o'})); + EXPECT_EQ("", FromStringLike({})); + EXPECT_EQ("foo", FromStringLike({'f', 'o', 'o'})); const char buf[] = "foo"; - EXPECT_EQ("foo", ToString({buf, buf + 3})); + EXPECT_EQ("foo", FromStringLike({buf, buf + 3})); } TEST(StrEqTest, MatchesEqualString) { diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index 805f75309..d7bdd047f 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -45,7 +45,6 @@ #include #include #include -#include #include #include "gtest/gtest-printers.h" @@ -813,36 +812,9 @@ class [[nodiscard]] ImplicitCastEqMatcher { StoredRhs stored_rhs_; }; -// Dummy function (never defined) whose return type evaluates to std::string if -// the given type is a string-like type that can be converted to std::string, -// either directly or through an intermediate std::string_view. -template -extern std::enable_if_t || - (std::is_constructible_v && - std::is_convertible_v), - std::string> -ResolveAsString(const void* /* preferred */); - -#if GTEST_HAS_STD_WSTRING -// Same as above, but for std::wstring. In cases where both conversions are -// possible, this overload takes lower priority. -template -extern std::enable_if_t || - (std::is_constructible_v && - std::is_convertible_v), - std::wstring> -ResolveAsString(... /* fallback */); -#endif - -// Evaluates to the std::basic_string type that the given string-like type can -// be converted to. Prefers std::string over std::wstring if both are possible. -// Fails in a SFINAE-friendly way if no conversion was viable. -// -// For example, const char* and std::string_view would both evaluate to -// std::string, but std::allocator would fail to evaluate via SFINAE -// (despite std::string being constructible from it). -template -using StringType = decltype(ResolveAsString(nullptr)); +template >> +using StringLike = T; // Implements polymorphic matchers MatchesRegex(regex) and // ContainsRegex(regex), which can be used as a Matcher as long as @@ -905,10 +877,9 @@ inline PolymorphicMatcher MatchesRegex( return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); } template -std::enable_if_t>, - PolymorphicMatcher> -MatchesRegex(const T& regex) { - return MatchesRegex(new internal::RE(internal::StringType(regex))); +PolymorphicMatcher MatchesRegex( + const internal::StringLike& regex) { + return MatchesRegex(new internal::RE(std::string(regex))); } // Matches a string that contains regular expression 'regex'. @@ -918,10 +889,9 @@ inline PolymorphicMatcher ContainsRegex( return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); } template -std::enable_if_t>, - PolymorphicMatcher> -ContainsRegex(const T& regex) { - return ContainsRegex(new internal::RE(internal::StringType(regex))); +PolymorphicMatcher ContainsRegex( + const internal::StringLike& regex) { + return ContainsRegex(new internal::RE(std::string(regex))); } // Creates a polymorphic matcher that matches anything equal to x.