Update googletest

Fixed: 419067923
Change-Id: Ida41103ce2edf5f408e47f69f81abb0575b44eb3
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/79448
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/third_party/googletest/BUILD.bazel b/third_party/googletest/BUILD.bazel
index 0306468..cc25445 100644
--- a/third_party/googletest/BUILD.bazel
+++ b/third_party/googletest/BUILD.bazel
@@ -83,6 +83,10 @@
 )
 
 # Google Test including Google Mock
+
+# For an actual test, use `gtest` and also `gtest_main` if you depend on gtest's
+# main(). For a library, use `gtest_for_library` instead if the library can be
+# testonly.
 cc_library(
     name = "gtest",
     srcs = glob(
@@ -147,10 +151,7 @@
             "@abseil-cpp//absl/flags:reflection",
             "@abseil-cpp//absl/flags:usage",
             "@abseil-cpp//absl/strings",
-            "@abseil-cpp//absl/types:any",
-            "@abseil-cpp//absl/types:optional",
-            "@abseil-cpp//absl/types:variant",
-            "@re2//:re2",
+            "@re2",
         ],
         "//conditions:default": [],
     }) + select({
@@ -167,6 +168,16 @@
     }),
 )
 
+# `gtest`, but testonly. See guidance on `gtest` for when to use this.
+alias(
+    name = "gtest_for_library",
+    testonly = True,
+    actual = ":gtest",
+)
+
+# Implements main() for tests using gtest. Prefer to depend on `gtest` as well
+# to ensure compliance with the layering_check Bazel feature where only the
+# direct hdrs values are available.
 cc_library(
     name = "gtest_main",
     srcs = ["googlemock/src/gmock_main.cc"],
diff --git a/third_party/googletest/METADATA b/third_party/googletest/METADATA
index 7679179..d7ae5fc 100644
--- a/third_party/googletest/METADATA
+++ b/third_party/googletest/METADATA
@@ -6,6 +6,6 @@
     type: HOMEPAGE
     value: "https://github.com/google/googletest"
   }
-  version: "54501746a6cfd366b6e7bab3c902e0f8d5826521"
-  last_upgrade_date { year: 2025 month: 2 day: 24 }
+  version: "16d4f8eff6d7cefca6975d82a53f8fc995a6feb7"
+  last_upgrade_date { year: 2025 month: 5 day: 20 }
 }
diff --git a/third_party/googletest/MODULE.bazel b/third_party/googletest/MODULE.bazel
index 66eee54..c2fb850 100644
--- a/third_party/googletest/MODULE.bazel
+++ b/third_party/googletest/MODULE.bazel
@@ -41,20 +41,20 @@
 
 bazel_dep(
     name = "abseil-cpp",
-    version = "20250127.0",
+    version = "20250512.0",
 )
 bazel_dep(
     name = "platforms",
-    version = "0.0.10",
+    version = "0.0.11",
 )
 bazel_dep(
     name = "re2",
-    version = "2024-07-02",
+    version = "2024-07-02.bcr.1",
 )
 
 bazel_dep(
     name = "rules_python",
-    version = "1.1.0",
+    version = "1.3.0",
     dev_dependency = True,
 )
 
diff --git a/third_party/googletest/README.md b/third_party/googletest/README.md
index 2a2a722..54b1237 100644
--- a/third_party/googletest/README.md
+++ b/third_party/googletest/README.md
@@ -2,30 +2,19 @@
 
 ### Announcements
 
-#### Live at Head
-
-GoogleTest now follows the
-[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support).
-We recommend
-[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it).
-We do publish occasional semantic versions, tagged with
-`v${major}.${minor}.${patch}` (e.g. `v1.16.0`).
-
 #### Documentation Updates
 
 Our documentation is now live on GitHub Pages at
 https://google.github.io/googletest/. We recommend browsing the documentation on
 GitHub Pages rather than directly in the repository.
 
-#### Release 1.16.0
+#### Release 1.17.0
 
-[Release 1.16.0](https://github.com/google/googletest/releases/tag/v1.16.0) is
+[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is
 now available.
 
-The 1.16.x branch requires at least C++14.
-
-The 1.16.x branch will be the last to support C++14. Future development will
-[require at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
+The 1.17.x branch [requires at least
+C++17]((https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
 
 #### Continuous Integration
 
diff --git a/third_party/googletest/WORKSPACE b/third_party/googletest/WORKSPACE
index 4c76102..0ae5dee 100644
--- a/third_party/googletest/WORKSPACE
+++ b/third_party/googletest/WORKSPACE
@@ -37,9 +37,9 @@
 
 http_archive(
     name = "rules_python",
-    sha256 = "9c6e26911a79fbf510a8f06d8eedb40f412023cf7fa6d1461def27116bff022c",
-    strip_prefix = "rules_python-1.1.0",
-    url = "https://github.com/bazelbuild/rules_python/releases/download/1.1.0/rules_python-1.1.0.tar.gz",
+    sha256 = "2cc26bbd53854ceb76dd42a834b1002cd4ba7f8df35440cf03482e045affc244",
+    strip_prefix = "rules_python-1.3.0",
+    url = "https://github.com/bazelbuild/rules_python/releases/download/1.3.0/rules_python-1.3.0.tar.gz",
 )
 # https://github.com/bazelbuild/rules_python/releases/tag/1.1.0
 load("@rules_python//python:repositories.bzl", "py_repositories")
@@ -54,8 +54,8 @@
 http_archive(
     name = "platforms",
     urls = [
-        "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
-        "https://github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
+        "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz",
+        "https://github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz",
     ],
-    sha256 = "218efe8ee736d26a3572663b374a253c012b716d8af0c07e842e82f238a0a7ee",
+    sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f",
 )
diff --git a/third_party/googletest/ci/linux-presubmit.sh b/third_party/googletest/ci/linux-presubmit.sh
index 6491e79..c4ad579 100644
--- a/third_party/googletest/ci/linux-presubmit.sh
+++ b/third_party/googletest/ci/linux-presubmit.sh
@@ -31,15 +31,23 @@
 
 set -euox pipefail
 
-readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20241218"
-readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250205"
+readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20250430"
+readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250430"
 
 if [[ -z ${GTEST_ROOT:-} ]]; then
   GTEST_ROOT="$(realpath $(dirname ${0})/..)"
 fi
 
+# Use Bazel Vendor mode to reduce reliance on external dependencies.
+# See https://bazel.build/external/vendor and the Dockerfile for
+# an explaination of how this works.
+if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" ]]; then
+  DOCKER_EXTRA_ARGS="--mount type=bind,source=${KOKORO_GFILE_DIR}/distdir,target=/distdir,readonly --env=BAZEL_VENDOR_ARCHIVE=/distdir/googletest_vendor.tar.gz ${DOCKER_EXTRA_ARGS:-}"
+  BAZEL_EXTRA_ARGS="--vendor_dir=/googletest_vendor ${BAZEL_EXTRA_ARGS:-}"
+fi
+
 if [[ -z ${STD:-} ]]; then
-  STD="c++17 c++20"
+  STD="c++17 c++20 c++23"
 fi
 
 # Test CMake + GCC
@@ -93,18 +101,21 @@
   --rm \
   --env="CC=/usr/local/bin/gcc" \
   --env="BAZEL_CXXOPTS=-std=c++17" \
+  ${DOCKER_EXTRA_ARGS:-} \
   ${LINUX_GCC_FLOOR_CONTAINER} \
+  /bin/bash --login -c "
     /usr/local/bin/bazel test ... \
-      --copt="-Wall" \
-      --copt="-Werror" \
-      --copt="-Wuninitialized" \
-      --copt="-Wundef" \
-      --copt="-Wno-error=pragmas" \
+      --copt=\"-Wall\" \
+      --copt=\"-Werror\" \
+      --copt=\"-Wuninitialized\" \
+      --copt=\"-Wundef\" \
+      --copt=\"-Wno-error=pragmas\" \
       --enable_bzlmod=false \
       --features=external_include_paths \
       --keep_going \
       --show_timestamps \
-      --test_output=errors
+      --test_output=errors \
+      ${BAZEL_EXTRA_ARGS:-}"
 
 # Test GCC
 for std in ${STD}; do
@@ -115,18 +126,21 @@
       --rm \
       --env="CC=/usr/local/bin/gcc" \
       --env="BAZEL_CXXOPTS=-std=${std}" \
+      ${DOCKER_EXTRA_ARGS:-} \
       ${LINUX_LATEST_CONTAINER} \
-      /usr/local/bin/bazel test ... \
-        --copt="-Wall" \
-        --copt="-Werror" \
-        --copt="-Wuninitialized" \
-        --copt="-Wundef" \
-        --define="absl=${absl}" \
-        --enable_bzlmod=true \
-        --features=external_include_paths \
-        --keep_going \
-        --show_timestamps \
-        --test_output=errors
+      /bin/bash --login -c "
+        /usr/local/bin/bazel test ... \
+          --copt=\"-Wall\" \
+          --copt=\"-Werror\" \
+          --copt=\"-Wuninitialized\" \
+          --copt=\"-Wundef\" \
+          --define=\"absl=${absl}\" \
+          --enable_bzlmod=true \
+          --features=external_include_paths \
+          --keep_going \
+          --show_timestamps \
+          --test_output=errors \
+          ${BAZEL_EXTRA_ARGS:-}"
   done
 done
 
@@ -139,19 +153,22 @@
       --rm \
       --env="CC=/opt/llvm/clang/bin/clang" \
       --env="BAZEL_CXXOPTS=-std=${std}" \
+      ${DOCKER_EXTRA_ARGS:-} \
       ${LINUX_LATEST_CONTAINER} \
-      /usr/local/bin/bazel test ... \
-        --copt="--gcc-toolchain=/usr/local" \
-        --copt="-Wall" \
-        --copt="-Werror" \
-        --copt="-Wuninitialized" \
-        --copt="-Wundef" \
-        --define="absl=${absl}" \
-        --enable_bzlmod=true \
-        --features=external_include_paths \
-        --keep_going \
-        --linkopt="--gcc-toolchain=/usr/local" \
-        --show_timestamps \
-        --test_output=errors
+      /bin/bash --login -c "
+        /usr/local/bin/bazel test ... \
+          --copt=\"--gcc-toolchain=/usr/local\" \
+          --copt=\"-Wall\" \
+          --copt=\"-Werror\" \
+          --copt=\"-Wuninitialized\" \
+          --copt=\"-Wundef\" \
+          --define=\"absl=${absl}\" \
+          --enable_bzlmod=true \
+          --features=external_include_paths \
+          --keep_going \
+          --linkopt=\"--gcc-toolchain=/usr/local\" \
+          --show_timestamps \
+          --test_output=errors \
+          ${BAZEL_EXTRA_ARGS:-}"
   done
 done
diff --git a/third_party/googletest/ci/macos-presubmit.sh b/third_party/googletest/ci/macos-presubmit.sh
index 5370ed6..63cf814 100644
--- a/third_party/googletest/ci/macos-presubmit.sh
+++ b/third_party/googletest/ci/macos-presubmit.sh
@@ -56,7 +56,7 @@
 # Test the Bazel build
 
 # If we are running on Kokoro, check for a versioned Bazel binary.
-KOKORO_GFILE_BAZEL_BIN="bazel-8.0.0-darwin-x86_64"
+KOKORO_GFILE_BAZEL_BIN="bazel-8.2.1-darwin-x86_64"
 if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
   BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
   chmod +x ${BAZEL_BIN}
@@ -64,6 +64,12 @@
   BAZEL_BIN="bazel"
 fi
 
+# Use Bazel Vendor mode to reduce reliance on external dependencies.
+if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" ]]; then
+  tar -xf "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" -C "${TMP}/"
+  BAZEL_EXTRA_ARGS="--vendor_dir=\"${TMP}/googletest_vendor\" ${BAZEL_EXTRA_ARGS:-}"
+fi
+
 cd ${GTEST_ROOT}
 for absl in 0 1; do
   ${BAZEL_BIN} test ... \
@@ -76,5 +82,6 @@
     --features=external_include_paths \
     --keep_going \
     --show_timestamps \
-    --test_output=errors
+    --test_output=errors \
+    ${BAZEL_EXTRA_ARGS:-}
 done
diff --git a/third_party/googletest/ci/windows-presubmit.bat b/third_party/googletest/ci/windows-presubmit.bat
index e2664c5..267e2e9 100644
--- a/third_party/googletest/ci/windows-presubmit.bat
+++ b/third_party/googletest/ci/windows-presubmit.bat
@@ -1,6 +1,6 @@
 SETLOCAL ENABLEDELAYEDEXPANSION
 
-SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-8.0.0-windows-x86_64.exe
+SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-8.2.1-windows-x86_64.exe
 
 SET PATH=C:\Python34;%PATH%
 SET BAZEL_PYTHON=C:\python34\python.exe
@@ -48,6 +48,14 @@
 :: --output_user_root=C:\tmp causes Bazel to use a shorter path.
 SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
 
+:: Use Bazel Vendor mode to reduce reliance on external dependencies.
+IF EXIST "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" (
+  tar --force-local -xf "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" -C c:
+  SET VENDOR_FLAG=--vendor_dir=c:\googletest_vendor
+) ELSE (
+  SET VENDOR_FLAG=
+)
+
 :: C++17
 %BAZEL_EXE% ^
   --output_user_root=C:\tmp ^
@@ -58,7 +66,8 @@
   --enable_bzlmod=true ^
   --keep_going ^
   --test_output=errors ^
-  --test_tag_filters=-no_test_msvc2017
+  --test_tag_filters=-no_test_msvc2017 ^
+  %VENDOR_FLAG%
 IF %errorlevel% neq 0 EXIT /B 1
 
 :: C++20
@@ -71,5 +80,6 @@
   --enable_bzlmod=true ^
   --keep_going ^
   --test_output=errors ^
-  --test_tag_filters=-no_test_msvc2017
+  --test_tag_filters=-no_test_msvc2017 ^
+  %VENDOR_FLAG%
 IF %errorlevel% neq 0 EXIT /B 1
diff --git a/third_party/googletest/docs/advanced.md b/third_party/googletest/docs/advanced.md
index 9b1220a..35a237d 100644
--- a/third_party/googletest/docs/advanced.md
+++ b/third_party/googletest/docs/advanced.md
@@ -1471,10 +1471,7 @@
 
     Another way to test private members is to refactor them into an
     implementation class, which is then declared in a `*-internal.h` file. Your
-    clients aren't allowed to include this header but your tests can. Such is
-    called the
-    [Pimpl](https://www.gamedev.net/articles/programming/general-and-gameplay-programming/the-c-pimpl-r1794/)
-    (Private Implementation) idiom.
+    clients aren't allowed to include this header but your tests can.
 
     Or, you can declare an individual test as a friend of your class by adding
     this line in the class body:
diff --git a/third_party/googletest/docs/faq.md b/third_party/googletest/docs/faq.md
index c7d10b5..4e95838 100644
--- a/third_party/googletest/docs/faq.md
+++ b/third_party/googletest/docs/faq.md
@@ -511,19 +511,6 @@
     list of the constructor. (Early versions of `gcc` doesn't force you to
     initialize the const member. It's a bug that has been fixed in `gcc 4`.)
 
-## Why does ASSERT_DEATH complain about previous threads that were already joined?
-
-With the Linux pthread library, there is no turning back once you cross the line
-from a single thread to multiple threads. The first time you create a thread, a
-manager thread is created in addition, so you get 3, not 2, threads. Later when
-the thread you create joins the main thread, the thread count decrements by 1,
-but the manager thread will never be killed, so you still have 2 threads, which
-means you cannot safely run a death test.
-
-The new NPTL thread library doesn't suffer from this problem, as it doesn't
-create a manager thread. However, if you don't control which machine your test
-runs on, you shouldn't depend on this.
-
 ## Why does GoogleTest require the entire test suite, instead of individual tests, to be named `*DeathTest` when it uses `ASSERT_DEATH`?
 
 GoogleTest does not interleave tests from different test suites. That is, it
diff --git a/third_party/googletest/docs/gmock_cook_book.md b/third_party/googletest/docs/gmock_cook_book.md
index 633dbc3..9e59b4c 100644
--- a/third_party/googletest/docs/gmock_cook_book.md
+++ b/third_party/googletest/docs/gmock_cook_book.md
@@ -3567,10 +3567,15 @@
 
 ### Writing New Monomorphic Matchers
 
-A matcher of argument type `T` implements the matcher interface for `T` and does
-two things: it tests whether a value of type `T` matches the matcher, and can
-describe what kind of values it matches. The latter ability is used for
-generating readable error messages when expectations are violated.
+A matcher of type `testing::Matcher<T>` implements the matcher interface for `T`
+and does two things: it tests whether a value of type `T` matches the matcher,
+and can describe what kind of values it matches. The latter ability is used for
+generating readable error messages when expectations are violated. Some matchers
+can even explain why it matches or doesn't match a certain value, which can be
+helpful when the reason isn't obvious.
+
+Because a matcher of type `testing::Matcher<T>` for a particular type `T` can
+only be used to match a value of type `T`, we call it "monomorphic."
 
 A matcher of `T` must declare a typedef like:
 
@@ -3662,8 +3667,16 @@
 
 ### Writing New Polymorphic Matchers
 
-Expanding what we learned above to *polymorphic* matchers is now just as simple
-as adding templates in the right place.
+Unlike a monomorphic matcher, which can only be used to match a value of a
+particular type, a *polymorphic* matcher is one that can be used to match values
+of multiple types. For example, `Eq(5)` is a polymorhpic matcher as it can be
+used to match an `int`, a `double`, a `float`, and so on. You should think of a
+polymorphic matcher as a *matcher factory* as opposed to a
+`testing::Matcher<SomeType>` - itself is not an actual matcher, but can be
+implicitly converted to a `testing::Matcher<SomeType>` depending on the context.
+
+Expanding what we learned above to polymorphic matchers is now as simple as
+adding templates in the right place.
 
 ```cpp
 
@@ -3789,6 +3802,26 @@
 Like in a monomorphic matcher, you may explain the match result by streaming
 additional information to the `listener` argument in `MatchAndExplain()`.
 
+### Implementing Composite Matchers {#CompositeMatchers}
+
+Sometimes we want to define a matcher that takes other matchers as parameters.
+For example, `DistanceFrom(target, m)` is a polymorphic matcher that takes a
+matcher `m` as a parameter. It tests that the distance from `target` to the
+value being matched satisfies sub-matcher `m`.
+
+If you are implementing such a composite matcher, you'll need to generate the
+description of the matcher based on the description(s) of its sub-matcher(s).
+You can see the implementation of `DistanceFrom()` in
+`googlemock/include/gmock/gmock-matchers.h` for an example. In particular, pay
+attention to `DistanceFromMatcherImpl`. Notice that it stores the sub-matcher as
+a `const Matcher<const Distance&> distance_matcher_` instead of a polymorphic
+matcher - this allows it to call `distance_matcher_.DescribeTo(os)` to describe
+the sub-matcher. If the sub-matcher is stored as a polymorphic matcher instead,
+it would not be possible to get its description as in general polymorphic
+matchers don't know how to describe themselves - they are matcher factories
+instead of actual matchers; only after being converted to `Matcher<SomeType>`
+can they be described.
+
 ### Writing New Cardinalities
 
 A cardinality is used in `Times()` to tell gMock how many times you expect a
diff --git a/third_party/googletest/docs/quickstart-bazel.md b/third_party/googletest/docs/quickstart-bazel.md
index 5750f02..04fa829 100644
--- a/third_party/googletest/docs/quickstart-bazel.md
+++ b/third_party/googletest/docs/quickstart-bazel.md
@@ -9,7 +9,7 @@
 To complete this tutorial, you'll need:
 
 *   A compatible operating system (e.g. Linux, macOS, Windows).
-*   A compatible C++ compiler that supports at least C++14.
+*   A compatible C++ compiler that supports at least C++17.
 *   [Bazel](https://bazel.build/) 7.0 or higher, the preferred build system used
     by the GoogleTest team.
 
@@ -48,7 +48,7 @@
 
 # Choose the most recent version available at
 # https://registry.bazel.build/modules/googletest
-bazel_dep(name = "googletest", version = "1.15.2")
+bazel_dep(name = "googletest", version = "1.17.0")
 ```
 
 Now you're ready to build C++ code that uses GoogleTest.
@@ -99,16 +99,16 @@
 [Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
 
 {: .callout .note}
-NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++14`
-to ensure that GoogleTest is compiled as C++14 instead of the compiler's default
-setting (which could be C++11). For MSVC, the equivalent would be
-`--cxxopt=/std:c++14`. See [Supported Platforms](platforms.md) for more details
-on supported language versions.
+NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++17`
+to ensure that GoogleTest is compiled as C++17 instead of the compiler's default
+setting. For MSVC, the equivalent would be `--cxxopt=/std:c++17`. See
+[Supported Platforms](platforms.md) for more details on supported language
+versions.
 
 Now you can build and run your test:
 
 <pre>
-<strong>$ bazel test --cxxopt=-std=c++14 --test_output=all //:hello_test</strong>
+<strong>$ bazel test --cxxopt=-std=c++17 --test_output=all //:hello_test</strong>
 INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured).
 INFO: Found 1 test target...
 INFO: From Testing //:hello_test:
diff --git a/third_party/googletest/docs/quickstart-cmake.md b/third_party/googletest/docs/quickstart-cmake.md
index 4e422b7..bcdb1b5 100644
--- a/third_party/googletest/docs/quickstart-cmake.md
+++ b/third_party/googletest/docs/quickstart-cmake.md
@@ -10,7 +10,7 @@
 To complete this tutorial, you'll need:
 
 *   A compatible operating system (e.g. Linux, macOS, Windows).
-*   A compatible C++ compiler that supports at least C++14.
+*   A compatible C++ compiler that supports at least C++17.
 *   [CMake](https://cmake.org/) and a compatible build tool for building the
     project.
     *   Compatible build tools include
@@ -52,8 +52,8 @@
 cmake_minimum_required(VERSION 3.14)
 project(my_project)
 
-# GoogleTest requires at least C++14
-set(CMAKE_CXX_STANDARD 14)
+# GoogleTest requires at least C++17
+set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 include(FetchContent)
diff --git a/third_party/googletest/docs/reference/actions.md b/third_party/googletest/docs/reference/actions.md
index 0ebdc1e..2ca3a9f 100644
--- a/third_party/googletest/docs/reference/actions.md
+++ b/third_party/googletest/docs/reference/actions.md
@@ -48,8 +48,8 @@
 | `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. |
 | `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. |
 
-The return value of the invoked function is used as the return value of the
-action.
+The return value of the invoked function (except `InvokeArgument`) is used as
+the return value of the action.
 
 When defining a callable to be used with `Invoke*()`, you can declare any unused
 parameters as `Unused`:
diff --git a/third_party/googletest/docs/reference/matchers.md b/third_party/googletest/docs/reference/matchers.md
index 16397ef..8ff9e0b 100644
--- a/third_party/googletest/docs/reference/matchers.md
+++ b/third_party/googletest/docs/reference/matchers.md
@@ -42,6 +42,8 @@
 | `Lt(value)`            | `argument < value`                                  |
 | `Ne(value)`            | `argument != value`                                 |
 | `IsFalse()`            | `argument` evaluates to `false` in a Boolean context. |
+| `DistanceFrom(target, m)` | The distance between `argument` and `target` (computed by `abs(argument - target)`) matches `m`. |
+| `DistanceFrom(target, get_distance, m)` | The distance between `argument` and `target` (computed by `get_distance(argument, target)`) matches `m`. |
 | `IsTrue()`             | `argument` evaluates to `true` in a Boolean context. |
 | `IsNull()`             | `argument` is a `NULL` pointer (raw or smart).      |
 | `NotNull()`            | `argument` is a non-null pointer (raw or smart).    |
diff --git a/third_party/googletest/docs/reference/testing.md b/third_party/googletest/docs/reference/testing.md
index 3ed5211..d7dc5cf 100644
--- a/third_party/googletest/docs/reference/testing.md
+++ b/third_party/googletest/docs/reference/testing.md
@@ -110,7 +110,7 @@
 | `ValuesIn(container)` or `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)`. |
 | `Bool()`                     | Yields sequence `{false, true}`.            |
 | `Combine(g1, g2, ..., gN)`   | Yields as `std::tuple` *n*-tuples all combinations (Cartesian product) of the values generated by the given *n* generators `g1`, `g2`, ..., `gN`. |
-| `ConvertGenerator<T>(g)`     | Yields values generated by generator `g`, `static_cast` to `T`. |
+| `ConvertGenerator<T>(g)` or `ConvertGenerator(g, func)`    | Yields values generated by generator `g`, `static_cast` from `T`. (Note: `T` might not be what you expect. See [*Using ConvertGenerator*](#using-convertgenerator) below.) The second overload uses `func` to perform the conversion. |
 
 The optional last argument *`name_generator`* is a function or functor that
 generates custom test name suffixes based on the test parameters. The function
@@ -137,6 +137,103 @@
 See also
 [`GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST`](#GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST).
 
+###### Using `ConvertGenerator`
+
+The functions listed in the table above appear to return generators that create
+values of the desired types, but this is not generally the case. Rather, they
+typically return factory objects that convert to the the desired generators.
+This affords some flexibility in allowing you to specify values of types that
+are different from, yet implicitly convertible to, the actual parameter type
+required by your fixture class.
+
+For example, you can do the following with a fixture that requires an `int`
+parameter:
+
+```cpp
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    testing::Values(1, 1.2));  // Yes, Values() supports heterogeneous argument types.
+```
+
+It might seem obvious that `1.2` &mdash; a `double` &mdash; will be converted to
+an `int` but in actuality it requires some template gymnastics involving the
+indirection described in the previous paragraph.
+
+What if your parameter type is not implicitly convertible from the generated
+type but is *explicitly* convertible? There will be no automatic conversion, but
+you can force it by applying `ConvertGenerator<T>`. The compiler can
+automatically deduce the target type (your fixture's parameter type), but
+because of the aforementioned indirection it cannot decide what the generated
+type should be. You need to tell it, by providing the type `T` explicitly. Thus
+`T` should not be your fixture's parameter type, but rather an intermediate type
+that is supported by the factory object, and which can be `static_cast` to the
+fixture's parameter type:
+
+```cpp
+// The fixture's parameter type.
+class MyParam {
+ public:
+  // Explicit converting ctor.
+  explicit MyParam(const std::tuple<int, bool>& t);
+  ...
+};
+
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    ConvertGenerator<std::tuple<int, bool>>(Combine(Values(0.1, 1.2), Bool())));
+```
+
+In this example `Combine` supports the generation of `std::tuple<int, bool>>`
+objects (even though the provided values for the first tuple element are
+`double`s) and those `tuple`s get converted into `MyParam` objects by virtue of
+the call to `ConvertGenerator`.
+
+For parameter types that are not convertible from the generated types you can
+provide a callable that does the conversion. The callable accepts an object of
+the generated type and returns an object of the fixture's parameter type. The
+generated type can often be deduced by the compiler from the callable's call
+signature so you do not usually need specify it explicitly (but see a caveat
+below).
+
+```cpp
+// The fixture's parameter type.
+class MyParam {
+ public:
+  MyParam(int, bool);
+  ...
+};
+
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    ConvertGenerator(Combine(Values(1, 1.2), Bool()),
+        [](const std::tuple<int i, bool>& t){
+          const auto [i, b] = t;
+          return MyParam(i, b);
+        }));
+```
+
+The callable may be anything that can be used to initialize a `std::function`
+with the appropriate call signature. Note the callable's return object gets
+`static_cast` to the fixture's parameter type, so it does not have to be of that
+exact type, only convertible to it.
+
+**Caveat:** Consider the following example.
+
+```cpp
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    ConvertGenerator(Values(std::string("s")), [](std::string_view s) { ... }));
+```
+
+The `string` argument gets copied into the factory object returned by `Values`.
+Then, because the generated type deduced from the lambda is `string_view`, the
+factory object spawns a generator that holds a `string_view` referencing that
+`string`. Unfortunately, by the time this generator gets invoked, the factory
+object is gone and the `string_view` is dangling.
+
+To overcome this problem you can specify the generated type explicitly:
+`ConvertGenerator<std::string>(Values(std::string("s")), [](std::string_view s)
+{ ... })`. Alternatively, you can change the lambda's signature to take a
+`std::string` or a `const std::string&` (the latter will not leave you with a
+dangling reference because the type deduction strips off the reference and the
+`const`).
+
 ### TYPED_TEST_SUITE {#TYPED_TEST_SUITE}
 
 `TYPED_TEST_SUITE(`*`TestFixtureName`*`,`*`Types`*`)`
diff --git a/third_party/googletest/googlemock/include/gmock/gmock-actions.h b/third_party/googletest/googlemock/include/gmock/gmock-actions.h
index 040e702..5fe50e3 100644
--- a/third_party/googletest/googlemock/include/gmock/gmock-actions.h
+++ b/third_party/googletest/googlemock/include/gmock/gmock-actions.h
@@ -835,6 +835,10 @@
     Result operator()(const InArgs&...) const {
       return function_impl();
     }
+    template <typename... InArgs>
+    Result operator()(const InArgs&...) {
+      return function_impl();
+    }
 
     FunctionImpl function_impl;
   };
@@ -1451,6 +1455,30 @@
     return OA{std::move(inner_action)};
   }
 
+  // As above, but in the case where we want to create a OnceAction from a const
+  // WithArgsAction. This is fine as long as the inner action doesn't need to
+  // move any of its state to create a OnceAction.
+  template <
+      typename R, typename... Args,
+      typename std::enable_if<
+          std::is_convertible<const InnerAction&,
+                              OnceAction<R(internal::TupleElement<
+                                           I, std::tuple<Args...>>...)>>::value,
+          int>::type = 0>
+  operator OnceAction<R(Args...)>() const& {  // NOLINT
+    struct OA {
+      OnceAction<InnerSignature<R, Args...>> inner_action;
+
+      R operator()(Args&&... args) && {
+        return std::move(inner_action)
+            .Call(std::get<I>(
+                std::forward_as_tuple(std::forward<Args>(args)...))...);
+      }
+    };
+
+    return OA{inner_action};
+  }
+
   template <
       typename R, typename... Args,
       typename std::enable_if<
@@ -1703,9 +1731,8 @@
 struct ReturnArgAction {
   template <typename... Args,
             typename = typename std::enable_if<(k < sizeof...(Args))>::type>
-  auto operator()(Args&&... args) const
-      -> decltype(std::get<k>(
-          std::forward_as_tuple(std::forward<Args>(args)...))) {
+  auto operator()(Args&&... args) const -> decltype(std::get<k>(
+      std::forward_as_tuple(std::forward<Args>(args)...))) {
     return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...));
   }
 };
diff --git a/third_party/googletest/googlemock/include/gmock/gmock-matchers.h b/third_party/googletest/googlemock/include/gmock/gmock-matchers.h
index 8903c7a..b999d6e 100644
--- a/third_party/googletest/googlemock/include/gmock/gmock-matchers.h
+++ b/third_party/googletest/googlemock/include/gmock/gmock-matchers.h
@@ -257,6 +257,7 @@
 
 #include <algorithm>
 #include <cmath>
+#include <cstddef>
 #include <exception>
 #include <functional>
 #include <initializer_list>
@@ -1311,6 +1312,15 @@
 
   bool MatchAndExplain(const T& x,
                        MatchResultListener* listener) const override {
+    if (!listener->IsInterested()) {
+      // Fast path to avoid unnecessary formatting.
+      for (const Matcher<T>& matcher : matchers_) {
+        if (!matcher.Matches(x)) {
+          return false;
+        }
+      }
+      return true;
+    }
     // This method uses matcher's explanation when explaining the result.
     // However, if matcher doesn't provide one, this method uses matcher's
     // description.
@@ -1430,6 +1440,15 @@
 
   bool MatchAndExplain(const T& x,
                        MatchResultListener* listener) const override {
+    if (!listener->IsInterested()) {
+      // Fast path to avoid unnecessary formatting of match explanations.
+      for (const Matcher<T>& matcher : matchers_) {
+        if (matcher.Matches(x)) {
+          return true;
+        }
+      }
+      return false;
+    }
     // This method uses matcher's explanation when explaining the result.
     // However, if matcher doesn't provide one, this method uses matcher's
     // description.
@@ -2097,11 +2116,11 @@
 template <typename Class, typename FieldType>
 class FieldMatcher {
  public:
-  FieldMatcher(FieldType Class::*field,
+  FieldMatcher(FieldType Class::* field,
                const Matcher<const FieldType&>& matcher)
       : field_(field), matcher_(matcher), whose_field_("whose given field ") {}
 
-  FieldMatcher(const std::string& field_name, FieldType Class::*field,
+  FieldMatcher(const std::string& field_name, FieldType Class::* field,
                const Matcher<const FieldType&>& matcher)
       : field_(field),
         matcher_(matcher),
@@ -2145,7 +2164,7 @@
     return MatchAndExplainImpl(std::false_type(), *p, listener);
   }
 
-  const FieldType Class::*field_;
+  const FieldType Class::* field_;
   const Matcher<const FieldType&> matcher_;
 
   // Contains either "whose given field " if the name of the field is unknown
@@ -2855,6 +2874,54 @@
   }
 };
 
+// Implements DistanceFrom(target, get_distance, distance_matcher) for the given
+// argument types:
+//   * V is the type of the value to be matched.
+//   * T is the type of the target value.
+//   * Distance is the type of the distance between V and T.
+//   * GetDistance is the type of the functor for computing the distance between
+//     V and T.
+template <typename V, typename T, typename Distance, typename GetDistance>
+class DistanceFromMatcherImpl : public MatcherInterface<V> {
+ public:
+  // Arguments:
+  //   * target: the target value.
+  //   * get_distance: the functor for computing the distance between the value
+  //   being matched and target.
+  //   * distance_matcher: the matcher for checking the distance.
+  DistanceFromMatcherImpl(T target, GetDistance get_distance,
+                          Matcher<const Distance&> distance_matcher)
+      : target_(std::move(target)),
+        get_distance_(std::move(get_distance)),
+        distance_matcher_(std::move(distance_matcher)) {}
+
+  // Describes what this matcher does.
+  void DescribeTo(::std::ostream* os) const override {
+    distance_matcher_.DescribeTo(os);
+    *os << " away from " << PrintToString(target_);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    distance_matcher_.DescribeNegationTo(os);
+    *os << " away from " << PrintToString(target_);
+  }
+
+  bool MatchAndExplain(V value, MatchResultListener* listener) const override {
+    const auto distance = get_distance_(value, target_);
+    const bool match = distance_matcher_.Matches(distance);
+    if (!match && listener->IsInterested()) {
+      *listener << "which is " << PrintToString(distance) << " away from "
+                << PrintToString(target_);
+    }
+    return match;
+  }
+
+ private:
+  const T target_;
+  const GetDistance get_distance_;
+  const Matcher<const Distance&> distance_matcher_;
+};
+
 // Implements Each(element_matcher) for the given argument type Container.
 // Symmetric to ContainsMatcherImpl.
 template <typename Container>
@@ -2990,6 +3057,52 @@
 }
 }  // namespace pair_getters
 
+// Default functor for computing the distance between two values.
+struct DefaultGetDistance {
+  template <typename T, typename U>
+  auto operator()(const T& lhs, const U& rhs) const {
+    using std::abs;
+    // Allow finding abs() in the type's namespace via ADL.
+    return abs(lhs - rhs);
+  }
+};
+
+// Implements polymorphic DistanceFrom(target, get_distance, distance_matcher)
+// matcher. Template arguments:
+//   * T is the type of the target value.
+//   * GetDistance is the type of the functor for computing the distance between
+//     the value being matched and the target.
+//   * DistanceMatcher is the type of the matcher for checking the distance.
+template <typename T, typename GetDistance, typename DistanceMatcher>
+class DistanceFromMatcher {
+ public:
+  // Arguments:
+  //   * target: the target value.
+  //   * get_distance: the functor for computing the distance between the value
+  //     being matched and target.
+  //   * distance_matcher: the matcher for checking the distance.
+  DistanceFromMatcher(T target, GetDistance get_distance,
+                      DistanceMatcher distance_matcher)
+      : target_(std::move(target)),
+        get_distance_(std::move(get_distance)),
+        distance_matcher_(std::move(distance_matcher)) {}
+
+  DistanceFromMatcher(const DistanceFromMatcher& other) = default;
+
+  // Implicitly converts to a monomorphic matcher of the given type.
+  template <typename V>
+  operator Matcher<V>() const {  // NOLINT
+    using Distance = decltype(get_distance_(std::declval<V>(), target_));
+    return Matcher<V>(new DistanceFromMatcherImpl<V, T, Distance, GetDistance>(
+        target_, get_distance_, distance_matcher_));
+  }
+
+ private:
+  const T target_;
+  const GetDistance get_distance_;
+  const DistanceMatcher distance_matcher_;
+};
+
 // Implements Key(inner_matcher) for the given argument pair type.
 // Key(inner_matcher) matches an std::pair whose 'first' field matches
 // inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an
@@ -3197,8 +3310,8 @@
 };
 
 template <typename T, size_t... I>
-auto UnpackStructImpl(const T& t, std::index_sequence<I...>,
-                      int) -> decltype(std::tie(get<I>(t)...)) {
+auto UnpackStructImpl(const T& t, std::index_sequence<I...>, int)
+    -> decltype(std::tie(get<I>(t)...)) {
   static_assert(std::tuple_size<T>::value == sizeof...(I),
                 "Number of arguments doesn't match the number of fields.");
   return std::tie(get<I>(t)...);
@@ -3305,6 +3418,29 @@
   const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = u;
   return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t);
 }
+template <typename T>
+auto UnpackStructImpl(const T& in, std::make_index_sequence<21>, char) {
+  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u] =
+      in;
+  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
+                  u);
+}
+
+template <typename T>
+auto UnpackStructImpl(const T& in, std::make_index_sequence<22>, char) {
+  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
+               v] = in;
+  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
+                  v);
+}
+
+template <typename T>
+auto UnpackStructImpl(const T& in, std::make_index_sequence<23>, char) {
+  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
+               w] = in;
+  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
+                  v, w);
+}
 #endif  // defined(__cpp_structured_bindings)
 
 template <size_t I, typename T>
@@ -3480,7 +3616,7 @@
     StlContainerReference stl_container = View::ConstReference(container);
     auto it = stl_container.begin();
     size_t exam_pos = 0;
-    bool mismatch_found = false;  // Have we found a mismatched element yet?
+    bool unmatched_found = false;
 
     // Go through the elements and matchers in pairs, until we reach
     // the end of either the elements or the matchers, or until we find a
@@ -3496,11 +3632,23 @@
       }
 
       if (!match) {
-        mismatch_found = true;
+        unmatched_found = true;
+        // We cannot store the iterator for the unmatched element to be used
+        // later, as some users use ElementsAre() with a "container" whose
+        // iterator is not copy-constructible or copy-assignable.
+        //
+        // We cannot store a pointer to the element either, as some container's
+        // iterators return a temporary.
+        //
+        // We cannot store the element itself either, as the element may not be
+        // copyable.
+        //
+        // Therefore, we just remember the index of the unmatched element,
+        // and use it later to print the unmatched element.
         break;
       }
     }
-    // If mismatch_found is true, 'exam_pos' is the index of the mismatch.
+    // If unmatched_found is true, exam_pos is the index of the mismatch.
 
     // Find how many elements the actual container has.  We avoid
     // calling size() s.t. this code works for stream-like "containers"
@@ -3521,10 +3669,27 @@
       return false;
     }
 
-    if (mismatch_found) {
+    if (unmatched_found) {
       // The element count matches, but the exam_pos-th element doesn't match.
       if (listener_interested) {
-        *listener << "whose element #" << exam_pos << " doesn't match";
+        // Find the unmatched element.
+        auto unmatched_it = stl_container.begin();
+        // We cannot call std::advance() on the iterator, as some users use
+        // ElementsAre() with a "container" whose iterator is incompatible with
+        // std::advance() (e.g. it may not have the difference_type member
+        // type).
+        for (size_t i = 0; i != exam_pos; ++i) {
+          ++unmatched_it;
+        }
+
+        // If the array is long or the elements' print-out is large, it may be
+        // hard for the user to find the mismatched element and its
+        // corresponding matcher description. Therefore we print the index, the
+        // value of the mismatched element, and the corresponding matcher
+        // description to ease debugging.
+        *listener << "whose element #" << exam_pos << " ("
+                  << PrintToString(*unmatched_it) << ") ";
+        matchers_[exam_pos].DescribeNegationTo(listener->stream());
         PrintIfNotEmpty(explanations[exam_pos], listener->stream());
       }
       return false;
@@ -3930,15 +4095,15 @@
 // Overloads to support `OptionalMatcher` being used with a type that either
 // supports implicit conversion to bool or a `has_value()` method.
 template <typename Optional>
-auto IsOptionalEngaged(const Optional& optional,
-                       Rank1) -> decltype(!!optional) {
+auto IsOptionalEngaged(const Optional& optional, Rank1)
+    -> decltype(!!optional) {
   // The use of double-negation here is to preserve historical behavior where
   // the matcher used `operator!` rather than directly using `operator bool`.
   return !static_cast<bool>(!optional);
 }
 template <typename Optional>
-auto IsOptionalEngaged(const Optional& optional,
-                       Rank0) -> decltype(!optional.has_value()) {
+auto IsOptionalEngaged(const Optional& optional, Rank0)
+    -> decltype(!optional.has_value()) {
   return optional.has_value();
 }
 
@@ -3979,6 +4144,10 @@
         return false;
       }
       const ValueType& value = *optional;
+      if (!listener->IsInterested()) {
+        // Fast path to avoid unnecessary generation of match explanation.
+        return value_matcher_.Matches(value);
+      }
       StringMatchResultListener value_listener;
       const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
       *listener << "whose value " << PrintToString(value)
@@ -4365,6 +4534,42 @@
   return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error);
 }
 
+// The DistanceFrom(target, get_distance, m) and DistanceFrom(target, m)
+// matchers work on arbitrary types that have the "distance" concept. What they
+// do:
+//
+// 1. compute the distance between the value and the target using
+//    get_distance(value, target) if get_distance is provided; otherwise compute
+//    the distance as abs(value - target).
+// 2. match the distance against the user-provided matcher m; if the match
+//    succeeds, the DistanceFrom() match succeeds.
+//
+// Examples:
+//
+//   // 0.5's distance from 0.6 should be <= 0.2.
+//   EXPECT_THAT(0.5, DistanceFrom(0.6, Le(0.2)));
+//
+//   Vector2D v1(3.0, 4.0), v2(3.2, 6.0);
+//   // v1's distance from v2, as computed by EuclideanDistance(v1, v2),
+//   // should be >= 1.0.
+//   EXPECT_THAT(v1, DistanceFrom(v2, EuclideanDistance, Ge(1.0)));
+
+template <typename T, typename GetDistance, typename DistanceMatcher>
+inline internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>
+DistanceFrom(T target, GetDistance get_distance,
+             DistanceMatcher distance_matcher) {
+  return internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>(
+      std::move(target), std::move(get_distance), std::move(distance_matcher));
+}
+
+template <typename T, typename DistanceMatcher>
+inline internal::DistanceFromMatcher<T, internal::DefaultGetDistance,
+                                     DistanceMatcher>
+DistanceFrom(T target, DistanceMatcher distance_matcher) {
+  return DistanceFrom(std::move(target), internal::DefaultGetDistance(),
+                      std::move(distance_matcher));
+}
+
 // Creates a matcher that matches any double argument approximately equal to
 // rhs, up to the specified max absolute error bound, including NaN values when
 // rhs is NaN.  The max absolute error bound must be non-negative.
@@ -4430,7 +4635,7 @@
 // matches a Foo object x if and only if x.number >= 5.
 template <typename Class, typename FieldType, typename FieldMatcher>
 inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
-    FieldType Class::*field, const FieldMatcher& matcher) {
+    FieldType Class::* field, const FieldMatcher& matcher) {
   return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
       field, MatcherCast<const FieldType&>(matcher)));
   // The call to MatcherCast() is required for supporting inner
@@ -4443,7 +4648,7 @@
 // messages.
 template <typename Class, typename FieldType, typename FieldMatcher>
 inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
-    const std::string& field_name, FieldType Class::*field,
+    const std::string& field_name, FieldType Class::* field,
     const FieldMatcher& matcher) {
   return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
       field_name, field, MatcherCast<const FieldType&>(matcher)));
diff --git a/third_party/googletest/googlemock/test/gmock-actions_test.cc b/third_party/googletest/googlemock/test/gmock-actions_test.cc
index 84db511..46b0e91 100644
--- a/third_party/googletest/googlemock/test/gmock-actions_test.cc
+++ b/third_party/googletest/googlemock/test/gmock-actions_test.cc
@@ -1645,6 +1645,22 @@
   EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
 }
 
+// It should be fine to provide an lvalue WithArgsAction to WillOnce, even when
+// the inner action only wants to convert to OnceAction.
+TEST(WithArgsTest, ProvideAsLvalueToWillOnce) {
+  struct SomeAction {
+    operator OnceAction<int(int)>() const {  // NOLINT
+      return [](const int arg) { return arg + 2; };
+    }
+  };
+
+  const auto wa = WithArg<1>(SomeAction{});
+
+  MockFunction<int(int, int)> mock;
+  EXPECT_CALL(mock, Call).WillOnce(wa);
+  EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
+}
+
 #ifndef GTEST_OS_WINDOWS_MOBILE
 
 class SetErrnoAndReturnTest : public testing::Test {
diff --git a/third_party/googletest/googlemock/test/gmock-matchers-arithmetic_test.cc b/third_party/googletest/googlemock/test/gmock-matchers-arithmetic_test.cc
index 06b0b47..b6c3511 100644
--- a/third_party/googletest/googlemock/test/gmock-matchers-arithmetic_test.cc
+++ b/third_party/googletest/googlemock/test/gmock-matchers-arithmetic_test.cc
@@ -34,6 +34,7 @@
 #include <cmath>
 #include <limits>
 #include <memory>
+#include <ostream>
 #include <string>
 
 #include "gmock/gmock.h"
@@ -398,6 +399,188 @@
   EXPECT_EQ("are an almost-equal pair", Describe(m));
 }
 
+// Tests that DistanceFrom() can describe itself properly.
+TEST(DistanceFrom, CanDescribeSelf) {
+  Matcher<double> m = DistanceFrom(1.5, Lt(0.1));
+  EXPECT_EQ(Describe(m), "is < 0.1 away from 1.5");
+
+  m = DistanceFrom(2.5, Gt(0.2));
+  EXPECT_EQ(Describe(m), "is > 0.2 away from 2.5");
+}
+
+// Tests that DistanceFrom() can explain match failure.
+TEST(DistanceFrom, CanExplainMatchFailure) {
+  Matcher<double> m = DistanceFrom(1.5, Lt(0.1));
+  EXPECT_EQ(Explain(m, 2.0), "which is 0.5 away from 1.5");
+}
+
+// Tests that DistanceFrom() matches a double that is within the given range of
+// the given value.
+TEST(DistanceFrom, MatchesDoubleWithinRange) {
+  const Matcher<double> m = DistanceFrom(0.5, Le(0.1));
+  EXPECT_TRUE(m.Matches(0.45));
+  EXPECT_TRUE(m.Matches(0.5));
+  EXPECT_TRUE(m.Matches(0.55));
+  EXPECT_FALSE(m.Matches(0.39));
+  EXPECT_FALSE(m.Matches(0.61));
+}
+
+// Tests that DistanceFrom() matches a double reference that is within the given
+// range of the given value.
+TEST(DistanceFrom, MatchesDoubleRefWithinRange) {
+  const Matcher<const double&> m = DistanceFrom(0.5, Le(0.1));
+  EXPECT_TRUE(m.Matches(0.45));
+  EXPECT_TRUE(m.Matches(0.5));
+  EXPECT_TRUE(m.Matches(0.55));
+  EXPECT_FALSE(m.Matches(0.39));
+  EXPECT_FALSE(m.Matches(0.61));
+}
+
+// Tests that DistanceFrom() can be implicitly converted to a matcher depending
+// on the type of the argument.
+TEST(DistanceFrom, CanBeImplicitlyConvertedToMatcher) {
+  EXPECT_THAT(0.58, DistanceFrom(0.5, Le(0.1)));
+  EXPECT_THAT(0.2, Not(DistanceFrom(0.5, Le(0.1))));
+
+  EXPECT_THAT(0.58f, DistanceFrom(0.5f, Le(0.1f)));
+  EXPECT_THAT(0.7f, Not(DistanceFrom(0.5f, Le(0.1f))));
+}
+
+// Tests that DistanceFrom() can be used on compatible types (i.e. not
+// everything has to be of the same type).
+TEST(DistanceFrom, CanBeUsedOnCompatibleTypes) {
+  EXPECT_THAT(0.58, DistanceFrom(0.5, Le(0.1f)));
+  EXPECT_THAT(0.2, Not(DistanceFrom(0.5, Le(0.1f))));
+
+  EXPECT_THAT(0.58, DistanceFrom(0.5f, Le(0.1)));
+  EXPECT_THAT(0.2, Not(DistanceFrom(0.5f, Le(0.1))));
+
+  EXPECT_THAT(0.58, DistanceFrom(0.5f, Le(0.1f)));
+  EXPECT_THAT(0.2, Not(DistanceFrom(0.5f, Le(0.1f))));
+
+  EXPECT_THAT(0.58f, DistanceFrom(0.5, Le(0.1)));
+  EXPECT_THAT(0.2f, Not(DistanceFrom(0.5, Le(0.1))));
+
+  EXPECT_THAT(0.58f, DistanceFrom(0.5, Le(0.1f)));
+  EXPECT_THAT(0.2f, Not(DistanceFrom(0.5, Le(0.1f))));
+
+  EXPECT_THAT(0.58f, DistanceFrom(0.5f, Le(0.1)));
+  EXPECT_THAT(0.2f, Not(DistanceFrom(0.5f, Le(0.1))));
+}
+
+// A 2-dimensional point. For testing using DistanceFrom() with a custom type
+// that doesn't have a built-in distance function.
+class Point {
+ public:
+  Point(double x, double y) : x_(x), y_(y) {}
+  double x() const { return x_; }
+  double y() const { return y_; }
+
+ private:
+  double x_;
+  double y_;
+};
+
+// Returns the distance between two points.
+double PointDistance(const Point& lhs, const Point& rhs) {
+  return std::sqrt(std::pow(lhs.x() - rhs.x(), 2) +
+                   std::pow(lhs.y() - rhs.y(), 2));
+}
+
+// Tests that DistanceFrom() can be used on a type with a custom distance
+// function.
+TEST(DistanceFrom, CanBeUsedOnTypeWithCustomDistanceFunction) {
+  const Matcher<Point> m =
+      DistanceFrom(Point(0.5, 0.5), PointDistance, Le(0.1));
+  EXPECT_THAT(Point(0.45, 0.45), m);
+  EXPECT_THAT(Point(0.2, 0.45), Not(m));
+}
+
+// A wrapper around a double value. For testing using DistanceFrom() with a
+// custom type that has neither a built-in distance function nor a built-in
+// distance comparator.
+class Double {
+ public:
+  explicit Double(double value) : value_(value) {}
+  Double(const Double& other) = default;
+  double value() const { return value_; }
+
+  // Defines how to print a Double value. We don't use the AbslStringify API
+  // because googletest doesn't require absl yet.
+  friend void PrintTo(const Double& value, std::ostream* os) {
+    *os << "Double(" << value.value() << ")";
+  }
+
+ private:
+  double value_;
+};
+
+// Returns the distance between two Double values.
+Double DoubleDistance(Double lhs, Double rhs) {
+  return Double(std::abs(lhs.value() - rhs.value()));
+}
+
+MATCHER_P(DoubleLe, rhs, (negation ? "is > " : "is <= ") + PrintToString(rhs)) {
+  return arg.value() <= rhs.value();
+}
+
+// Tests that DistanceFrom() can describe itself properly for a type with a
+// custom printer.
+TEST(DistanceFrom, CanDescribeWithCustomPrinter) {
+  const Matcher<Double> m =
+      DistanceFrom(Double(0.5), DoubleDistance, DoubleLe(Double(0.1)));
+  EXPECT_EQ(Describe(m), "is <= Double(0.1) away from Double(0.5)");
+  EXPECT_EQ(DescribeNegation(m), "is > Double(0.1) away from Double(0.5)");
+}
+
+// Tests that DistanceFrom() can be used with a custom distance function and
+// comparator.
+TEST(DistanceFrom, CanCustomizeDistanceAndComparator) {
+  const Matcher<Double> m =
+      DistanceFrom(Double(0.5), DoubleDistance, DoubleLe(Double(0.1)));
+  EXPECT_TRUE(m.Matches(Double(0.45)));
+  EXPECT_TRUE(m.Matches(Double(0.5)));
+  EXPECT_FALSE(m.Matches(Double(0.39)));
+  EXPECT_FALSE(m.Matches(Double(0.61)));
+}
+
+// For testing using DistanceFrom() with a type that supports both - and abs.
+class Float {
+ public:
+  explicit Float(float value) : value_(value) {}
+  Float(const Float& other) = default;
+  float value() const { return value_; }
+
+ private:
+  float value_ = 0.0f;
+};
+
+// Returns the difference between two Float values. This must be defined in the
+// same namespace as Float.
+Float operator-(const Float& lhs, const Float& rhs) {
+  return Float(lhs.value() - rhs.value());
+}
+
+// Returns the absolute value of a Float value. This must be defined in the
+// same namespace as Float.
+Float abs(Float value) { return Float(std::abs(value.value())); }
+
+// Returns true if and only if the first Float value is less than the second
+// Float value. This must be defined in the same namespace as Float.
+bool operator<(const Float& lhs, const Float& rhs) {
+  return lhs.value() < rhs.value();
+}
+
+// Tests that DistanceFrom() can be used with a type that supports both - and
+// abs.
+TEST(DistanceFrom, CanBeUsedWithTypeThatSupportsBothMinusAndAbs) {
+  const Matcher<Float> m = DistanceFrom(Float(0.5f), Lt(Float(0.1f)));
+  EXPECT_TRUE(m.Matches(Float(0.45f)));
+  EXPECT_TRUE(m.Matches(Float(0.55f)));
+  EXPECT_FALSE(m.Matches(Float(0.39f)));
+  EXPECT_FALSE(m.Matches(Float(0.61f)));
+}
+
 // Tests that Not(m) matches any value that doesn't match m.
 TEST(NotTest, NegatesMatcher) {
   Matcher<int> m;
diff --git a/third_party/googletest/googlemock/test/gmock-matchers-comparisons_test.cc b/third_party/googletest/googlemock/test/gmock-matchers-comparisons_test.cc
index a331aec..87eca08 100644
--- a/third_party/googletest/googlemock/test/gmock-matchers-comparisons_test.cc
+++ b/third_party/googletest/googlemock/test/gmock-matchers-comparisons_test.cc
@@ -33,6 +33,7 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
@@ -2396,6 +2397,74 @@
   EXPECT_EQ("is >= 2, and is <= 3", Explain(m, 2));
 }
 
+// A matcher that records whether the listener was interested.
+template <typename T>
+class CountingMatcher : public MatcherInterface<T> {
+ public:
+  explicit CountingMatcher(const Matcher<T>& base_matcher,
+                           std::vector<bool>* listener_interested)
+      : base_matcher_(base_matcher),
+        listener_interested_(listener_interested) {}
+
+  bool MatchAndExplain(T x, MatchResultListener* listener) const override {
+    listener_interested_->push_back(listener->IsInterested());
+    return base_matcher_.MatchAndExplain(x, listener);
+  }
+
+  void DescribeTo(ostream* os) const override { base_matcher_.DescribeTo(os); }
+
+ private:
+  Matcher<T> base_matcher_;
+  std::vector<bool>* listener_interested_;
+};
+
+TEST(AllOfTest, DoesNotFormatChildMatchersWhenNotInterested) {
+  std::vector<bool> listener_interested;
+  Matcher<int> matcher =
+      MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
+  EXPECT_TRUE(matcher.Matches(1));
+  EXPECT_THAT(listener_interested, ElementsAre(false));
+  listener_interested.clear();
+  Matcher<int> all_of_matcher = AllOf(matcher, matcher);
+  EXPECT_TRUE(all_of_matcher.Matches(1));
+  EXPECT_THAT(listener_interested, ElementsAre(false, false));
+  listener_interested.clear();
+  EXPECT_FALSE(all_of_matcher.Matches(0));
+  EXPECT_THAT(listener_interested, ElementsAre(false));
+}
+
+TEST(AnyOfTest, DoesNotFormatChildMatchersWhenNotInterested) {
+  std::vector<bool> listener_interested;
+  Matcher<int> matcher =
+      MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
+  EXPECT_TRUE(matcher.Matches(1));
+  EXPECT_THAT(listener_interested, ElementsAre(false));
+  listener_interested.clear();
+  Matcher<int> any_of_matcher = AnyOf(matcher, matcher);
+  EXPECT_TRUE(any_of_matcher.Matches(1));
+  EXPECT_THAT(listener_interested, ElementsAre(false));
+  listener_interested.clear();
+  EXPECT_FALSE(any_of_matcher.Matches(0));
+  EXPECT_THAT(listener_interested, ElementsAre(false, false));
+}
+
+TEST(OptionalTest, DoesNotFormatChildMatcherWhenNotInterested) {
+  std::vector<bool> listener_interested;
+  Matcher<int> matcher =
+      MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
+  EXPECT_TRUE(matcher.Matches(1));
+  EXPECT_THAT(listener_interested, ElementsAre(false));
+  listener_interested.clear();
+  Matcher<std::optional<int>> optional_matcher = Optional(matcher);
+  EXPECT_FALSE(optional_matcher.Matches(std::nullopt));
+  EXPECT_THAT(listener_interested, ElementsAre());
+  EXPECT_TRUE(optional_matcher.Matches(1));
+  EXPECT_THAT(listener_interested, ElementsAre(false));
+  listener_interested.clear();
+  EXPECT_FALSE(matcher.Matches(0));
+  EXPECT_THAT(listener_interested, ElementsAre(false));
+}
+
 INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest);
 
 TEST_P(ExplainmatcherResultTestP, MonomorphicMatcher) {
diff --git a/third_party/googletest/googlemock/test/gmock-matchers-containers_test.cc b/third_party/googletest/googlemock/test/gmock-matchers-containers_test.cc
index 751fb60..e9f1a02 100644
--- a/third_party/googletest/googlemock/test/gmock-matchers-containers_test.cc
+++ b/third_party/googletest/googlemock/test/gmock-matchers-containers_test.cc
@@ -33,6 +33,7 @@
 
 #include <algorithm>
 #include <array>
+#include <cstddef>
 #include <deque>
 #include <forward_list>
 #include <iterator>
@@ -1271,10 +1272,11 @@
 
 TEST(WhenSortedByTest, ExplainsMatchResult) {
   const int a[] = {2, 1};
-  EXPECT_EQ("which is { 1, 2 } when sorted, whose element #0 doesn't match",
-            Explain(WhenSortedBy(less<int>(), ElementsAre(2, 3)), a));
-  EXPECT_EQ("which is { 1, 2 } when sorted",
-            Explain(WhenSortedBy(less<int>(), ElementsAre(1, 2)), a));
+  EXPECT_EQ(
+      Explain(WhenSortedBy(less<int>(), ElementsAre(2, 3)), a),
+      "which is { 1, 2 } when sorted, whose element #0 (1) isn't equal to 2");
+  EXPECT_EQ(Explain(WhenSortedBy(less<int>(), ElementsAre(1, 2)), a),
+            "which is { 1, 2 } when sorted");
 }
 
 // WhenSorted() is a simple wrapper on WhenSortedBy().  Hence we don't
@@ -1775,6 +1777,295 @@
   helper.Call(MakeUniquePtrs({2}));
 }
 
+// A container whose iterator returns a temporary. This can iterate over the
+// characters in a string.
+class CharString {
+ public:
+  using value_type = char;
+
+  class const_iterator {
+   public:
+    using iterator_category = std::input_iterator_tag;
+    using value_type = char;
+    using difference_type = std::ptrdiff_t;
+    using pointer = const char*;
+    using reference = const char&;
+
+    // Create an iterator that points to the given character.
+    explicit const_iterator(const char* ptr) : ptr_(ptr) {}
+
+    // Returns the current character. IMPORTANT: this must return a temporary,
+    // not a reference, to test that ElementsAre() works with containers whose
+    // iterators return temporaries.
+    char operator*() const { return *ptr_; }
+
+    // Advances to the next character.
+    const_iterator& operator++() {
+      ++ptr_;
+      return *this;
+    }
+
+    // Compares two iterators.
+    bool operator==(const const_iterator& other) const {
+      return ptr_ == other.ptr_;
+    }
+    bool operator!=(const const_iterator& other) const {
+      return ptr_ != other.ptr_;
+    }
+
+   private:
+    const char* ptr_ = nullptr;
+  };
+
+  // Creates a CharString that contains the given string.
+  explicit CharString(const std::string& s) : s_(s) {}
+
+  // Returns an iterator pointing to the first character in the string.
+  const_iterator begin() const { return const_iterator(s_.c_str()); }
+
+  // Returns an iterator pointing past the last character in the string.
+  const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
+
+ private:
+  std::string s_;
+};
+
+// Tests using ElementsAre() with a container whose iterator returns a
+// temporary.
+TEST(ElementsAreTest, WorksWithContainerThatReturnsTempInIterator) {
+  CharString s("abc");
+  EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
+  EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
+}
+
+// Tests using ElementsAreArray() with a container whose iterator returns a
+// temporary.
+TEST(ElementsAreArrayTest, WorksWithContainerThatReturnsTempInIterator) {
+  CharString s("abc");
+  EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
+  EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
+}
+
+// A container whose iterator returns a temporary and is not copy-assignable.
+// This simulates the behavior of the proxy object returned by absl::StrSplit().
+class CharString2 {
+ public:
+  using value_type = char;
+
+  class const_iterator {
+   public:
+    using iterator_category = std::input_iterator_tag;
+    using value_type = char;
+    using difference_type = std::ptrdiff_t;
+    using pointer = const char*;
+    using reference = const char&;
+
+    // Make const_iterator copy-constructible but not copy-assignable,
+    // simulating the behavior of the proxy object returned by absl::StrSplit().
+    const_iterator(const const_iterator&) = default;
+    const_iterator& operator=(const const_iterator&) = delete;
+
+    // Create an iterator that points to the given character.
+    explicit const_iterator(const char* ptr) : ptr_(ptr) {}
+
+    // Returns the current character. IMPORTANT: this must return a temporary,
+    // not a reference, to test that ElementsAre() works with containers whose
+    // iterators return temporaries.
+    char operator*() const { return *ptr_; }
+
+    // Advances to the next character.
+    const_iterator& operator++() {
+      ++ptr_;
+      return *this;
+    }
+
+    // Compares two iterators.
+    bool operator==(const const_iterator& other) const {
+      return ptr_ == other.ptr_;
+    }
+    bool operator!=(const const_iterator& other) const {
+      return ptr_ != other.ptr_;
+    }
+
+   private:
+    const char* ptr_ = nullptr;
+  };
+
+  // Creates a CharString that contains the given string.
+  explicit CharString2(const std::string& s) : s_(s) {}
+
+  // Returns an iterator pointing to the first character in the string.
+  const_iterator begin() const { return const_iterator(s_.c_str()); }
+
+  // Returns an iterator pointing past the last character in the string.
+  const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
+
+ private:
+  std::string s_;
+};
+
+// Tests using ElementsAre() with a container whose iterator returns a
+// temporary and is not copy-assignable.
+TEST(ElementsAreTest, WorksWithContainerThatReturnsTempInUnassignableIterator) {
+  CharString2 s("abc");
+  EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
+  EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
+}
+
+// Tests using ElementsAreArray() with a container whose iterator returns a
+// temporary and is not copy-assignable.
+TEST(ElementsAreArrayTest,
+     WorksWithContainerThatReturnsTempInUnassignableIterator) {
+  CharString2 s("abc");
+  EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
+  EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
+}
+
+// A container whose iterator returns a temporary and is neither
+// copy-constructible nor copy-assignable.
+class CharString3 {
+ public:
+  using value_type = char;
+
+  class const_iterator {
+   public:
+    using iterator_category = std::input_iterator_tag;
+    using value_type = char;
+    using difference_type = std::ptrdiff_t;
+    using pointer = const char*;
+    using reference = const char&;
+
+    // Make const_iterator neither copy-constructible nor copy-assignable.
+    const_iterator(const const_iterator&) = delete;
+    const_iterator& operator=(const const_iterator&) = delete;
+
+    // Create an iterator that points to the given character.
+    explicit const_iterator(const char* ptr) : ptr_(ptr) {}
+
+    // Returns the current character. IMPORTANT: this must return a temporary,
+    // not a reference, to test that ElementsAre() works with containers whose
+    // iterators return temporaries.
+    char operator*() const { return *ptr_; }
+
+    // Advances to the next character.
+    const_iterator& operator++() {
+      ++ptr_;
+      return *this;
+    }
+
+    // Compares two iterators.
+    bool operator==(const const_iterator& other) const {
+      return ptr_ == other.ptr_;
+    }
+    bool operator!=(const const_iterator& other) const {
+      return ptr_ != other.ptr_;
+    }
+
+   private:
+    const char* ptr_ = nullptr;
+  };
+
+  // Creates a CharString that contains the given string.
+  explicit CharString3(const std::string& s) : s_(s) {}
+
+  // Returns an iterator pointing to the first character in the string.
+  const_iterator begin() const { return const_iterator(s_.c_str()); }
+
+  // Returns an iterator pointing past the last character in the string.
+  const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
+
+ private:
+  std::string s_;
+};
+
+// Tests using ElementsAre() with a container whose iterator returns a
+// temporary and is neither copy-constructible nor copy-assignable.
+TEST(ElementsAreTest, WorksWithContainerThatReturnsTempInUncopyableIterator) {
+  CharString3 s("abc");
+  EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
+  EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
+}
+
+// Tests using ElementsAreArray() with a container whose iterator returns a
+// temporary and is neither copy-constructible nor copy-assignable.
+TEST(ElementsAreArrayTest,
+     WorksWithContainerThatReturnsTempInUncopyableIterator) {
+  CharString3 s("abc");
+  EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
+  EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
+}
+
+// A container whose iterator returns a temporary, is neither
+// copy-constructible nor copy-assignable, and has no member types.
+class CharString4 {
+ public:
+  using value_type = char;
+
+  class const_iterator {
+   public:
+    // Do not define difference_type, etc.
+
+    // Make const_iterator neither copy-constructible nor copy-assignable.
+    const_iterator(const const_iterator&) = delete;
+    const_iterator& operator=(const const_iterator&) = delete;
+
+    // Create an iterator that points to the given character.
+    explicit const_iterator(const char* ptr) : ptr_(ptr) {}
+
+    // Returns the current character. IMPORTANT: this must return a temporary,
+    // not a reference, to test that ElementsAre() works with containers whose
+    // iterators return temporaries.
+    char operator*() const { return *ptr_; }
+
+    // Advances to the next character.
+    const_iterator& operator++() {
+      ++ptr_;
+      return *this;
+    }
+
+    // Compares two iterators.
+    bool operator==(const const_iterator& other) const {
+      return ptr_ == other.ptr_;
+    }
+    bool operator!=(const const_iterator& other) const {
+      return ptr_ != other.ptr_;
+    }
+
+   private:
+    const char* ptr_ = nullptr;
+  };
+
+  // Creates a CharString that contains the given string.
+  explicit CharString4(const std::string& s) : s_(s) {}
+
+  // Returns an iterator pointing to the first character in the string.
+  const_iterator begin() const { return const_iterator(s_.c_str()); }
+
+  // Returns an iterator pointing past the last character in the string.
+  const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
+
+ private:
+  std::string s_;
+};
+
+// Tests using ElementsAre() with a container whose iterator returns a
+// temporary, is neither copy-constructible nor copy-assignable, and has no
+// member types.
+TEST(ElementsAreTest, WorksWithContainerWithIteratorWithNoMemberTypes) {
+  CharString4 s("abc");
+  EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
+  EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
+}
+
+// Tests using ElementsAreArray() with a container whose iterator returns a
+// temporary, is neither copy-constructible nor copy-assignable, and has no
+// member types.
+TEST(ElementsAreArrayTest, WorksWithContainerWithIteratorWithNoMemberTypes) {
+  CharString4 s("abc");
+  EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
+  EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
+}
+
 // Tests using ElementsAre() and ElementsAreArray() with stream-like
 // "containers".
 
@@ -2155,7 +2446,7 @@
   Matcher<set<int>> m = Each(2);
   EXPECT_EQ("", Explain(m, a));
 
-  Matcher<const int(&)[1]> n = Each(1);  // NOLINT
+  Matcher<const int (&)[1]> n = Each(1);  // NOLINT
 
   const int b[1] = {1};
   EXPECT_EQ("", Explain(n, b));
@@ -2290,7 +2581,7 @@
   rhs.push_back(4);
 
   int lhs[] = {1, 2};
-  const Matcher<const int(&)[2]> m = Pointwise(IsHalfOf(), rhs);
+  const Matcher<const int (&)[2]> m = Pointwise(IsHalfOf(), rhs);
   EXPECT_THAT(lhs, m);
 
   // Changing rhs now shouldn't affect m, which made a copy of rhs.
@@ -2418,7 +2709,7 @@
   rhs.push_back(4);
 
   int lhs[] = {2, 1};
-  const Matcher<const int(&)[2]> m = UnorderedPointwise(IsHalfOf(), rhs);
+  const Matcher<const int (&)[2]> m = UnorderedPointwise(IsHalfOf(), rhs);
   EXPECT_THAT(lhs, m);
 
   // Changing rhs now shouldn't affect m, which made a copy of rhs.
@@ -2669,11 +2960,11 @@
   vector<int> v;
   v.push_back(2);
   v.push_back(1);
-  EXPECT_EQ("whose element #0 doesn't match", Explain(m, v));
+  EXPECT_EQ(Explain(m, v), "whose element #0 (2) isn't equal to 1");
 
   v[0] = 1;
-  EXPECT_EQ("whose element #1 doesn't match, which is 4 less than 5",
-            Explain(m, v));
+  EXPECT_EQ(Explain(m, v),
+            "whose element #1 (1) is <= 5, which is 4 less than 5");
 }
 
 TEST(ElementsAreTest, MatchesOneElementVector) {
@@ -3073,7 +3364,7 @@
 
 TEST_P(ContainsTestP, ExplainsMatchResultCorrectly) {
   const int a[2] = {1, 2};
-  Matcher<const int(&)[2]> m = Contains(2);
+  Matcher<const int (&)[2]> m = Contains(2);
   EXPECT_EQ("whose element #1 matches", Explain(m, a));
 
   m = Contains(3);
diff --git a/third_party/googletest/googletest/CMakeLists.txt b/third_party/googletest/googletest/CMakeLists.txt
index dce6a7c..2e53889 100644
--- a/third_party/googletest/googletest/CMakeLists.txt
+++ b/third_party/googletest/googletest/CMakeLists.txt
@@ -132,9 +132,6 @@
     absl::flags_reflection
     absl::flags_usage
     absl::strings
-    absl::any
-    absl::optional
-    absl::variant
     re2::re2
   )
 endif()
diff --git a/third_party/googletest/googletest/README.md b/third_party/googletest/googletest/README.md
index 5de23c5..26e48d1 100644
--- a/third_party/googletest/googletest/README.md
+++ b/third_party/googletest/googletest/README.md
@@ -25,7 +25,7 @@
 with
 
 ```
-git clone https://github.com/google/googletest.git -b v1.16.0
+git clone https://github.com/google/googletest.git -b v1.17.0
 cd googletest        # Main directory of the cloned repository.
 mkdir build          # Create a directory to hold the build output.
 cd build
@@ -124,9 +124,9 @@
 
 #### C++ Standard Version
 
-An environment that supports C++14 is required in order to successfully build
+An environment that supports C++17 is required in order to successfully build
 GoogleTest. One way to ensure this is to specify the standard in the top-level
-project, for example by using the `set(CMAKE_CXX_STANDARD 14)` command along
+project, for example by using the `set(CMAKE_CXX_STANDARD 17)` command along
 with `set(CMAKE_CXX_STANDARD_REQUIRED ON)`. If this is not feasible, for example
 in a C project using GoogleTest for validation, then it can be specified by
 adding it to the options for cmake via the`-DCMAKE_CXX_FLAGS` option.
@@ -145,9 +145,9 @@
 ### Multi-threaded Tests
 
 GoogleTest is thread-safe where the pthread library is available. After
-`#include <gtest/gtest.h>`, you can check the
-`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is
-`#defined` to 1, no if it's undefined.).
+`#include <gtest/gtest.h>`, you can check the `GTEST_IS_THREADSAFE` macro to see
+whether this is the case (yes if the macro is `#defined` to 1, no if it's
+undefined.).
 
 If GoogleTest doesn't correctly detect whether pthread is available in your
 environment, you can force it with
diff --git a/third_party/googletest/googletest/include/gtest/gtest-param-test.h b/third_party/googletest/googletest/include/gtest/gtest-param-test.h
index dbfc5c8..9e023f9 100644
--- a/third_party/googletest/googletest/include/gtest/gtest-param-test.h
+++ b/third_party/googletest/googletest/include/gtest/gtest-param-test.h
@@ -174,6 +174,7 @@
 
 #endif  // 0
 
+#include <functional>
 #include <iterator>
 #include <utility>
 
@@ -413,7 +414,8 @@
 // Synopsis:
 // ConvertGenerator<T>(gen)
 //   - returns a generator producing the same elements as generated by gen, but
-//     each element is static_cast to type T before being returned
+//     each T-typed element is static_cast to a type deduced from the interface
+//     that accepts this generator, and then returned
 //
 // It is useful when using the Combine() function to get the generated
 // parameters in a custom type instead of std::tuple
@@ -441,10 +443,65 @@
 //                              Combine(Values("cat", "dog"),
 //                                      Values(BLACK, WHITE))));
 //
-template <typename T>
-internal::ParamConverterGenerator<T> ConvertGenerator(
-    internal::ParamGenerator<T> gen) {
-  return internal::ParamConverterGenerator<T>(gen);
+template <typename RequestedT>
+internal::ParamConverterGenerator<RequestedT> ConvertGenerator(
+    internal::ParamGenerator<RequestedT> gen) {
+  return internal::ParamConverterGenerator<RequestedT>(std::move(gen));
+}
+
+// As above, but takes a callable as a second argument. The callable converts
+// the generated parameter to the test fixture's parameter type. This allows you
+// to use a parameter type that does not have a converting constructor from the
+// generated type.
+//
+// Example:
+//
+// This will instantiate tests in test suite AnimalTest each one with
+// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
+// tuple("dog", BLACK), and tuple("dog", WHITE):
+//
+// enum Color { BLACK, GRAY, WHITE };
+// struct ParamType {
+//   std::string animal;
+//   Color color;
+// };
+// class AnimalTest
+//     : public testing::TestWithParam<ParamType> {...};
+//
+// TEST_P(AnimalTest, AnimalLooksNice) {...}
+//
+// INSTANTIATE_TEST_SUITE_P(
+//     AnimalVariations, AnimalTest,
+//     ConvertGenerator(Combine(Values("cat", "dog"), Values(BLACK, WHITE)),
+//                      [](std::tuple<std::string, Color> t) {
+//                        return ParamType{.animal = std::get<0>(t),
+//                                         .color = std::get<1>(t)};
+//                      }));
+//
+template <typename T, int&... ExplicitArgumentBarrier, typename Gen,
+          typename Func,
+          typename StdFunction = decltype(std::function(std::declval<Func>()))>
+internal::ParamConverterGenerator<T, StdFunction> ConvertGenerator(Gen&& gen,
+                                                                   Func&& f) {
+  return internal::ParamConverterGenerator<T, StdFunction>(
+      std::forward<Gen>(gen), std::forward<Func>(f));
+}
+
+// As above, but infers the T from the supplied std::function instead of
+// having the caller specify it.
+template <int&... ExplicitArgumentBarrier, typename Gen, typename Func,
+          typename StdFunction = decltype(std::function(std::declval<Func>()))>
+auto ConvertGenerator(Gen&& gen, Func&& f) {
+  constexpr bool is_single_arg_std_function =
+      internal::IsSingleArgStdFunction<StdFunction>::value;
+  if constexpr (is_single_arg_std_function) {
+    return ConvertGenerator<
+        typename internal::FuncSingleParamType<StdFunction>::type>(
+        std::forward<Gen>(gen), std::forward<Func>(f));
+  } else {
+    static_assert(is_single_arg_std_function,
+                  "The call signature must contain a single argument.");
+  }
 }
 
 #define TEST_P(test_suite_name, test_name)                                     \
diff --git a/third_party/googletest/googletest/include/gtest/gtest-printers.h b/third_party/googletest/googletest/include/gtest/gtest-printers.h
index 198a769..cb73ef2 100644
--- a/third_party/googletest/googletest/include/gtest/gtest-printers.h
+++ b/third_party/googletest/googletest/include/gtest/gtest-printers.h
@@ -104,8 +104,10 @@
 #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
 #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
 
+#include <any>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <ostream>  // NOLINT
 #include <sstream>
 #include <string>
@@ -113,6 +115,7 @@
 #include <type_traits>
 #include <typeinfo>
 #include <utility>
+#include <variant>
 #include <vector>
 
 #ifdef GTEST_HAS_ABSL
@@ -521,11 +524,15 @@
 
 GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
 inline void PrintTo(char16_t c, ::std::ostream* os) {
-  PrintTo(ImplicitCast_<char32_t>(c), os);
+  // TODO(b/418738869): Incorrect for values not representing valid codepoints.
+  // Also see https://github.com/google/googletest/issues/4762.
+  PrintTo(static_cast<char32_t>(c), os);
 }
 #ifdef __cpp_lib_char8_t
 inline void PrintTo(char8_t c, ::std::ostream* os) {
-  PrintTo(ImplicitCast_<char32_t>(c), os);
+  // TODO(b/418738869): Incorrect for values not representing valid codepoints.
+  // Also see https://github.com/google/googletest/issues/4762.
+  PrintTo(static_cast<char32_t>(c), os);
 }
 #endif
 
@@ -890,14 +897,11 @@
 template <typename T>
 class UniversalPrinter<const T> : public UniversalPrinter<T> {};
 
-#if GTEST_INTERNAL_HAS_ANY
-
-// Printer for std::any / absl::any
-
+// Printer for std::any
 template <>
-class UniversalPrinter<Any> {
+class UniversalPrinter<std::any> {
  public:
-  static void Print(const Any& value, ::std::ostream* os) {
+  static void Print(const std::any& value, ::std::ostream* os) {
     if (value.has_value()) {
       *os << "value of type " << GetTypeName(value);
     } else {
@@ -906,7 +910,7 @@
   }
 
  private:
-  static std::string GetTypeName(const Any& value) {
+  static std::string GetTypeName(const std::any& value) {
 #if GTEST_HAS_RTTI
     return internal::GetTypeName(value.type());
 #else
@@ -916,16 +920,11 @@
   }
 };
 
-#endif  // GTEST_INTERNAL_HAS_ANY
-
-#if GTEST_INTERNAL_HAS_OPTIONAL
-
-// Printer for std::optional / absl::optional
-
+// Printer for std::optional
 template <typename T>
-class UniversalPrinter<Optional<T>> {
+class UniversalPrinter<std::optional<T>> {
  public:
-  static void Print(const Optional<T>& value, ::std::ostream* os) {
+  static void Print(const std::optional<T>& value, ::std::ostream* os) {
     *os << '(';
     if (!value) {
       *os << "nullopt";
@@ -937,29 +936,18 @@
 };
 
 template <>
-class UniversalPrinter<decltype(Nullopt())> {
+class UniversalPrinter<std::nullopt_t> {
  public:
-  static void Print(decltype(Nullopt()), ::std::ostream* os) {
-    *os << "(nullopt)";
-  }
+  static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
 };
 
-#endif  // GTEST_INTERNAL_HAS_OPTIONAL
-
-#if GTEST_INTERNAL_HAS_VARIANT
-
-// Printer for std::variant / absl::variant
-
+// Printer for std::variant
 template <typename... T>
-class UniversalPrinter<Variant<T...>> {
+class UniversalPrinter<std::variant<T...>> {
  public:
-  static void Print(const Variant<T...>& value, ::std::ostream* os) {
+  static void Print(const std::variant<T...>& value, ::std::ostream* os) {
     *os << '(';
-#ifdef GTEST_HAS_ABSL
-    absl::visit(Visitor{os, value.index()}, value);
-#else
     std::visit(Visitor{os, value.index()}, value);
-#endif  // GTEST_HAS_ABSL
     *os << ')';
   }
 
@@ -976,8 +964,6 @@
   };
 };
 
-#endif  // GTEST_INTERNAL_HAS_VARIANT
-
 // UniversalPrintArray(begin, len, os) prints an array of 'len'
 // elements, starting at address 'begin'.
 template <typename T>
diff --git a/third_party/googletest/googletest/include/gtest/gtest.h b/third_party/googletest/googletest/include/gtest/gtest.h
index 7be0caa..cbe680c 100644
--- a/third_party/googletest/googletest/include/gtest/gtest.h
+++ b/third_party/googletest/googletest/include/gtest/gtest.h
@@ -1693,7 +1693,7 @@
 
   // The current parameter value. Is also available in the test fixture's
   // constructor.
-  static const ParamType& GetParam() {
+  [[nodiscard]] static const ParamType& GetParam() {
     GTEST_CHECK_(parameter_ != nullptr)
         << "GetParam() can only be called inside a value-parameterized test "
         << "-- did you intend to write TEST_P instead of TEST_F?";
diff --git a/third_party/googletest/googletest/include/gtest/internal/gtest-internal.h b/third_party/googletest/googletest/include/gtest/internal/gtest-internal.h
index dcab397..808d89b 100644
--- a/third_party/googletest/googletest/include/gtest/internal/gtest-internal.h
+++ b/third_party/googletest/googletest/include/gtest/internal/gtest-internal.h
@@ -290,17 +290,17 @@
   // around may change its bits, although the new value is guaranteed
   // to be also a NAN.  Therefore, don't expect this constructor to
   // preserve the bits in x when x is a NAN.
-  explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
+  explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); }
 
   // Static methods
 
   // Reinterprets a bit pattern as a floating-point number.
   //
   // This function is needed to test the AlmostEquals() method.
-  static RawType ReinterpretBits(const Bits bits) {
-    FloatingPoint fp(0);
-    fp.u_.bits_ = bits;
-    return fp.u_.value_;
+  static RawType ReinterpretBits(Bits bits) {
+    RawType fp;
+    memcpy(&fp, &bits, sizeof(fp));
+    return fp;
   }
 
   // Returns the floating-point number that represent positive infinity.
@@ -309,16 +309,16 @@
   // Non-static methods
 
   // Returns the bits that represents this number.
-  const Bits& bits() const { return u_.bits_; }
+  const Bits& bits() const { return bits_; }
 
   // Returns the exponent bits of this number.
-  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
+  Bits exponent_bits() const { return kExponentBitMask & bits_; }
 
   // Returns the fraction bits of this number.
-  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
+  Bits fraction_bits() const { return kFractionBitMask & bits_; }
 
   // Returns the sign bit of this number.
-  Bits sign_bit() const { return kSignBitMask & u_.bits_; }
+  Bits sign_bit() const { return kSignBitMask & bits_; }
 
   // Returns true if and only if this is NAN (not a number).
   bool is_nan() const {
@@ -332,23 +332,16 @@
   //
   //   - returns false if either number is (or both are) NAN.
   //   - treats really large numbers as almost equal to infinity.
-  //   - thinks +0.0 and -0.0 are 0 DLP's apart.
+  //   - thinks +0.0 and -0.0 are 0 ULP's apart.
   bool AlmostEquals(const FloatingPoint& rhs) const {
     // The IEEE standard says that any comparison operation involving
     // a NAN must return false.
     if (is_nan() || rhs.is_nan()) return false;
 
-    return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
-           kMaxUlps;
+    return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
   }
 
  private:
-  // The data type used to store the actual floating-point number.
-  union FloatingPointUnion {
-    RawType value_;  // The raw floating-point number.
-    Bits bits_;      // The bits that represent the number.
-  };
-
   // Converts an integer from the sign-and-magnitude representation to
   // the biased representation.  More precisely, let N be 2 to the
   // power of (kBitCount - 1), an integer x is represented by the
@@ -364,7 +357,7 @@
   //
   // Read https://en.wikipedia.org/wiki/Signed_number_representations
   // for more details on signed number representations.
-  static Bits SignAndMagnitudeToBiased(const Bits& sam) {
+  static Bits SignAndMagnitudeToBiased(Bits sam) {
     if (kSignBitMask & sam) {
       // sam represents a negative number.
       return ~sam + 1;
@@ -376,14 +369,13 @@
 
   // Given two numbers in the sign-and-magnitude representation,
   // returns the distance between them as an unsigned number.
-  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
-                                                     const Bits& sam2) {
+  static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
     const Bits biased1 = SignAndMagnitudeToBiased(sam1);
     const Bits biased2 = SignAndMagnitudeToBiased(sam2);
     return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
   }
 
-  FloatingPointUnion u_;
+  Bits bits_;  // The bits that represent the number.
 };
 
 // Typedefs the instances of the FloatingPoint template class that we
diff --git a/third_party/googletest/googletest/include/gtest/internal/gtest-param-util.h b/third_party/googletest/googletest/include/gtest/internal/gtest-param-util.h
index cc7ea53..a092a86 100644
--- a/third_party/googletest/googletest/include/gtest/internal/gtest-param-util.h
+++ b/third_party/googletest/googletest/include/gtest/internal/gtest-param-util.h
@@ -39,6 +39,7 @@
 #include <ctype.h>
 
 #include <cassert>
+#include <functional>
 #include <iterator>
 #include <map>
 #include <memory>
@@ -529,8 +530,7 @@
   // prefix). test_base_name is the name of an individual test without
   // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
   // test suite base name and DoBar is test base name.
-  void AddTestPattern(const char*,
-                      const char* test_base_name,
+  void AddTestPattern(const char*, const char* test_base_name,
                       TestMetaFactoryBase<ParamType>* meta_factory,
                       CodeLocation code_location) {
     tests_.emplace_back(
@@ -952,11 +952,11 @@
   std::tuple<Gen...> generators_;
 };
 
-template <typename From, typename To>
+template <typename From, typename To, typename Func>
 class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
  public:
-  ParamGeneratorConverter(ParamGenerator<From> gen)  // NOLINT
-      : generator_(std::move(gen)) {}
+  ParamGeneratorConverter(ParamGenerator<From> gen, Func converter)  // NOLINT
+      : generator_(std::move(gen)), converter_(std::move(converter)) {}
 
   ParamIteratorInterface<To>* Begin() const override {
     return new Iterator(this, generator_.begin(), generator_.end());
@@ -965,13 +965,21 @@
     return new Iterator(this, generator_.end(), generator_.end());
   }
 
+  // Returns the std::function wrapping the user-supplied converter callable. It
+  // is used by the iterator (see class Iterator below) to convert the object
+  // (of type FROM) returned by the ParamGenerator to an object of a type that
+  // can be static_cast to type TO.
+  const Func& TypeConverter() const { return converter_; }
+
  private:
   class Iterator : public ParamIteratorInterface<To> {
    public:
-    Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
+    Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
              ParamIterator<From> end)
         : base_(base), it_(it), end_(end) {
-      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
+      if (it_ != end_)
+        value_ =
+            std::make_shared<To>(static_cast<To>(base->TypeConverter()(*it_)));
     }
     ~Iterator() override = default;
 
@@ -980,7 +988,9 @@
     }
     void Advance() override {
       ++it_;
-      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
+      if (it_ != end_)
+        value_ =
+            std::make_shared<To>(static_cast<To>(base_->TypeConverter()(*it_)));
     }
     ParamIteratorInterface<To>* Clone() const override {
       return new Iterator(*this);
@@ -1000,30 +1010,54 @@
    private:
     Iterator(const Iterator& other) = default;
 
-    const ParamGeneratorInterface<To>* const base_;
+    const ParamGeneratorConverter* const base_;
     ParamIterator<From> it_;
     ParamIterator<From> end_;
     std::shared_ptr<To> value_;
   };  // class ParamGeneratorConverter::Iterator
 
   ParamGenerator<From> generator_;
+  Func converter_;
 };  // class ParamGeneratorConverter
 
-template <class Gen>
+template <class GeneratedT,
+          typename StdFunction =
+              std::function<const GeneratedT&(const GeneratedT&)>>
 class ParamConverterGenerator {
  public:
-  ParamConverterGenerator(ParamGenerator<Gen> g)  // NOLINT
-      : generator_(std::move(g)) {}
+  ParamConverterGenerator(ParamGenerator<GeneratedT> g)  // NOLINT
+      : generator_(std::move(g)), converter_(Identity) {}
+
+  ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
+      : generator_(std::move(g)), converter_(std::move(converter)) {}
 
   template <typename T>
   operator ParamGenerator<T>() const {  // NOLINT
-    return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
+    return ParamGenerator<T>(
+        new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
+                                                                converter_));
   }
 
  private:
-  ParamGenerator<Gen> generator_;
+  static const GeneratedT& Identity(const GeneratedT& v) { return v; }
+
+  ParamGenerator<GeneratedT> generator_;
+  StdFunction converter_;
 };
 
+// Template to determine the param type of a single-param std::function.
+template <typename T>
+struct FuncSingleParamType;
+template <typename R, typename P>
+struct FuncSingleParamType<std::function<R(P)>> {
+  using type = std::remove_cv_t<std::remove_reference_t<P>>;
+};
+
+template <typename T>
+struct IsSingleArgStdFunction : public std::false_type {};
+template <typename R, typename P>
+struct IsSingleArgStdFunction<std::function<R(P)>> : public std::true_type {};
+
 }  // namespace internal
 }  // namespace testing
 
diff --git a/third_party/googletest/googletest/include/gtest/internal/gtest-port.h b/third_party/googletest/googletest/include/gtest/internal/gtest-port.h
index 4cfc16c..06a5a8e 100644
--- a/third_party/googletest/googletest/include/gtest/internal/gtest-port.h
+++ b/third_party/googletest/googletest/include/gtest/internal/gtest-port.h
@@ -198,21 +198,8 @@
 //                                        suppressed (constant conditional).
 //   GTEST_INTENTIONAL_CONST_COND_POP_  - finish code section where MSVC C4127
 //                                        is suppressed.
-//   GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
-//                            UniversalPrinter<absl::any> specializations.
-//                            Always defined to 0 or 1.
-//   GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>
-//   or
-//                                 UniversalPrinter<absl::optional>
-//                                 specializations. Always defined to 0 or 1.
 //   GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
 //                                 specializations. Always defined to 0 or 1
-//   GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
-//                                    Matcher<absl::string_view>
-//                                    specializations. Always defined to 0 or 1.
-//   GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
-//                                UniversalPrinter<absl::variant>
-//                                specializations. Always defined to 0 or 1.
 //   GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.
 //   GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.
 //   GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
@@ -282,10 +269,14 @@
 
 // Detect C++ feature test macros as gracefully as possible.
 // MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.
-#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \
-    (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<version>))
-#include <version>  // C++20 and later
-#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))
+//
+// GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
+// <version> instead, even though <version> is not available in C++17 mode prior
+// to GCC9.
+#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L || \
+    GTEST_INTERNAL_HAS_INCLUDE(<version>)
+#include <version>  // C++20 or <version> support.
+#else
 #include <ciso646>  // Pre-C++20
 #endif
 
@@ -2331,73 +2322,6 @@
 }  // namespace internal
 }  // namespace testing
 
-#ifdef GTEST_HAS_ABSL
-// Always use absl::any for UniversalPrinter<> specializations if googletest
-// is built with absl support.
-#define GTEST_INTERNAL_HAS_ANY 1
-#include "absl/types/any.h"
-namespace testing {
-namespace internal {
-using Any = ::absl::any;
-}  // namespace internal
-}  // namespace testing
-#else
-#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) &&        \
-                               GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
-                               (!defined(_MSC_VER) || GTEST_HAS_RTTI))
-// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
-// specializations.
-#define GTEST_INTERNAL_HAS_ANY 1
-#include <any>
-namespace testing {
-namespace internal {
-using Any = ::std::any;
-}  // namespace internal
-}  // namespace testing
-// The case where absl is configured NOT to alias std::any is not
-// supported.
-#endif  // __cpp_lib_any
-#endif  // GTEST_HAS_ABSL
-
-#ifndef GTEST_INTERNAL_HAS_ANY
-#define GTEST_INTERNAL_HAS_ANY 0
-#endif
-
-#ifdef GTEST_HAS_ABSL
-// Always use absl::optional for UniversalPrinter<> specializations if
-// googletest is built with absl support.
-#define GTEST_INTERNAL_HAS_OPTIONAL 1
-#include "absl/types/optional.h"
-namespace testing {
-namespace internal {
-template <typename T>
-using Optional = ::absl::optional<T>;
-inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
-}  // namespace internal
-}  // namespace testing
-#else
-#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \
-                                    GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
-// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
-// specializations.
-#define GTEST_INTERNAL_HAS_OPTIONAL 1
-#include <optional>
-namespace testing {
-namespace internal {
-template <typename T>
-using Optional = ::std::optional<T>;
-inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
-}  // namespace internal
-}  // namespace testing
-// The case where absl is configured NOT to alias std::optional is not
-// supported.
-#endif  // __cpp_lib_optional
-#endif  // GTEST_HAS_ABSL
-
-#ifndef GTEST_INTERNAL_HAS_OPTIONAL
-#define GTEST_INTERNAL_HAS_OPTIONAL 0
-#endif
-
 #if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
                                 GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)
 #define GTEST_INTERNAL_HAS_STD_SPAN 1
@@ -2439,38 +2363,6 @@
 #define GTEST_INTERNAL_HAS_STRING_VIEW 0
 #endif
 
-#ifdef GTEST_HAS_ABSL
-// Always use absl::variant for UniversalPrinter<> specializations if googletest
-// is built with absl support.
-#define GTEST_INTERNAL_HAS_VARIANT 1
-#include "absl/types/variant.h"
-namespace testing {
-namespace internal {
-template <typename... T>
-using Variant = ::absl::variant<T...>;
-}  // namespace internal
-}  // namespace testing
-#else
-#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \
-                                   GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
-// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
-// specializations.
-#define GTEST_INTERNAL_HAS_VARIANT 1
-#include <variant>
-namespace testing {
-namespace internal {
-template <typename... T>
-using Variant = ::std::variant<T...>;
-}  // namespace internal
-}  // namespace testing
-// The case where absl is configured NOT to alias std::variant is not supported.
-#endif  // __cpp_lib_variant
-#endif  // GTEST_HAS_ABSL
-
-#ifndef GTEST_INTERNAL_HAS_VARIANT
-#define GTEST_INTERNAL_HAS_VARIANT 0
-#endif
-
 #if (defined(__cpp_lib_three_way_comparison) || \
      (GTEST_INTERNAL_HAS_INCLUDE(<compare>) &&  \
       GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
diff --git a/third_party/googletest/googletest/src/gtest-internal-inl.h b/third_party/googletest/googletest/src/gtest-internal-inl.h
index cc6f004..6a39b93 100644
--- a/third_party/googletest/googletest/src/gtest-internal-inl.h
+++ b/third_party/googletest/googletest/src/gtest-internal-inl.h
@@ -826,6 +826,10 @@
   bool catch_exceptions() const { return catch_exceptions_; }
 
  private:
+  // Returns true if a warning should be issued if no tests match the test
+  // filter flag.
+  bool ShouldWarnIfNoTestsMatchFilter() const;
+
   struct CompareTestSuitesByPointer {
     bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
       return lhs->name_ < rhs->name_;
diff --git a/third_party/googletest/googletest/src/gtest.cc b/third_party/googletest/googletest/src/gtest.cc
index 81096ae..09af151 100644
--- a/third_party/googletest/googletest/src/gtest.cc
+++ b/third_party/googletest/googletest/src/gtest.cc
@@ -192,12 +192,17 @@
 // The default output file.
 static const char kDefaultOutputFile[] = "test_detail";
 
+// These environment variables are set by Bazel.
+// https://bazel.build/reference/test-encyclopedia#initial-conditions
+//
 // The environment variable name for the test shard index.
 static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
 // The environment variable name for the total number of test shards.
 static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
 // The environment variable name for the test shard status file.
 static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
+// The environment variable name for the test output warnings file.
+static const char kTestWarningsOutputFile[] = "TEST_WARNINGS_OUTPUT_FILE";
 
 namespace internal {
 
@@ -5875,6 +5880,23 @@
 static void SetUpEnvironment(Environment* env) { env->SetUp(); }
 static void TearDownEnvironment(Environment* env) { env->TearDown(); }
 
+// If the environment variable TEST_WARNINGS_OUTPUT_FILE was provided, appends
+// `str` to the file, creating the file if necessary.
+#if GTEST_HAS_FILE_SYSTEM
+static void AppendToTestWarningsOutputFile(const std::string& str) {
+  const char* const filename = posix::GetEnv(kTestWarningsOutputFile);
+  if (filename == nullptr) {
+    return;
+  }
+  auto* const file = posix::FOpen(filename, "a");
+  if (file == nullptr) {
+    return;
+  }
+  GTEST_CHECK_(fwrite(str.data(), 1, str.size(), file) == str.size());
+  GTEST_CHECK_(posix::FClose(file) == 0);
+}
+#endif  // GTEST_HAS_FILE_SYSTEM
+
 // Runs all tests in this UnitTest object, prints the result, and
 // returns true if all tests are successful.  If any exception is
 // thrown during a test, the test is considered to be failed, but the
@@ -5896,12 +5918,26 @@
   // user didn't call InitGoogleTest.
   PostFlagParsingInit();
 
-  if (GTEST_FLAG_GET(fail_if_no_test_linked) && total_test_count() == 0) {
+  // Handle the case where the program has no tests linked.
+  // Sometimes this is a programmer mistake, but sometimes it is intended.
+  if (total_test_count() == 0) {
+    constexpr char kNoTestLinkedMessage[] =
+        "This test program does NOT link in any test case.";
+    constexpr char kNoTestLinkedFatal[] =
+        "This is INVALID. Please make sure to link in at least one test case.";
+    constexpr char kNoTestLinkedWarning[] =
+        "Please make sure this is intended.";
+    const bool fail_if_no_test_linked = GTEST_FLAG_GET(fail_if_no_test_linked);
     ColoredPrintf(
-        GTestColor::kRed,
-        "This test program does NOT link in any test case. This is INVALID. "
-        "Please make sure to link in at least one test case.\n");
-    return false;
+        GTestColor::kRed, "%s %s\n", kNoTestLinkedMessage,
+        fail_if_no_test_linked ? kNoTestLinkedFatal : kNoTestLinkedWarning);
+    if (fail_if_no_test_linked) {
+      return false;
+    }
+#if GTEST_HAS_FILE_SYSTEM
+    AppendToTestWarningsOutputFile(std::string(kNoTestLinkedMessage) + ' ' +
+                                   kNoTestLinkedWarning + '\n');
+#endif  // GTEST_HAS_FILE_SYSTEM
   }
 
 #if GTEST_HAS_FILE_SYSTEM
@@ -6077,6 +6113,17 @@
     environments_.clear();
   }
 
+  // Try to warn the user if no tests matched the test filter.
+  if (ShouldWarnIfNoTestsMatchFilter()) {
+    const std::string filter_warning =
+        std::string("filter \"") + GTEST_FLAG_GET(filter) +
+        "\" did not match any test; no tests were run\n";
+    ColoredPrintf(GTestColor::kRed, "WARNING: %s", filter_warning.c_str());
+#if GTEST_HAS_FILE_SYSTEM
+    AppendToTestWarningsOutputFile(filter_warning);
+#endif  // GTEST_HAS_FILE_SYSTEM
+  }
+
   if (!gtest_is_initialized_before_run_all_tests) {
     ColoredPrintf(
         GTestColor::kRed,
@@ -6245,6 +6292,30 @@
   return num_selected_tests;
 }
 
+// Returns true if a warning should be issued if no tests match the test filter
+// flag. We can't simply count the number of tests that ran because, for
+// instance, test sharding and death tests might mean no tests are expected to
+// run in this process, but will run in another process.
+bool UnitTestImpl::ShouldWarnIfNoTestsMatchFilter() const {
+  if (total_test_count() == 0) {
+    // No tests were linked in to program.
+    // This case is handled by a different warning.
+    return false;
+  }
+  const PositiveAndNegativeUnitTestFilter gtest_flag_filter(
+      GTEST_FLAG_GET(filter));
+  for (auto* test_suite : test_suites_) {
+    const std::string& test_suite_name = test_suite->name_;
+    for (TestInfo* test_info : test_suite->test_info_list()) {
+      const std::string& test_name = test_info->name_;
+      if (gtest_flag_filter.MatchesTest(test_suite_name, test_name)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
 // Prints the given C-string on a single line by replacing all '\n'
 // characters with string "\\n".  If the output takes more than
 // max_length characters, only prints the first max_length characters
diff --git a/third_party/googletest/googletest/test/googletest-fail-if-no-test-linked-test.py b/third_party/googletest/googletest/test/googletest-fail-if-no-test-linked-test.py
index 3ecf208..f5854ba 100755
--- a/third_party/googletest/googletest/test/googletest-fail-if-no-test-linked-test.py
+++ b/third_party/googletest/googletest/test/googletest-fail-if-no-test-linked-test.py
@@ -31,21 +31,26 @@
 
 """Tests for Google Test's --gtest_fail_if_no_test_linked flag."""
 
+import os
 from googletest.test import gtest_test_utils
 
 # The command line flag for enabling the fail-if-no-test-linked behavior.
 FAIL_IF_NO_TEST_LINKED_FLAG = "gtest_fail_if_no_test_linked"
 
+# The environment variable for the test output warnings file.
+TEST_WARNINGS_OUTPUT_FILE = "TEST_WARNINGS_OUTPUT_FILE"
+
 
 class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
   """Tests the --gtest_fail_if_no_test_linked flag."""
 
-  def Run(self, program_name, flag=None):
+  def Run(self, program_name, flag=None, env=None):
     """Run the given program with the given flag.
 
     Args:
       program_name: Name of the program to run.
       flag: The command line flag to pass to the program, or None.
+      env: Dictionary with environment to pass to the subprocess.
 
     Returns:
       True if the program exits with code 0, false otherwise.
@@ -55,59 +60,109 @@
     args = [exe_path]
     if flag is not None:
       args += [flag]
-    process = gtest_test_utils.Subprocess(args, capture_stderr=False)
+    process = gtest_test_utils.Subprocess(args, capture_stderr=False, env=env)
     return process.exited and process.exit_code == 0
 
   def testSucceedsIfNoTestLinkedAndFlagNotSpecified(self):
     """Tests the behavior of no test linked and flag not specified."""
-
     self.assertTrue(
         self.Run("googletest-fail-if-no-test-linked-test-without-test_")
     )
 
+  def testSucceedsIfNoTestLinkedAndFlagNotSpecifiedWithWarningFile(self):
+    """Tests that no test linked results in warning file output."""
+
+    warning_file = os.path.join(gtest_test_utils.GetTempDir(), "NO_TEST_LINKED")
+    self.assertTrue(
+        self.Run(
+            "googletest-fail-if-no-test-linked-test-without-test_",
+            env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
+        )
+    )
+    warning_file_contents = open(warning_file, "r").read()
+    self.assertEqual(
+        warning_file_contents,
+        "This test program does NOT link in any test case. Please make sure"
+        " this is intended.\n",
+    )
+
   def testFailsIfNoTestLinkedAndFlagSpecified(self):
     """Tests the behavior of no test linked and flag specified."""
 
+    warning_file = os.path.join(
+        gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
+    )
     self.assertFalse(
         self.Run(
             "googletest-fail-if-no-test-linked-test-without-test_",
             f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
+            env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
         )
     )
+    with self.assertRaises(FileNotFoundError):
+      open(warning_file, "r")
 
   def testSucceedsIfEnabledTestLinkedAndFlagNotSpecified(self):
     """Tests the behavior of enabled test linked and flag not specified."""
 
-    self.assertTrue(
-        self.Run("googletest-fail-if-no-test-linked-test-with-enabled-test_")
+    warning_file = os.path.join(
+        gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
     )
+    self.assertTrue(
+        self.Run(
+            "googletest-fail-if-no-test-linked-test-with-enabled-test_",
+            env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
+        )
+    )
+    with self.assertRaises(FileNotFoundError):
+      open(warning_file, "r")
 
   def testSucceedsIfEnabledTestLinkedAndFlagSpecified(self):
     """Tests the behavior of enabled test linked and flag specified."""
 
+    warning_file = os.path.join(
+        gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
+    )
     self.assertTrue(
         self.Run(
             "googletest-fail-if-no-test-linked-test-with-enabled-test_",
             f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
+            env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
         )
     )
+    with self.assertRaises(FileNotFoundError):
+      open(warning_file, "r")
 
   def testSucceedsIfDisabledTestLinkedAndFlagNotSpecified(self):
     """Tests the behavior of disabled test linked and flag not specified."""
 
-    self.assertTrue(
-        self.Run("googletest-fail-if-no-test-linked-test-with-disabled-test_")
+    warning_file = os.path.join(
+        gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
     )
+    self.assertTrue(
+        self.Run(
+            "googletest-fail-if-no-test-linked-test-with-disabled-test_",
+            env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
+        )
+    )
+    with self.assertRaises(FileNotFoundError):
+      open(warning_file, "r")
 
   def testSucceedsIfDisabledTestLinkedAndFlagSpecified(self):
     """Tests the behavior of disabled test linked and flag specified."""
 
+    warning_file = os.path.join(
+        gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
+    )
     self.assertTrue(
         self.Run(
             "googletest-fail-if-no-test-linked-test-with-disabled-test_",
             f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
+            env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
         )
     )
+    with self.assertRaises(FileNotFoundError):
+      open(warning_file, "r")
 
 
 if __name__ == "__main__":
diff --git a/third_party/googletest/googletest/test/googletest-filter-unittest.py b/third_party/googletest/googletest/test/googletest-filter-unittest.py
index f1f3c7a..a44882a 100755
--- a/third_party/googletest/googletest/test/googletest-filter-unittest.py
+++ b/third_party/googletest/googletest/test/googletest-filter-unittest.py
@@ -97,6 +97,9 @@
 SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
 SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE'
 
+# The environment variable for the test warnings output file.
+TEST_WARNINGS_OUTPUT_FILE = 'TEST_WARNINGS_OUTPUT_FILE'
+
 # The command line flag for specifying the test filters.
 FILTER_FLAG = 'gtest_filter'
 
@@ -419,6 +422,22 @@
     self.RunAndVerify('BadFilter', [])
     self.RunAndVerifyAllowingDisabled('BadFilter', [])
 
+  def testBadFilterWithWarningFile(self):
+    """Tests the warning file when a filter that matches nothing."""
+
+    warning_file = os.path.join(
+        gtest_test_utils.GetTempDir(), 'testBadFilterWithWarningFile'
+    )
+    extra_env = {TEST_WARNINGS_OUTPUT_FILE: warning_file}
+    args = ['--%s=%s' % (FILTER_FLAG, 'BadFilter')]
+    InvokeWithModifiedEnv(extra_env, RunAndReturnOutput, args)
+    with open(warning_file, 'r') as f:
+      warning_file_contents = f.read()
+      self.assertEqual(
+          warning_file_contents,
+          'filter "BadFilter" did not match any test; no tests were run\n',
+      )
+
   def testFullName(self):
     """Tests filtering by full name."""
 
diff --git a/third_party/googletest/googletest/test/googletest-param-test-test.cc b/third_party/googletest/googletest/test/googletest-param-test-test.cc
index c9c5e78..fab977e 100644
--- a/third_party/googletest/googletest/test/googletest-param-test-test.cc
+++ b/third_party/googletest/googletest/test/googletest-param-test-test.cc
@@ -35,12 +35,17 @@
 #include "test/googletest-param-test-test.h"
 
 #include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
 #include <iostream>
 #include <list>
 #include <set>
 #include <sstream>
 #include <string>
+#include <string_view>
 #include <tuple>
+#include <type_traits>
 #include <vector>
 
 #include "gtest/gtest.h"
@@ -583,6 +588,71 @@
   EXPECT_TRUE(it == gen.end());
 }
 
+TEST(ConvertTest, WithConverterLambdaAndDeducedType) {
+  const ParamGenerator<ConstructFromT<int8_t>> gen =
+      ConvertGenerator(Values("0", std::string("1")), [](const std::string& s) {
+        size_t pos;
+        int64_t value = std::stoll(s, &pos);
+        EXPECT_EQ(pos, s.size());
+        return value;
+      });
+
+  ConstructFromT<int8_t> expected_values[] = {ConstructFromT<int8_t>(0),
+                                              ConstructFromT<int8_t>(1)};
+  VerifyGenerator(gen, expected_values);
+}
+
+TEST(ConvertTest, WithConverterLambdaAndExplicitType) {
+  auto convert_generator = ConvertGenerator<std::string>(
+      Values("0", std::string("1")), [](std::string_view s) {
+        size_t pos;
+        int64_t value = std::stoll(std::string(s), &pos);
+        EXPECT_EQ(pos, s.size());
+        return value;
+      });
+  constexpr bool is_correct_type = std::is_same_v<
+      decltype(convert_generator),
+      testing::internal::ParamConverterGenerator<
+          std::string, std::function<int64_t(std::string_view)>>>;
+  EXPECT_TRUE(is_correct_type);
+  const ParamGenerator<ConstructFromT<int8_t>> gen = convert_generator;
+
+  ConstructFromT<int8_t> expected_values[] = {ConstructFromT<int8_t>(0),
+                                              ConstructFromT<int8_t>(1)};
+  VerifyGenerator(gen, expected_values);
+}
+
+TEST(ConvertTest, WithConverterFunctionPointer) {
+  int64_t (*func_ptr)(const std::string&) = [](const std::string& s) {
+    size_t pos;
+    int64_t value = std::stoll(s, &pos);
+    EXPECT_EQ(pos, s.size());
+    return value;
+  };
+  const ParamGenerator<ConstructFromT<int8_t>> gen =
+      ConvertGenerator(Values("0", std::string("1")), func_ptr);
+
+  ConstructFromT<int8_t> expected_values[] = {ConstructFromT<int8_t>(0),
+                                              ConstructFromT<int8_t>(1)};
+  VerifyGenerator(gen, expected_values);
+}
+
+TEST(ConvertTest, WithConverterFunctionReference) {
+  int64_t (*func_ptr)(const std::string&) = [](const std::string& s) {
+    size_t pos;
+    int64_t value = std::stoll(s, &pos);
+    EXPECT_EQ(pos, s.size());
+    return value;
+  };
+  int64_t (&func_ref)(const std::string&) = *func_ptr;
+  const ParamGenerator<ConstructFromT<int8_t>> gen =
+      ConvertGenerator(Values("0", std::string("1")), func_ref);
+
+  ConstructFromT<int8_t> expected_values[] = {ConstructFromT<int8_t>(0),
+                                              ConstructFromT<int8_t>(1)};
+  VerifyGenerator(gen, expected_values);
+}
+
 // Tests that an generator produces correct sequence after being
 // assigned from another generator.
 TEST(ParamGeneratorTest, AssignmentWorks) {
@@ -1104,7 +1174,7 @@
 class ParameterizedDeathTest : public ::testing::TestWithParam<int> {};
 
 TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
-  EXPECT_DEATH_IF_SUPPORTED(GetParam(), ".* value-parameterized test .*");
+  EXPECT_DEATH_IF_SUPPORTED((void)GetParam(), ".* value-parameterized test .*");
 }
 
 INSTANTIATE_TEST_SUITE_P(RangeZeroToFive, ParameterizedDerivedTest,
diff --git a/third_party/googletest/googletest/test/googletest-printers-test.cc b/third_party/googletest/googletest/test/googletest-printers-test.cc
index 52b2c49..a016e8a 100644
--- a/third_party/googletest/googletest/test/googletest-printers-test.cc
+++ b/third_party/googletest/googletest/test/googletest-printers-test.cc
@@ -32,6 +32,7 @@
 // This file tests the universal value printer.
 
 #include <algorithm>
+#include <any>
 #include <cctype>
 #include <cstdint>
 #include <cstring>
@@ -42,6 +43,7 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <set>
 #include <sstream>
@@ -50,6 +52,7 @@
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
+#include <variant>
 #include <vector>
 
 #include "gtest/gtest-printers.h"
@@ -1920,7 +1923,6 @@
   EXPECT_EQ("\"a\"", result[1]);
 }
 
-#if GTEST_INTERNAL_HAS_ANY
 class PrintAnyTest : public ::testing::Test {
  protected:
   template <typename T>
@@ -1934,12 +1936,12 @@
 };
 
 TEST_F(PrintAnyTest, Empty) {
-  internal::Any any;
+  std::any any;
   EXPECT_EQ("no value", PrintToString(any));
 }
 
 TEST_F(PrintAnyTest, NonEmpty) {
-  internal::Any any;
+  std::any any;
   constexpr int val1 = 10;
   const std::string val2 = "content";
 
@@ -1950,27 +1952,23 @@
   EXPECT_EQ("value of type " + ExpectedTypeName<std::string>(),
             PrintToString(any));
 }
-#endif  // GTEST_INTERNAL_HAS_ANY
 
-#if GTEST_INTERNAL_HAS_OPTIONAL
 TEST(PrintOptionalTest, Basic) {
-  EXPECT_EQ("(nullopt)", PrintToString(internal::Nullopt()));
-  internal::Optional<int> value;
+  EXPECT_EQ("(nullopt)", PrintToString(std::nullopt));
+  std::optional<int> value;
   EXPECT_EQ("(nullopt)", PrintToString(value));
   value = {7};
   EXPECT_EQ("(7)", PrintToString(value));
-  EXPECT_EQ("(1.1)", PrintToString(internal::Optional<double>{1.1}));
-  EXPECT_EQ("(\"A\")", PrintToString(internal::Optional<std::string>{"A"}));
+  EXPECT_EQ("(1.1)", PrintToString(std::optional<double>{1.1}));
+  EXPECT_EQ("(\"A\")", PrintToString(std::optional<std::string>{"A"}));
 }
-#endif  // GTEST_INTERNAL_HAS_OPTIONAL
 
-#if GTEST_INTERNAL_HAS_VARIANT
 struct NonPrintable {
   unsigned char contents = 17;
 };
 
 TEST(PrintOneofTest, Basic) {
-  using Type = internal::Variant<int, StreamableInGlobal, NonPrintable>;
+  using Type = std::variant<int, StreamableInGlobal, NonPrintable>;
   EXPECT_EQ("('int(index = 0)' with value 7)", PrintToString(Type(7)));
   EXPECT_EQ("('StreamableInGlobal(index = 1)' with value StreamableInGlobal)",
             PrintToString(Type(StreamableInGlobal{})));
@@ -1979,7 +1977,6 @@
       "1-byte object <11>)",
       PrintToString(Type(NonPrintable{})));
 }
-#endif  // GTEST_INTERNAL_HAS_VARIANT
 
 #if GTEST_INTERNAL_HAS_COMPARE_LIB
 TEST(PrintOrderingTest, Basic) {
diff --git a/third_party/googletest/googletest_deps.bzl b/third_party/googletest/googletest_deps.bzl
index d3dd03e..9eb7270 100644
--- a/third_party/googletest/googletest_deps.bzl
+++ b/third_party/googletest/googletest_deps.bzl
@@ -17,9 +17,9 @@
     if not native.existing_rule("abseil-cpp"):
         http_archive(
             name = "abseil-cpp",
-            sha256 = "16242f394245627e508ec6bb296b433c90f8d914f73b9c026fddb905e27276e8",
-            strip_prefix = "abseil-cpp-20250127.0",
-            urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250127.0/abseil-cpp-20250127.0.tar.gz"],
+            sha256 = "7262daa7c1711406248c10f41026d685e88223bc92817d16fb93c19adb57f669",
+            strip_prefix = "abseil-cpp-20250512.0",
+            urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250512.0/abseil-cpp-20250512.0.tar.gz"],
         )
 
     if not native.existing_rule("fuchsia_sdk"):