Merge pull request #5041 from alvinjaison:fix/get-test-suite-shuffle-index

PiperOrigin-RevId: 955317170
Change-Id: I40e01cdafe58768ccdb743dcf38717e48edcde41
diff --git a/docs/gmock_cheat_sheet.md b/docs/gmock_cheat_sheet.md
index 6215999..dd63226 100644
--- a/docs/gmock_cheat_sheet.md
+++ b/docs/gmock_cheat_sheet.md
@@ -153,7 +153,7 @@
   EXPECT_NE(buzz1, buzz2);
 
   // Resets the default action for return type std::unique_ptr<Buzz>,
-  // to avoid interfere with other tests.
+  // to avoid interfering with other tests.
   DefaultValue<std::unique_ptr<Buzz>>::Clear();
 ```
 
diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt
index 99b2411..33ec963 100644
--- a/googlemock/CMakeLists.txt
+++ b/googlemock/CMakeLists.txt
@@ -105,10 +105,10 @@
 string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}")
 target_include_directories(gmock SYSTEM INTERFACE
   "$<BUILD_INTERFACE:${dirs}>"
-  "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
+  "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
 target_include_directories(gmock_main SYSTEM INTERFACE
   "$<BUILD_INTERFACE:${dirs}>"
-  "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
+  "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
 
 ########################################################################
 #
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index 687da5c..b0a6bde 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -427,21 +427,20 @@
   // via StdFunctionAdaptor.
   template <typename Callable>
   using IsDirectlyCompatible = internal::conjunction<
-      // It must be possible to capture the callable in StdFunctionAdaptor.
-      std::is_constructible<typename std::decay<Callable>::type, Callable>,
       // The callable must be compatible with our signature.
-      internal::is_callable_r<Result, typename std::decay<Callable>::type,
-                              Args...>>;
+      internal::is_callable_r<Result, std::decay_t<Callable>, Args...>,
+      // It must be possible to capture the callable in StdFunctionAdaptor.
+      std::is_constructible<std::decay_t<Callable>, Callable>>;
 
   // True iff we can use the given callable type via StdFunctionAdaptor once we
   // ignore incoming arguments.
   template <typename Callable>
   using IsCompatibleAfterIgnoringArguments = internal::conjunction<
-      // It must be possible to capture the callable in a lambda.
-      std::is_constructible<typename std::decay<Callable>::type, Callable>,
       // The callable must be invocable with zero arguments, returning something
       // convertible to Result.
-      internal::is_callable_r<Result, typename std::decay<Callable>::type>>;
+      internal::is_callable_r<Result, std::decay_t<Callable>>,
+      // It must be possible to capture the callable in a lambda.
+      std::is_constructible<std::decay_t<Callable>, Callable>>;
 
  public:
   // Construct from a callable that is directly compatible with our mocked
diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc
index f0218b7..2a2aa55 100644
--- a/googlemock/test/gmock-actions_test.cc
+++ b/googlemock/test/gmock-actions_test.cc
@@ -1243,16 +1243,16 @@
 TEST(InvokeWithoutArgsTest, Functor) {
   GTEST_DISABLE_DEPRECATED_PUSH_()
   // As an action that takes no argument.
-  Action<int()> a = InvokeWithoutArgs(NullaryFunctor());  // NOLINT
+  Action<int()> a = NullaryFunctor();  // NOLINT
   EXPECT_EQ(2, a.Perform(std::make_tuple()));
 
   // As an action that takes three arguments.
   Action<int(int, double, char)> a2 =  // NOLINT
-      InvokeWithoutArgs(NullaryFunctor());
+      NullaryFunctor();
   EXPECT_EQ(2, a2.Perform(std::make_tuple(3, 3.5, 'a')));
 
   // As an action that returns void.
-  Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor());
+  Action<void()> a3 = VoidNullaryFunctor();
   g_done = false;
   a3.Perform(std::make_tuple());
   EXPECT_TRUE(g_done);
diff --git a/googlemock/test/gmock_link_test.h b/googlemock/test/gmock_link_test.h
index 6f749bb..c33723e 100644
--- a/googlemock/test/gmock_link_test.h
+++ b/googlemock/test/gmock_link_test.h
@@ -340,7 +340,7 @@
 
   GTEST_DISABLE_DEPRECATED_PUSH_()
   EXPECT_CALL(mock, VoidFromString(_))
-      .WillOnce(InvokeWithoutArgs(&InvokeHelper::StaticVoidFromVoid))
+      .WillOnce(&InvokeHelper::StaticVoidFromVoid)
       .WillOnce(
           InvokeWithoutArgs(&test_invoke_helper, &InvokeHelper::VoidFromVoid));
   GTEST_DISABLE_DEPRECATED_POP_()
diff --git a/googlemock/test/gmock_stress_test.cc b/googlemock/test/gmock_stress_test.cc
index 9e42cd9..f45cf67 100644
--- a/googlemock/test/gmock_stress_test.cc
+++ b/googlemock/test/gmock_stress_test.cc
@@ -30,6 +30,8 @@
 // Tests that Google Mock constructs can be used in a large number of
 // threads concurrently.
 
+#include <iterator>
+
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -188,7 +190,7 @@
       &TestPartiallyOrderedExpectationsWithThreads,
   };
 
-  const int kRoutines = sizeof(test_routines) / sizeof(test_routines[0]);
+  const int kRoutines = std::size(test_routines);
   const int kCopiesOfEachRoutine = kMaxTestThreads / kRoutines;
   const int kTestThreads = kCopiesOfEachRoutine * kRoutines;
   ThreadWithParam<Dummy>* threads[kTestThreads] = {};
diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt
index 2e53889..64c0510 100644
--- a/googletest/CMakeLists.txt
+++ b/googletest/CMakeLists.txt
@@ -140,10 +140,10 @@
 string(REPLACE ";" "$<SEMICOLON>" dirs "${gtest_build_include_dirs}")
 target_include_directories(gtest SYSTEM INTERFACE
   "$<BUILD_INTERFACE:${dirs}>"
-  "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
+  "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
 target_include_directories(gtest_main SYSTEM INTERFACE
   "$<BUILD_INTERFACE:${dirs}>"
-  "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
+  "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
 if(CMAKE_SYSTEM_NAME MATCHES "QNX" AND CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL 7.1)
   target_link_libraries(gtest PUBLIC regex)
 endif()
diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake
index da1923f..4ce3717 100644
--- a/googletest/cmake/internal_utils.cmake
+++ b/googletest/cmake/internal_utils.cmake
@@ -28,28 +28,19 @@
              CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
              CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
       if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
-        # When Google Test is built as a shared library, it should also use
-        # shared runtime libraries. Otherwise, it may end up with multiple
-        # copies of runtime library data in different modules, resulting in
-        # hard-to-find crashes. When it is built as a static library, it is
-        # preferable to use CRT as static libraries, as we don't have to rely
-        # on CRT DLLs being available. CMake always defaults to using shared
-        # CRT libraries, so we override that default here.
-        string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
-
         # When using Ninja with Clang, static builds pass -D_DLL on Windows.
         # This is incorrect and should not happen, so we fix that here.
-        string(REPLACE "-D_DLL" "" ${flag_var} "${${flag_var}}")
+        string(REGEX REPLACE "([/-])D_DLL" "" ${flag_var} "${${flag_var}}")
       endif()
 
       # We prefer more strict warning checking for building Google Test.
       # Replaces /W3 with /W4 in defaults.
-      string(REPLACE "/W3" "/W4" ${flag_var} "${${flag_var}}")
+      string(REGEX REPLACE "([/-])W3" "\\1W4" ${flag_var} "${${flag_var}}")
 
       # Prevent D9025 warning for targets that have exception handling
       # turned off (/EHs-c- flag). Where required, exceptions are explicitly
       # re-enabled using the cxx_exception_flags variable.
-      string(REPLACE "/EHsc" "" ${flag_var} "${${flag_var}}")
+      string(REGEX REPLACE "([/-])EHsc" "" ${flag_var} "${${flag_var}}")
     endforeach()
   endif()
 endmacro()
@@ -71,7 +62,19 @@
   endif()
 
   fix_default_compiler_settings_()
+  set(cxx_strict_flags "")
   if (MSVC)
+    # When Google Test is built as a shared library, it should also use shared
+    # runtime libraries. Otherwise, it may end up with multiple copies of
+    # runtime library data in different modules, resulting in hard-to-find
+    # crashes. When it is built as a static library, it is preferable to use CRT
+    # as static libraries, as we don't have to rely on CRT DLLs being available.
+    # CMake always defaults to using shared CRT libraries, so we override that
+    # default here.
+    if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
+      set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+    endif()
+
     # Newlines inside flags variables break CMake's NMake generator.
     # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.
     set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J")
@@ -101,7 +104,12 @@
       set(cxx_strict_flags "${cxx_strict_flags} -Wchar-subscripts")
     endif()
     if (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
-      set(cxx_base_flags "${cxx_base_flags} -Wno-implicit-float-size-conversion -ffp-model=precise")
+      set(cxx_base_flags "${cxx_base_flags} -ffp-model=precise")
+      if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2025.2.0)
+        set(cxx_base_flags "${cxx_base_flags} -Wno-implicit-float-size-conversion")
+      else()
+        set(cxx_base_flags "${cxx_base_flags} -Wno-sycl-implicit-float-size-conversion")
+      endif()
     endif()
   elseif (CMAKE_COMPILER_IS_GNUCXX)
     set(cxx_base_flags "-Wall -Wshadow -Wundef")
diff --git a/googletest/include/gtest/gtest-assertion-result.h b/googletest/include/gtest/gtest-assertion-result.h
index 7a5e223..a72ac93 100644
--- a/googletest/include/gtest/gtest-assertion-result.h
+++ b/googletest/include/gtest/gtest-assertion-result.h
@@ -158,13 +158,18 @@
   // The second parameter prevents this overload from being considered if
   // the argument is implicitly convertible to AssertionResult. In that case
   // we want AssertionResult's copy constructor to be used.
-  template <typename T>
-  explicit AssertionResult(
-      const T& success,
-      std::enable_if_t<!std::is_convertible_v<T, AssertionResult>>*
-      /*enabler*/
-      = nullptr)
-      : success_(success) {}
+  template <typename T,
+            std::enable_if_t<!std::is_convertible_v<T, AssertionResult> &&
+                                 !std::is_trivially_constructible_v<bool, T>,
+                             int> = 0>
+  explicit AssertionResult(T&& success) : success_(std::forward<T>(success)) {}
+
+  // Similar to the mutable overload, but for cases where mutability is
+  // unnecessary or problematic (e.g., bitfields).
+  template <typename T,
+            std::enable_if_t<!std::is_convertible_v<const T&, AssertionResult>,
+                             int> = 0>
+  explicit AssertionResult(const T& success) : success_(success) {}
 
 #if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
   GTEST_DISABLE_MSC_WARNINGS_POP_()
@@ -226,6 +231,24 @@
   std::unique_ptr< ::std::string> message_;
 };
 
+namespace internal {
+
+// A pair containing the result that an assertion is evaluating, and the
+// expected result (true, false).
+//
+// Contains a conversion operator that indicates whether the two match.
+struct AssertionResultExpectation {
+  testing::AssertionResult assertion_result;
+  bool expected_result;
+
+  explicit operator bool() const {
+    bool converted(assertion_result);
+    return converted == expected_result;
+  }
+};
+
+}  // namespace internal
+
 // Makes a successful assertion result.
 GTEST_API_ AssertionResult AssertionSuccess();
 
diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h
index a719337..089b10e 100644
--- a/googletest/include/gtest/gtest.h
+++ b/googletest/include/gtest/gtest.h
@@ -1818,14 +1818,13 @@
 #define GTEST_EXPECT_TRUE(condition)                      \
   GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
                       GTEST_NONFATAL_FAILURE_)
-#define GTEST_EXPECT_FALSE(condition)                        \
-  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+#define GTEST_EXPECT_FALSE(condition)                     \
+  GTEST_TEST_BOOLEAN_(condition, #condition, true, false, \
                       GTEST_NONFATAL_FAILURE_)
 #define GTEST_ASSERT_TRUE(condition) \
   GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)
-#define GTEST_ASSERT_FALSE(condition)                        \
-  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
-                      GTEST_FATAL_FAILURE_)
+#define GTEST_ASSERT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN_(condition, #condition, true, false, GTEST_FATAL_FAILURE_)
 
 // Define these macros to 1 to omit the definition of the corresponding
 // EXPECT or ASSERT, which clashes with some users' own code.
diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h
index 8f66d1b..2b048c5 100644
--- a/googletest/include/gtest/internal/gtest-internal.h
+++ b/googletest/include/gtest/internal/gtest-internal.h
@@ -1453,12 +1453,12 @@
 // representation of expression as it was passed into the EXPECT_TRUE.
 #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
   GTEST_AMBIGUOUS_ELSE_BLOCKER_                                       \
-  if (const ::testing::AssertionResult gtest_ar_ =                    \
-          ::testing::AssertionResult(expression))                     \
+  if (::testing::internal::AssertionResultExpectation gtest_are_ = {  \
+          ::testing::AssertionResult(expression), expected})          \
     ;                                                                 \
   else                                                                \
     fail(::testing::internal::GetBoolAssertionFailureMessage(         \
-        gtest_ar_, text, #actual, #expected))
+        gtest_are_.assertion_result, text, #actual, #expected))
 
 #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail)               \
   GTEST_AMBIGUOUS_ELSE_BLOCKER_                                     \
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
index df10ca6..31654b0 100644
--- a/googletest/include/gtest/internal/gtest-port.h
+++ b/googletest/include/gtest/internal/gtest-port.h
@@ -2308,22 +2308,29 @@
 
 // Macros for defining flags.
 #define GTEST_DEFINE_bool_(name, default_val, doc)  \
+  GTEST_DECLARE_bool_(name);                        \
   namespace testing {                               \
   GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
   }                                                 \
   static_assert(true, "no-op to require trailing semicolon")
 #define GTEST_DEFINE_int32_(name, default_val, doc)         \
+  GTEST_DECLARE_int32_(name);                               \
   namespace testing {                                       \
   GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \
   }                                                         \
   static_assert(true, "no-op to require trailing semicolon")
 #define GTEST_DEFINE_string_(name, default_val, doc)         \
+  GTEST_DECLARE_string_(name);                               \
   namespace testing {                                        \
   GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
   }                                                          \
   static_assert(true, "no-op to require trailing semicolon")
 
 // Macros for declaring flags.
+//
+// We also need to declare the flag in the public namespace to avoid triggering
+// -Wmissing-variable-declarations warnings, as reported here:
+// https://github.com/google/googletest/issues/4897
 #define GTEST_DECLARE_bool_(name)          \
   namespace testing {                      \
   GTEST_API_ extern bool GTEST_FLAG(name); \
diff --git a/googletest/samples/sample2_unittest.cc b/googletest/samples/sample2_unittest.cc
index cd734f9..b959a24 100644
--- a/googletest/samples/sample2_unittest.cc
+++ b/googletest/samples/sample2_unittest.cc
@@ -39,6 +39,8 @@
 
 #include "sample2.h"
 
+#include <iterator>
+
 #include "gtest/gtest.h"
 namespace {
 // In this example, we test the MyString class (a simple string).
@@ -78,7 +80,7 @@
 TEST(MyString, ConstructorFromCString) {
   const MyString s(kHelloString);
   EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
-  EXPECT_EQ(sizeof(kHelloString) / sizeof(kHelloString[0]) - 1, s.Length());
+  EXPECT_EQ(std::size(kHelloString) - 1, s.Length());
 }
 
 // Tests the copy c'tor.
diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h
index 28ab664..4bebca1 100644
--- a/googletest/src/gtest-internal-inl.h
+++ b/googletest/src/gtest-internal-inl.h
@@ -1106,7 +1106,7 @@
       GTEST_CHECK_(sockfd_ != -1)
           << "Send() can be called only when there is a connection.";
 
-      const auto len = static_cast<size_t>(message.length());
+      const size_t len = message.length();
       if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
         GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to "
                             << host_name_ << ":" << port_num_;
diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc
index 4f4f2d8..433586f 100644
--- a/googletest/src/gtest-port.cc
+++ b/googletest/src/gtest-port.cc
@@ -1095,10 +1095,12 @@
                                             0,  // Generate unique file name.
                                             temp_file_path);
     GTEST_CHECK_(success != 0)
-        << "Unable to create a temporary file in " << temp_dir_path;
+        << "Failed to create temporary file in " << temp_dir_path
+        << " with error " << ::GetLastError();
     const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
     GTEST_CHECK_(captured_fd != -1)
-        << "Unable to open temporary file " << temp_file_path;
+        << "Failed to open temporary file " << temp_file_path << " with error "
+        << ::GetLastError();
     filename_ = temp_file_path;
 #else
     // There's no guarantee that a test has write access to the current
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index b38f551..307ecc6 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -1209,7 +1209,7 @@
 // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
 std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
   return os_stack_trace_getter()->CurrentStackTrace(
-      static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1
+      GTEST_FLAG_GET(stack_trace_depth), skip_count + 1
       // Skips the user-specified number of frames plus this function
       // itself.
   );  // NOLINT
@@ -2700,7 +2700,7 @@
 }
 
 // Runs the given method and catches and reports C++ and/or SEH-style
-// exceptions, if they are supported; returns the 0-value for type
+// exceptions, if they are supported; returns the default-value for type
 // Result in case of an SEH exception.
 template <class T, typename Result>
 Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
@@ -2748,7 +2748,7 @@
           TestPartResult::kFatalFailure,
           FormatCxxExceptionMessage(nullptr, location));
     }
-    return static_cast<Result>(0);
+    return Result();
 #else
     return HandleSehExceptionsInMethodIfSupported(object, method, location);
 #endif  // GTEST_HAS_EXCEPTIONS
@@ -4239,8 +4239,7 @@
   for (;;) {
     const char* const next_segment = strstr(segment, "]]>");
     if (next_segment != nullptr) {
-      stream->write(segment,
-                    static_cast<std::streamsize>(next_segment - segment));
+      stream->write(segment, next_segment - segment);
       *stream << "]]>]]&gt;<![CDATA[";
       segment = next_segment + strlen("]]>");
     } else {
@@ -5172,9 +5171,12 @@
       // create the file with a single "0" character in it.  I/O
       // errors are ignored as there's nothing better we can do and we
       // don't want to fail the test because of this.
-      FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w");
-      fwrite("0", 1, 1, pfile);
-      fclose(pfile);
+      if (FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w")) {
+        fwrite("0", 1, 1, pfile);
+        fclose(pfile);
+      } else {
+        premature_exit_filepath_.clear();
+      }
     }
   }
 
@@ -5192,7 +5194,7 @@
   }
 
  private:
-  const std::string premature_exit_filepath_;
+  std::string premature_exit_filepath_;
 
   ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
   ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;
diff --git a/googletest/test/googletest-listener-test.cc b/googletest/test/googletest-listener-test.cc
index d7c47c2..f7882a4 100644
--- a/googletest/test/googletest-listener-test.cc
+++ b/googletest/test/googletest-listener-test.cc
@@ -32,6 +32,7 @@
 // This file verifies Google Test event listeners receive events at the
 // right times.
 
+#include <iterator>
 #include <string>
 #include <vector>
 
@@ -498,8 +499,7 @@
                                          "1st.OnTestProgramEnd"};
 #endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
-  VerifyResults(events, expected_events,
-                sizeof(expected_events) / sizeof(expected_events[0]));
+  VerifyResults(events, expected_events, std::size(expected_events));
 
   // We need to check manually for ad hoc test failures that happen after
   // RUN_ALL_TESTS finishes.
diff --git a/googletest/test/googletest-output-test_.cc b/googletest/test/googletest-output-test_.cc
index e3560c0..175aa61 100644
--- a/googletest/test/googletest-output-test_.cc
+++ b/googletest/test/googletest-output-test_.cc
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 
 #include <algorithm>
+#include <iterator>
 #include <string>
 
 #include "gtest/gtest-spi.h"
@@ -149,7 +150,7 @@
   static const int a[4] = {3, 9, 2, 6};
 
   printf("(expecting 2 failures on (3) >= (a[i]))\n");
-  for (int i = 0; i < static_cast<int>(sizeof(a) / sizeof(*a)); i++) {
+  for (int i = 0; i < static_cast<int>(std::size(a)); i++) {
     printf("i == %d\n", i);
     EXPECT_GE(3, a[i]);
   }
diff --git a/googletest/test/googletest-param-test-test.cc b/googletest/test/googletest-param-test-test.cc
index 10d429c..78a1a22 100644
--- a/googletest/test/googletest-param-test-test.cc
+++ b/googletest/test/googletest-param-test-test.cc
@@ -39,6 +39,7 @@
 #include <cstdint>
 #include <functional>
 #include <iostream>
+#include <iterator>
 #include <list>
 #include <set>
 #include <sstream>
@@ -737,10 +738,7 @@
 
 class TestGenerationTest : public TestWithParam<int> {
  public:
-  enum {
-    PARAMETER_COUNT =
-        sizeof(test_generation_params) / sizeof(test_generation_params[0])
-  };
+  enum { PARAMETER_COUNT = std::size(test_generation_params) };
 
   typedef TestGenerationEnvironment<PARAMETER_COUNT> Environment;
 
diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc
index 7d7e933..0b11f8e 100644
--- a/googletest/test/googletest-printers-test.cc
+++ b/googletest/test/googletest-printers-test.cc
@@ -39,6 +39,7 @@
 #include <deque>
 #include <forward_list>
 #include <functional>
+#include <iterator>
 #include <limits>
 #include <list>
 #include <map>
@@ -1784,7 +1785,7 @@
       // too.
       {"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n    As Text: \"\""}};
 
-  for (int i = 0; i < int(sizeof(kTestdata) / sizeof(kTestdata[0])); ++i) {
+  for (int i = 0; i < int(std::size(kTestdata)); ++i) {
     EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]);
   }
 }
diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc
index c753c36..d759f80 100644
--- a/googletest/test/gtest_unittest.cc
+++ b/googletest/test/gtest_unittest.cc
@@ -33,6 +33,8 @@
 
 #include "gtest/gtest.h"
 
+#include <iterator>
+
 // Verifies that the command line flag variables can be accessed in
 // code once "gtest.h" has been #included.
 // Do not move it after other gtest #includes.
@@ -88,6 +90,20 @@
                               << 1)(*)()) > 0,
               "error in operator<< overload resolution");
 
+namespace {
+
+template <bool MutableResult, bool ConstResult>
+struct ConvertibleToBool {
+  explicit operator bool() { return MutableResult; }
+  explicit operator bool() const { return ConstResult; }
+};
+
+struct Bitfield {
+  bool bit : 1;
+};
+
+}  // namespace
+
 namespace testing {
 namespace internal {
 
@@ -3699,6 +3715,15 @@
 TEST(AssertionTest, ASSERT_TRUE) {
   ASSERT_TRUE(2 > 1);  // NOLINT
   EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1), "2 < 1");
+
+  ASSERT_TRUE((ConvertibleToBool<true, false>()));
+  ASSERT_TRUE((std::add_const_t<ConvertibleToBool<false, true>>()));
+
+  Bitfield bf = {true};
+  ASSERT_TRUE(bf.bit);                                             // &
+  ASSERT_TRUE(Bitfield{true}.bit);                                 // &&
+  ASSERT_TRUE(static_cast<const Bitfield&>(Bitfield{true}).bit);   // const&
+  ASSERT_TRUE(static_cast<const Bitfield&&>(Bitfield{true}).bit);  // const&&
 }
 
 // Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
@@ -3725,6 +3750,15 @@
                        "Value of: 2 > 1\n"
                        "  Actual: true\n"
                        "Expected: false");
+
+  ASSERT_FALSE((ConvertibleToBool<false, true>()));
+  ASSERT_FALSE((std::add_const_t<ConvertibleToBool<true, false>>()));
+
+  Bitfield bf = {false};
+  ASSERT_FALSE(bf.bit);                                              // &
+  ASSERT_FALSE(Bitfield{false}.bit);                                 // &&
+  ASSERT_FALSE(static_cast<const Bitfield&>(Bitfield{false}).bit);   // const&
+  ASSERT_FALSE(static_cast<const Bitfield&&>(Bitfield{false}).bit);  // const&&
 }
 
 // Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
@@ -4426,6 +4460,15 @@
                           "  Actual: false\n"
                           "Expected: true");
   EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3), "2 > 3");
+
+  EXPECT_TRUE((ConvertibleToBool<true, false>()));
+  EXPECT_TRUE((std::add_const_t<ConvertibleToBool<false, true>>()));
+
+  Bitfield bf = {true};
+  EXPECT_TRUE(bf.bit);                                             // &
+  EXPECT_TRUE(Bitfield{true}.bit);                                 // &&
+  EXPECT_TRUE(static_cast<const Bitfield&>(Bitfield{true}).bit);   // const&
+  EXPECT_TRUE(static_cast<const Bitfield&&>(Bitfield{true}).bit);  // const&&
 }
 
 // Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult.
@@ -4455,6 +4498,15 @@
                           "  Actual: true\n"
                           "Expected: false");
   EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3), "2 < 3");
+
+  EXPECT_FALSE((ConvertibleToBool<false, true>()));
+  EXPECT_FALSE((std::add_const_t<ConvertibleToBool<true, false>>()));
+
+  Bitfield bf = {false};
+  EXPECT_FALSE(bf.bit);                                              // &
+  EXPECT_FALSE(Bitfield{false}.bit);                                 // &&
+  EXPECT_FALSE(static_cast<const Bitfield&>(Bitfield{false}).bit);   // const&
+  EXPECT_FALSE(static_cast<const Bitfield&&>(Bitfield{false}).bit);  // const&&
 }
 
 // Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult.
@@ -5803,9 +5855,8 @@
   // to specify the array sizes.
 
 #define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \
-  TestParsingFlags(sizeof(argv1) / sizeof(*argv1) - 1, argv1,                \
-                   sizeof(argv2) / sizeof(*argv2) - 1, argv2, expected,      \
-                   should_print_help)
+  TestParsingFlags(std::size(argv1) - 1, argv1, std::size(argv2) - 1, argv2, \
+                   expected, should_print_help)
 };
 
 // Tests parsing an empty command line.