From d29b143bda80baad6fd3f5b523ed54f10eb0eea3 Mon Sep 17 00:00:00 2001
From: Abseil Team <absl-team@google.com>
Date: Wed, 12 Oct 2022 10:30:15 -0700
Subject: Workaround for Visual C++ error C2039 with std::tuple_element_t.

Fixes #3931

PiperOrigin-RevId: 480659507
Change-Id: I6fabef63b1285189a06375227273d9de2456e37a
---
 googlemock/include/gmock/gmock-actions.h                 | 12 ++++++++----
 googlemock/include/gmock/internal/gmock-internal-utils.h |  7 +++++++
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index 7e78c09..aad07d5 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -1428,8 +1428,10 @@ struct WithArgsAction {
                     // MSVC complains about the I parameter pack not being
                     // expanded (error C3520) despite it being expanded in the
                     // type alias.
-                    OnceAction<R(typename std::tuple_element<
-                                 I, std::tuple<Args...>>::type...)>>::value,
+                    // TupleElement is also an MSVC workaround.
+                    // See its definition for details.
+                    OnceAction<R(internal::TupleElement<
+                                 I, std::tuple<Args...>>...)>>::value,
                 int>::type = 0>
   operator OnceAction<R(Args...)>() && {  // NOLINT
     struct OA {
@@ -1453,8 +1455,10 @@ struct WithArgsAction {
                     // MSVC complains about the I parameter pack not being
                     // expanded (error C3520) despite it being expanded in the
                     // type alias.
-                    Action<R(typename std::tuple_element<
-                             I, std::tuple<Args...>>::type...)>>::value,
+                    // TupleElement is also an MSVC workaround.
+                    // See its definition for details.
+                    Action<R(internal::TupleElement<
+                             I, std::tuple<Args...>>...)>>::value,
                 int>::type = 0>
   operator Action<R(Args...)>() const {  // NOLINT
     Action<InnerSignature<R, Args...>> converted(inner_action);
diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h
index 92d8eb9..2678920 100644
--- a/googlemock/include/gmock/internal/gmock-internal-utils.h
+++ b/googlemock/include/gmock/internal/gmock-internal-utils.h
@@ -453,6 +453,13 @@ struct Function<R(Args...)> {
 template <typename R, typename... Args>
 constexpr size_t Function<R(Args...)>::ArgumentCount;
 
+// Workaround for MSVC error C2039: 'type': is not a member of 'std'
+// when std::tuple_element is used.
+// See: https://github.com/google/googletest/issues/3931
+// Can be replaced with std::tuple_element_t in C++14.
+template <size_t I, typename T>
+using TupleElement = typename std::tuple_element<I, T>::type;
+
 bool Base64Unescape(const std::string& encoded, std::string* decoded);
 
 #ifdef _MSC_VER
-- 
cgit v0.12