Merge pull request #4146 from lygstate:fixes_std_pair_diff

PiperOrigin-RevId: 528781910
Change-Id: I4038332a6255921792bfb4a8098aa84243d48e15
diff --git a/googlemock/test/gmock_output_test_.cc b/googlemock/test/gmock_output_test_.cc
index 04a6e8b..03d8421 100644
--- a/googlemock/test/gmock_output_test_.cc
+++ b/googlemock/test/gmock_output_test_.cc
@@ -33,7 +33,6 @@
 #include <stdio.h>
 
 #include <string>
-#include <tuple>
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -255,16 +254,12 @@
 }
 
 MATCHER_P2(IsPair, first, second, "") {
-  return Value(std::get<0>(arg), first) && Value(std::get<1>(arg), second);
+  return Value(arg.first, first) && Value(arg.second, second);
 }
 
 TEST_F(GMockOutputTest, PrintsMatcher) {
   const testing::Matcher<int> m1 = Ge(48);
-  // Explicitly using std::tuple instead of std::pair due to differences between
-  // MSVC and other compilers. std::pair is printed as
-  // "struct std::pair<int,bool>" when using MSVC vs "std::pair<int,bool>" with
-  // other compilers.
-  EXPECT_THAT((std::tuple<int, bool>(42, true)), IsPair(m1, true));
+  EXPECT_THAT((std::pair<int, bool>(42, true)), IsPair(m1, true));
 }
 
 void TestCatchesLeakedMocksInAdHocTests() {
diff --git a/googlemock/test/gmock_output_test_golden.txt b/googlemock/test/gmock_output_test_golden.txt
index a225644..ca88af0 100644
--- a/googlemock/test/gmock_output_test_golden.txt
+++ b/googlemock/test/gmock_output_test_golden.txt
@@ -307,9 +307,9 @@
 [       OK ] GMockOutputTest.CatchesLeakedMocks
 [ RUN      ] GMockOutputTest.PrintsMatcher
 FILE:#: Failure
-Value of: (std::tuple<int, bool>(42, true))
+Value of: (std::pair<int, bool>(42, true))
 Expected: is pair (first: is >= 48, second: true)
-  Actual: (42, true)
+  Actual: (42, true) (of type std::pair<int,bool>)
 
 [  FAILED  ] GMockOutputTest.PrintsMatcher
 [  FAILED  ] GMockOutputTest.UnexpectedCall
diff --git a/googletest/include/gtest/internal/gtest-type-util.h b/googletest/include/gtest/internal/gtest-type-util.h
index 17a470b..f94cf61 100644
--- a/googletest/include/gtest/internal/gtest-type-util.h
+++ b/googletest/include/gtest/internal/gtest-type-util.h
@@ -67,6 +67,22 @@
       s.erase(strlen("std"), end - strlen("std"));
     }
   }
+
+  // Strip redundant spaces in typename to match MSVC
+  // For example, std::pair<int, bool> -> std::pair<int,bool>
+  static const char to_search[] = ", ";
+  static const char replace_str[] = ",";
+  size_t pos = 0;
+  while (true) {
+    // Get the next occurrence from the current position
+    pos = s.find(to_search, pos);
+    if (pos == std::string::npos) {
+      break;
+    }
+    // Replace this occurrence of substring
+    s.replace(pos, strlen(to_search), replace_str);
+    pos += strlen(replace_str);
+  }
   return s;
 }
 
@@ -85,6 +101,20 @@
   const std::string name_str(status == 0 ? readable_name : name);
   free(readable_name);
   return CanonicalizeForStdLibVersioning(name_str);
+#elif defined(_MSC_VER)
+  // Strip struct and class due to differences between
+  // MSVC and other compilers. std::pair<int,bool> is printed as
+  // "struct std::pair<int,bool>" when using MSVC vs "std::pair<int, bool>" with
+  // other compilers.
+  std::string s = name;
+  // Only strip the leading "struct " and "class ", so uses rfind == 0 to
+  // ensure that
+  if (s.rfind("struct ", 0) == 0) {
+    s = s.substr(strlen("struct "));
+  } else if (s.rfind("class ", 0) == 0) {
+    s = s.substr(strlen("class "));
+  }
+  return s;
 #else
   return name;
 #endif  // GTEST_HAS_CXXABI_H_ || __HP_aCC
diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc
index 9b4b833..77d968a 100644
--- a/googletest/test/gtest_unittest.cc
+++ b/googletest/test/gtest_unittest.cc
@@ -3312,11 +3312,7 @@
 
 #if GTEST_HAS_RTTI
 
-#ifdef _MSC_VER
-#define ERROR_DESC "class std::runtime_error"
-#else
 #define ERROR_DESC "std::runtime_error"
-#endif
 
 #else  // GTEST_HAS_RTTI
 
@@ -6679,7 +6675,7 @@
   SetEnv("TERM", "linux");            // TERM supports colors.
   EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
 
-  SetEnv("TERM", "cygwin");           // TERM supports colors.
+  SetEnv("TERM", "cygwin");  // TERM supports colors.
   EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
 #endif  // GTEST_OS_WINDOWS
 }