Merge pull request #2400 from kuzkry:custom-type-traits-enable_if

PiperOrigin-RevId: 264693952
diff --git a/BUILD.bazel b/BUILD.bazel
index f0c4ce5..9b48aee 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -30,6 +30,8 @@
 #
 #   Bazel Build for Google C++ Testing Framework(Google Test)
 
+load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
+
 package(default_visibility = ["//visibility:public"])
 
 licenses(["notice"])
@@ -81,6 +83,10 @@
         ":has_absl": ["GTEST_HAS_ABSL=1"],
         "//conditions:default": [],
     }),
+    features = select({
+        ":windows": ["windows_export_all_symbols"],
+        "//conditions:default": [],
+    }),
     includes = [
         "googlemock",
         "googlemock/include",
@@ -102,20 +108,16 @@
         ],
         "//conditions:default": [],
     }),
-    features = select({
-        ":windows": ["windows_export_all_symbols"],
-        "//conditions:default": [],
-    })
 )
 
 cc_library(
     name = "gtest_main",
     srcs = ["googlemock/src/gmock_main.cc"],
-    deps = [":gtest"],
     features = select({
         ":windows": ["windows_export_all_symbols"],
         "//conditions:default": [],
-    })
+    }),
+    deps = [":gtest"],
 )
 
 # The following rules build samples of how to use gTest.
@@ -136,7 +138,7 @@
     features = select({
         ":windows": ["windows_export_all_symbols"],
         "//conditions:default": [],
-    })
+    }),
 )
 
 cc_test(
@@ -155,11 +157,11 @@
         "googletest/samples/sample7_unittest.cc",
         "googletest/samples/sample8_unittest.cc",
     ],
+    linkstatic = 0,
     deps = [
         "gtest_sample_lib",
         ":gtest_main",
     ],
-    linkstatic = 0,
 )
 
 cc_test(
diff --git a/WORKSPACE b/WORKSPACE
index b69578b..2289bdb 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -8,3 +8,16 @@
      urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
      strip_prefix = "abseil-cpp-master",
 )
+
+http_archive(
+    name = "rules_cc",
+    strip_prefix = "rules_cc-master",
+    urls = ["https://github.com/bazelbuild/rules_cc/archive/master.zip"],
+)
+
+http_archive(
+    name = "rules_python",
+    strip_prefix = "rules_python-master",
+    urls = ["https://github.com/bazelbuild/rules_python/archive/master.zip"],
+)
+
diff --git a/appveyor.yml b/appveyor.yml
index 6ef08fd..a58b768 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -58,7 +58,7 @@
 
     # install Bazel
     if ($env:build_system -eq "bazel") {
-        appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/0.21.0/bazel-0.21.0-windows-x86_64.exe -FileName bazel.exe
+        appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/0.28.1/bazel-0.28.1-windows-x86_64.exe -FileName bazel.exe
     }
 
     if ($env:build_system -eq "cmake") {
diff --git a/ci/build-linux-bazel.sh b/ci/build-linux-bazel.sh
index 3f1c784..ae8fb75 100755
--- a/ci/build-linux-bazel.sh
+++ b/ci/build-linux-bazel.sh
@@ -31,6 +31,7 @@
 
 set -e
 
+bazel version
 bazel build --curses=no //...:all
 bazel test --curses=no //...:all
 bazel test --curses=no //...:all --define absl=1
diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt
index f75ec45..d32b70b 100644
--- a/googlemock/CMakeLists.txt
+++ b/googlemock/CMakeLists.txt
@@ -150,6 +150,14 @@
 & $args")
   endif()
 
+  if (MINGW OR CYGWIN)
+    if (CMAKE_VERSION VERSION_LESS "2.8.12")
+      add_compile_options("-Wa,-mbig-obj")
+    else()
+      add_definitions("-Wa,-mbig-obj")
+    endif()
+  endif()
+
   ############################################################
   # C++ tests built with standard compiler flags.
 
@@ -162,9 +170,6 @@
   cxx_test(gmock-generated-matchers_test gmock_main)
   cxx_test(gmock-internal-utils_test gmock_main)
   cxx_test(gmock-matchers_test gmock_main)
-  if (MINGW OR CYGWIN)
-    target_compile_options(gmock-matchers_test PRIVATE "-Wa,-mbig-obj")
-  endif()
   cxx_test(gmock-more-actions_test gmock_main)
   cxx_test(gmock-nice-strict_test gmock_main)
   cxx_test(gmock-port_test gmock_main)
diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md
index 37c808f..239a4c6 100644
--- a/googlemock/docs/cheat_sheet.md
+++ b/googlemock/docs/cheat_sheet.md
@@ -312,8 +312,9 @@
 
 `ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
 use the regular expression syntax defined
-[here](advanced.md#regular-expression-syntax). `StrCaseEq()`, `StrCaseNe()`,
-`StrEq()`, and `StrNe()` work for wide strings as well.
+[here](../../googletest/docs/advanced.md#regular-expression-syntax).
+`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide strings as
+well.
 
 #### Container Matchers
 
diff --git a/googlemock/docs/cook_book.md b/googlemock/docs/cook_book.md
index 923817e..28f7ba1 100644
--- a/googlemock/docs/cook_book.md
+++ b/googlemock/docs/cook_book.md
@@ -178,7 +178,7 @@
 #### Mocking Non-virtual Methods {#MockingNonVirtualMethods}
 
 gMock can mock non-virtual functions to be used in Hi-perf dependency
-injection.<!-- GOOGLETEST_CM0017 DO NOT DELETE -->.
+injection.<!-- GOOGLETEST_CM0017 DO NOT DELETE -->
 
 In this case, instead of sharing a common base class with the real class, your
 mock class will be *unrelated* to the real class, but contain methods with the
diff --git a/googlemock/docs/for_dummies.md b/googlemock/docs/for_dummies.md
index 9107282..e11c18d 100644
--- a/googlemock/docs/for_dummies.md
+++ b/googlemock/docs/for_dummies.md
@@ -375,7 +375,7 @@
 the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be
 equal (using `operator==`) to the matcher argument. There are many
 [built-in matchers](#MatcherList) for common types (as well as
-[custom matchers](#NewMatchers)); for example:
+[custom matchers](cook_book.md#NewMatchers)); for example:
 
 ```cpp
 using ::testing::Ge;
@@ -396,7 +396,8 @@
 
 This works for all non-overloaded methods; if a method is overloaded, you need
 to help gMock resolve which overload is expected by specifying the number of
-arguments and possibly also the [types of the arguments](#SelectOverload).
+arguments and possibly also the
+[types of the arguments](cook_book.md#SelectOverload).
 
 #### Cardinalities: How Many Times Will It Be Called?
 
@@ -482,7 +483,7 @@
 
 What can we do inside `WillOnce()` besides `Return()`? You can return a
 reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among
-[others](#ActionList).
+[others](cook_book.md#using-actions).
 
 **Important note:** The `EXPECT_CALL()` statement evaluates the action clause
 only once, even though the action may be performed many times. Therefore you
@@ -560,7 +561,7 @@
 for methods that are not mentioned at all (these are "uninteresting"), but is
 useful for methods that have some expectations, but for which other calls are
 ok. See
-[Understanding Uninteresting vs Unexpected Calls](#uninteresting-vs-unexpected).
+[Understanding Uninteresting vs Unexpected Calls](cook_book.md#uninteresting-vs-unexpected).
 
 #### Ordered vs Unordered Calls {#OrderedCalls}
 
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index e921cf4..9605c43 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -532,7 +532,7 @@
     // in the Impl class. But both definitions must be the same.
     typedef typename Function<F>::Result Result;
     GTEST_COMPILE_ASSERT_(
-        !is_reference<Result>::value,
+        !std::is_reference<Result>::value,
         use_ReturnRef_instead_of_Return_to_return_a_reference);
     static_assert(!std::is_void<Result>::value,
                   "Can't use Return() on an action expected to return `void`.");
@@ -561,7 +561,7 @@
     Result Perform(const ArgumentTuple&) override { return value_; }
 
    private:
-    GTEST_COMPILE_ASSERT_(!is_reference<Result>::value,
+    GTEST_COMPILE_ASSERT_(!std::is_reference<Result>::value,
                           Result_cannot_be_a_reference_type);
     // We save the value before casting just in case it is being cast to a
     // wrapper type.
@@ -640,7 +640,7 @@
     // Asserts that the function return type is a reference.  This
     // catches the user error of using ReturnRef(x) when Return(x)
     // should be used, and generates some helpful error message.
-    GTEST_COMPILE_ASSERT_(internal::is_reference<Result>::value,
+    GTEST_COMPILE_ASSERT_(std::is_reference<Result>::value,
                           use_Return_instead_of_ReturnRef_to_return_a_value);
     return Action<F>(new Impl<F>(ref_));
   }
@@ -687,7 +687,7 @@
     // catches the user error of using ReturnRefOfCopy(x) when Return(x)
     // should be used, and generates some helpful error message.
     GTEST_COMPILE_ASSERT_(
-        internal::is_reference<Result>::value,
+        std::is_reference<Result>::value,
         use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
     return Action<F>(new Impl<F>(value_));
   }
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index 7075082..5fe3820 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -280,7 +280,7 @@
     // Enforce that we are not converting a non-reference type T to a reference
     // type U.
     GTEST_COMPILE_ASSERT_(
-        internal::is_reference<T>::value || !internal::is_reference<U>::value,
+        std::is_reference<T>::value || !std::is_reference<U>::value,
         cannot_convert_non_reference_arg_to_reference);
     // In case both T and U are arithmetic types, enforce that the
     // conversion is not lossy.
@@ -1610,8 +1610,9 @@
   template <typename Pointer>
   class Impl : public MatcherInterface<Pointer> {
    public:
-    typedef typename PointeeOf<GTEST_REMOVE_CONST_(  // NOLINT
-        GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee;
+    typedef
+        typename PointeeOf<typename std::remove_const<GTEST_REMOVE_REFERENCE_(
+            Pointer)>::type>::type Pointee;
 
     explicit Impl(const InnerMatcher& matcher)
         : matcher_(MatcherCast<const Pointee&>(matcher)) {}
@@ -1749,8 +1750,8 @@
     // FIXME: The dispatch on std::is_pointer was introduced as a workaround for
     // a compiler bug, and can now be removed.
     return MatchAndExplainImpl(
-        typename std::is_pointer<GTEST_REMOVE_CONST_(T)>::type(), value,
-        listener);
+        typename std::is_pointer<typename std::remove_const<T>::type>::type(),
+        value, listener);
   }
 
  private:
@@ -1816,8 +1817,8 @@
   template <typename T>
   bool MatchAndExplain(const T&value, MatchResultListener* listener) const {
     return MatchAndExplainImpl(
-        typename std::is_pointer<GTEST_REMOVE_CONST_(T)>::type(), value,
-        listener);
+        typename std::is_pointer<typename std::remove_const<T>::type>::type(),
+        value, listener);
   }
 
  private:
@@ -2093,9 +2094,8 @@
   template <typename LhsContainer>
   bool MatchAndExplain(const LhsContainer& lhs,
                        MatchResultListener* listener) const {
-    // GTEST_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug
-    // that causes LhsContainer to be a const type sometimes.
-    typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)>
+    typedef internal::StlContainerView<
+        typename std::remove_const<LhsContainer>::type>
         LhsView;
     typedef typename LhsView::type LhsStlContainer;
     StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
@@ -4034,12 +4034,12 @@
 // values that are included in one container but not the other. (Duplicate
 // values and order differences are not explained.)
 template <typename Container>
-inline PolymorphicMatcher<internal::ContainerEqMatcher<  // NOLINT
-                            GTEST_REMOVE_CONST_(Container)> >
-    ContainerEq(const Container& rhs) {
+inline PolymorphicMatcher<internal::ContainerEqMatcher<
+    typename std::remove_const<Container>::type>>
+ContainerEq(const Container& rhs) {
   // This following line is for working around a bug in MSVC 8.0,
   // which causes Container to be a const type sometimes.
-  typedef GTEST_REMOVE_CONST_(Container) RawContainer;
+  typedef typename std::remove_const<Container>::type RawContainer;
   return MakePolymorphicMatcher(
       internal::ContainerEqMatcher<RawContainer>(rhs));
 }
@@ -4072,12 +4072,12 @@
 // LHS container and the RHS container respectively.
 template <typename TupleMatcher, typename Container>
 inline internal::PointwiseMatcher<TupleMatcher,
-                                  GTEST_REMOVE_CONST_(Container)>
+                                  typename std::remove_const<Container>::type>
 Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
   // This following line is for working around a bug in MSVC 8.0,
   // which causes Container to be a const type sometimes (e.g. when
   // rhs is a const int[])..
-  typedef GTEST_REMOVE_CONST_(Container) RawContainer;
+  typedef typename std::remove_const<Container>::type RawContainer;
   return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
       tuple_matcher, rhs);
 }
@@ -4105,14 +4105,15 @@
 template <typename Tuple2Matcher, typename RhsContainer>
 inline internal::UnorderedElementsAreArrayMatcher<
     typename internal::BoundSecondMatcher<
-        Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_(
-                           RhsContainer)>::type::value_type> >
+        Tuple2Matcher,
+        typename internal::StlContainerView<
+            typename std::remove_const<RhsContainer>::type>::type::value_type>>
 UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
                    const RhsContainer& rhs_container) {
   // This following line is for working around a bug in MSVC 8.0,
   // which causes RhsContainer to be a const type sometimes (e.g. when
   // rhs_container is a const int[]).
-  typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer;
+  typedef typename std::remove_const<RhsContainer>::type RawRhsContainer;
 
   // RhsView allows the same code to handle RhsContainer being a
   // STL-style container and it being a native C-style array.
diff --git a/googlemock/include/gmock/gmock-more-actions.h b/googlemock/include/gmock/gmock-more-actions.h
index a052495..d42484a 100644
--- a/googlemock/include/gmock/gmock-more-actions.h
+++ b/googlemock/include/gmock/gmock-more-actions.h
@@ -105,7 +105,7 @@
   // Ensures that argument #k is a reference.  If you get a compiler
   // error on the next line, you are using SetArgReferee<k>(value) in
   // a mock function whose k-th (0-based) argument is not a reference.
-  GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
+  GTEST_COMPILE_ASSERT_(std::is_reference<argk_type>::value,
                         SetArgReferee_must_be_used_with_a_reference_argument);
   ::std::get<k>(args) = value;
 }
diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h
index 735a3bc..0d1adda 100644
--- a/googlemock/include/gmock/gmock-spec-builders.h
+++ b/googlemock/include/gmock/gmock-spec-builders.h
@@ -67,6 +67,7 @@
 #include <set>
 #include <sstream>
 #include <string>
+#include <type_traits>
 #include <utility>
 #include <vector>
 #include "gmock/gmock-actions.h"
@@ -1653,9 +1654,8 @@
     const OnCallSpec<F>* const spec = FindOnCallSpec(args);
 
     if (spec == nullptr) {
-      *os << (internal::type_equals<Result, void>::value ?
-              "returning directly.\n" :
-              "returning default value.\n");
+      *os << (std::is_void<Result>::value ? "returning directly.\n"
+                                          : "returning default value.\n");
     } else {
       *os << "taking default action specified at:\n"
           << FormatFileLocation(spec->file(), spec->line()) << "\n";
diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h
index ee00479..c49e28e 100644
--- a/googlemock/include/gmock/internal/gmock-internal-utils.h
+++ b/googlemock/include/gmock/internal/gmock-internal-utils.h
@@ -106,25 +106,6 @@
 # define GMOCK_WCHAR_T_IS_NATIVE_ 1
 #endif
 
-// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
-// Using them is a bad practice and not portable.  So DON'T use them.
-//
-// Still, Google Mock is designed to work even if the user uses signed
-// wchar_t or unsigned wchar_t (obviously, assuming the compiler
-// supports them).
-//
-// To gcc,
-//   wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
-//
-// gcc-9 appears to treat signed/unsigned wchar_t as ill-formed
-// regardless of the signage of its underlying type.
-#ifdef __GNUC__
-#if !defined(__WCHAR_UNSIGNED__) && (__GNUC__ < 9)
-// signed/unsigned wchar_t are valid types.
-# define GMOCK_HAS_SIGNED_WCHAR_T_ 1
-#endif
-#endif
-
 // In what follows, we use the term "kind" to indicate whether a type
 // is bool, an integer type (excluding bool), a floating-point type,
 // or none of them.  This categorization is useful for determining
@@ -355,14 +336,6 @@
 
 // Type traits.
 
-// is_reference<T>::value is non-zero if T is a reference type.
-template <typename T> struct is_reference : public false_type {};
-template <typename T> struct is_reference<T&> : public true_type {};
-
-// type_equals<T1, T2>::value is non-zero if T1 and T2 are the same type.
-template <typename T1, typename T2> struct type_equals : public false_type {};
-template <typename T> struct type_equals<T, T> : public true_type {};
-
 // remove_reference<T>::type removes the reference from type T, if any.
 template <typename T> struct remove_reference { typedef T type; };  // NOLINT
 template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
@@ -429,8 +402,8 @@
 
   static const_reference ConstReference(const RawContainer& container) {
     // Ensures that RawContainer is not a const type.
-    testing::StaticAssertTypeEq<RawContainer,
-        GTEST_REMOVE_CONST_(RawContainer)>();
+    testing::StaticAssertTypeEq<
+        RawContainer, typename std::remove_const<RawContainer>::type>();
     return container;
   }
   static type Copy(const RawContainer& container) { return container; }
@@ -440,7 +413,7 @@
 template <typename Element, size_t N>
 class StlContainerView<Element[N]> {
  public:
-  typedef GTEST_REMOVE_CONST_(Element) RawElement;
+  typedef typename std::remove_const<Element>::type RawElement;
   typedef internal::NativeArray<RawElement> type;
   // NativeArray<T> can represent a native array either by value or by
   // reference (selected by a constructor argument), so 'const type'
@@ -464,8 +437,8 @@
 template <typename ElementPointer, typename Size>
 class StlContainerView< ::std::tuple<ElementPointer, Size> > {
  public:
-  typedef GTEST_REMOVE_CONST_(
-      typename internal::PointeeOf<ElementPointer>::type) RawElement;
+  typedef typename std::remove_const<
+      typename internal::PointeeOf<ElementPointer>::type>::type RawElement;
   typedef internal::NativeArray<RawElement> type;
   typedef const type const_reference;
 
diff --git a/googlemock/test/BUILD.bazel b/googlemock/test/BUILD.bazel
index e74102f..da95ed5 100644
--- a/googlemock/test/BUILD.bazel
+++ b/googlemock/test/BUILD.bazel
@@ -32,6 +32,9 @@
 #
 #   Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
 
+load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
+load("@rules_python//python:defs.bzl", "py_library", "py_test")
+
 licenses(["notice"])
 
 # Tests for GMock itself
diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc
index f761b44..f63c8c5 100644
--- a/googlemock/test/gmock-actions_test.cc
+++ b/googlemock/test/gmock-actions_test.cc
@@ -105,10 +105,6 @@
   EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get());
   EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
   EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
-#if GMOCK_HAS_SIGNED_WCHAR_T_
-  EXPECT_EQ(0U, BuiltInDefaultValue<unsigned wchar_t>::Get());
-  EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get());
-#endif
 #if GMOCK_WCHAR_T_IS_NATIVE_
 #if !defined(__WCHAR_UNSIGNED__)
   EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
@@ -137,10 +133,6 @@
   EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists());
   EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists());
   EXPECT_TRUE(BuiltInDefaultValue<char>::Exists());
-#if GMOCK_HAS_SIGNED_WCHAR_T_
-  EXPECT_TRUE(BuiltInDefaultValue<unsigned wchar_t>::Exists());
-  EXPECT_TRUE(BuiltInDefaultValue<signed wchar_t>::Exists());
-#endif
 #if GMOCK_WCHAR_T_IS_NATIVE_
   EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists());
 #endif
diff --git a/googlemock/test/gmock-internal-utils_test.cc b/googlemock/test/gmock-internal-utils_test.cc
index a76e777..67865c2 100644
--- a/googlemock/test/gmock-internal-utils_test.cc
+++ b/googlemock/test/gmock-internal-utils_test.cc
@@ -38,6 +38,7 @@
 #include <memory>
 #include <string>
 #include <sstream>
+#include <type_traits>
 #include <vector>
 #include "gmock/gmock.h"
 #include "gmock/internal/gmock-port.h"
@@ -512,25 +513,12 @@
   EXPECT_FALSE(false_type::value);
 }
 
-TEST(TypeTraitsTest, is_reference) {
-  EXPECT_FALSE(is_reference<int>::value);
-  EXPECT_FALSE(is_reference<char*>::value);
-  EXPECT_TRUE(is_reference<const int&>::value);
-}
-
-TEST(TypeTraitsTest, type_equals) {
-  EXPECT_FALSE((type_equals<int, const int>::value));
-  EXPECT_FALSE((type_equals<int, int&>::value));
-  EXPECT_FALSE((type_equals<int, double>::value));
-  EXPECT_TRUE((type_equals<char, char>::value));
-}
-
 TEST(TypeTraitsTest, remove_reference) {
-  EXPECT_TRUE((type_equals<char, remove_reference<char&>::type>::value));
-  EXPECT_TRUE((type_equals<const int,
-               remove_reference<const int&>::type>::value));
-  EXPECT_TRUE((type_equals<int, remove_reference<int>::type>::value));
-  EXPECT_TRUE((type_equals<double*, remove_reference<double*>::type>::value));
+  EXPECT_TRUE((std::is_same<char, remove_reference<char&>::type>::value));
+  EXPECT_TRUE(
+      (std::is_same<const int, remove_reference<const int&>::type>::value));
+  EXPECT_TRUE((std::is_same<int, remove_reference<int>::type>::value));
+  EXPECT_TRUE((std::is_same<double*, remove_reference<double*>::type>::value));
 }
 
 #if GTEST_HAS_STREAM_REDIRECTION
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index 74e9294..a61d040 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -6434,7 +6434,7 @@
 
   template <typename T>
   friend bool holds_alternative(const SampleVariantIntString& value) {
-    return value.has_int_ == internal::IsSame<T, int>::value;
+    return value.has_int_ == std::is_same<T, int>::value;
   }
 
   template <typename T>
diff --git a/googletest/docs/advanced.md b/googletest/docs/advanced.md
index e05d317..51005e9 100644
--- a/googletest/docs/advanced.md
+++ b/googletest/docs/advanced.md
@@ -543,8 +543,6 @@
 do that, define `<<` for your type:
 
 ```c++
-// Streams are allowed only for logging.  Don't include this for
-// any other purpose.
 #include <ostream>
 
 namespace foo {
@@ -573,8 +571,6 @@
 define a `PrintTo()` function like this:
 
 ```c++
-// Streams are allowed only for logging.  Don't include this for
-// any other purpose.
 #include <ostream>
 
 namespace foo {
diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h
index 5eb0a4e..c10d650 100644
--- a/googletest/include/gtest/gtest-matchers.h
+++ b/googletest/include/gtest/gtest-matchers.h
@@ -300,7 +300,7 @@
   template <typename U>
   explicit MatcherBase(
       const MatcherInterface<U>* impl,
-      typename std::enable_if<!internal::IsSame<U, const U&>::value>::type* =
+      typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
           nullptr)
       : impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
 
@@ -336,7 +336,7 @@
   template <typename U>
   explicit Matcher(
       const MatcherInterface<U>* impl,
-      typename std::enable_if<!internal::IsSame<U, const U&>::value>::type* =
+      typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
           nullptr)
       : internal::MatcherBase<T>(impl) {}
 
diff --git a/googletest/include/gtest/gtest-typed-test.h b/googletest/include/gtest/gtest-typed-test.h
index 25c2613..095ce05 100644
--- a/googletest/include/gtest/gtest-typed-test.h
+++ b/googletest/include/gtest/gtest-typed-test.h
@@ -188,9 +188,6 @@
 #define GTEST_NAME_GENERATOR_(TestSuiteName) \
   gtest_type_params_##TestSuiteName##_NameGenerator
 
-// The 'Types' template argument below must have spaces around it
-// since some compilers may choke on '>>' when passing a template
-// instance (e.g. Types<int>)
 #define TYPED_TEST_SUITE(CaseName, Types, ...)                           \
   typedef ::testing::internal::TypeList<Types>::type GTEST_TYPE_PARAMS_( \
       CaseName);                                                         \
@@ -306,9 +303,6 @@
   REGISTER_TYPED_TEST_SUITE_P
 #endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
-// The 'Types' template argument below must have spaces around it
-// since some compilers may choke on '>>' when passing a template
-// instance (e.g. Types<int>)
 #define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)       \
   static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ =        \
       ::testing::internal::TypeParameterizedTestSuite<                      \
diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h
index 8b05062..3313445 100644
--- a/googletest/include/gtest/internal/gtest-internal.h
+++ b/googletest/include/gtest/internal/gtest-internal.h
@@ -869,30 +869,9 @@
 #define GTEST_REMOVE_REFERENCE_(T) \
     typename ::testing::internal::RemoveReference<T>::type
 
-// Removes const from a type if it is a const type, otherwise leaves
-// it unchanged.  This is the same as tr1::remove_const, which is not
-// widely available yet.
-template <typename T>
-struct RemoveConst { typedef T type; };  // NOLINT
-template <typename T>
-struct RemoveConst<const T> { typedef T type; };  // NOLINT
-
-// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above
-// definition to fail to remove the const in 'const int[3]' and 'const
-// char[3][4]'.  The following specialization works around the bug.
-template <typename T, size_t N>
-struct RemoveConst<const T[N]> {
-  typedef typename RemoveConst<T>::type type[N];
-};
-
-// A handy wrapper around RemoveConst that works when the argument
-// T depends on template parameters.
-#define GTEST_REMOVE_CONST_(T) \
-    typename ::testing::internal::RemoveConst<T>::type
-
 // Turns const U&, U&, const U, and U all into U.
 #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
-    GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
+  typename std::remove_const<GTEST_REMOVE_REFERENCE_(T)>::type
 
 // IsAProtocolMessage<T>::value is a compile-time bool constant that's
 // true if T is type proto2::Message or a subclass of it.
@@ -977,9 +956,9 @@
 struct IsRecursiveContainerImpl<C, true> {
   using value_type = decltype(*std::declval<typename C::const_iterator>());
   using type =
-      is_same<typename std::remove_const<
-                  typename std::remove_reference<value_type>::type>::type,
-              C>;
+      std::is_same<typename std::remove_const<
+                       typename std::remove_reference<value_type>::type>::type,
+                   C>;
 };
 
 // IsRecursiveContainer<Type> is a unary compile-time predicate that
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
index 4f887c5..7f00fe7 100644
--- a/googletest/include/gtest/internal/gtest-port.h
+++ b/googletest/include/gtest/internal/gtest-port.h
@@ -869,16 +869,6 @@
   enum { value = true };
 };
 
-// Same as std::is_same<>.
-template <typename T, typename U>
-struct IsSame {
-  enum { value = false };
-};
-template <typename T>
-struct IsSame<T, T> {
-  enum { value = true };
-};
-
 // Evaluates to the number of elements in 'array'.
 #define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
 
@@ -1931,12 +1921,6 @@
 typedef bool_constant<false> false_type;
 typedef bool_constant<true> true_type;
 
-template <typename T, typename U>
-struct is_same : public false_type {};
-
-template <typename T>
-struct is_same<T, T> : public true_type {};
-
 template <typename Iterator>
 struct IteratorTraits {
   typedef typename Iterator::value_type value_type;
diff --git a/googletest/include/gtest/internal/gtest-type-util.h b/googletest/include/gtest/internal/gtest-type-util.h
index 5f9a056..3d7542d 100644
--- a/googletest/include/gtest/internal/gtest-type-util.h
+++ b/googletest/include/gtest/internal/gtest-type-util.h
@@ -105,18 +105,6 @@
 
 #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
 
-// AssertyTypeEq<T1, T2>::type is defined if T1 and T2 are the same
-// type.  This can be used as a compile-time assertion to ensure that
-// two types are equal.
-
-template <typename T1, typename T2>
-struct AssertTypeEq;
-
-template <typename T>
-struct AssertTypeEq<T, T> {
-  typedef bool type;
-};
-
 // A unique type used as the default value for the arguments of class
 // template Types.  This allows us to simulate variadic templates
 // (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
diff --git a/googletest/include/gtest/internal/gtest-type-util.h.pump b/googletest/include/gtest/internal/gtest-type-util.h.pump
index 3a3896b..5e31b7b 100644
--- a/googletest/include/gtest/internal/gtest-type-util.h.pump
+++ b/googletest/include/gtest/internal/gtest-type-util.h.pump
@@ -104,18 +104,6 @@
 
 #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
 
-// AssertyTypeEq<T1, T2>::type is defined if T1 and T2 are the same
-// type.  This can be used as a compile-time assertion to ensure that
-// two types are equal.
-
-template <typename T1, typename T2>
-struct AssertTypeEq;
-
-template <typename T>
-struct AssertTypeEq<T, T> {
-  typedef bool type;
-};
-
 // A unique type used as the default value for the arguments of class
 // template Types.  This allows us to simulate variadic templates
 // (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel
index 45dff30..156d5d4 100644
--- a/googletest/test/BUILD.bazel
+++ b/googletest/test/BUILD.bazel
@@ -32,6 +32,9 @@
 #
 # Bazel BUILD for The Google C++ Testing Framework (Google Test)
 
+load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
+load("@rules_python//python:defs.bzl", "py_library", "py_test")
+
 licenses(["notice"])
 
 #on windows exclude gtest-tuple.h
diff --git a/googletest/test/googletest-output-test_.cc b/googletest/test/googletest-output-test_.cc
index 83be568..4f716d8 100644
--- a/googletest/test/googletest-output-test_.cc
+++ b/googletest/test/googletest-output-test_.cc
@@ -816,9 +816,9 @@
  public:
   template <typename T>
   static std::string GetName(int i) {
-    if (testing::internal::IsSame<T, char>::value)
+    if (std::is_same<T, char>::value)
       return std::string("char") + ::testing::PrintToString(i);
-    if (testing::internal::IsSame<T, int>::value)
+    if (std::is_same<T, int>::value)
       return std::string("int") + ::testing::PrintToString(i);
   }
 };
@@ -857,10 +857,10 @@
  public:
   template <typename T>
   static std::string GetName(int i) {
-    if (testing::internal::IsSame<T, unsigned char>::value) {
+    if (std::is_same<T, unsigned char>::value) {
       return std::string("unsignedChar") + ::testing::PrintToString(i);
     }
-    if (testing::internal::IsSame<T, unsigned int>::value) {
+    if (std::is_same<T, unsigned int>::value) {
       return std::string("unsignedInt") + ::testing::PrintToString(i);
     }
   }
diff --git a/googletest/test/gtest-typed-test_test.cc b/googletest/test/gtest-typed-test_test.cc
index f1ca937..5411832 100644
--- a/googletest/test/gtest-typed-test_test.cc
+++ b/googletest/test/gtest-typed-test_test.cc
@@ -31,6 +31,7 @@
 #include "test/gtest-typed-test_test.h"
 
 #include <set>
+#include <type_traits>
 #include <vector>
 
 #include "gtest/gtest.h"
@@ -177,10 +178,10 @@
  public:
   template <typename T>
   static std::string GetName(int i) {
-    if (testing::internal::IsSame<T, char>::value) {
+    if (std::is_same<T, char>::value) {
       return std::string("char") + ::testing::PrintToString(i);
     }
-    if (testing::internal::IsSame<T, int>::value) {
+    if (std::is_same<T, int>::value) {
       return std::string("int") + ::testing::PrintToString(i);
     }
   }
@@ -189,13 +190,13 @@
 TYPED_TEST_SUITE(TypedTestWithNames, TwoTypes, TypedTestNames);
 
 TYPED_TEST(TypedTestWithNames, TestSuiteName) {
-  if (testing::internal::IsSame<TypeParam, char>::value) {
+  if (std::is_same<TypeParam, char>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
                      ->test_case_name(),
                  "TypedTestWithNames/char0");
   }
-  if (testing::internal::IsSame<TypeParam, int>::value) {
+  if (std::is_same<TypeParam, int>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
                      ->test_case_name(),
@@ -311,13 +312,13 @@
 TYPED_TEST_SUITE_P(TypeParametrizedTestWithNames);
 
 TYPED_TEST_P(TypeParametrizedTestWithNames, TestSuiteName) {
-  if (testing::internal::IsSame<TypeParam, char>::value) {
+  if (std::is_same<TypeParam, char>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
                      ->test_case_name(),
                  "CustomName/TypeParametrizedTestWithNames/parChar0");
   }
-  if (testing::internal::IsSame<TypeParam, int>::value) {
+  if (std::is_same<TypeParam, int>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
                      ->test_case_name(),
@@ -331,10 +332,10 @@
  public:
   template <typename T>
   static std::string GetName(int i) {
-    if (testing::internal::IsSame<T, char>::value) {
+    if (std::is_same<T, char>::value) {
       return std::string("parChar") + ::testing::PrintToString(i);
     }
-    if (testing::internal::IsSame<T, int>::value) {
+    if (std::is_same<T, int>::value) {
       return std::string("parInt") + ::testing::PrintToString(i);
     }
   }
diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc
index 2b00b70..0047f53 100644
--- a/googletest/test/gtest_unittest.cc
+++ b/googletest/test/gtest_unittest.cc
@@ -61,9 +61,10 @@
 #include <time.h>
 
 #include <map>
-#include <vector>
 #include <ostream>
+#include <type_traits>
 #include <unordered_set>
+#include <vector>
 
 #include "gtest/gtest-spi.h"
 #include "src/gtest-internal-inl.h"
@@ -262,7 +263,6 @@
 using testing::internal::ParseInt32Flag;
 using testing::internal::RelationToSourceCopy;
 using testing::internal::RelationToSourceReference;
-using testing::internal::RemoveConst;
 using testing::internal::RemoveReference;
 using testing::internal::ShouldRunTestOnShard;
 using testing::internal::ShouldShard;
@@ -7135,33 +7135,6 @@
   TestGTestRemoveReference<const char, const char&>();
 }
 
-
-// Tests that RemoveConst does not affect non-const types.
-TEST(RemoveConstTest, DoesNotAffectNonConstType) {
-  CompileAssertTypesEqual<int, RemoveConst<int>::type>();
-  CompileAssertTypesEqual<char&, RemoveConst<char&>::type>();
-}
-
-// Tests that RemoveConst removes const from const types.
-TEST(RemoveConstTest, RemovesConst) {
-  CompileAssertTypesEqual<int, RemoveConst<const int>::type>();
-  CompileAssertTypesEqual<char[2], RemoveConst<const char[2]>::type>();
-  CompileAssertTypesEqual<char[2][3], RemoveConst<const char[2][3]>::type>();
-}
-
-// Tests GTEST_REMOVE_CONST_.
-
-template <typename T1, typename T2>
-void TestGTestRemoveConst() {
-  CompileAssertTypesEqual<T1, GTEST_REMOVE_CONST_(T2)>();
-}
-
-TEST(RemoveConstTest, MacroVersion) {
-  TestGTestRemoveConst<int, int>();
-  TestGTestRemoveConst<double&, double&>();
-  TestGTestRemoveConst<char, const char>();
-}
-
 // Tests GTEST_REMOVE_REFERENCE_AND_CONST_.
 
 template <typename T1, typename T2>