xref: /freebsd-src/contrib/googletest/googlemock/include/gmock/gmock-actions.h (revision 5ca8c28cd8c725b81781201cfdb5f9969396f934)
1b89a7cc2SEnji Cooper // Copyright 2007, Google Inc.
2b89a7cc2SEnji Cooper // All rights reserved.
3b89a7cc2SEnji Cooper //
4b89a7cc2SEnji Cooper // Redistribution and use in source and binary forms, with or without
5b89a7cc2SEnji Cooper // modification, are permitted provided that the following conditions are
6b89a7cc2SEnji Cooper // met:
7b89a7cc2SEnji Cooper //
8b89a7cc2SEnji Cooper //     * Redistributions of source code must retain the above copyright
9b89a7cc2SEnji Cooper // notice, this list of conditions and the following disclaimer.
10b89a7cc2SEnji Cooper //     * Redistributions in binary form must reproduce the above
11b89a7cc2SEnji Cooper // copyright notice, this list of conditions and the following disclaimer
12b89a7cc2SEnji Cooper // in the documentation and/or other materials provided with the
13b89a7cc2SEnji Cooper // distribution.
14b89a7cc2SEnji Cooper //     * Neither the name of Google Inc. nor the names of its
15b89a7cc2SEnji Cooper // contributors may be used to endorse or promote products derived from
16b89a7cc2SEnji Cooper // this software without specific prior written permission.
17b89a7cc2SEnji Cooper //
18b89a7cc2SEnji Cooper // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19b89a7cc2SEnji Cooper // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20b89a7cc2SEnji Cooper // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21b89a7cc2SEnji Cooper // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22b89a7cc2SEnji Cooper // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23b89a7cc2SEnji Cooper // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24b89a7cc2SEnji Cooper // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25b89a7cc2SEnji Cooper // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26b89a7cc2SEnji Cooper // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b89a7cc2SEnji Cooper // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28b89a7cc2SEnji Cooper // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29b89a7cc2SEnji Cooper 
30b89a7cc2SEnji Cooper // Google Mock - a framework for writing C++ mock classes.
31b89a7cc2SEnji Cooper //
3228f6c2f2SEnji Cooper // The ACTION* family of macros can be used in a namespace scope to
3328f6c2f2SEnji Cooper // define custom actions easily.  The syntax:
3428f6c2f2SEnji Cooper //
3528f6c2f2SEnji Cooper //   ACTION(name) { statements; }
3628f6c2f2SEnji Cooper //
3728f6c2f2SEnji Cooper // will define an action with the given name that executes the
3828f6c2f2SEnji Cooper // statements.  The value returned by the statements will be used as
3928f6c2f2SEnji Cooper // the return value of the action.  Inside the statements, you can
4028f6c2f2SEnji Cooper // refer to the K-th (0-based) argument of the mock function by
4128f6c2f2SEnji Cooper // 'argK', and refer to its type by 'argK_type'.  For example:
4228f6c2f2SEnji Cooper //
4328f6c2f2SEnji Cooper //   ACTION(IncrementArg1) {
4428f6c2f2SEnji Cooper //     arg1_type temp = arg1;
4528f6c2f2SEnji Cooper //     return ++(*temp);
4628f6c2f2SEnji Cooper //   }
4728f6c2f2SEnji Cooper //
4828f6c2f2SEnji Cooper // allows you to write
4928f6c2f2SEnji Cooper //
5028f6c2f2SEnji Cooper //   ...WillOnce(IncrementArg1());
5128f6c2f2SEnji Cooper //
5228f6c2f2SEnji Cooper // You can also refer to the entire argument tuple and its type by
5328f6c2f2SEnji Cooper // 'args' and 'args_type', and refer to the mock function type and its
5428f6c2f2SEnji Cooper // return type by 'function_type' and 'return_type'.
5528f6c2f2SEnji Cooper //
5628f6c2f2SEnji Cooper // Note that you don't need to specify the types of the mock function
5728f6c2f2SEnji Cooper // arguments.  However rest assured that your code is still type-safe:
5828f6c2f2SEnji Cooper // you'll get a compiler error if *arg1 doesn't support the ++
5928f6c2f2SEnji Cooper // operator, or if the type of ++(*arg1) isn't compatible with the
6028f6c2f2SEnji Cooper // mock function's return type, for example.
6128f6c2f2SEnji Cooper //
6228f6c2f2SEnji Cooper // Sometimes you'll want to parameterize the action.   For that you can use
6328f6c2f2SEnji Cooper // another macro:
6428f6c2f2SEnji Cooper //
6528f6c2f2SEnji Cooper //   ACTION_P(name, param_name) { statements; }
6628f6c2f2SEnji Cooper //
6728f6c2f2SEnji Cooper // For example:
6828f6c2f2SEnji Cooper //
6928f6c2f2SEnji Cooper //   ACTION_P(Add, n) { return arg0 + n; }
7028f6c2f2SEnji Cooper //
7128f6c2f2SEnji Cooper // will allow you to write:
7228f6c2f2SEnji Cooper //
7328f6c2f2SEnji Cooper //   ...WillOnce(Add(5));
7428f6c2f2SEnji Cooper //
7528f6c2f2SEnji Cooper // Note that you don't need to provide the type of the parameter
7628f6c2f2SEnji Cooper // either.  If you need to reference the type of a parameter named
7728f6c2f2SEnji Cooper // 'foo', you can write 'foo_type'.  For example, in the body of
7828f6c2f2SEnji Cooper // ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
7928f6c2f2SEnji Cooper // of 'n'.
8028f6c2f2SEnji Cooper //
8128f6c2f2SEnji Cooper // We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support
8228f6c2f2SEnji Cooper // multi-parameter actions.
8328f6c2f2SEnji Cooper //
8428f6c2f2SEnji Cooper // For the purpose of typing, you can view
8528f6c2f2SEnji Cooper //
8628f6c2f2SEnji Cooper //   ACTION_Pk(Foo, p1, ..., pk) { ... }
8728f6c2f2SEnji Cooper //
8828f6c2f2SEnji Cooper // as shorthand for
8928f6c2f2SEnji Cooper //
9028f6c2f2SEnji Cooper //   template <typename p1_type, ..., typename pk_type>
9128f6c2f2SEnji Cooper //   FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
9228f6c2f2SEnji Cooper //
9328f6c2f2SEnji Cooper // In particular, you can provide the template type arguments
9428f6c2f2SEnji Cooper // explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
9528f6c2f2SEnji Cooper // although usually you can rely on the compiler to infer the types
9628f6c2f2SEnji Cooper // for you automatically.  You can assign the result of expression
9728f6c2f2SEnji Cooper // Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
9828f6c2f2SEnji Cooper // pk_type>.  This can be useful when composing actions.
9928f6c2f2SEnji Cooper //
10028f6c2f2SEnji Cooper // You can also overload actions with different numbers of parameters:
10128f6c2f2SEnji Cooper //
10228f6c2f2SEnji Cooper //   ACTION_P(Plus, a) { ... }
10328f6c2f2SEnji Cooper //   ACTION_P2(Plus, a, b) { ... }
10428f6c2f2SEnji Cooper //
10528f6c2f2SEnji Cooper // While it's tempting to always use the ACTION* macros when defining
10628f6c2f2SEnji Cooper // a new action, you should also consider implementing ActionInterface
10728f6c2f2SEnji Cooper // or using MakePolymorphicAction() instead, especially if you need to
10828f6c2f2SEnji Cooper // use the action a lot.  While these approaches require more work,
10928f6c2f2SEnji Cooper // they give you more control on the types of the mock function
11028f6c2f2SEnji Cooper // arguments and the action parameters, which in general leads to
11128f6c2f2SEnji Cooper // better compiler error messages that pay off in the long run.  They
11228f6c2f2SEnji Cooper // also allow overloading actions based on parameter types (as opposed
11328f6c2f2SEnji Cooper // to just based on the number of parameters).
11428f6c2f2SEnji Cooper //
11528f6c2f2SEnji Cooper // CAVEAT:
11628f6c2f2SEnji Cooper //
11728f6c2f2SEnji Cooper // ACTION*() can only be used in a namespace scope as templates cannot be
11828f6c2f2SEnji Cooper // declared inside of a local class.
11928f6c2f2SEnji Cooper // Users can, however, define any local functors (e.g. a lambda) that
12028f6c2f2SEnji Cooper // can be used as actions.
12128f6c2f2SEnji Cooper //
12228f6c2f2SEnji Cooper // MORE INFORMATION:
12328f6c2f2SEnji Cooper //
12428f6c2f2SEnji Cooper // To learn more about using these macros, please search for 'ACTION' on
12528f6c2f2SEnji Cooper // https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md
126b89a7cc2SEnji Cooper 
12728f6c2f2SEnji Cooper // IWYU pragma: private, include "gmock/gmock.h"
12828f6c2f2SEnji Cooper // IWYU pragma: friend gmock/.*
129b89a7cc2SEnji Cooper 
13028f6c2f2SEnji Cooper #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
13128f6c2f2SEnji Cooper #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
132b89a7cc2SEnji Cooper 
133b89a7cc2SEnji Cooper #ifndef _WIN32_WCE
134b89a7cc2SEnji Cooper #include <errno.h>
135b89a7cc2SEnji Cooper #endif
136b89a7cc2SEnji Cooper 
137b89a7cc2SEnji Cooper #include <algorithm>
138*5ca8c28cSEnji Cooper #include <exception>
13928f6c2f2SEnji Cooper #include <functional>
14028f6c2f2SEnji Cooper #include <memory>
141b89a7cc2SEnji Cooper #include <string>
14228f6c2f2SEnji Cooper #include <tuple>
14328f6c2f2SEnji Cooper #include <type_traits>
14428f6c2f2SEnji Cooper #include <utility>
145b89a7cc2SEnji Cooper 
146b89a7cc2SEnji Cooper #include "gmock/internal/gmock-internal-utils.h"
147b89a7cc2SEnji Cooper #include "gmock/internal/gmock-port.h"
14828f6c2f2SEnji Cooper #include "gmock/internal/gmock-pp.h"
149b89a7cc2SEnji Cooper 
15028f6c2f2SEnji Cooper GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
151b89a7cc2SEnji Cooper 
152b89a7cc2SEnji Cooper namespace testing {
153b89a7cc2SEnji Cooper 
154b89a7cc2SEnji Cooper // To implement an action Foo, define:
155b89a7cc2SEnji Cooper //   1. a class FooAction that implements the ActionInterface interface, and
156b89a7cc2SEnji Cooper //   2. a factory function that creates an Action object from a
157b89a7cc2SEnji Cooper //      const FooAction*.
158b89a7cc2SEnji Cooper //
159b89a7cc2SEnji Cooper // The two-level delegation design follows that of Matcher, providing
160b89a7cc2SEnji Cooper // consistency for extension developers.  It also eases ownership
161b89a7cc2SEnji Cooper // management as Action objects can now be copied like plain values.
162b89a7cc2SEnji Cooper 
163b89a7cc2SEnji Cooper namespace internal {
164b89a7cc2SEnji Cooper 
165b89a7cc2SEnji Cooper // BuiltInDefaultValueGetter<T, true>::Get() returns a
166b89a7cc2SEnji Cooper // default-constructed T value.  BuiltInDefaultValueGetter<T,
167b89a7cc2SEnji Cooper // false>::Get() crashes with an error.
168b89a7cc2SEnji Cooper //
169b89a7cc2SEnji Cooper // This primary template is used when kDefaultConstructible is true.
170b89a7cc2SEnji Cooper template <typename T, bool kDefaultConstructible>
171b89a7cc2SEnji Cooper struct BuiltInDefaultValueGetter {
172b89a7cc2SEnji Cooper   static T Get() { return T(); }
173b89a7cc2SEnji Cooper };
174b89a7cc2SEnji Cooper template <typename T>
175b89a7cc2SEnji Cooper struct BuiltInDefaultValueGetter<T, false> {
176b89a7cc2SEnji Cooper   static T Get() {
177b89a7cc2SEnji Cooper     Assert(false, __FILE__, __LINE__,
178b89a7cc2SEnji Cooper            "Default action undefined for the function return type.");
179*5ca8c28cSEnji Cooper #if defined(__GNUC__) || defined(__clang__)
180*5ca8c28cSEnji Cooper     __builtin_unreachable();
181*5ca8c28cSEnji Cooper #elif defined(_MSC_VER)
182*5ca8c28cSEnji Cooper     __assume(0);
183*5ca8c28cSEnji Cooper #else
184*5ca8c28cSEnji Cooper     return Invalid<T>();
185b89a7cc2SEnji Cooper     // The above statement will never be reached, but is required in
186b89a7cc2SEnji Cooper     // order for this function to compile.
187*5ca8c28cSEnji Cooper #endif
188b89a7cc2SEnji Cooper   }
189b89a7cc2SEnji Cooper };
190b89a7cc2SEnji Cooper 
191b89a7cc2SEnji Cooper // BuiltInDefaultValue<T>::Get() returns the "built-in" default value
192b89a7cc2SEnji Cooper // for type T, which is NULL when T is a raw pointer type, 0 when T is
193b89a7cc2SEnji Cooper // a numeric type, false when T is bool, or "" when T is string or
194b89a7cc2SEnji Cooper // std::string.  In addition, in C++11 and above, it turns a
195b89a7cc2SEnji Cooper // default-constructed T value if T is default constructible.  For any
196b89a7cc2SEnji Cooper // other type T, the built-in default T value is undefined, and the
197b89a7cc2SEnji Cooper // function will abort the process.
198b89a7cc2SEnji Cooper template <typename T>
199b89a7cc2SEnji Cooper class BuiltInDefaultValue {
200b89a7cc2SEnji Cooper  public:
20128f6c2f2SEnji Cooper   // This function returns true if and only if type T has a built-in default
20228f6c2f2SEnji Cooper   // value.
20328f6c2f2SEnji Cooper   static bool Exists() { return ::std::is_default_constructible<T>::value; }
204b89a7cc2SEnji Cooper 
205b89a7cc2SEnji Cooper   static T Get() {
206b89a7cc2SEnji Cooper     return BuiltInDefaultValueGetter<
207b89a7cc2SEnji Cooper         T, ::std::is_default_constructible<T>::value>::Get();
208b89a7cc2SEnji Cooper   }
209b89a7cc2SEnji Cooper };
210b89a7cc2SEnji Cooper 
211b89a7cc2SEnji Cooper // This partial specialization says that we use the same built-in
212b89a7cc2SEnji Cooper // default value for T and const T.
213b89a7cc2SEnji Cooper template <typename T>
214b89a7cc2SEnji Cooper class BuiltInDefaultValue<const T> {
215b89a7cc2SEnji Cooper  public:
216b89a7cc2SEnji Cooper   static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
217b89a7cc2SEnji Cooper   static T Get() { return BuiltInDefaultValue<T>::Get(); }
218b89a7cc2SEnji Cooper };
219b89a7cc2SEnji Cooper 
220b89a7cc2SEnji Cooper // This partial specialization defines the default values for pointer
221b89a7cc2SEnji Cooper // types.
222b89a7cc2SEnji Cooper template <typename T>
223b89a7cc2SEnji Cooper class BuiltInDefaultValue<T*> {
224b89a7cc2SEnji Cooper  public:
225b89a7cc2SEnji Cooper   static bool Exists() { return true; }
22628f6c2f2SEnji Cooper   static T* Get() { return nullptr; }
227b89a7cc2SEnji Cooper };
228b89a7cc2SEnji Cooper 
229b89a7cc2SEnji Cooper // The following specializations define the default values for
230b89a7cc2SEnji Cooper // specific types we care about.
231b89a7cc2SEnji Cooper #define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \
232b89a7cc2SEnji Cooper   template <>                                                     \
233b89a7cc2SEnji Cooper   class BuiltInDefaultValue<type> {                               \
234b89a7cc2SEnji Cooper    public:                                                        \
235b89a7cc2SEnji Cooper     static bool Exists() { return true; }                         \
236b89a7cc2SEnji Cooper     static type Get() { return value; }                           \
237b89a7cc2SEnji Cooper   }
238b89a7cc2SEnji Cooper 
239b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, );  // NOLINT
240b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, "");
241b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);
242b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
243b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0');
244b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0');
245b89a7cc2SEnji Cooper 
246b89a7cc2SEnji Cooper // There's no need for a default action for signed wchar_t, as that
247b89a7cc2SEnji Cooper // type is the same as wchar_t for gcc, and invalid for MSVC.
248b89a7cc2SEnji Cooper //
249b89a7cc2SEnji Cooper // There's also no need for a default action for unsigned wchar_t, as
250b89a7cc2SEnji Cooper // that type is the same as unsigned int for gcc, and invalid for
251b89a7cc2SEnji Cooper // MSVC.
252b89a7cc2SEnji Cooper #if GMOCK_WCHAR_T_IS_NATIVE_
253b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U);  // NOLINT
254b89a7cc2SEnji Cooper #endif
255b89a7cc2SEnji Cooper 
256b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U);  // NOLINT
257b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0);     // NOLINT
258b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U);
259b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0);
260b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL);     // NOLINT
261b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L);        // NOLINT
26228f6c2f2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0);  // NOLINT
26328f6c2f2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0);    // NOLINT
264b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0);
265b89a7cc2SEnji Cooper GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);
266b89a7cc2SEnji Cooper 
267b89a7cc2SEnji Cooper #undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
268b89a7cc2SEnji Cooper 
26928f6c2f2SEnji Cooper // Partial implementations of metaprogramming types from the standard library
27028f6c2f2SEnji Cooper // not available in C++11.
27128f6c2f2SEnji Cooper 
27228f6c2f2SEnji Cooper template <typename P>
27328f6c2f2SEnji Cooper struct negation
27428f6c2f2SEnji Cooper     // NOLINTNEXTLINE
27528f6c2f2SEnji Cooper     : std::integral_constant<bool, bool(!P::value)> {};
27628f6c2f2SEnji Cooper 
27728f6c2f2SEnji Cooper // Base case: with zero predicates the answer is always true.
27828f6c2f2SEnji Cooper template <typename...>
27928f6c2f2SEnji Cooper struct conjunction : std::true_type {};
28028f6c2f2SEnji Cooper 
28128f6c2f2SEnji Cooper // With a single predicate, the answer is that predicate.
28228f6c2f2SEnji Cooper template <typename P1>
28328f6c2f2SEnji Cooper struct conjunction<P1> : P1 {};
28428f6c2f2SEnji Cooper 
28528f6c2f2SEnji Cooper // With multiple predicates the answer is the first predicate if that is false,
28628f6c2f2SEnji Cooper // and we recurse otherwise.
28728f6c2f2SEnji Cooper template <typename P1, typename... Ps>
28828f6c2f2SEnji Cooper struct conjunction<P1, Ps...>
28928f6c2f2SEnji Cooper     : std::conditional<bool(P1::value), conjunction<Ps...>, P1>::type {};
29028f6c2f2SEnji Cooper 
29128f6c2f2SEnji Cooper template <typename...>
29228f6c2f2SEnji Cooper struct disjunction : std::false_type {};
29328f6c2f2SEnji Cooper 
29428f6c2f2SEnji Cooper template <typename P1>
29528f6c2f2SEnji Cooper struct disjunction<P1> : P1 {};
29628f6c2f2SEnji Cooper 
29728f6c2f2SEnji Cooper template <typename P1, typename... Ps>
29828f6c2f2SEnji Cooper struct disjunction<P1, Ps...>
29928f6c2f2SEnji Cooper     // NOLINTNEXTLINE
30028f6c2f2SEnji Cooper     : std::conditional<!bool(P1::value), disjunction<Ps...>, P1>::type {};
30128f6c2f2SEnji Cooper 
30228f6c2f2SEnji Cooper template <typename...>
30328f6c2f2SEnji Cooper using void_t = void;
30428f6c2f2SEnji Cooper 
30528f6c2f2SEnji Cooper // Detects whether an expression of type `From` can be implicitly converted to
30628f6c2f2SEnji Cooper // `To` according to [conv]. In C++17, [conv]/3 defines this as follows:
30728f6c2f2SEnji Cooper //
30828f6c2f2SEnji Cooper //     An expression e can be implicitly converted to a type T if and only if
30928f6c2f2SEnji Cooper //     the declaration T t=e; is well-formed, for some invented temporary
31028f6c2f2SEnji Cooper //     variable t ([dcl.init]).
31128f6c2f2SEnji Cooper //
31228f6c2f2SEnji Cooper // [conv]/2 implies we can use function argument passing to detect whether this
31328f6c2f2SEnji Cooper // initialization is valid.
31428f6c2f2SEnji Cooper //
31528f6c2f2SEnji Cooper // Note that this is distinct from is_convertible, which requires this be valid:
31628f6c2f2SEnji Cooper //
31728f6c2f2SEnji Cooper //     To test() {
31828f6c2f2SEnji Cooper //       return declval<From>();
31928f6c2f2SEnji Cooper //     }
32028f6c2f2SEnji Cooper //
32128f6c2f2SEnji Cooper // In particular, is_convertible doesn't give the correct answer when `To` and
32228f6c2f2SEnji Cooper // `From` are the same non-moveable type since `declval<From>` will be an rvalue
32328f6c2f2SEnji Cooper // reference, defeating the guaranteed copy elision that would otherwise make
32428f6c2f2SEnji Cooper // this function work.
32528f6c2f2SEnji Cooper //
32628f6c2f2SEnji Cooper // REQUIRES: `From` is not cv void.
32728f6c2f2SEnji Cooper template <typename From, typename To>
32828f6c2f2SEnji Cooper struct is_implicitly_convertible {
32928f6c2f2SEnji Cooper  private:
33028f6c2f2SEnji Cooper   // A function that accepts a parameter of type T. This can be called with type
33128f6c2f2SEnji Cooper   // U successfully only if U is implicitly convertible to T.
33228f6c2f2SEnji Cooper   template <typename T>
33328f6c2f2SEnji Cooper   static void Accept(T);
33428f6c2f2SEnji Cooper 
33528f6c2f2SEnji Cooper   // A function that creates a value of type T.
33628f6c2f2SEnji Cooper   template <typename T>
33728f6c2f2SEnji Cooper   static T Make();
33828f6c2f2SEnji Cooper 
33928f6c2f2SEnji Cooper   // An overload be selected when implicit conversion from T to To is possible.
34028f6c2f2SEnji Cooper   template <typename T, typename = decltype(Accept<To>(Make<T>()))>
34128f6c2f2SEnji Cooper   static std::true_type TestImplicitConversion(int);
34228f6c2f2SEnji Cooper 
34328f6c2f2SEnji Cooper   // A fallback overload selected in all other cases.
34428f6c2f2SEnji Cooper   template <typename T>
34528f6c2f2SEnji Cooper   static std::false_type TestImplicitConversion(...);
34628f6c2f2SEnji Cooper 
34728f6c2f2SEnji Cooper  public:
34828f6c2f2SEnji Cooper   using type = decltype(TestImplicitConversion<From>(0));
34928f6c2f2SEnji Cooper   static constexpr bool value = type::value;
35028f6c2f2SEnji Cooper };
35128f6c2f2SEnji Cooper 
35228f6c2f2SEnji Cooper // Like std::invoke_result_t from C++17, but works only for objects with call
35328f6c2f2SEnji Cooper // operators (not e.g. member function pointers, which we don't need specific
35428f6c2f2SEnji Cooper // support for in OnceAction because std::function deals with them).
35528f6c2f2SEnji Cooper template <typename F, typename... Args>
35628f6c2f2SEnji Cooper using call_result_t = decltype(std::declval<F>()(std::declval<Args>()...));
35728f6c2f2SEnji Cooper 
35828f6c2f2SEnji Cooper template <typename Void, typename R, typename F, typename... Args>
35928f6c2f2SEnji Cooper struct is_callable_r_impl : std::false_type {};
36028f6c2f2SEnji Cooper 
36128f6c2f2SEnji Cooper // Specialize the struct for those template arguments where call_result_t is
36228f6c2f2SEnji Cooper // well-formed. When it's not, the generic template above is chosen, resulting
36328f6c2f2SEnji Cooper // in std::false_type.
36428f6c2f2SEnji Cooper template <typename R, typename F, typename... Args>
36528f6c2f2SEnji Cooper struct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...>
36628f6c2f2SEnji Cooper     : std::conditional<
36728f6c2f2SEnji Cooper           std::is_void<R>::value,  //
36828f6c2f2SEnji Cooper           std::true_type,          //
36928f6c2f2SEnji Cooper           is_implicitly_convertible<call_result_t<F, Args...>, R>>::type {};
37028f6c2f2SEnji Cooper 
37128f6c2f2SEnji Cooper // Like std::is_invocable_r from C++17, but works only for objects with call
37228f6c2f2SEnji Cooper // operators. See the note on call_result_t.
37328f6c2f2SEnji Cooper template <typename R, typename F, typename... Args>
37428f6c2f2SEnji Cooper using is_callable_r = is_callable_r_impl<void, R, F, Args...>;
37528f6c2f2SEnji Cooper 
37628f6c2f2SEnji Cooper // Like std::as_const from C++17.
37728f6c2f2SEnji Cooper template <typename T>
37828f6c2f2SEnji Cooper typename std::add_const<T>::type& as_const(T& t) {
37928f6c2f2SEnji Cooper   return t;
38028f6c2f2SEnji Cooper }
38128f6c2f2SEnji Cooper 
382b89a7cc2SEnji Cooper }  // namespace internal
383b89a7cc2SEnji Cooper 
38428f6c2f2SEnji Cooper // Specialized for function types below.
38528f6c2f2SEnji Cooper template <typename F>
38628f6c2f2SEnji Cooper class OnceAction;
38728f6c2f2SEnji Cooper 
38828f6c2f2SEnji Cooper // An action that can only be used once.
38928f6c2f2SEnji Cooper //
39028f6c2f2SEnji Cooper // This is accepted by WillOnce, which doesn't require the underlying action to
39128f6c2f2SEnji Cooper // be copy-constructible (only move-constructible), and promises to invoke it as
39228f6c2f2SEnji Cooper // an rvalue reference. This allows the action to work with move-only types like
39328f6c2f2SEnji Cooper // std::move_only_function in a type-safe manner.
39428f6c2f2SEnji Cooper //
39528f6c2f2SEnji Cooper // For example:
39628f6c2f2SEnji Cooper //
39728f6c2f2SEnji Cooper //     // Assume we have some API that needs to accept a unique pointer to some
39828f6c2f2SEnji Cooper //     // non-copyable object Foo.
39928f6c2f2SEnji Cooper //     void AcceptUniquePointer(std::unique_ptr<Foo> foo);
40028f6c2f2SEnji Cooper //
40128f6c2f2SEnji Cooper //     // We can define an action that provides a Foo to that API. Because It
40228f6c2f2SEnji Cooper //     // has to give away its unique pointer, it must not be called more than
40328f6c2f2SEnji Cooper //     // once, so its call operator is &&-qualified.
40428f6c2f2SEnji Cooper //     struct ProvideFoo {
40528f6c2f2SEnji Cooper //       std::unique_ptr<Foo> foo;
40628f6c2f2SEnji Cooper //
40728f6c2f2SEnji Cooper //       void operator()() && {
40828f6c2f2SEnji Cooper //         AcceptUniquePointer(std::move(Foo));
40928f6c2f2SEnji Cooper //       }
41028f6c2f2SEnji Cooper //     };
41128f6c2f2SEnji Cooper //
41228f6c2f2SEnji Cooper //     // This action can be used with WillOnce.
41328f6c2f2SEnji Cooper //     EXPECT_CALL(mock, Call)
41428f6c2f2SEnji Cooper //         .WillOnce(ProvideFoo{std::make_unique<Foo>(...)});
41528f6c2f2SEnji Cooper //
41628f6c2f2SEnji Cooper //     // But a call to WillRepeatedly will fail to compile. This is correct,
41728f6c2f2SEnji Cooper //     // since the action cannot correctly be used repeatedly.
41828f6c2f2SEnji Cooper //     EXPECT_CALL(mock, Call)
41928f6c2f2SEnji Cooper //         .WillRepeatedly(ProvideFoo{std::make_unique<Foo>(...)});
42028f6c2f2SEnji Cooper //
42128f6c2f2SEnji Cooper // A less-contrived example would be an action that returns an arbitrary type,
42228f6c2f2SEnji Cooper // whose &&-qualified call operator is capable of dealing with move-only types.
42328f6c2f2SEnji Cooper template <typename Result, typename... Args>
42428f6c2f2SEnji Cooper class OnceAction<Result(Args...)> final {
42528f6c2f2SEnji Cooper  private:
42628f6c2f2SEnji Cooper   // True iff we can use the given callable type (or lvalue reference) directly
42728f6c2f2SEnji Cooper   // via StdFunctionAdaptor.
42828f6c2f2SEnji Cooper   template <typename Callable>
42928f6c2f2SEnji Cooper   using IsDirectlyCompatible = internal::conjunction<
43028f6c2f2SEnji Cooper       // It must be possible to capture the callable in StdFunctionAdaptor.
43128f6c2f2SEnji Cooper       std::is_constructible<typename std::decay<Callable>::type, Callable>,
43228f6c2f2SEnji Cooper       // The callable must be compatible with our signature.
43328f6c2f2SEnji Cooper       internal::is_callable_r<Result, typename std::decay<Callable>::type,
43428f6c2f2SEnji Cooper                               Args...>>;
43528f6c2f2SEnji Cooper 
43628f6c2f2SEnji Cooper   // True iff we can use the given callable type via StdFunctionAdaptor once we
43728f6c2f2SEnji Cooper   // ignore incoming arguments.
43828f6c2f2SEnji Cooper   template <typename Callable>
43928f6c2f2SEnji Cooper   using IsCompatibleAfterIgnoringArguments = internal::conjunction<
44028f6c2f2SEnji Cooper       // It must be possible to capture the callable in a lambda.
44128f6c2f2SEnji Cooper       std::is_constructible<typename std::decay<Callable>::type, Callable>,
44228f6c2f2SEnji Cooper       // The callable must be invocable with zero arguments, returning something
44328f6c2f2SEnji Cooper       // convertible to Result.
44428f6c2f2SEnji Cooper       internal::is_callable_r<Result, typename std::decay<Callable>::type>>;
44528f6c2f2SEnji Cooper 
44628f6c2f2SEnji Cooper  public:
44728f6c2f2SEnji Cooper   // Construct from a callable that is directly compatible with our mocked
44828f6c2f2SEnji Cooper   // signature: it accepts our function type's arguments and returns something
44928f6c2f2SEnji Cooper   // convertible to our result type.
45028f6c2f2SEnji Cooper   template <typename Callable,
45128f6c2f2SEnji Cooper             typename std::enable_if<
45228f6c2f2SEnji Cooper                 internal::conjunction<
45328f6c2f2SEnji Cooper                     // Teach clang on macOS that we're not talking about a
45428f6c2f2SEnji Cooper                     // copy/move constructor here. Otherwise it gets confused
45528f6c2f2SEnji Cooper                     // when checking the is_constructible requirement of our
45628f6c2f2SEnji Cooper                     // traits above.
45728f6c2f2SEnji Cooper                     internal::negation<std::is_same<
45828f6c2f2SEnji Cooper                         OnceAction, typename std::decay<Callable>::type>>,
45928f6c2f2SEnji Cooper                     IsDirectlyCompatible<Callable>>  //
46028f6c2f2SEnji Cooper                 ::value,
46128f6c2f2SEnji Cooper                 int>::type = 0>
46228f6c2f2SEnji Cooper   OnceAction(Callable&& callable)  // NOLINT
46328f6c2f2SEnji Cooper       : function_(StdFunctionAdaptor<typename std::decay<Callable>::type>(
46428f6c2f2SEnji Cooper             {}, std::forward<Callable>(callable))) {}
46528f6c2f2SEnji Cooper 
46628f6c2f2SEnji Cooper   // As above, but for a callable that ignores the mocked function's arguments.
46728f6c2f2SEnji Cooper   template <typename Callable,
46828f6c2f2SEnji Cooper             typename std::enable_if<
46928f6c2f2SEnji Cooper                 internal::conjunction<
47028f6c2f2SEnji Cooper                     // Teach clang on macOS that we're not talking about a
47128f6c2f2SEnji Cooper                     // copy/move constructor here. Otherwise it gets confused
47228f6c2f2SEnji Cooper                     // when checking the is_constructible requirement of our
47328f6c2f2SEnji Cooper                     // traits above.
47428f6c2f2SEnji Cooper                     internal::negation<std::is_same<
47528f6c2f2SEnji Cooper                         OnceAction, typename std::decay<Callable>::type>>,
47628f6c2f2SEnji Cooper                     // Exclude callables for which the overload above works.
47728f6c2f2SEnji Cooper                     // We'd rather provide the arguments if possible.
47828f6c2f2SEnji Cooper                     internal::negation<IsDirectlyCompatible<Callable>>,
47928f6c2f2SEnji Cooper                     IsCompatibleAfterIgnoringArguments<Callable>>::value,
48028f6c2f2SEnji Cooper                 int>::type = 0>
48128f6c2f2SEnji Cooper   OnceAction(Callable&& callable)  // NOLINT
48228f6c2f2SEnji Cooper                                    // Call the constructor above with a callable
48328f6c2f2SEnji Cooper                                    // that ignores the input arguments.
48428f6c2f2SEnji Cooper       : OnceAction(IgnoreIncomingArguments<typename std::decay<Callable>::type>{
48528f6c2f2SEnji Cooper             std::forward<Callable>(callable)}) {}
48628f6c2f2SEnji Cooper 
48728f6c2f2SEnji Cooper   // We are naturally copyable because we store only an std::function, but
48828f6c2f2SEnji Cooper   // semantically we should not be copyable.
48928f6c2f2SEnji Cooper   OnceAction(const OnceAction&) = delete;
49028f6c2f2SEnji Cooper   OnceAction& operator=(const OnceAction&) = delete;
49128f6c2f2SEnji Cooper   OnceAction(OnceAction&&) = default;
49228f6c2f2SEnji Cooper 
49328f6c2f2SEnji Cooper   // Invoke the underlying action callable with which we were constructed,
49428f6c2f2SEnji Cooper   // handing it the supplied arguments.
49528f6c2f2SEnji Cooper   Result Call(Args... args) && {
49628f6c2f2SEnji Cooper     return function_(std::forward<Args>(args)...);
49728f6c2f2SEnji Cooper   }
49828f6c2f2SEnji Cooper 
49928f6c2f2SEnji Cooper  private:
50028f6c2f2SEnji Cooper   // An adaptor that wraps a callable that is compatible with our signature and
50128f6c2f2SEnji Cooper   // being invoked as an rvalue reference so that it can be used as an
50228f6c2f2SEnji Cooper   // StdFunctionAdaptor. This throws away type safety, but that's fine because
50328f6c2f2SEnji Cooper   // this is only used by WillOnce, which we know calls at most once.
50428f6c2f2SEnji Cooper   //
50528f6c2f2SEnji Cooper   // Once we have something like std::move_only_function from C++23, we can do
50628f6c2f2SEnji Cooper   // away with this.
50728f6c2f2SEnji Cooper   template <typename Callable>
50828f6c2f2SEnji Cooper   class StdFunctionAdaptor final {
50928f6c2f2SEnji Cooper    public:
51028f6c2f2SEnji Cooper     // A tag indicating that the (otherwise universal) constructor is accepting
51128f6c2f2SEnji Cooper     // the callable itself, instead of e.g. stealing calls for the move
51228f6c2f2SEnji Cooper     // constructor.
51328f6c2f2SEnji Cooper     struct CallableTag final {};
51428f6c2f2SEnji Cooper 
51528f6c2f2SEnji Cooper     template <typename F>
51628f6c2f2SEnji Cooper     explicit StdFunctionAdaptor(CallableTag, F&& callable)
51728f6c2f2SEnji Cooper         : callable_(std::make_shared<Callable>(std::forward<F>(callable))) {}
51828f6c2f2SEnji Cooper 
51928f6c2f2SEnji Cooper     // Rather than explicitly returning Result, we return whatever the wrapped
52028f6c2f2SEnji Cooper     // callable returns. This allows for compatibility with existing uses like
52128f6c2f2SEnji Cooper     // the following, when the mocked function returns void:
52228f6c2f2SEnji Cooper     //
52328f6c2f2SEnji Cooper     //     EXPECT_CALL(mock_fn_, Call)
52428f6c2f2SEnji Cooper     //         .WillOnce([&] {
52528f6c2f2SEnji Cooper     //            [...]
52628f6c2f2SEnji Cooper     //            return 0;
52728f6c2f2SEnji Cooper     //         });
52828f6c2f2SEnji Cooper     //
52928f6c2f2SEnji Cooper     // Such a callable can be turned into std::function<void()>. If we use an
53028f6c2f2SEnji Cooper     // explicit return type of Result here then it *doesn't* work with
53128f6c2f2SEnji Cooper     // std::function, because we'll get a "void function should not return a
53228f6c2f2SEnji Cooper     // value" error.
53328f6c2f2SEnji Cooper     //
53428f6c2f2SEnji Cooper     // We need not worry about incompatible result types because the SFINAE on
53528f6c2f2SEnji Cooper     // OnceAction already checks this for us. std::is_invocable_r_v itself makes
53628f6c2f2SEnji Cooper     // the same allowance for void result types.
53728f6c2f2SEnji Cooper     template <typename... ArgRefs>
53828f6c2f2SEnji Cooper     internal::call_result_t<Callable, ArgRefs...> operator()(
53928f6c2f2SEnji Cooper         ArgRefs&&... args) const {
54028f6c2f2SEnji Cooper       return std::move(*callable_)(std::forward<ArgRefs>(args)...);
54128f6c2f2SEnji Cooper     }
54228f6c2f2SEnji Cooper 
54328f6c2f2SEnji Cooper    private:
54428f6c2f2SEnji Cooper     // We must put the callable on the heap so that we are copyable, which
54528f6c2f2SEnji Cooper     // std::function needs.
54628f6c2f2SEnji Cooper     std::shared_ptr<Callable> callable_;
54728f6c2f2SEnji Cooper   };
54828f6c2f2SEnji Cooper 
54928f6c2f2SEnji Cooper   // An adaptor that makes a callable that accepts zero arguments callable with
55028f6c2f2SEnji Cooper   // our mocked arguments.
55128f6c2f2SEnji Cooper   template <typename Callable>
55228f6c2f2SEnji Cooper   struct IgnoreIncomingArguments {
55328f6c2f2SEnji Cooper     internal::call_result_t<Callable> operator()(Args&&...) {
55428f6c2f2SEnji Cooper       return std::move(callable)();
55528f6c2f2SEnji Cooper     }
55628f6c2f2SEnji Cooper 
55728f6c2f2SEnji Cooper     Callable callable;
55828f6c2f2SEnji Cooper   };
55928f6c2f2SEnji Cooper 
56028f6c2f2SEnji Cooper   std::function<Result(Args...)> function_;
56128f6c2f2SEnji Cooper };
56228f6c2f2SEnji Cooper 
563b89a7cc2SEnji Cooper // When an unexpected function call is encountered, Google Mock will
564b89a7cc2SEnji Cooper // let it return a default value if the user has specified one for its
565b89a7cc2SEnji Cooper // return type, or if the return type has a built-in default value;
566b89a7cc2SEnji Cooper // otherwise Google Mock won't know what value to return and will have
567b89a7cc2SEnji Cooper // to abort the process.
568b89a7cc2SEnji Cooper //
569b89a7cc2SEnji Cooper // The DefaultValue<T> class allows a user to specify the
570b89a7cc2SEnji Cooper // default value for a type T that is both copyable and publicly
571b89a7cc2SEnji Cooper // destructible (i.e. anything that can be used as a function return
572b89a7cc2SEnji Cooper // type).  The usage is:
573b89a7cc2SEnji Cooper //
574b89a7cc2SEnji Cooper //   // Sets the default value for type T to be foo.
575b89a7cc2SEnji Cooper //   DefaultValue<T>::Set(foo);
576b89a7cc2SEnji Cooper template <typename T>
577b89a7cc2SEnji Cooper class DefaultValue {
578b89a7cc2SEnji Cooper  public:
579b89a7cc2SEnji Cooper   // Sets the default value for type T; requires T to be
580b89a7cc2SEnji Cooper   // copy-constructable and have a public destructor.
581b89a7cc2SEnji Cooper   static void Set(T x) {
582b89a7cc2SEnji Cooper     delete producer_;
583b89a7cc2SEnji Cooper     producer_ = new FixedValueProducer(x);
584b89a7cc2SEnji Cooper   }
585b89a7cc2SEnji Cooper 
586b89a7cc2SEnji Cooper   // Provides a factory function to be called to generate the default value.
587b89a7cc2SEnji Cooper   // This method can be used even if T is only move-constructible, but it is not
588b89a7cc2SEnji Cooper   // limited to that case.
589b89a7cc2SEnji Cooper   typedef T (*FactoryFunction)();
590b89a7cc2SEnji Cooper   static void SetFactory(FactoryFunction factory) {
591b89a7cc2SEnji Cooper     delete producer_;
592b89a7cc2SEnji Cooper     producer_ = new FactoryValueProducer(factory);
593b89a7cc2SEnji Cooper   }
594b89a7cc2SEnji Cooper 
595b89a7cc2SEnji Cooper   // Unsets the default value for type T.
596b89a7cc2SEnji Cooper   static void Clear() {
597b89a7cc2SEnji Cooper     delete producer_;
59828f6c2f2SEnji Cooper     producer_ = nullptr;
599b89a7cc2SEnji Cooper   }
600b89a7cc2SEnji Cooper 
60128f6c2f2SEnji Cooper   // Returns true if and only if the user has set the default value for type T.
60228f6c2f2SEnji Cooper   static bool IsSet() { return producer_ != nullptr; }
603b89a7cc2SEnji Cooper 
604b89a7cc2SEnji Cooper   // Returns true if T has a default return value set by the user or there
605b89a7cc2SEnji Cooper   // exists a built-in default value.
606b89a7cc2SEnji Cooper   static bool Exists() {
607b89a7cc2SEnji Cooper     return IsSet() || internal::BuiltInDefaultValue<T>::Exists();
608b89a7cc2SEnji Cooper   }
609b89a7cc2SEnji Cooper 
610b89a7cc2SEnji Cooper   // Returns the default value for type T if the user has set one;
611b89a7cc2SEnji Cooper   // otherwise returns the built-in default value. Requires that Exists()
612b89a7cc2SEnji Cooper   // is true, which ensures that the return value is well-defined.
613b89a7cc2SEnji Cooper   static T Get() {
61428f6c2f2SEnji Cooper     return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get()
61528f6c2f2SEnji Cooper                                 : producer_->Produce();
616b89a7cc2SEnji Cooper   }
617b89a7cc2SEnji Cooper 
618b89a7cc2SEnji Cooper  private:
619b89a7cc2SEnji Cooper   class ValueProducer {
620b89a7cc2SEnji Cooper    public:
62128f6c2f2SEnji Cooper     virtual ~ValueProducer() = default;
622b89a7cc2SEnji Cooper     virtual T Produce() = 0;
623b89a7cc2SEnji Cooper   };
624b89a7cc2SEnji Cooper 
625b89a7cc2SEnji Cooper   class FixedValueProducer : public ValueProducer {
626b89a7cc2SEnji Cooper    public:
627b89a7cc2SEnji Cooper     explicit FixedValueProducer(T value) : value_(value) {}
62828f6c2f2SEnji Cooper     T Produce() override { return value_; }
629b89a7cc2SEnji Cooper 
630b89a7cc2SEnji Cooper    private:
631b89a7cc2SEnji Cooper     const T value_;
63228f6c2f2SEnji Cooper     FixedValueProducer(const FixedValueProducer&) = delete;
63328f6c2f2SEnji Cooper     FixedValueProducer& operator=(const FixedValueProducer&) = delete;
634b89a7cc2SEnji Cooper   };
635b89a7cc2SEnji Cooper 
636b89a7cc2SEnji Cooper   class FactoryValueProducer : public ValueProducer {
637b89a7cc2SEnji Cooper    public:
638b89a7cc2SEnji Cooper     explicit FactoryValueProducer(FactoryFunction factory)
639b89a7cc2SEnji Cooper         : factory_(factory) {}
64028f6c2f2SEnji Cooper     T Produce() override { return factory_(); }
641b89a7cc2SEnji Cooper 
642b89a7cc2SEnji Cooper    private:
643b89a7cc2SEnji Cooper     const FactoryFunction factory_;
64428f6c2f2SEnji Cooper     FactoryValueProducer(const FactoryValueProducer&) = delete;
64528f6c2f2SEnji Cooper     FactoryValueProducer& operator=(const FactoryValueProducer&) = delete;
646b89a7cc2SEnji Cooper   };
647b89a7cc2SEnji Cooper 
648b89a7cc2SEnji Cooper   static ValueProducer* producer_;
649b89a7cc2SEnji Cooper };
650b89a7cc2SEnji Cooper 
651b89a7cc2SEnji Cooper // This partial specialization allows a user to set default values for
652b89a7cc2SEnji Cooper // reference types.
653b89a7cc2SEnji Cooper template <typename T>
654b89a7cc2SEnji Cooper class DefaultValue<T&> {
655b89a7cc2SEnji Cooper  public:
656b89a7cc2SEnji Cooper   // Sets the default value for type T&.
657b89a7cc2SEnji Cooper   static void Set(T& x) {  // NOLINT
658b89a7cc2SEnji Cooper     address_ = &x;
659b89a7cc2SEnji Cooper   }
660b89a7cc2SEnji Cooper 
661b89a7cc2SEnji Cooper   // Unsets the default value for type T&.
66228f6c2f2SEnji Cooper   static void Clear() { address_ = nullptr; }
663b89a7cc2SEnji Cooper 
66428f6c2f2SEnji Cooper   // Returns true if and only if the user has set the default value for type T&.
66528f6c2f2SEnji Cooper   static bool IsSet() { return address_ != nullptr; }
666b89a7cc2SEnji Cooper 
667b89a7cc2SEnji Cooper   // Returns true if T has a default return value set by the user or there
668b89a7cc2SEnji Cooper   // exists a built-in default value.
669b89a7cc2SEnji Cooper   static bool Exists() {
670b89a7cc2SEnji Cooper     return IsSet() || internal::BuiltInDefaultValue<T&>::Exists();
671b89a7cc2SEnji Cooper   }
672b89a7cc2SEnji Cooper 
673b89a7cc2SEnji Cooper   // Returns the default value for type T& if the user has set one;
674b89a7cc2SEnji Cooper   // otherwise returns the built-in default value if there is one;
675b89a7cc2SEnji Cooper   // otherwise aborts the process.
676b89a7cc2SEnji Cooper   static T& Get() {
67728f6c2f2SEnji Cooper     return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get()
67828f6c2f2SEnji Cooper                                : *address_;
679b89a7cc2SEnji Cooper   }
680b89a7cc2SEnji Cooper 
681b89a7cc2SEnji Cooper  private:
682b89a7cc2SEnji Cooper   static T* address_;
683b89a7cc2SEnji Cooper };
684b89a7cc2SEnji Cooper 
685b89a7cc2SEnji Cooper // This specialization allows DefaultValue<void>::Get() to
686b89a7cc2SEnji Cooper // compile.
687b89a7cc2SEnji Cooper template <>
688b89a7cc2SEnji Cooper class DefaultValue<void> {
689b89a7cc2SEnji Cooper  public:
690b89a7cc2SEnji Cooper   static bool Exists() { return true; }
691b89a7cc2SEnji Cooper   static void Get() {}
692b89a7cc2SEnji Cooper };
693b89a7cc2SEnji Cooper 
694b89a7cc2SEnji Cooper // Points to the user-set default value for type T.
695b89a7cc2SEnji Cooper template <typename T>
69628f6c2f2SEnji Cooper typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr;
697b89a7cc2SEnji Cooper 
698b89a7cc2SEnji Cooper // Points to the user-set default value for type T&.
699b89a7cc2SEnji Cooper template <typename T>
70028f6c2f2SEnji Cooper T* DefaultValue<T&>::address_ = nullptr;
701b89a7cc2SEnji Cooper 
702b89a7cc2SEnji Cooper // Implement this interface to define an action for function type F.
703b89a7cc2SEnji Cooper template <typename F>
704b89a7cc2SEnji Cooper class ActionInterface {
705b89a7cc2SEnji Cooper  public:
706b89a7cc2SEnji Cooper   typedef typename internal::Function<F>::Result Result;
707b89a7cc2SEnji Cooper   typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
708b89a7cc2SEnji Cooper 
70928f6c2f2SEnji Cooper   ActionInterface() = default;
71028f6c2f2SEnji Cooper   virtual ~ActionInterface() = default;
711b89a7cc2SEnji Cooper 
712b89a7cc2SEnji Cooper   // Performs the action.  This method is not const, as in general an
713b89a7cc2SEnji Cooper   // action can have side effects and be stateful.  For example, a
714b89a7cc2SEnji Cooper   // get-the-next-element-from-the-collection action will need to
715b89a7cc2SEnji Cooper   // remember the current element.
716b89a7cc2SEnji Cooper   virtual Result Perform(const ArgumentTuple& args) = 0;
717b89a7cc2SEnji Cooper 
718b89a7cc2SEnji Cooper  private:
71928f6c2f2SEnji Cooper   ActionInterface(const ActionInterface&) = delete;
72028f6c2f2SEnji Cooper   ActionInterface& operator=(const ActionInterface&) = delete;
721b89a7cc2SEnji Cooper };
722b89a7cc2SEnji Cooper 
723b89a7cc2SEnji Cooper template <typename F>
72428f6c2f2SEnji Cooper class Action;
72528f6c2f2SEnji Cooper 
72628f6c2f2SEnji Cooper // An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)
72728f6c2f2SEnji Cooper // object that represents an action to be taken when a mock function of type
72828f6c2f2SEnji Cooper // R(Args...) is called. The implementation of Action<T> is just a
72928f6c2f2SEnji Cooper // std::shared_ptr to const ActionInterface<T>. Don't inherit from Action! You
73028f6c2f2SEnji Cooper // can view an object implementing ActionInterface<F> as a concrete action
73128f6c2f2SEnji Cooper // (including its current state), and an Action<F> object as a handle to it.
73228f6c2f2SEnji Cooper template <typename R, typename... Args>
73328f6c2f2SEnji Cooper class Action<R(Args...)> {
73428f6c2f2SEnji Cooper  private:
73528f6c2f2SEnji Cooper   using F = R(Args...);
73628f6c2f2SEnji Cooper 
73728f6c2f2SEnji Cooper   // Adapter class to allow constructing Action from a legacy ActionInterface.
73828f6c2f2SEnji Cooper   // New code should create Actions from functors instead.
73928f6c2f2SEnji Cooper   struct ActionAdapter {
74028f6c2f2SEnji Cooper     // Adapter must be copyable to satisfy std::function requirements.
74128f6c2f2SEnji Cooper     ::std::shared_ptr<ActionInterface<F>> impl_;
74228f6c2f2SEnji Cooper 
74328f6c2f2SEnji Cooper     template <typename... InArgs>
74428f6c2f2SEnji Cooper     typename internal::Function<F>::Result operator()(InArgs&&... args) {
74528f6c2f2SEnji Cooper       return impl_->Perform(
74628f6c2f2SEnji Cooper           ::std::forward_as_tuple(::std::forward<InArgs>(args)...));
74728f6c2f2SEnji Cooper     }
74828f6c2f2SEnji Cooper   };
74928f6c2f2SEnji Cooper 
75028f6c2f2SEnji Cooper   template <typename G>
75128f6c2f2SEnji Cooper   using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>;
75228f6c2f2SEnji Cooper 
753b89a7cc2SEnji Cooper  public:
754b89a7cc2SEnji Cooper   typedef typename internal::Function<F>::Result Result;
755b89a7cc2SEnji Cooper   typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
756b89a7cc2SEnji Cooper 
757b89a7cc2SEnji Cooper   // Constructs a null Action.  Needed for storing Action objects in
758b89a7cc2SEnji Cooper   // STL containers.
75928f6c2f2SEnji Cooper   Action() = default;
760b89a7cc2SEnji Cooper 
761b89a7cc2SEnji Cooper   // Construct an Action from a specified callable.
762b89a7cc2SEnji Cooper   // This cannot take std::function directly, because then Action would not be
763b89a7cc2SEnji Cooper   // directly constructible from lambda (it would require two conversions).
76428f6c2f2SEnji Cooper   template <
76528f6c2f2SEnji Cooper       typename G,
76628f6c2f2SEnji Cooper       typename = typename std::enable_if<internal::disjunction<
76728f6c2f2SEnji Cooper           IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>,
76828f6c2f2SEnji Cooper                                                         G>>::value>::type>
76928f6c2f2SEnji Cooper   Action(G&& fun) {  // NOLINT
77028f6c2f2SEnji Cooper     Init(::std::forward<G>(fun), IsCompatibleFunctor<G>());
77128f6c2f2SEnji Cooper   }
772b89a7cc2SEnji Cooper 
773b89a7cc2SEnji Cooper   // Constructs an Action from its implementation.
77428f6c2f2SEnji Cooper   explicit Action(ActionInterface<F>* impl)
77528f6c2f2SEnji Cooper       : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}
776b89a7cc2SEnji Cooper 
777b89a7cc2SEnji Cooper   // This constructor allows us to turn an Action<Func> object into an
778b89a7cc2SEnji Cooper   // Action<F>, as long as F's arguments can be implicitly converted
77928f6c2f2SEnji Cooper   // to Func's and Func's return type can be implicitly converted to F's.
780b89a7cc2SEnji Cooper   template <typename Func>
78128f6c2f2SEnji Cooper   Action(const Action<Func>& action)  // NOLINT
78228f6c2f2SEnji Cooper       : fun_(action.fun_) {}
783b89a7cc2SEnji Cooper 
78428f6c2f2SEnji Cooper   // Returns true if and only if this is the DoDefault() action.
78528f6c2f2SEnji Cooper   bool IsDoDefault() const { return fun_ == nullptr; }
786b89a7cc2SEnji Cooper 
787b89a7cc2SEnji Cooper   // Performs the action.  Note that this method is const even though
788b89a7cc2SEnji Cooper   // the corresponding method in ActionInterface is not.  The reason
789b89a7cc2SEnji Cooper   // is that a const Action<F> means that it cannot be re-bound to
790b89a7cc2SEnji Cooper   // another concrete action, not that the concrete action it binds to
791b89a7cc2SEnji Cooper   // cannot change state.  (Think of the difference between a const
792b89a7cc2SEnji Cooper   // pointer and a pointer to const.)
793b89a7cc2SEnji Cooper   Result Perform(ArgumentTuple args) const {
794b89a7cc2SEnji Cooper     if (IsDoDefault()) {
795b89a7cc2SEnji Cooper       internal::IllegalDoDefault(__FILE__, __LINE__);
796b89a7cc2SEnji Cooper     }
797b89a7cc2SEnji Cooper     return internal::Apply(fun_, ::std::move(args));
798b89a7cc2SEnji Cooper   }
79928f6c2f2SEnji Cooper 
80028f6c2f2SEnji Cooper   // An action can be used as a OnceAction, since it's obviously safe to call it
80128f6c2f2SEnji Cooper   // once.
80228f6c2f2SEnji Cooper   operator OnceAction<F>() const {  // NOLINT
80328f6c2f2SEnji Cooper     // Return a OnceAction-compatible callable that calls Perform with the
80428f6c2f2SEnji Cooper     // arguments it is provided. We could instead just return fun_, but then
80528f6c2f2SEnji Cooper     // we'd need to handle the IsDoDefault() case separately.
80628f6c2f2SEnji Cooper     struct OA {
80728f6c2f2SEnji Cooper       Action<F> action;
80828f6c2f2SEnji Cooper 
80928f6c2f2SEnji Cooper       R operator()(Args... args) && {
81028f6c2f2SEnji Cooper         return action.Perform(
81128f6c2f2SEnji Cooper             std::forward_as_tuple(std::forward<Args>(args)...));
81228f6c2f2SEnji Cooper       }
81328f6c2f2SEnji Cooper     };
81428f6c2f2SEnji Cooper 
81528f6c2f2SEnji Cooper     return OA{*this};
816b89a7cc2SEnji Cooper   }
817b89a7cc2SEnji Cooper 
818b89a7cc2SEnji Cooper  private:
819b89a7cc2SEnji Cooper   template <typename G>
820b89a7cc2SEnji Cooper   friend class Action;
821b89a7cc2SEnji Cooper 
82228f6c2f2SEnji Cooper   template <typename G>
82328f6c2f2SEnji Cooper   void Init(G&& g, ::std::true_type) {
82428f6c2f2SEnji Cooper     fun_ = ::std::forward<G>(g);
82528f6c2f2SEnji Cooper   }
82628f6c2f2SEnji Cooper 
82728f6c2f2SEnji Cooper   template <typename G>
82828f6c2f2SEnji Cooper   void Init(G&& g, ::std::false_type) {
82928f6c2f2SEnji Cooper     fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)};
83028f6c2f2SEnji Cooper   }
83128f6c2f2SEnji Cooper 
83228f6c2f2SEnji Cooper   template <typename FunctionImpl>
83328f6c2f2SEnji Cooper   struct IgnoreArgs {
83428f6c2f2SEnji Cooper     template <typename... InArgs>
83528f6c2f2SEnji Cooper     Result operator()(const InArgs&...) const {
83628f6c2f2SEnji Cooper       return function_impl();
83728f6c2f2SEnji Cooper     }
83828f6c2f2SEnji Cooper 
83928f6c2f2SEnji Cooper     FunctionImpl function_impl;
84028f6c2f2SEnji Cooper   };
84128f6c2f2SEnji Cooper 
84228f6c2f2SEnji Cooper   // fun_ is an empty function if and only if this is the DoDefault() action.
843b89a7cc2SEnji Cooper   ::std::function<F> fun_;
844b89a7cc2SEnji Cooper };
845b89a7cc2SEnji Cooper 
846b89a7cc2SEnji Cooper // The PolymorphicAction class template makes it easy to implement a
847b89a7cc2SEnji Cooper // polymorphic action (i.e. an action that can be used in mock
848b89a7cc2SEnji Cooper // functions of than one type, e.g. Return()).
849b89a7cc2SEnji Cooper //
850b89a7cc2SEnji Cooper // To define a polymorphic action, a user first provides a COPYABLE
851b89a7cc2SEnji Cooper // implementation class that has a Perform() method template:
852b89a7cc2SEnji Cooper //
853b89a7cc2SEnji Cooper //   class FooAction {
854b89a7cc2SEnji Cooper //    public:
855b89a7cc2SEnji Cooper //     template <typename Result, typename ArgumentTuple>
856b89a7cc2SEnji Cooper //     Result Perform(const ArgumentTuple& args) const {
857b89a7cc2SEnji Cooper //       // Processes the arguments and returns a result, using
85828f6c2f2SEnji Cooper //       // std::get<N>(args) to get the N-th (0-based) argument in the tuple.
859b89a7cc2SEnji Cooper //     }
860b89a7cc2SEnji Cooper //     ...
861b89a7cc2SEnji Cooper //   };
862b89a7cc2SEnji Cooper //
863b89a7cc2SEnji Cooper // Then the user creates the polymorphic action using
864b89a7cc2SEnji Cooper // MakePolymorphicAction(object) where object has type FooAction.  See
865b89a7cc2SEnji Cooper // the definition of Return(void) and SetArgumentPointee<N>(value) for
866b89a7cc2SEnji Cooper // complete examples.
867b89a7cc2SEnji Cooper template <typename Impl>
868b89a7cc2SEnji Cooper class PolymorphicAction {
869b89a7cc2SEnji Cooper  public:
870b89a7cc2SEnji Cooper   explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
871b89a7cc2SEnji Cooper 
872b89a7cc2SEnji Cooper   template <typename F>
873b89a7cc2SEnji Cooper   operator Action<F>() const {
874b89a7cc2SEnji Cooper     return Action<F>(new MonomorphicImpl<F>(impl_));
875b89a7cc2SEnji Cooper   }
876b89a7cc2SEnji Cooper 
877b89a7cc2SEnji Cooper  private:
878b89a7cc2SEnji Cooper   template <typename F>
879b89a7cc2SEnji Cooper   class MonomorphicImpl : public ActionInterface<F> {
880b89a7cc2SEnji Cooper    public:
881b89a7cc2SEnji Cooper     typedef typename internal::Function<F>::Result Result;
882b89a7cc2SEnji Cooper     typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
883b89a7cc2SEnji Cooper 
884b89a7cc2SEnji Cooper     explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
885b89a7cc2SEnji Cooper 
88628f6c2f2SEnji Cooper     Result Perform(const ArgumentTuple& args) override {
887b89a7cc2SEnji Cooper       return impl_.template Perform<Result>(args);
888b89a7cc2SEnji Cooper     }
889b89a7cc2SEnji Cooper 
890b89a7cc2SEnji Cooper    private:
891b89a7cc2SEnji Cooper     Impl impl_;
892b89a7cc2SEnji Cooper   };
893b89a7cc2SEnji Cooper 
894b89a7cc2SEnji Cooper   Impl impl_;
895b89a7cc2SEnji Cooper };
896b89a7cc2SEnji Cooper 
897b89a7cc2SEnji Cooper // Creates an Action from its implementation and returns it.  The
898b89a7cc2SEnji Cooper // created Action object owns the implementation.
899b89a7cc2SEnji Cooper template <typename F>
900b89a7cc2SEnji Cooper Action<F> MakeAction(ActionInterface<F>* impl) {
901b89a7cc2SEnji Cooper   return Action<F>(impl);
902b89a7cc2SEnji Cooper }
903b89a7cc2SEnji Cooper 
904b89a7cc2SEnji Cooper // Creates a polymorphic action from its implementation.  This is
905b89a7cc2SEnji Cooper // easier to use than the PolymorphicAction<Impl> constructor as it
906b89a7cc2SEnji Cooper // doesn't require you to explicitly write the template argument, e.g.
907b89a7cc2SEnji Cooper //
908b89a7cc2SEnji Cooper //   MakePolymorphicAction(foo);
909b89a7cc2SEnji Cooper // vs
910b89a7cc2SEnji Cooper //   PolymorphicAction<TypeOfFoo>(foo);
911b89a7cc2SEnji Cooper template <typename Impl>
912b89a7cc2SEnji Cooper inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
913b89a7cc2SEnji Cooper   return PolymorphicAction<Impl>(impl);
914b89a7cc2SEnji Cooper }
915b89a7cc2SEnji Cooper 
916b89a7cc2SEnji Cooper namespace internal {
917b89a7cc2SEnji Cooper 
918b89a7cc2SEnji Cooper // Helper struct to specialize ReturnAction to execute a move instead of a copy
919b89a7cc2SEnji Cooper // on return. Useful for move-only types, but could be used on any type.
920b89a7cc2SEnji Cooper template <typename T>
921b89a7cc2SEnji Cooper struct ByMoveWrapper {
92228f6c2f2SEnji Cooper   explicit ByMoveWrapper(T value) : payload(std::move(value)) {}
923b89a7cc2SEnji Cooper   T payload;
924b89a7cc2SEnji Cooper };
925b89a7cc2SEnji Cooper 
92628f6c2f2SEnji Cooper // The general implementation of Return(R). Specializations follow below.
92728f6c2f2SEnji Cooper template <typename R>
92828f6c2f2SEnji Cooper class ReturnAction final {
92928f6c2f2SEnji Cooper  public:
93028f6c2f2SEnji Cooper   explicit ReturnAction(R value) : value_(std::move(value)) {}
93128f6c2f2SEnji Cooper 
93228f6c2f2SEnji Cooper   template <typename U, typename... Args,
93328f6c2f2SEnji Cooper             typename = typename std::enable_if<conjunction<
93428f6c2f2SEnji Cooper                 // See the requirements documented on Return.
93528f6c2f2SEnji Cooper                 negation<std::is_same<void, U>>,  //
93628f6c2f2SEnji Cooper                 negation<std::is_reference<U>>,   //
93728f6c2f2SEnji Cooper                 std::is_convertible<R, U>,        //
93828f6c2f2SEnji Cooper                 std::is_move_constructible<U>>::value>::type>
93928f6c2f2SEnji Cooper   operator OnceAction<U(Args...)>() && {  // NOLINT
94028f6c2f2SEnji Cooper     return Impl<U>(std::move(value_));
94128f6c2f2SEnji Cooper   }
94228f6c2f2SEnji Cooper 
94328f6c2f2SEnji Cooper   template <typename U, typename... Args,
94428f6c2f2SEnji Cooper             typename = typename std::enable_if<conjunction<
94528f6c2f2SEnji Cooper                 // See the requirements documented on Return.
94628f6c2f2SEnji Cooper                 negation<std::is_same<void, U>>,   //
94728f6c2f2SEnji Cooper                 negation<std::is_reference<U>>,    //
94828f6c2f2SEnji Cooper                 std::is_convertible<const R&, U>,  //
94928f6c2f2SEnji Cooper                 std::is_copy_constructible<U>>::value>::type>
95028f6c2f2SEnji Cooper   operator Action<U(Args...)>() const {  // NOLINT
95128f6c2f2SEnji Cooper     return Impl<U>(value_);
95228f6c2f2SEnji Cooper   }
95328f6c2f2SEnji Cooper 
95428f6c2f2SEnji Cooper  private:
95528f6c2f2SEnji Cooper   // Implements the Return(x) action for a mock function that returns type U.
95628f6c2f2SEnji Cooper   template <typename U>
95728f6c2f2SEnji Cooper   class Impl final {
95828f6c2f2SEnji Cooper    public:
95928f6c2f2SEnji Cooper     // The constructor used when the return value is allowed to move from the
96028f6c2f2SEnji Cooper     // input value (i.e. we are converting to OnceAction).
96128f6c2f2SEnji Cooper     explicit Impl(R&& input_value)
96228f6c2f2SEnji Cooper         : state_(new State(std::move(input_value))) {}
96328f6c2f2SEnji Cooper 
96428f6c2f2SEnji Cooper     // The constructor used when the return value is not allowed to move from
96528f6c2f2SEnji Cooper     // the input value (i.e. we are converting to Action).
96628f6c2f2SEnji Cooper     explicit Impl(const R& input_value) : state_(new State(input_value)) {}
96728f6c2f2SEnji Cooper 
96828f6c2f2SEnji Cooper     U operator()() && { return std::move(state_->value); }
96928f6c2f2SEnji Cooper     U operator()() const& { return state_->value; }
97028f6c2f2SEnji Cooper 
97128f6c2f2SEnji Cooper    private:
97228f6c2f2SEnji Cooper     // We put our state on the heap so that the compiler-generated copy/move
97328f6c2f2SEnji Cooper     // constructors work correctly even when U is a reference-like type. This is
97428f6c2f2SEnji Cooper     // necessary only because we eagerly create State::value (see the note on
97528f6c2f2SEnji Cooper     // that symbol for details). If we instead had only the input value as a
97628f6c2f2SEnji Cooper     // member then the default constructors would work fine.
977b89a7cc2SEnji Cooper     //
97828f6c2f2SEnji Cooper     // For example, when R is std::string and U is std::string_view, value is a
97928f6c2f2SEnji Cooper     // reference to the string backed by input_value. The copy constructor would
98028f6c2f2SEnji Cooper     // copy both, so that we wind up with a new input_value object (with the
98128f6c2f2SEnji Cooper     // same contents) and a reference to the *old* input_value object rather
98228f6c2f2SEnji Cooper     // than the new one.
98328f6c2f2SEnji Cooper     struct State {
98428f6c2f2SEnji Cooper       explicit State(const R& input_value_in)
98528f6c2f2SEnji Cooper           : input_value(input_value_in),
98628f6c2f2SEnji Cooper             // Make an implicit conversion to Result before initializing the U
98728f6c2f2SEnji Cooper             // object we store, avoiding calling any explicit constructor of U
98828f6c2f2SEnji Cooper             // from R.
989b89a7cc2SEnji Cooper             //
99028f6c2f2SEnji Cooper             // This simulates the language rules: a function with return type U
99128f6c2f2SEnji Cooper             // that does `return R()` requires R to be implicitly convertible to
99228f6c2f2SEnji Cooper             // U, and uses that path for the conversion, even U Result has an
99328f6c2f2SEnji Cooper             // explicit constructor from R.
99428f6c2f2SEnji Cooper             value(ImplicitCast_<U>(internal::as_const(input_value))) {}
99528f6c2f2SEnji Cooper 
99628f6c2f2SEnji Cooper       // As above, but for the case where we're moving from the ReturnAction
99728f6c2f2SEnji Cooper       // object because it's being used as a OnceAction.
99828f6c2f2SEnji Cooper       explicit State(R&& input_value_in)
99928f6c2f2SEnji Cooper           : input_value(std::move(input_value_in)),
100028f6c2f2SEnji Cooper             // For the same reason as above we make an implicit conversion to U
100128f6c2f2SEnji Cooper             // before initializing the value.
100228f6c2f2SEnji Cooper             //
100328f6c2f2SEnji Cooper             // Unlike above we provide the input value as an rvalue to the
100428f6c2f2SEnji Cooper             // implicit conversion because this is a OnceAction: it's fine if it
100528f6c2f2SEnji Cooper             // wants to consume the input value.
100628f6c2f2SEnji Cooper             value(ImplicitCast_<U>(std::move(input_value))) {}
100728f6c2f2SEnji Cooper 
100828f6c2f2SEnji Cooper       // A copy of the value originally provided by the user. We retain this in
100928f6c2f2SEnji Cooper       // addition to the value of the mock function's result type below in case
101028f6c2f2SEnji Cooper       // the latter is a reference-like type. See the std::string_view example
101128f6c2f2SEnji Cooper       // in the documentation on Return.
101228f6c2f2SEnji Cooper       R input_value;
101328f6c2f2SEnji Cooper 
101428f6c2f2SEnji Cooper       // The value we actually return, as the type returned by the mock function
101528f6c2f2SEnji Cooper       // itself.
101628f6c2f2SEnji Cooper       //
101728f6c2f2SEnji Cooper       // We eagerly initialize this here, rather than lazily doing the implicit
101828f6c2f2SEnji Cooper       // conversion automatically each time Perform is called, for historical
101928f6c2f2SEnji Cooper       // reasons: in 2009-11, commit a070cbd91c (Google changelist 13540126)
102028f6c2f2SEnji Cooper       // made the Action<U()> conversion operator eagerly convert the R value to
102128f6c2f2SEnji Cooper       // U, but without keeping the R alive. This broke the use case discussed
102228f6c2f2SEnji Cooper       // in the documentation for Return, making reference-like types such as
102328f6c2f2SEnji Cooper       // std::string_view not safe to use as U where the input type R is a
102428f6c2f2SEnji Cooper       // value-like type such as std::string.
102528f6c2f2SEnji Cooper       //
102628f6c2f2SEnji Cooper       // The example the commit gave was not very clear, nor was the issue
102728f6c2f2SEnji Cooper       // thread (https://github.com/google/googlemock/issues/86), but it seems
102828f6c2f2SEnji Cooper       // the worry was about reference-like input types R that flatten to a
102928f6c2f2SEnji Cooper       // value-like type U when being implicitly converted. An example of this
103028f6c2f2SEnji Cooper       // is std::vector<bool>::reference, which is often a proxy type with an
103128f6c2f2SEnji Cooper       // reference to the underlying vector:
103228f6c2f2SEnji Cooper       //
103328f6c2f2SEnji Cooper       //     // Helper method: have the mock function return bools according
103428f6c2f2SEnji Cooper       //     // to the supplied script.
103528f6c2f2SEnji Cooper       //     void SetActions(MockFunction<bool(size_t)>& mock,
103628f6c2f2SEnji Cooper       //                     const std::vector<bool>& script) {
103728f6c2f2SEnji Cooper       //       for (size_t i = 0; i < script.size(); ++i) {
103828f6c2f2SEnji Cooper       //         EXPECT_CALL(mock, Call(i)).WillOnce(Return(script[i]));
103928f6c2f2SEnji Cooper       //       }
1040b89a7cc2SEnji Cooper       //     }
1041b89a7cc2SEnji Cooper       //
104228f6c2f2SEnji Cooper       //     TEST(Foo, Bar) {
104328f6c2f2SEnji Cooper       //       // Set actions using a temporary vector, whose operator[]
104428f6c2f2SEnji Cooper       //       // returns proxy objects that references that will be
104528f6c2f2SEnji Cooper       //       // dangling once the call to SetActions finishes and the
104628f6c2f2SEnji Cooper       //       // vector is destroyed.
104728f6c2f2SEnji Cooper       //       MockFunction<bool(size_t)> mock;
104828f6c2f2SEnji Cooper       //       SetActions(mock, {false, true});
1049b89a7cc2SEnji Cooper       //
105028f6c2f2SEnji Cooper       //       EXPECT_FALSE(mock.AsStdFunction()(0));
105128f6c2f2SEnji Cooper       //       EXPECT_TRUE(mock.AsStdFunction()(1));
105228f6c2f2SEnji Cooper       //     }
1053b89a7cc2SEnji Cooper       //
105428f6c2f2SEnji Cooper       // This eager conversion helps with a simple case like this, but doesn't
105528f6c2f2SEnji Cooper       // fully make these types work in general. For example the following still
105628f6c2f2SEnji Cooper       // uses a dangling reference:
105728f6c2f2SEnji Cooper       //
105828f6c2f2SEnji Cooper       //     TEST(Foo, Baz) {
105928f6c2f2SEnji Cooper       //       MockFunction<std::vector<std::string>()> mock;
106028f6c2f2SEnji Cooper       //
106128f6c2f2SEnji Cooper       //       // Return the same vector twice, and then the empty vector
106228f6c2f2SEnji Cooper       //       // thereafter.
106328f6c2f2SEnji Cooper       //       auto action = Return(std::initializer_list<std::string>{
106428f6c2f2SEnji Cooper       //           "taco", "burrito",
106528f6c2f2SEnji Cooper       //       });
106628f6c2f2SEnji Cooper       //
106728f6c2f2SEnji Cooper       //       EXPECT_CALL(mock, Call)
106828f6c2f2SEnji Cooper       //           .WillOnce(action)
106928f6c2f2SEnji Cooper       //           .WillOnce(action)
107028f6c2f2SEnji Cooper       //           .WillRepeatedly(Return(std::vector<std::string>{}));
107128f6c2f2SEnji Cooper       //
107228f6c2f2SEnji Cooper       //       EXPECT_THAT(mock.AsStdFunction()(),
107328f6c2f2SEnji Cooper       //                   ElementsAre("taco", "burrito"));
107428f6c2f2SEnji Cooper       //       EXPECT_THAT(mock.AsStdFunction()(),
107528f6c2f2SEnji Cooper       //                   ElementsAre("taco", "burrito"));
107628f6c2f2SEnji Cooper       //       EXPECT_THAT(mock.AsStdFunction()(), IsEmpty());
107728f6c2f2SEnji Cooper       //     }
107828f6c2f2SEnji Cooper       //
107928f6c2f2SEnji Cooper       U value;
108028f6c2f2SEnji Cooper     };
1081b89a7cc2SEnji Cooper 
108228f6c2f2SEnji Cooper     const std::shared_ptr<State> state_;
108328f6c2f2SEnji Cooper   };
108428f6c2f2SEnji Cooper 
108528f6c2f2SEnji Cooper   R value_;
108628f6c2f2SEnji Cooper };
108728f6c2f2SEnji Cooper 
108828f6c2f2SEnji Cooper // A specialization of ReturnAction<R> when R is ByMoveWrapper<T> for some T.
108928f6c2f2SEnji Cooper //
109028f6c2f2SEnji Cooper // This version applies the type system-defeating hack of moving from T even in
109128f6c2f2SEnji Cooper // the const call operator, checking at runtime that it isn't called more than
109228f6c2f2SEnji Cooper // once, since the user has declared their intent to do so by using ByMove.
109328f6c2f2SEnji Cooper template <typename T>
109428f6c2f2SEnji Cooper class ReturnAction<ByMoveWrapper<T>> final {
109528f6c2f2SEnji Cooper  public:
109628f6c2f2SEnji Cooper   explicit ReturnAction(ByMoveWrapper<T> wrapper)
109728f6c2f2SEnji Cooper       : state_(new State(std::move(wrapper.payload))) {}
109828f6c2f2SEnji Cooper 
109928f6c2f2SEnji Cooper   T operator()() const {
110028f6c2f2SEnji Cooper     GTEST_CHECK_(!state_->called)
110128f6c2f2SEnji Cooper         << "A ByMove() action must be performed at most once.";
110228f6c2f2SEnji Cooper 
110328f6c2f2SEnji Cooper     state_->called = true;
110428f6c2f2SEnji Cooper     return std::move(state_->value);
1105b89a7cc2SEnji Cooper   }
1106b89a7cc2SEnji Cooper 
1107b89a7cc2SEnji Cooper  private:
110828f6c2f2SEnji Cooper   // We store our state on the heap so that we are copyable as required by
110928f6c2f2SEnji Cooper   // Action, despite the fact that we are stateful and T may not be copyable.
111028f6c2f2SEnji Cooper   struct State {
111128f6c2f2SEnji Cooper     explicit State(T&& value_in) : value(std::move(value_in)) {}
1112b89a7cc2SEnji Cooper 
111328f6c2f2SEnji Cooper     T value;
111428f6c2f2SEnji Cooper     bool called = false;
1115b89a7cc2SEnji Cooper   };
1116b89a7cc2SEnji Cooper 
111728f6c2f2SEnji Cooper   const std::shared_ptr<State> state_;
1118b89a7cc2SEnji Cooper };
1119b89a7cc2SEnji Cooper 
1120b89a7cc2SEnji Cooper // Implements the ReturnNull() action.
1121b89a7cc2SEnji Cooper class ReturnNullAction {
1122b89a7cc2SEnji Cooper  public:
1123b89a7cc2SEnji Cooper   // Allows ReturnNull() to be used in any pointer-returning function. In C++11
1124b89a7cc2SEnji Cooper   // this is enforced by returning nullptr, and in non-C++11 by asserting a
1125b89a7cc2SEnji Cooper   // pointer type on compile time.
1126b89a7cc2SEnji Cooper   template <typename Result, typename ArgumentTuple>
1127b89a7cc2SEnji Cooper   static Result Perform(const ArgumentTuple&) {
1128b89a7cc2SEnji Cooper     return nullptr;
1129b89a7cc2SEnji Cooper   }
1130b89a7cc2SEnji Cooper };
1131b89a7cc2SEnji Cooper 
1132b89a7cc2SEnji Cooper // Implements the Return() action.
1133b89a7cc2SEnji Cooper class ReturnVoidAction {
1134b89a7cc2SEnji Cooper  public:
1135b89a7cc2SEnji Cooper   // Allows Return() to be used in any void-returning function.
1136b89a7cc2SEnji Cooper   template <typename Result, typename ArgumentTuple>
1137b89a7cc2SEnji Cooper   static void Perform(const ArgumentTuple&) {
113828f6c2f2SEnji Cooper     static_assert(std::is_void<Result>::value, "Result should be void.");
1139b89a7cc2SEnji Cooper   }
1140b89a7cc2SEnji Cooper };
1141b89a7cc2SEnji Cooper 
1142b89a7cc2SEnji Cooper // Implements the polymorphic ReturnRef(x) action, which can be used
1143b89a7cc2SEnji Cooper // in any function that returns a reference to the type of x,
1144b89a7cc2SEnji Cooper // regardless of the argument types.
1145b89a7cc2SEnji Cooper template <typename T>
1146b89a7cc2SEnji Cooper class ReturnRefAction {
1147b89a7cc2SEnji Cooper  public:
1148b89a7cc2SEnji Cooper   // Constructs a ReturnRefAction object from the reference to be returned.
1149b89a7cc2SEnji Cooper   explicit ReturnRefAction(T& ref) : ref_(ref) {}  // NOLINT
1150b89a7cc2SEnji Cooper 
1151b89a7cc2SEnji Cooper   // This template type conversion operator allows ReturnRef(x) to be
1152b89a7cc2SEnji Cooper   // used in ANY function that returns a reference to x's type.
1153b89a7cc2SEnji Cooper   template <typename F>
1154b89a7cc2SEnji Cooper   operator Action<F>() const {
1155b89a7cc2SEnji Cooper     typedef typename Function<F>::Result Result;
1156b89a7cc2SEnji Cooper     // Asserts that the function return type is a reference.  This
1157b89a7cc2SEnji Cooper     // catches the user error of using ReturnRef(x) when Return(x)
1158b89a7cc2SEnji Cooper     // should be used, and generates some helpful error message.
115928f6c2f2SEnji Cooper     static_assert(std::is_reference<Result>::value,
116028f6c2f2SEnji Cooper                   "use Return instead of ReturnRef to return a value");
1161b89a7cc2SEnji Cooper     return Action<F>(new Impl<F>(ref_));
1162b89a7cc2SEnji Cooper   }
1163b89a7cc2SEnji Cooper 
1164b89a7cc2SEnji Cooper  private:
1165b89a7cc2SEnji Cooper   // Implements the ReturnRef(x) action for a particular function type F.
1166b89a7cc2SEnji Cooper   template <typename F>
1167b89a7cc2SEnji Cooper   class Impl : public ActionInterface<F> {
1168b89a7cc2SEnji Cooper    public:
1169b89a7cc2SEnji Cooper     typedef typename Function<F>::Result Result;
1170b89a7cc2SEnji Cooper     typedef typename Function<F>::ArgumentTuple ArgumentTuple;
1171b89a7cc2SEnji Cooper 
1172b89a7cc2SEnji Cooper     explicit Impl(T& ref) : ref_(ref) {}  // NOLINT
1173b89a7cc2SEnji Cooper 
117428f6c2f2SEnji Cooper     Result Perform(const ArgumentTuple&) override { return ref_; }
1175b89a7cc2SEnji Cooper 
1176b89a7cc2SEnji Cooper    private:
1177b89a7cc2SEnji Cooper     T& ref_;
1178b89a7cc2SEnji Cooper   };
1179b89a7cc2SEnji Cooper 
1180b89a7cc2SEnji Cooper   T& ref_;
1181b89a7cc2SEnji Cooper };
1182b89a7cc2SEnji Cooper 
1183b89a7cc2SEnji Cooper // Implements the polymorphic ReturnRefOfCopy(x) action, which can be
1184b89a7cc2SEnji Cooper // used in any function that returns a reference to the type of x,
1185b89a7cc2SEnji Cooper // regardless of the argument types.
1186b89a7cc2SEnji Cooper template <typename T>
1187b89a7cc2SEnji Cooper class ReturnRefOfCopyAction {
1188b89a7cc2SEnji Cooper  public:
1189b89a7cc2SEnji Cooper   // Constructs a ReturnRefOfCopyAction object from the reference to
1190b89a7cc2SEnji Cooper   // be returned.
1191b89a7cc2SEnji Cooper   explicit ReturnRefOfCopyAction(const T& value) : value_(value) {}  // NOLINT
1192b89a7cc2SEnji Cooper 
1193b89a7cc2SEnji Cooper   // This template type conversion operator allows ReturnRefOfCopy(x) to be
1194b89a7cc2SEnji Cooper   // used in ANY function that returns a reference to x's type.
1195b89a7cc2SEnji Cooper   template <typename F>
1196b89a7cc2SEnji Cooper   operator Action<F>() const {
1197b89a7cc2SEnji Cooper     typedef typename Function<F>::Result Result;
1198b89a7cc2SEnji Cooper     // Asserts that the function return type is a reference.  This
1199b89a7cc2SEnji Cooper     // catches the user error of using ReturnRefOfCopy(x) when Return(x)
1200b89a7cc2SEnji Cooper     // should be used, and generates some helpful error message.
120128f6c2f2SEnji Cooper     static_assert(std::is_reference<Result>::value,
120228f6c2f2SEnji Cooper                   "use Return instead of ReturnRefOfCopy to return a value");
1203b89a7cc2SEnji Cooper     return Action<F>(new Impl<F>(value_));
1204b89a7cc2SEnji Cooper   }
1205b89a7cc2SEnji Cooper 
1206b89a7cc2SEnji Cooper  private:
1207b89a7cc2SEnji Cooper   // Implements the ReturnRefOfCopy(x) action for a particular function type F.
1208b89a7cc2SEnji Cooper   template <typename F>
1209b89a7cc2SEnji Cooper   class Impl : public ActionInterface<F> {
1210b89a7cc2SEnji Cooper    public:
1211b89a7cc2SEnji Cooper     typedef typename Function<F>::Result Result;
1212b89a7cc2SEnji Cooper     typedef typename Function<F>::ArgumentTuple ArgumentTuple;
1213b89a7cc2SEnji Cooper 
1214b89a7cc2SEnji Cooper     explicit Impl(const T& value) : value_(value) {}  // NOLINT
1215b89a7cc2SEnji Cooper 
121628f6c2f2SEnji Cooper     Result Perform(const ArgumentTuple&) override { return value_; }
1217b89a7cc2SEnji Cooper 
1218b89a7cc2SEnji Cooper    private:
1219b89a7cc2SEnji Cooper     T value_;
1220b89a7cc2SEnji Cooper   };
1221b89a7cc2SEnji Cooper 
1222b89a7cc2SEnji Cooper   const T value_;
122328f6c2f2SEnji Cooper };
1224b89a7cc2SEnji Cooper 
122528f6c2f2SEnji Cooper // Implements the polymorphic ReturnRoundRobin(v) action, which can be
122628f6c2f2SEnji Cooper // used in any function that returns the element_type of v.
122728f6c2f2SEnji Cooper template <typename T>
122828f6c2f2SEnji Cooper class ReturnRoundRobinAction {
122928f6c2f2SEnji Cooper  public:
123028f6c2f2SEnji Cooper   explicit ReturnRoundRobinAction(std::vector<T> values) {
123128f6c2f2SEnji Cooper     GTEST_CHECK_(!values.empty())
123228f6c2f2SEnji Cooper         << "ReturnRoundRobin requires at least one element.";
123328f6c2f2SEnji Cooper     state_->values = std::move(values);
123428f6c2f2SEnji Cooper   }
123528f6c2f2SEnji Cooper 
123628f6c2f2SEnji Cooper   template <typename... Args>
123728f6c2f2SEnji Cooper   T operator()(Args&&...) const {
123828f6c2f2SEnji Cooper     return state_->Next();
123928f6c2f2SEnji Cooper   }
124028f6c2f2SEnji Cooper 
124128f6c2f2SEnji Cooper  private:
124228f6c2f2SEnji Cooper   struct State {
124328f6c2f2SEnji Cooper     T Next() {
124428f6c2f2SEnji Cooper       T ret_val = values[i++];
124528f6c2f2SEnji Cooper       if (i == values.size()) i = 0;
124628f6c2f2SEnji Cooper       return ret_val;
124728f6c2f2SEnji Cooper     }
124828f6c2f2SEnji Cooper 
124928f6c2f2SEnji Cooper     std::vector<T> values;
125028f6c2f2SEnji Cooper     size_t i = 0;
125128f6c2f2SEnji Cooper   };
125228f6c2f2SEnji Cooper   std::shared_ptr<State> state_ = std::make_shared<State>();
1253b89a7cc2SEnji Cooper };
1254b89a7cc2SEnji Cooper 
1255b89a7cc2SEnji Cooper // Implements the polymorphic DoDefault() action.
1256b89a7cc2SEnji Cooper class DoDefaultAction {
1257b89a7cc2SEnji Cooper  public:
1258b89a7cc2SEnji Cooper   // This template type conversion operator allows DoDefault() to be
1259b89a7cc2SEnji Cooper   // used in any function.
1260b89a7cc2SEnji Cooper   template <typename F>
126128f6c2f2SEnji Cooper   operator Action<F>() const {
126228f6c2f2SEnji Cooper     return Action<F>();
126328f6c2f2SEnji Cooper   }  // NOLINT
1264b89a7cc2SEnji Cooper };
1265b89a7cc2SEnji Cooper 
1266b89a7cc2SEnji Cooper // Implements the Assign action to set a given pointer referent to a
1267b89a7cc2SEnji Cooper // particular value.
1268b89a7cc2SEnji Cooper template <typename T1, typename T2>
1269b89a7cc2SEnji Cooper class AssignAction {
1270b89a7cc2SEnji Cooper  public:
1271b89a7cc2SEnji Cooper   AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
1272b89a7cc2SEnji Cooper 
1273b89a7cc2SEnji Cooper   template <typename Result, typename ArgumentTuple>
1274b89a7cc2SEnji Cooper   void Perform(const ArgumentTuple& /* args */) const {
1275b89a7cc2SEnji Cooper     *ptr_ = value_;
1276b89a7cc2SEnji Cooper   }
1277b89a7cc2SEnji Cooper 
1278b89a7cc2SEnji Cooper  private:
1279b89a7cc2SEnji Cooper   T1* const ptr_;
1280b89a7cc2SEnji Cooper   const T2 value_;
1281b89a7cc2SEnji Cooper };
1282b89a7cc2SEnji Cooper 
128328f6c2f2SEnji Cooper #ifndef GTEST_OS_WINDOWS_MOBILE
1284b89a7cc2SEnji Cooper 
1285b89a7cc2SEnji Cooper // Implements the SetErrnoAndReturn action to simulate return from
1286b89a7cc2SEnji Cooper // various system calls and libc functions.
1287b89a7cc2SEnji Cooper template <typename T>
1288b89a7cc2SEnji Cooper class SetErrnoAndReturnAction {
1289b89a7cc2SEnji Cooper  public:
1290b89a7cc2SEnji Cooper   SetErrnoAndReturnAction(int errno_value, T result)
129128f6c2f2SEnji Cooper       : errno_(errno_value), result_(result) {}
1292b89a7cc2SEnji Cooper   template <typename Result, typename ArgumentTuple>
1293b89a7cc2SEnji Cooper   Result Perform(const ArgumentTuple& /* args */) const {
1294b89a7cc2SEnji Cooper     errno = errno_;
1295b89a7cc2SEnji Cooper     return result_;
1296b89a7cc2SEnji Cooper   }
1297b89a7cc2SEnji Cooper 
1298b89a7cc2SEnji Cooper  private:
1299b89a7cc2SEnji Cooper   const int errno_;
1300b89a7cc2SEnji Cooper   const T result_;
1301b89a7cc2SEnji Cooper };
1302b89a7cc2SEnji Cooper 
1303b89a7cc2SEnji Cooper #endif  // !GTEST_OS_WINDOWS_MOBILE
1304b89a7cc2SEnji Cooper 
1305b89a7cc2SEnji Cooper // Implements the SetArgumentPointee<N>(x) action for any function
130628f6c2f2SEnji Cooper // whose N-th argument (0-based) is a pointer to x's type.
130728f6c2f2SEnji Cooper template <size_t N, typename A, typename = void>
130828f6c2f2SEnji Cooper struct SetArgumentPointeeAction {
130928f6c2f2SEnji Cooper   A value;
1310b89a7cc2SEnji Cooper 
131128f6c2f2SEnji Cooper   template <typename... Args>
131228f6c2f2SEnji Cooper   void operator()(const Args&... args) const {
131328f6c2f2SEnji Cooper     *::std::get<N>(std::tie(args...)) = value;
1314b89a7cc2SEnji Cooper   }
1315b89a7cc2SEnji Cooper };
1316b89a7cc2SEnji Cooper 
131728f6c2f2SEnji Cooper // Implements the Invoke(object_ptr, &Class::Method) action.
131828f6c2f2SEnji Cooper template <class Class, typename MethodPtr>
131928f6c2f2SEnji Cooper struct InvokeMethodAction {
132028f6c2f2SEnji Cooper   Class* const obj_ptr;
132128f6c2f2SEnji Cooper   const MethodPtr method_ptr;
132228f6c2f2SEnji Cooper 
132328f6c2f2SEnji Cooper   template <typename... Args>
132428f6c2f2SEnji Cooper   auto operator()(Args&&... args) const
132528f6c2f2SEnji Cooper       -> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {
132628f6c2f2SEnji Cooper     return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);
1327b89a7cc2SEnji Cooper   }
1328b89a7cc2SEnji Cooper };
1329b89a7cc2SEnji Cooper 
1330b89a7cc2SEnji Cooper // Implements the InvokeWithoutArgs(f) action.  The template argument
1331b89a7cc2SEnji Cooper // FunctionImpl is the implementation type of f, which can be either a
1332b89a7cc2SEnji Cooper // function pointer or a functor.  InvokeWithoutArgs(f) can be used as an
133328f6c2f2SEnji Cooper // Action<F> as long as f's type is compatible with F.
1334b89a7cc2SEnji Cooper template <typename FunctionImpl>
133528f6c2f2SEnji Cooper struct InvokeWithoutArgsAction {
133628f6c2f2SEnji Cooper   FunctionImpl function_impl;
1337b89a7cc2SEnji Cooper 
1338b89a7cc2SEnji Cooper   // Allows InvokeWithoutArgs(f) to be used as any action whose type is
1339b89a7cc2SEnji Cooper   // compatible with f.
134028f6c2f2SEnji Cooper   template <typename... Args>
134128f6c2f2SEnji Cooper   auto operator()(const Args&...) -> decltype(function_impl()) {
134228f6c2f2SEnji Cooper     return function_impl();
134328f6c2f2SEnji Cooper   }
1344b89a7cc2SEnji Cooper };
1345b89a7cc2SEnji Cooper 
1346b89a7cc2SEnji Cooper // Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
1347b89a7cc2SEnji Cooper template <class Class, typename MethodPtr>
134828f6c2f2SEnji Cooper struct InvokeMethodWithoutArgsAction {
134928f6c2f2SEnji Cooper   Class* const obj_ptr;
135028f6c2f2SEnji Cooper   const MethodPtr method_ptr;
1351b89a7cc2SEnji Cooper 
135228f6c2f2SEnji Cooper   using ReturnType =
135328f6c2f2SEnji Cooper       decltype((std::declval<Class*>()->*std::declval<MethodPtr>())());
135428f6c2f2SEnji Cooper 
135528f6c2f2SEnji Cooper   template <typename... Args>
135628f6c2f2SEnji Cooper   ReturnType operator()(const Args&...) const {
135728f6c2f2SEnji Cooper     return (obj_ptr->*method_ptr)();
1358b89a7cc2SEnji Cooper   }
1359b89a7cc2SEnji Cooper };
1360b89a7cc2SEnji Cooper 
1361b89a7cc2SEnji Cooper // Implements the IgnoreResult(action) action.
1362b89a7cc2SEnji Cooper template <typename A>
1363b89a7cc2SEnji Cooper class IgnoreResultAction {
1364b89a7cc2SEnji Cooper  public:
1365b89a7cc2SEnji Cooper   explicit IgnoreResultAction(const A& action) : action_(action) {}
1366b89a7cc2SEnji Cooper 
1367b89a7cc2SEnji Cooper   template <typename F>
1368b89a7cc2SEnji Cooper   operator Action<F>() const {
1369b89a7cc2SEnji Cooper     // Assert statement belongs here because this is the best place to verify
1370b89a7cc2SEnji Cooper     // conditions on F. It produces the clearest error messages
1371b89a7cc2SEnji Cooper     // in most compilers.
1372b89a7cc2SEnji Cooper     // Impl really belongs in this scope as a local class but can't
1373b89a7cc2SEnji Cooper     // because MSVC produces duplicate symbols in different translation units
1374b89a7cc2SEnji Cooper     // in this case. Until MS fixes that bug we put Impl into the class scope
1375b89a7cc2SEnji Cooper     // and put the typedef both here (for use in assert statement) and
1376b89a7cc2SEnji Cooper     // in the Impl class. But both definitions must be the same.
1377b89a7cc2SEnji Cooper     typedef typename internal::Function<F>::Result Result;
1378b89a7cc2SEnji Cooper 
1379b89a7cc2SEnji Cooper     // Asserts at compile time that F returns void.
138028f6c2f2SEnji Cooper     static_assert(std::is_void<Result>::value, "Result type should be void.");
1381b89a7cc2SEnji Cooper 
1382b89a7cc2SEnji Cooper     return Action<F>(new Impl<F>(action_));
1383b89a7cc2SEnji Cooper   }
1384b89a7cc2SEnji Cooper 
1385b89a7cc2SEnji Cooper  private:
1386b89a7cc2SEnji Cooper   template <typename F>
1387b89a7cc2SEnji Cooper   class Impl : public ActionInterface<F> {
1388b89a7cc2SEnji Cooper    public:
1389b89a7cc2SEnji Cooper     typedef typename internal::Function<F>::Result Result;
1390b89a7cc2SEnji Cooper     typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
1391b89a7cc2SEnji Cooper 
1392b89a7cc2SEnji Cooper     explicit Impl(const A& action) : action_(action) {}
1393b89a7cc2SEnji Cooper 
139428f6c2f2SEnji Cooper     void Perform(const ArgumentTuple& args) override {
1395b89a7cc2SEnji Cooper       // Performs the action and ignores its result.
1396b89a7cc2SEnji Cooper       action_.Perform(args);
1397b89a7cc2SEnji Cooper     }
1398b89a7cc2SEnji Cooper 
1399b89a7cc2SEnji Cooper    private:
1400b89a7cc2SEnji Cooper     // Type OriginalFunction is the same as F except that its return
1401b89a7cc2SEnji Cooper     // type is IgnoredValue.
140228f6c2f2SEnji Cooper     typedef
140328f6c2f2SEnji Cooper         typename internal::Function<F>::MakeResultIgnoredValue OriginalFunction;
1404b89a7cc2SEnji Cooper 
1405b89a7cc2SEnji Cooper     const Action<OriginalFunction> action_;
1406b89a7cc2SEnji Cooper   };
1407b89a7cc2SEnji Cooper 
1408b89a7cc2SEnji Cooper   const A action_;
1409b89a7cc2SEnji Cooper };
1410b89a7cc2SEnji Cooper 
141128f6c2f2SEnji Cooper template <typename InnerAction, size_t... I>
141228f6c2f2SEnji Cooper struct WithArgsAction {
141328f6c2f2SEnji Cooper   InnerAction inner_action;
141428f6c2f2SEnji Cooper 
141528f6c2f2SEnji Cooper   // The signature of the function as seen by the inner action, given an out
141628f6c2f2SEnji Cooper   // action with the given result and argument types.
141728f6c2f2SEnji Cooper   template <typename R, typename... Args>
141828f6c2f2SEnji Cooper   using InnerSignature =
141928f6c2f2SEnji Cooper       R(typename std::tuple_element<I, std::tuple<Args...>>::type...);
142028f6c2f2SEnji Cooper 
142128f6c2f2SEnji Cooper   // Rather than a call operator, we must define conversion operators to
142228f6c2f2SEnji Cooper   // particular action types. This is necessary for embedded actions like
142328f6c2f2SEnji Cooper   // DoDefault(), which rely on an action conversion operators rather than
142428f6c2f2SEnji Cooper   // providing a call operator because even with a particular set of arguments
142528f6c2f2SEnji Cooper   // they don't have a fixed return type.
142628f6c2f2SEnji Cooper 
142728f6c2f2SEnji Cooper   template <
142828f6c2f2SEnji Cooper       typename R, typename... Args,
142928f6c2f2SEnji Cooper       typename std::enable_if<
143028f6c2f2SEnji Cooper           std::is_convertible<InnerAction,
143128f6c2f2SEnji Cooper                               // Unfortunately we can't use the InnerSignature
143228f6c2f2SEnji Cooper                               // alias here; MSVC complains about the I
143328f6c2f2SEnji Cooper                               // parameter pack not being expanded (error C3520)
143428f6c2f2SEnji Cooper                               // despite it being expanded in the type alias.
143528f6c2f2SEnji Cooper                               // TupleElement is also an MSVC workaround.
143628f6c2f2SEnji Cooper                               // See its definition for details.
143728f6c2f2SEnji Cooper                               OnceAction<R(internal::TupleElement<
143828f6c2f2SEnji Cooper                                            I, std::tuple<Args...>>...)>>::value,
143928f6c2f2SEnji Cooper           int>::type = 0>
144028f6c2f2SEnji Cooper   operator OnceAction<R(Args...)>() && {  // NOLINT
144128f6c2f2SEnji Cooper     struct OA {
144228f6c2f2SEnji Cooper       OnceAction<InnerSignature<R, Args...>> inner_action;
144328f6c2f2SEnji Cooper 
144428f6c2f2SEnji Cooper       R operator()(Args&&... args) && {
144528f6c2f2SEnji Cooper         return std::move(inner_action)
144628f6c2f2SEnji Cooper             .Call(std::get<I>(
144728f6c2f2SEnji Cooper                 std::forward_as_tuple(std::forward<Args>(args)...))...);
144828f6c2f2SEnji Cooper       }
144928f6c2f2SEnji Cooper     };
145028f6c2f2SEnji Cooper 
145128f6c2f2SEnji Cooper     return OA{std::move(inner_action)};
145228f6c2f2SEnji Cooper   }
145328f6c2f2SEnji Cooper 
145428f6c2f2SEnji Cooper   template <
145528f6c2f2SEnji Cooper       typename R, typename... Args,
145628f6c2f2SEnji Cooper       typename std::enable_if<
145728f6c2f2SEnji Cooper           std::is_convertible<const InnerAction&,
145828f6c2f2SEnji Cooper                               // Unfortunately we can't use the InnerSignature
145928f6c2f2SEnji Cooper                               // alias here; MSVC complains about the I
146028f6c2f2SEnji Cooper                               // parameter pack not being expanded (error C3520)
146128f6c2f2SEnji Cooper                               // despite it being expanded in the type alias.
146228f6c2f2SEnji Cooper                               // TupleElement is also an MSVC workaround.
146328f6c2f2SEnji Cooper                               // See its definition for details.
146428f6c2f2SEnji Cooper                               Action<R(internal::TupleElement<
146528f6c2f2SEnji Cooper                                        I, std::tuple<Args...>>...)>>::value,
146628f6c2f2SEnji Cooper           int>::type = 0>
146728f6c2f2SEnji Cooper   operator Action<R(Args...)>() const {  // NOLINT
146828f6c2f2SEnji Cooper     Action<InnerSignature<R, Args...>> converted(inner_action);
146928f6c2f2SEnji Cooper 
147028f6c2f2SEnji Cooper     return [converted](Args&&... args) -> R {
147128f6c2f2SEnji Cooper       return converted.Perform(std::forward_as_tuple(
147228f6c2f2SEnji Cooper           std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));
147328f6c2f2SEnji Cooper     };
147428f6c2f2SEnji Cooper   }
147528f6c2f2SEnji Cooper };
147628f6c2f2SEnji Cooper 
147728f6c2f2SEnji Cooper template <typename... Actions>
147828f6c2f2SEnji Cooper class DoAllAction;
147928f6c2f2SEnji Cooper 
148028f6c2f2SEnji Cooper // Base case: only a single action.
148128f6c2f2SEnji Cooper template <typename FinalAction>
148228f6c2f2SEnji Cooper class DoAllAction<FinalAction> {
148328f6c2f2SEnji Cooper  public:
148428f6c2f2SEnji Cooper   struct UserConstructorTag {};
148528f6c2f2SEnji Cooper 
1486b89a7cc2SEnji Cooper   template <typename T>
148728f6c2f2SEnji Cooper   explicit DoAllAction(UserConstructorTag, T&& action)
148828f6c2f2SEnji Cooper       : final_action_(std::forward<T>(action)) {}
1489b89a7cc2SEnji Cooper 
149028f6c2f2SEnji Cooper   // Rather than a call operator, we must define conversion operators to
149128f6c2f2SEnji Cooper   // particular action types. This is necessary for embedded actions like
149228f6c2f2SEnji Cooper   // DoDefault(), which rely on an action conversion operators rather than
149328f6c2f2SEnji Cooper   // providing a call operator because even with a particular set of arguments
149428f6c2f2SEnji Cooper   // they don't have a fixed return type.
149528f6c2f2SEnji Cooper 
149628f6c2f2SEnji Cooper   template <typename R, typename... Args,
149728f6c2f2SEnji Cooper             typename std::enable_if<
149828f6c2f2SEnji Cooper                 std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
149928f6c2f2SEnji Cooper                 int>::type = 0>
150028f6c2f2SEnji Cooper   operator OnceAction<R(Args...)>() && {  // NOLINT
150128f6c2f2SEnji Cooper     return std::move(final_action_);
150228f6c2f2SEnji Cooper   }
150328f6c2f2SEnji Cooper 
150428f6c2f2SEnji Cooper   template <
150528f6c2f2SEnji Cooper       typename R, typename... Args,
150628f6c2f2SEnji Cooper       typename std::enable_if<
150728f6c2f2SEnji Cooper           std::is_convertible<const FinalAction&, Action<R(Args...)>>::value,
150828f6c2f2SEnji Cooper           int>::type = 0>
150928f6c2f2SEnji Cooper   operator Action<R(Args...)>() const {  // NOLINT
151028f6c2f2SEnji Cooper     return final_action_;
151128f6c2f2SEnji Cooper   }
151228f6c2f2SEnji Cooper 
1513b89a7cc2SEnji Cooper  private:
151428f6c2f2SEnji Cooper   FinalAction final_action_;
1515b89a7cc2SEnji Cooper };
1516b89a7cc2SEnji Cooper 
151728f6c2f2SEnji Cooper // Recursive case: support N actions by calling the initial action and then
151828f6c2f2SEnji Cooper // calling through to the base class containing N-1 actions.
151928f6c2f2SEnji Cooper template <typename InitialAction, typename... OtherActions>
152028f6c2f2SEnji Cooper class DoAllAction<InitialAction, OtherActions...>
152128f6c2f2SEnji Cooper     : private DoAllAction<OtherActions...> {
152228f6c2f2SEnji Cooper  private:
152328f6c2f2SEnji Cooper   using Base = DoAllAction<OtherActions...>;
152428f6c2f2SEnji Cooper 
152528f6c2f2SEnji Cooper   // The type of reference that should be provided to an initial action for a
152628f6c2f2SEnji Cooper   // mocked function parameter of type T.
152728f6c2f2SEnji Cooper   //
152828f6c2f2SEnji Cooper   // There are two quirks here:
152928f6c2f2SEnji Cooper   //
153028f6c2f2SEnji Cooper   //  *  Unlike most forwarding functions, we pass scalars through by value.
153128f6c2f2SEnji Cooper   //     This isn't strictly necessary because an lvalue reference would work
153228f6c2f2SEnji Cooper   //     fine too and be consistent with other non-reference types, but it's
153328f6c2f2SEnji Cooper   //     perhaps less surprising.
153428f6c2f2SEnji Cooper   //
153528f6c2f2SEnji Cooper   //     For example if the mocked function has signature void(int), then it
153628f6c2f2SEnji Cooper   //     might seem surprising for the user's initial action to need to be
153728f6c2f2SEnji Cooper   //     convertible to Action<void(const int&)>. This is perhaps less
153828f6c2f2SEnji Cooper   //     surprising for a non-scalar type where there may be a performance
153928f6c2f2SEnji Cooper   //     impact, or it might even be impossible, to pass by value.
154028f6c2f2SEnji Cooper   //
154128f6c2f2SEnji Cooper   //  *  More surprisingly, `const T&` is often not a const reference type.
154228f6c2f2SEnji Cooper   //     By the reference collapsing rules in C++17 [dcl.ref]/6, if T refers to
154328f6c2f2SEnji Cooper   //     U& or U&& for some non-scalar type U, then InitialActionArgType<T> is
154428f6c2f2SEnji Cooper   //     U&. In other words, we may hand over a non-const reference.
154528f6c2f2SEnji Cooper   //
154628f6c2f2SEnji Cooper   //     So for example, given some non-scalar type Obj we have the following
154728f6c2f2SEnji Cooper   //     mappings:
154828f6c2f2SEnji Cooper   //
154928f6c2f2SEnji Cooper   //            T               InitialActionArgType<T>
155028f6c2f2SEnji Cooper   //         -------            -----------------------
155128f6c2f2SEnji Cooper   //         Obj                const Obj&
155228f6c2f2SEnji Cooper   //         Obj&               Obj&
155328f6c2f2SEnji Cooper   //         Obj&&              Obj&
155428f6c2f2SEnji Cooper   //         const Obj          const Obj&
155528f6c2f2SEnji Cooper   //         const Obj&         const Obj&
155628f6c2f2SEnji Cooper   //         const Obj&&        const Obj&
155728f6c2f2SEnji Cooper   //
155828f6c2f2SEnji Cooper   //     In other words, the initial actions get a mutable view of an non-scalar
155928f6c2f2SEnji Cooper   //     argument if and only if the mock function itself accepts a non-const
156028f6c2f2SEnji Cooper   //     reference type. They are never given an rvalue reference to an
156128f6c2f2SEnji Cooper   //     non-scalar type.
156228f6c2f2SEnji Cooper   //
156328f6c2f2SEnji Cooper   //     This situation makes sense if you imagine use with a matcher that is
156428f6c2f2SEnji Cooper   //     designed to write through a reference. For example, if the caller wants
156528f6c2f2SEnji Cooper   //     to fill in a reference argument and then return a canned value:
156628f6c2f2SEnji Cooper   //
156728f6c2f2SEnji Cooper   //         EXPECT_CALL(mock, Call)
156828f6c2f2SEnji Cooper   //             .WillOnce(DoAll(SetArgReferee<0>(17), Return(19)));
156928f6c2f2SEnji Cooper   //
1570b89a7cc2SEnji Cooper   template <typename T>
157128f6c2f2SEnji Cooper   using InitialActionArgType =
157228f6c2f2SEnji Cooper       typename std::conditional<std::is_scalar<T>::value, T, const T&>::type;
157328f6c2f2SEnji Cooper 
157428f6c2f2SEnji Cooper  public:
157528f6c2f2SEnji Cooper   struct UserConstructorTag {};
157628f6c2f2SEnji Cooper 
157728f6c2f2SEnji Cooper   template <typename T, typename... U>
157828f6c2f2SEnji Cooper   explicit DoAllAction(UserConstructorTag, T&& initial_action,
157928f6c2f2SEnji Cooper                        U&&... other_actions)
158028f6c2f2SEnji Cooper       : Base({}, std::forward<U>(other_actions)...),
158128f6c2f2SEnji Cooper         initial_action_(std::forward<T>(initial_action)) {}
158228f6c2f2SEnji Cooper 
158328f6c2f2SEnji Cooper   template <typename R, typename... Args,
158428f6c2f2SEnji Cooper             typename std::enable_if<
158528f6c2f2SEnji Cooper                 conjunction<
158628f6c2f2SEnji Cooper                     // Both the initial action and the rest must support
158728f6c2f2SEnji Cooper                     // conversion to OnceAction.
158828f6c2f2SEnji Cooper                     std::is_convertible<
158928f6c2f2SEnji Cooper                         InitialAction,
159028f6c2f2SEnji Cooper                         OnceAction<void(InitialActionArgType<Args>...)>>,
159128f6c2f2SEnji Cooper                     std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
159228f6c2f2SEnji Cooper                 int>::type = 0>
159328f6c2f2SEnji Cooper   operator OnceAction<R(Args...)>() && {  // NOLINT
159428f6c2f2SEnji Cooper     // Return an action that first calls the initial action with arguments
159528f6c2f2SEnji Cooper     // filtered through InitialActionArgType, then forwards arguments directly
159628f6c2f2SEnji Cooper     // to the base class to deal with the remaining actions.
159728f6c2f2SEnji Cooper     struct OA {
159828f6c2f2SEnji Cooper       OnceAction<void(InitialActionArgType<Args>...)> initial_action;
159928f6c2f2SEnji Cooper       OnceAction<R(Args...)> remaining_actions;
160028f6c2f2SEnji Cooper 
160128f6c2f2SEnji Cooper       R operator()(Args... args) && {
160228f6c2f2SEnji Cooper         std::move(initial_action)
160328f6c2f2SEnji Cooper             .Call(static_cast<InitialActionArgType<Args>>(args)...);
160428f6c2f2SEnji Cooper 
160528f6c2f2SEnji Cooper         return std::move(remaining_actions).Call(std::forward<Args>(args)...);
160628f6c2f2SEnji Cooper       }
160728f6c2f2SEnji Cooper     };
160828f6c2f2SEnji Cooper 
160928f6c2f2SEnji Cooper     return OA{
161028f6c2f2SEnji Cooper         std::move(initial_action_),
161128f6c2f2SEnji Cooper         std::move(static_cast<Base&>(*this)),
161228f6c2f2SEnji Cooper     };
1613b89a7cc2SEnji Cooper   }
1614b89a7cc2SEnji Cooper 
161528f6c2f2SEnji Cooper   template <
161628f6c2f2SEnji Cooper       typename R, typename... Args,
161728f6c2f2SEnji Cooper       typename std::enable_if<
161828f6c2f2SEnji Cooper           conjunction<
161928f6c2f2SEnji Cooper               // Both the initial action and the rest must support conversion to
162028f6c2f2SEnji Cooper               // Action.
162128f6c2f2SEnji Cooper               std::is_convertible<const InitialAction&,
162228f6c2f2SEnji Cooper                                   Action<void(InitialActionArgType<Args>...)>>,
162328f6c2f2SEnji Cooper               std::is_convertible<const Base&, Action<R(Args...)>>>::value,
162428f6c2f2SEnji Cooper           int>::type = 0>
162528f6c2f2SEnji Cooper   operator Action<R(Args...)>() const {  // NOLINT
162628f6c2f2SEnji Cooper     // Return an action that first calls the initial action with arguments
162728f6c2f2SEnji Cooper     // filtered through InitialActionArgType, then forwards arguments directly
162828f6c2f2SEnji Cooper     // to the base class to deal with the remaining actions.
162928f6c2f2SEnji Cooper     struct OA {
163028f6c2f2SEnji Cooper       Action<void(InitialActionArgType<Args>...)> initial_action;
163128f6c2f2SEnji Cooper       Action<R(Args...)> remaining_actions;
1632b89a7cc2SEnji Cooper 
163328f6c2f2SEnji Cooper       R operator()(Args... args) const {
163428f6c2f2SEnji Cooper         initial_action.Perform(std::forward_as_tuple(
163528f6c2f2SEnji Cooper             static_cast<InitialActionArgType<Args>>(args)...));
163628f6c2f2SEnji Cooper 
163728f6c2f2SEnji Cooper         return remaining_actions.Perform(
163828f6c2f2SEnji Cooper             std::forward_as_tuple(std::forward<Args>(args)...));
163928f6c2f2SEnji Cooper       }
164028f6c2f2SEnji Cooper     };
164128f6c2f2SEnji Cooper 
164228f6c2f2SEnji Cooper     return OA{
164328f6c2f2SEnji Cooper         initial_action_,
164428f6c2f2SEnji Cooper         static_cast<const Base&>(*this),
164528f6c2f2SEnji Cooper     };
1646b89a7cc2SEnji Cooper   }
1647b89a7cc2SEnji Cooper 
1648b89a7cc2SEnji Cooper  private:
164928f6c2f2SEnji Cooper   InitialAction initial_action_;
165028f6c2f2SEnji Cooper };
1651b89a7cc2SEnji Cooper 
165228f6c2f2SEnji Cooper template <typename T, typename... Params>
165328f6c2f2SEnji Cooper struct ReturnNewAction {
165428f6c2f2SEnji Cooper   T* operator()() const {
165528f6c2f2SEnji Cooper     return internal::Apply(
165628f6c2f2SEnji Cooper         [](const Params&... unpacked_params) {
165728f6c2f2SEnji Cooper           return new T(unpacked_params...);
165828f6c2f2SEnji Cooper         },
165928f6c2f2SEnji Cooper         params);
1660b89a7cc2SEnji Cooper   }
166128f6c2f2SEnji Cooper   std::tuple<Params...> params;
1662b89a7cc2SEnji Cooper };
1663b89a7cc2SEnji Cooper 
166428f6c2f2SEnji Cooper template <size_t k>
166528f6c2f2SEnji Cooper struct ReturnArgAction {
166628f6c2f2SEnji Cooper   template <typename... Args,
166728f6c2f2SEnji Cooper             typename = typename std::enable_if<(k < sizeof...(Args))>::type>
166828f6c2f2SEnji Cooper   auto operator()(Args&&... args) const -> decltype(std::get<k>(
166928f6c2f2SEnji Cooper       std::forward_as_tuple(std::forward<Args>(args)...))) {
167028f6c2f2SEnji Cooper     return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...));
167128f6c2f2SEnji Cooper   }
1672b89a7cc2SEnji Cooper };
1673b89a7cc2SEnji Cooper 
167428f6c2f2SEnji Cooper template <size_t k, typename Ptr>
167528f6c2f2SEnji Cooper struct SaveArgAction {
167628f6c2f2SEnji Cooper   Ptr pointer;
167728f6c2f2SEnji Cooper 
167828f6c2f2SEnji Cooper   template <typename... Args>
167928f6c2f2SEnji Cooper   void operator()(const Args&... args) const {
168028f6c2f2SEnji Cooper     *pointer = std::get<k>(std::tie(args...));
168128f6c2f2SEnji Cooper   }
168228f6c2f2SEnji Cooper };
168328f6c2f2SEnji Cooper 
168428f6c2f2SEnji Cooper template <size_t k, typename Ptr>
168528f6c2f2SEnji Cooper struct SaveArgPointeeAction {
168628f6c2f2SEnji Cooper   Ptr pointer;
168728f6c2f2SEnji Cooper 
168828f6c2f2SEnji Cooper   template <typename... Args>
168928f6c2f2SEnji Cooper   void operator()(const Args&... args) const {
169028f6c2f2SEnji Cooper     *pointer = *std::get<k>(std::tie(args...));
169128f6c2f2SEnji Cooper   }
169228f6c2f2SEnji Cooper };
169328f6c2f2SEnji Cooper 
169428f6c2f2SEnji Cooper template <size_t k, typename T>
169528f6c2f2SEnji Cooper struct SetArgRefereeAction {
169628f6c2f2SEnji Cooper   T value;
169728f6c2f2SEnji Cooper 
169828f6c2f2SEnji Cooper   template <typename... Args>
169928f6c2f2SEnji Cooper   void operator()(Args&&... args) const {
170028f6c2f2SEnji Cooper     using argk_type =
170128f6c2f2SEnji Cooper         typename ::std::tuple_element<k, std::tuple<Args...>>::type;
170228f6c2f2SEnji Cooper     static_assert(std::is_lvalue_reference<argk_type>::value,
170328f6c2f2SEnji Cooper                   "Argument must be a reference type.");
170428f6c2f2SEnji Cooper     std::get<k>(std::tie(args...)) = value;
170528f6c2f2SEnji Cooper   }
170628f6c2f2SEnji Cooper };
170728f6c2f2SEnji Cooper 
170828f6c2f2SEnji Cooper template <size_t k, typename I1, typename I2>
170928f6c2f2SEnji Cooper struct SetArrayArgumentAction {
171028f6c2f2SEnji Cooper   I1 first;
171128f6c2f2SEnji Cooper   I2 last;
171228f6c2f2SEnji Cooper 
171328f6c2f2SEnji Cooper   template <typename... Args>
171428f6c2f2SEnji Cooper   void operator()(const Args&... args) const {
171528f6c2f2SEnji Cooper     auto value = std::get<k>(std::tie(args...));
171628f6c2f2SEnji Cooper     for (auto it = first; it != last; ++it, (void)++value) {
171728f6c2f2SEnji Cooper       *value = *it;
171828f6c2f2SEnji Cooper     }
171928f6c2f2SEnji Cooper   }
172028f6c2f2SEnji Cooper };
172128f6c2f2SEnji Cooper 
172228f6c2f2SEnji Cooper template <size_t k>
172328f6c2f2SEnji Cooper struct DeleteArgAction {
172428f6c2f2SEnji Cooper   template <typename... Args>
172528f6c2f2SEnji Cooper   void operator()(const Args&... args) const {
172628f6c2f2SEnji Cooper     delete std::get<k>(std::tie(args...));
172728f6c2f2SEnji Cooper   }
172828f6c2f2SEnji Cooper };
172928f6c2f2SEnji Cooper 
173028f6c2f2SEnji Cooper template <typename Ptr>
173128f6c2f2SEnji Cooper struct ReturnPointeeAction {
173228f6c2f2SEnji Cooper   Ptr pointer;
173328f6c2f2SEnji Cooper   template <typename... Args>
173428f6c2f2SEnji Cooper   auto operator()(const Args&...) const -> decltype(*pointer) {
173528f6c2f2SEnji Cooper     return *pointer;
173628f6c2f2SEnji Cooper   }
173728f6c2f2SEnji Cooper };
173828f6c2f2SEnji Cooper 
173928f6c2f2SEnji Cooper #if GTEST_HAS_EXCEPTIONS
174028f6c2f2SEnji Cooper template <typename T>
174128f6c2f2SEnji Cooper struct ThrowAction {
174228f6c2f2SEnji Cooper   T exception;
174328f6c2f2SEnji Cooper   // We use a conversion operator to adapt to any return type.
174428f6c2f2SEnji Cooper   template <typename R, typename... Args>
174528f6c2f2SEnji Cooper   operator Action<R(Args...)>() const {  // NOLINT
174628f6c2f2SEnji Cooper     T copy = exception;
174728f6c2f2SEnji Cooper     return [copy](Args...) -> R { throw copy; };
174828f6c2f2SEnji Cooper   }
174928f6c2f2SEnji Cooper };
1750*5ca8c28cSEnji Cooper struct RethrowAction {
1751*5ca8c28cSEnji Cooper   std::exception_ptr exception;
1752*5ca8c28cSEnji Cooper   template <typename R, typename... Args>
1753*5ca8c28cSEnji Cooper   operator Action<R(Args...)>() const {  // NOLINT
1754*5ca8c28cSEnji Cooper     return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
1755*5ca8c28cSEnji Cooper   }
1756*5ca8c28cSEnji Cooper };
175728f6c2f2SEnji Cooper #endif  // GTEST_HAS_EXCEPTIONS
175828f6c2f2SEnji Cooper 
1759b89a7cc2SEnji Cooper }  // namespace internal
1760b89a7cc2SEnji Cooper 
1761b89a7cc2SEnji Cooper // An Unused object can be implicitly constructed from ANY value.
1762b89a7cc2SEnji Cooper // This is handy when defining actions that ignore some or all of the
1763b89a7cc2SEnji Cooper // mock function arguments.  For example, given
1764b89a7cc2SEnji Cooper //
1765b89a7cc2SEnji Cooper //   MOCK_METHOD3(Foo, double(const string& label, double x, double y));
1766b89a7cc2SEnji Cooper //   MOCK_METHOD3(Bar, double(int index, double x, double y));
1767b89a7cc2SEnji Cooper //
1768b89a7cc2SEnji Cooper // instead of
1769b89a7cc2SEnji Cooper //
1770b89a7cc2SEnji Cooper //   double DistanceToOriginWithLabel(const string& label, double x, double y) {
1771b89a7cc2SEnji Cooper //     return sqrt(x*x + y*y);
1772b89a7cc2SEnji Cooper //   }
1773b89a7cc2SEnji Cooper //   double DistanceToOriginWithIndex(int index, double x, double y) {
1774b89a7cc2SEnji Cooper //     return sqrt(x*x + y*y);
1775b89a7cc2SEnji Cooper //   }
1776b89a7cc2SEnji Cooper //   ...
1777b89a7cc2SEnji Cooper //   EXPECT_CALL(mock, Foo("abc", _, _))
1778b89a7cc2SEnji Cooper //       .WillOnce(Invoke(DistanceToOriginWithLabel));
1779b89a7cc2SEnji Cooper //   EXPECT_CALL(mock, Bar(5, _, _))
1780b89a7cc2SEnji Cooper //       .WillOnce(Invoke(DistanceToOriginWithIndex));
1781b89a7cc2SEnji Cooper //
1782b89a7cc2SEnji Cooper // you could write
1783b89a7cc2SEnji Cooper //
1784b89a7cc2SEnji Cooper //   // We can declare any uninteresting argument as Unused.
1785b89a7cc2SEnji Cooper //   double DistanceToOrigin(Unused, double x, double y) {
1786b89a7cc2SEnji Cooper //     return sqrt(x*x + y*y);
1787b89a7cc2SEnji Cooper //   }
1788b89a7cc2SEnji Cooper //   ...
1789b89a7cc2SEnji Cooper //   EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
1790b89a7cc2SEnji Cooper //   EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
1791b89a7cc2SEnji Cooper typedef internal::IgnoredValue Unused;
1792b89a7cc2SEnji Cooper 
179328f6c2f2SEnji Cooper // Creates an action that does actions a1, a2, ..., sequentially in
179428f6c2f2SEnji Cooper // each invocation. All but the last action will have a readonly view of the
179528f6c2f2SEnji Cooper // arguments.
179628f6c2f2SEnji Cooper template <typename... Action>
179728f6c2f2SEnji Cooper internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
179828f6c2f2SEnji Cooper     Action&&... action) {
179928f6c2f2SEnji Cooper   return internal::DoAllAction<typename std::decay<Action>::type...>(
180028f6c2f2SEnji Cooper       {}, std::forward<Action>(action)...);
1801b89a7cc2SEnji Cooper }
1802b89a7cc2SEnji Cooper 
180328f6c2f2SEnji Cooper // WithArg<k>(an_action) creates an action that passes the k-th
180428f6c2f2SEnji Cooper // (0-based) argument of the mock function to an_action and performs
180528f6c2f2SEnji Cooper // it.  It adapts an action accepting one argument to one that accepts
180628f6c2f2SEnji Cooper // multiple arguments.  For convenience, we also provide
180728f6c2f2SEnji Cooper // WithArgs<k>(an_action) (defined below) as a synonym.
180828f6c2f2SEnji Cooper template <size_t k, typename InnerAction>
180928f6c2f2SEnji Cooper internal::WithArgsAction<typename std::decay<InnerAction>::type, k> WithArg(
181028f6c2f2SEnji Cooper     InnerAction&& action) {
181128f6c2f2SEnji Cooper   return {std::forward<InnerAction>(action)};
181228f6c2f2SEnji Cooper }
181328f6c2f2SEnji Cooper 
181428f6c2f2SEnji Cooper // WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
181528f6c2f2SEnji Cooper // the selected arguments of the mock function to an_action and
181628f6c2f2SEnji Cooper // performs it.  It serves as an adaptor between actions with
181728f6c2f2SEnji Cooper // different argument lists.
181828f6c2f2SEnji Cooper template <size_t k, size_t... ks, typename InnerAction>
181928f6c2f2SEnji Cooper internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>
182028f6c2f2SEnji Cooper WithArgs(InnerAction&& action) {
182128f6c2f2SEnji Cooper   return {std::forward<InnerAction>(action)};
182228f6c2f2SEnji Cooper }
182328f6c2f2SEnji Cooper 
182428f6c2f2SEnji Cooper // WithoutArgs(inner_action) can be used in a mock function with a
182528f6c2f2SEnji Cooper // non-empty argument list to perform inner_action, which takes no
182628f6c2f2SEnji Cooper // argument.  In other words, it adapts an action accepting no
182728f6c2f2SEnji Cooper // argument to one that accepts (and ignores) arguments.
182828f6c2f2SEnji Cooper template <typename InnerAction>
182928f6c2f2SEnji Cooper internal::WithArgsAction<typename std::decay<InnerAction>::type> WithoutArgs(
183028f6c2f2SEnji Cooper     InnerAction&& action) {
183128f6c2f2SEnji Cooper   return {std::forward<InnerAction>(action)};
183228f6c2f2SEnji Cooper }
183328f6c2f2SEnji Cooper 
183428f6c2f2SEnji Cooper // Creates an action that returns a value.
183528f6c2f2SEnji Cooper //
183628f6c2f2SEnji Cooper // The returned type can be used with a mock function returning a non-void,
183728f6c2f2SEnji Cooper // non-reference type U as follows:
183828f6c2f2SEnji Cooper //
183928f6c2f2SEnji Cooper //  *  If R is convertible to U and U is move-constructible, then the action can
184028f6c2f2SEnji Cooper //     be used with WillOnce.
184128f6c2f2SEnji Cooper //
184228f6c2f2SEnji Cooper //  *  If const R& is convertible to U and U is copy-constructible, then the
184328f6c2f2SEnji Cooper //     action can be used with both WillOnce and WillRepeatedly.
184428f6c2f2SEnji Cooper //
184528f6c2f2SEnji Cooper // The mock expectation contains the R value from which the U return value is
184628f6c2f2SEnji Cooper // constructed (a move/copy of the argument to Return). This means that the R
184728f6c2f2SEnji Cooper // value will survive at least until the mock object's expectations are cleared
184828f6c2f2SEnji Cooper // or the mock object is destroyed, meaning that U can safely be a
184928f6c2f2SEnji Cooper // reference-like type such as std::string_view:
185028f6c2f2SEnji Cooper //
185128f6c2f2SEnji Cooper //     // The mock function returns a view of a copy of the string fed to
185228f6c2f2SEnji Cooper //     // Return. The view is valid even after the action is performed.
185328f6c2f2SEnji Cooper //     MockFunction<std::string_view()> mock;
185428f6c2f2SEnji Cooper //     EXPECT_CALL(mock, Call).WillOnce(Return(std::string("taco")));
185528f6c2f2SEnji Cooper //     const std::string_view result = mock.AsStdFunction()();
185628f6c2f2SEnji Cooper //     EXPECT_EQ("taco", result);
185728f6c2f2SEnji Cooper //
1858b89a7cc2SEnji Cooper template <typename R>
1859b89a7cc2SEnji Cooper internal::ReturnAction<R> Return(R value) {
186028f6c2f2SEnji Cooper   return internal::ReturnAction<R>(std::move(value));
1861b89a7cc2SEnji Cooper }
1862b89a7cc2SEnji Cooper 
1863b89a7cc2SEnji Cooper // Creates an action that returns NULL.
1864b89a7cc2SEnji Cooper inline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {
1865b89a7cc2SEnji Cooper   return MakePolymorphicAction(internal::ReturnNullAction());
1866b89a7cc2SEnji Cooper }
1867b89a7cc2SEnji Cooper 
1868b89a7cc2SEnji Cooper // Creates an action that returns from a void function.
1869b89a7cc2SEnji Cooper inline PolymorphicAction<internal::ReturnVoidAction> Return() {
1870b89a7cc2SEnji Cooper   return MakePolymorphicAction(internal::ReturnVoidAction());
1871b89a7cc2SEnji Cooper }
1872b89a7cc2SEnji Cooper 
1873b89a7cc2SEnji Cooper // Creates an action that returns the reference to a variable.
1874b89a7cc2SEnji Cooper template <typename R>
1875b89a7cc2SEnji Cooper inline internal::ReturnRefAction<R> ReturnRef(R& x) {  // NOLINT
1876b89a7cc2SEnji Cooper   return internal::ReturnRefAction<R>(x);
1877b89a7cc2SEnji Cooper }
1878b89a7cc2SEnji Cooper 
187928f6c2f2SEnji Cooper // Prevent using ReturnRef on reference to temporary.
188028f6c2f2SEnji Cooper template <typename R, R* = nullptr>
188128f6c2f2SEnji Cooper internal::ReturnRefAction<R> ReturnRef(R&&) = delete;
188228f6c2f2SEnji Cooper 
1883b89a7cc2SEnji Cooper // Creates an action that returns the reference to a copy of the
1884b89a7cc2SEnji Cooper // argument.  The copy is created when the action is constructed and
1885b89a7cc2SEnji Cooper // lives as long as the action.
1886b89a7cc2SEnji Cooper template <typename R>
1887b89a7cc2SEnji Cooper inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {
1888b89a7cc2SEnji Cooper   return internal::ReturnRefOfCopyAction<R>(x);
1889b89a7cc2SEnji Cooper }
1890b89a7cc2SEnji Cooper 
189128f6c2f2SEnji Cooper // DEPRECATED: use Return(x) directly with WillOnce.
189228f6c2f2SEnji Cooper //
1893b89a7cc2SEnji Cooper // Modifies the parent action (a Return() action) to perform a move of the
1894b89a7cc2SEnji Cooper // argument instead of a copy.
1895b89a7cc2SEnji Cooper // Return(ByMove()) actions can only be executed once and will assert this
1896b89a7cc2SEnji Cooper // invariant.
1897b89a7cc2SEnji Cooper template <typename R>
1898b89a7cc2SEnji Cooper internal::ByMoveWrapper<R> ByMove(R x) {
189928f6c2f2SEnji Cooper   return internal::ByMoveWrapper<R>(std::move(x));
190028f6c2f2SEnji Cooper }
190128f6c2f2SEnji Cooper 
190228f6c2f2SEnji Cooper // Creates an action that returns an element of `vals`. Calling this action will
190328f6c2f2SEnji Cooper // repeatedly return the next value from `vals` until it reaches the end and
190428f6c2f2SEnji Cooper // will restart from the beginning.
190528f6c2f2SEnji Cooper template <typename T>
190628f6c2f2SEnji Cooper internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) {
190728f6c2f2SEnji Cooper   return internal::ReturnRoundRobinAction<T>(std::move(vals));
190828f6c2f2SEnji Cooper }
190928f6c2f2SEnji Cooper 
191028f6c2f2SEnji Cooper // Creates an action that returns an element of `vals`. Calling this action will
191128f6c2f2SEnji Cooper // repeatedly return the next value from `vals` until it reaches the end and
191228f6c2f2SEnji Cooper // will restart from the beginning.
191328f6c2f2SEnji Cooper template <typename T>
191428f6c2f2SEnji Cooper internal::ReturnRoundRobinAction<T> ReturnRoundRobin(
191528f6c2f2SEnji Cooper     std::initializer_list<T> vals) {
191628f6c2f2SEnji Cooper   return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals));
1917b89a7cc2SEnji Cooper }
1918b89a7cc2SEnji Cooper 
1919b89a7cc2SEnji Cooper // Creates an action that does the default action for the give mock function.
1920b89a7cc2SEnji Cooper inline internal::DoDefaultAction DoDefault() {
1921b89a7cc2SEnji Cooper   return internal::DoDefaultAction();
1922b89a7cc2SEnji Cooper }
1923b89a7cc2SEnji Cooper 
1924b89a7cc2SEnji Cooper // Creates an action that sets the variable pointed by the N-th
1925b89a7cc2SEnji Cooper // (0-based) function argument to 'value'.
1926b89a7cc2SEnji Cooper template <size_t N, typename T>
192728f6c2f2SEnji Cooper internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) {
192828f6c2f2SEnji Cooper   return {std::move(value)};
1929b89a7cc2SEnji Cooper }
1930b89a7cc2SEnji Cooper 
1931b89a7cc2SEnji Cooper // The following version is DEPRECATED.
1932b89a7cc2SEnji Cooper template <size_t N, typename T>
193328f6c2f2SEnji Cooper internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) {
193428f6c2f2SEnji Cooper   return {std::move(value)};
1935b89a7cc2SEnji Cooper }
1936b89a7cc2SEnji Cooper 
1937b89a7cc2SEnji Cooper // Creates an action that sets a pointer referent to a given value.
1938b89a7cc2SEnji Cooper template <typename T1, typename T2>
1939b89a7cc2SEnji Cooper PolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {
1940b89a7cc2SEnji Cooper   return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
1941b89a7cc2SEnji Cooper }
1942b89a7cc2SEnji Cooper 
194328f6c2f2SEnji Cooper #ifndef GTEST_OS_WINDOWS_MOBILE
1944b89a7cc2SEnji Cooper 
1945b89a7cc2SEnji Cooper // Creates an action that sets errno and returns the appropriate error.
1946b89a7cc2SEnji Cooper template <typename T>
194728f6c2f2SEnji Cooper PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
194828f6c2f2SEnji Cooper     int errval, T result) {
1949b89a7cc2SEnji Cooper   return MakePolymorphicAction(
1950b89a7cc2SEnji Cooper       internal::SetErrnoAndReturnAction<T>(errval, result));
1951b89a7cc2SEnji Cooper }
1952b89a7cc2SEnji Cooper 
1953b89a7cc2SEnji Cooper #endif  // !GTEST_OS_WINDOWS_MOBILE
1954b89a7cc2SEnji Cooper 
195528f6c2f2SEnji Cooper // Various overloads for Invoke().
195628f6c2f2SEnji Cooper 
195728f6c2f2SEnji Cooper // Legacy function.
195828f6c2f2SEnji Cooper // Actions can now be implicitly constructed from callables. No need to create
195928f6c2f2SEnji Cooper // wrapper objects.
196028f6c2f2SEnji Cooper // This function exists for backwards compatibility.
196128f6c2f2SEnji Cooper template <typename FunctionImpl>
196228f6c2f2SEnji Cooper typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
196328f6c2f2SEnji Cooper   return std::forward<FunctionImpl>(function_impl);
196428f6c2f2SEnji Cooper }
196528f6c2f2SEnji Cooper 
196628f6c2f2SEnji Cooper // Creates an action that invokes the given method on the given object
196728f6c2f2SEnji Cooper // with the mock function's arguments.
196828f6c2f2SEnji Cooper template <class Class, typename MethodPtr>
196928f6c2f2SEnji Cooper internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
197028f6c2f2SEnji Cooper                                                       MethodPtr method_ptr) {
197128f6c2f2SEnji Cooper   return {obj_ptr, method_ptr};
197228f6c2f2SEnji Cooper }
1973b89a7cc2SEnji Cooper 
1974b89a7cc2SEnji Cooper // Creates an action that invokes 'function_impl' with no argument.
1975b89a7cc2SEnji Cooper template <typename FunctionImpl>
197628f6c2f2SEnji Cooper internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
1977b89a7cc2SEnji Cooper InvokeWithoutArgs(FunctionImpl function_impl) {
197828f6c2f2SEnji Cooper   return {std::move(function_impl)};
1979b89a7cc2SEnji Cooper }
1980b89a7cc2SEnji Cooper 
1981b89a7cc2SEnji Cooper // Creates an action that invokes the given method on the given object
1982b89a7cc2SEnji Cooper // with no argument.
1983b89a7cc2SEnji Cooper template <class Class, typename MethodPtr>
198428f6c2f2SEnji Cooper internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(
198528f6c2f2SEnji Cooper     Class* obj_ptr, MethodPtr method_ptr) {
198628f6c2f2SEnji Cooper   return {obj_ptr, method_ptr};
1987b89a7cc2SEnji Cooper }
1988b89a7cc2SEnji Cooper 
1989b89a7cc2SEnji Cooper // Creates an action that performs an_action and throws away its
1990b89a7cc2SEnji Cooper // result.  In other words, it changes the return type of an_action to
1991b89a7cc2SEnji Cooper // void.  an_action MUST NOT return void, or the code won't compile.
1992b89a7cc2SEnji Cooper template <typename A>
1993b89a7cc2SEnji Cooper inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
1994b89a7cc2SEnji Cooper   return internal::IgnoreResultAction<A>(an_action);
1995b89a7cc2SEnji Cooper }
1996b89a7cc2SEnji Cooper 
1997b89a7cc2SEnji Cooper // Creates a reference wrapper for the given L-value.  If necessary,
1998b89a7cc2SEnji Cooper // you can explicitly specify the type of the reference.  For example,
1999b89a7cc2SEnji Cooper // suppose 'derived' is an object of type Derived, ByRef(derived)
2000b89a7cc2SEnji Cooper // would wrap a Derived&.  If you want to wrap a const Base& instead,
2001b89a7cc2SEnji Cooper // where Base is a base class of Derived, just write:
2002b89a7cc2SEnji Cooper //
2003b89a7cc2SEnji Cooper //   ByRef<const Base>(derived)
200428f6c2f2SEnji Cooper //
200528f6c2f2SEnji Cooper // N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper.
200628f6c2f2SEnji Cooper // However, it may still be used for consistency with ByMove().
2007b89a7cc2SEnji Cooper template <typename T>
200828f6c2f2SEnji Cooper inline ::std::reference_wrapper<T> ByRef(T& l_value) {  // NOLINT
200928f6c2f2SEnji Cooper   return ::std::reference_wrapper<T>(l_value);
2010b89a7cc2SEnji Cooper }
2011b89a7cc2SEnji Cooper 
201228f6c2f2SEnji Cooper // The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
201328f6c2f2SEnji Cooper // instance of type T, constructed on the heap with constructor arguments
201428f6c2f2SEnji Cooper // a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
201528f6c2f2SEnji Cooper template <typename T, typename... Params>
201628f6c2f2SEnji Cooper internal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew(
201728f6c2f2SEnji Cooper     Params&&... params) {
201828f6c2f2SEnji Cooper   return {std::forward_as_tuple(std::forward<Params>(params)...)};
201928f6c2f2SEnji Cooper }
202028f6c2f2SEnji Cooper 
202128f6c2f2SEnji Cooper // Action ReturnArg<k>() returns the k-th argument of the mock function.
202228f6c2f2SEnji Cooper template <size_t k>
202328f6c2f2SEnji Cooper internal::ReturnArgAction<k> ReturnArg() {
202428f6c2f2SEnji Cooper   return {};
202528f6c2f2SEnji Cooper }
202628f6c2f2SEnji Cooper 
202728f6c2f2SEnji Cooper // Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
202828f6c2f2SEnji Cooper // mock function to *pointer.
202928f6c2f2SEnji Cooper template <size_t k, typename Ptr>
203028f6c2f2SEnji Cooper internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
203128f6c2f2SEnji Cooper   return {pointer};
203228f6c2f2SEnji Cooper }
203328f6c2f2SEnji Cooper 
203428f6c2f2SEnji Cooper // Action SaveArgPointee<k>(pointer) saves the value pointed to
203528f6c2f2SEnji Cooper // by the k-th (0-based) argument of the mock function to *pointer.
203628f6c2f2SEnji Cooper template <size_t k, typename Ptr>
203728f6c2f2SEnji Cooper internal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) {
203828f6c2f2SEnji Cooper   return {pointer};
203928f6c2f2SEnji Cooper }
204028f6c2f2SEnji Cooper 
204128f6c2f2SEnji Cooper // Action SetArgReferee<k>(value) assigns 'value' to the variable
204228f6c2f2SEnji Cooper // referenced by the k-th (0-based) argument of the mock function.
204328f6c2f2SEnji Cooper template <size_t k, typename T>
204428f6c2f2SEnji Cooper internal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee(
204528f6c2f2SEnji Cooper     T&& value) {
204628f6c2f2SEnji Cooper   return {std::forward<T>(value)};
204728f6c2f2SEnji Cooper }
204828f6c2f2SEnji Cooper 
204928f6c2f2SEnji Cooper // Action SetArrayArgument<k>(first, last) copies the elements in
205028f6c2f2SEnji Cooper // source range [first, last) to the array pointed to by the k-th
205128f6c2f2SEnji Cooper // (0-based) argument, which can be either a pointer or an
205228f6c2f2SEnji Cooper // iterator. The action does not take ownership of the elements in the
205328f6c2f2SEnji Cooper // source range.
205428f6c2f2SEnji Cooper template <size_t k, typename I1, typename I2>
205528f6c2f2SEnji Cooper internal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first,
205628f6c2f2SEnji Cooper                                                              I2 last) {
205728f6c2f2SEnji Cooper   return {first, last};
205828f6c2f2SEnji Cooper }
205928f6c2f2SEnji Cooper 
206028f6c2f2SEnji Cooper // Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
206128f6c2f2SEnji Cooper // function.
206228f6c2f2SEnji Cooper template <size_t k>
206328f6c2f2SEnji Cooper internal::DeleteArgAction<k> DeleteArg() {
206428f6c2f2SEnji Cooper   return {};
206528f6c2f2SEnji Cooper }
206628f6c2f2SEnji Cooper 
206728f6c2f2SEnji Cooper // This action returns the value pointed to by 'pointer'.
206828f6c2f2SEnji Cooper template <typename Ptr>
206928f6c2f2SEnji Cooper internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
207028f6c2f2SEnji Cooper   return {pointer};
207128f6c2f2SEnji Cooper }
207228f6c2f2SEnji Cooper 
207328f6c2f2SEnji Cooper #if GTEST_HAS_EXCEPTIONS
2074*5ca8c28cSEnji Cooper // Action Throw(exception) can be used in a mock function of any type
2075*5ca8c28cSEnji Cooper // to throw the given exception.  Any copyable value can be thrown,
2076*5ca8c28cSEnji Cooper // except for std::exception_ptr, which is likely a mistake if
2077*5ca8c28cSEnji Cooper // thrown directly.
207828f6c2f2SEnji Cooper template <typename T>
2079*5ca8c28cSEnji Cooper typename std::enable_if<
2080*5ca8c28cSEnji Cooper     !std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
2081*5ca8c28cSEnji Cooper     internal::ThrowAction<typename std::decay<T>::type>>::type
2082*5ca8c28cSEnji Cooper Throw(T&& exception) {
208328f6c2f2SEnji Cooper   return {std::forward<T>(exception)};
208428f6c2f2SEnji Cooper }
2085*5ca8c28cSEnji Cooper // Action Rethrow(exception_ptr) can be used in a mock function of any type
2086*5ca8c28cSEnji Cooper // to rethrow any exception_ptr. Note that the same object is thrown each time.
2087*5ca8c28cSEnji Cooper inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
2088*5ca8c28cSEnji Cooper   return {std::move(exception)};
2089*5ca8c28cSEnji Cooper }
209028f6c2f2SEnji Cooper #endif  // GTEST_HAS_EXCEPTIONS
209128f6c2f2SEnji Cooper 
209228f6c2f2SEnji Cooper namespace internal {
209328f6c2f2SEnji Cooper 
209428f6c2f2SEnji Cooper // A macro from the ACTION* family (defined later in gmock-generated-actions.h)
209528f6c2f2SEnji Cooper // defines an action that can be used in a mock function.  Typically,
209628f6c2f2SEnji Cooper // these actions only care about a subset of the arguments of the mock
209728f6c2f2SEnji Cooper // function.  For example, if such an action only uses the second
209828f6c2f2SEnji Cooper // argument, it can be used in any mock function that takes >= 2
209928f6c2f2SEnji Cooper // arguments where the type of the second argument is compatible.
210028f6c2f2SEnji Cooper //
210128f6c2f2SEnji Cooper // Therefore, the action implementation must be prepared to take more
210228f6c2f2SEnji Cooper // arguments than it needs.  The ExcessiveArg type is used to
210328f6c2f2SEnji Cooper // represent those excessive arguments.  In order to keep the compiler
210428f6c2f2SEnji Cooper // error messages tractable, we define it in the testing namespace
210528f6c2f2SEnji Cooper // instead of testing::internal.  However, this is an INTERNAL TYPE
210628f6c2f2SEnji Cooper // and subject to change without notice, so a user MUST NOT USE THIS
210728f6c2f2SEnji Cooper // TYPE DIRECTLY.
210828f6c2f2SEnji Cooper struct ExcessiveArg {};
210928f6c2f2SEnji Cooper 
211028f6c2f2SEnji Cooper // Builds an implementation of an Action<> for some particular signature, using
211128f6c2f2SEnji Cooper // a class defined by an ACTION* macro.
211228f6c2f2SEnji Cooper template <typename F, typename Impl>
211328f6c2f2SEnji Cooper struct ActionImpl;
211428f6c2f2SEnji Cooper 
211528f6c2f2SEnji Cooper template <typename Impl>
211628f6c2f2SEnji Cooper struct ImplBase {
211728f6c2f2SEnji Cooper   struct Holder {
211828f6c2f2SEnji Cooper     // Allows each copy of the Action<> to get to the Impl.
211928f6c2f2SEnji Cooper     explicit operator const Impl&() const { return *ptr; }
212028f6c2f2SEnji Cooper     std::shared_ptr<Impl> ptr;
212128f6c2f2SEnji Cooper   };
212228f6c2f2SEnji Cooper   using type = typename std::conditional<std::is_constructible<Impl>::value,
212328f6c2f2SEnji Cooper                                          Impl, Holder>::type;
212428f6c2f2SEnji Cooper };
212528f6c2f2SEnji Cooper 
212628f6c2f2SEnji Cooper template <typename R, typename... Args, typename Impl>
212728f6c2f2SEnji Cooper struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
212828f6c2f2SEnji Cooper   using Base = typename ImplBase<Impl>::type;
212928f6c2f2SEnji Cooper   using function_type = R(Args...);
213028f6c2f2SEnji Cooper   using args_type = std::tuple<Args...>;
213128f6c2f2SEnji Cooper 
213228f6c2f2SEnji Cooper   ActionImpl() = default;  // Only defined if appropriate for Base.
213328f6c2f2SEnji Cooper   explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} {}
213428f6c2f2SEnji Cooper 
213528f6c2f2SEnji Cooper   R operator()(Args&&... arg) const {
213628f6c2f2SEnji Cooper     static constexpr size_t kMaxArgs =
213728f6c2f2SEnji Cooper         sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
2138*5ca8c28cSEnji Cooper     return Apply(std::make_index_sequence<kMaxArgs>{},
2139*5ca8c28cSEnji Cooper                  std::make_index_sequence<10 - kMaxArgs>{},
214028f6c2f2SEnji Cooper                  args_type{std::forward<Args>(arg)...});
214128f6c2f2SEnji Cooper   }
214228f6c2f2SEnji Cooper 
214328f6c2f2SEnji Cooper   template <std::size_t... arg_id, std::size_t... excess_id>
2144*5ca8c28cSEnji Cooper   R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,
214528f6c2f2SEnji Cooper           const args_type& args) const {
214628f6c2f2SEnji Cooper     // Impl need not be specific to the signature of action being implemented;
214728f6c2f2SEnji Cooper     // only the implementing function body needs to have all of the specific
214828f6c2f2SEnji Cooper     // types instantiated.  Up to 10 of the args that are provided by the
214928f6c2f2SEnji Cooper     // args_type get passed, followed by a dummy of unspecified type for the
215028f6c2f2SEnji Cooper     // remainder up to 10 explicit args.
215128f6c2f2SEnji Cooper     static constexpr ExcessiveArg kExcessArg{};
215228f6c2f2SEnji Cooper     return static_cast<const Impl&>(*this)
215328f6c2f2SEnji Cooper         .template gmock_PerformImpl<
215428f6c2f2SEnji Cooper             /*function_type=*/function_type, /*return_type=*/R,
215528f6c2f2SEnji Cooper             /*args_type=*/args_type,
215628f6c2f2SEnji Cooper             /*argN_type=*/
215728f6c2f2SEnji Cooper             typename std::tuple_element<arg_id, args_type>::type...>(
215828f6c2f2SEnji Cooper             /*args=*/args, std::get<arg_id>(args)...,
215928f6c2f2SEnji Cooper             ((void)excess_id, kExcessArg)...);
216028f6c2f2SEnji Cooper   }
216128f6c2f2SEnji Cooper };
216228f6c2f2SEnji Cooper 
216328f6c2f2SEnji Cooper // Stores a default-constructed Impl as part of the Action<>'s
216428f6c2f2SEnji Cooper // std::function<>. The Impl should be trivial to copy.
216528f6c2f2SEnji Cooper template <typename F, typename Impl>
216628f6c2f2SEnji Cooper ::testing::Action<F> MakeAction() {
216728f6c2f2SEnji Cooper   return ::testing::Action<F>(ActionImpl<F, Impl>());
216828f6c2f2SEnji Cooper }
216928f6c2f2SEnji Cooper 
217028f6c2f2SEnji Cooper // Stores just the one given instance of Impl.
217128f6c2f2SEnji Cooper template <typename F, typename Impl>
217228f6c2f2SEnji Cooper ::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) {
217328f6c2f2SEnji Cooper   return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl)));
217428f6c2f2SEnji Cooper }
217528f6c2f2SEnji Cooper 
217628f6c2f2SEnji Cooper #define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
2177*5ca8c28cSEnji Cooper   , GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i
217828f6c2f2SEnji Cooper #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_                               \
2179*5ca8c28cSEnji Cooper   GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \
218028f6c2f2SEnji Cooper       GMOCK_INTERNAL_ARG_UNUSED, , 10)
218128f6c2f2SEnji Cooper 
218228f6c2f2SEnji Cooper #define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
218328f6c2f2SEnji Cooper #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \
218428f6c2f2SEnji Cooper   const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10)
218528f6c2f2SEnji Cooper 
218628f6c2f2SEnji Cooper #define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type
218728f6c2f2SEnji Cooper #define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \
218828f6c2f2SEnji Cooper   GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10))
218928f6c2f2SEnji Cooper 
219028f6c2f2SEnji Cooper #define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type
219128f6c2f2SEnji Cooper #define GMOCK_ACTION_TYPENAME_PARAMS_(params) \
219228f6c2f2SEnji Cooper   GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params))
219328f6c2f2SEnji Cooper 
219428f6c2f2SEnji Cooper #define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type
219528f6c2f2SEnji Cooper #define GMOCK_ACTION_TYPE_PARAMS_(params) \
219628f6c2f2SEnji Cooper   GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params))
219728f6c2f2SEnji Cooper 
219828f6c2f2SEnji Cooper #define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \
219928f6c2f2SEnji Cooper   , param##_type gmock_p##i
220028f6c2f2SEnji Cooper #define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \
220128f6c2f2SEnji Cooper   GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params))
220228f6c2f2SEnji Cooper 
220328f6c2f2SEnji Cooper #define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \
220428f6c2f2SEnji Cooper   , std::forward<param##_type>(gmock_p##i)
220528f6c2f2SEnji Cooper #define GMOCK_ACTION_GVALUE_PARAMS_(params) \
220628f6c2f2SEnji Cooper   GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params))
220728f6c2f2SEnji Cooper 
220828f6c2f2SEnji Cooper #define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \
220928f6c2f2SEnji Cooper   , param(::std::forward<param##_type>(gmock_p##i))
221028f6c2f2SEnji Cooper #define GMOCK_ACTION_INIT_PARAMS_(params) \
221128f6c2f2SEnji Cooper   GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params))
221228f6c2f2SEnji Cooper 
221328f6c2f2SEnji Cooper #define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param;
221428f6c2f2SEnji Cooper #define GMOCK_ACTION_FIELD_PARAMS_(params) \
221528f6c2f2SEnji Cooper   GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params)
221628f6c2f2SEnji Cooper 
221728f6c2f2SEnji Cooper #define GMOCK_INTERNAL_ACTION(name, full_name, params)                         \
221828f6c2f2SEnji Cooper   template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \
221928f6c2f2SEnji Cooper   class full_name {                                                            \
222028f6c2f2SEnji Cooper    public:                                                                     \
222128f6c2f2SEnji Cooper     explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params))               \
222228f6c2f2SEnji Cooper         : impl_(std::make_shared<gmock_Impl>(                                  \
222328f6c2f2SEnji Cooper               GMOCK_ACTION_GVALUE_PARAMS_(params))) {}                         \
222428f6c2f2SEnji Cooper     full_name(const full_name&) = default;                                     \
222528f6c2f2SEnji Cooper     full_name(full_name&&) noexcept = default;                                 \
222628f6c2f2SEnji Cooper     template <typename F>                                                      \
222728f6c2f2SEnji Cooper     operator ::testing::Action<F>() const {                                    \
222828f6c2f2SEnji Cooper       return ::testing::internal::MakeAction<F>(impl_);                        \
222928f6c2f2SEnji Cooper     }                                                                          \
223028f6c2f2SEnji Cooper                                                                                \
223128f6c2f2SEnji Cooper    private:                                                                    \
223228f6c2f2SEnji Cooper     class gmock_Impl {                                                         \
223328f6c2f2SEnji Cooper      public:                                                                   \
223428f6c2f2SEnji Cooper       explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params))            \
223528f6c2f2SEnji Cooper           : GMOCK_ACTION_INIT_PARAMS_(params) {}                               \
223628f6c2f2SEnji Cooper       template <typename function_type, typename return_type,                  \
223728f6c2f2SEnji Cooper                 typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>         \
223828f6c2f2SEnji Cooper       return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;  \
223928f6c2f2SEnji Cooper       GMOCK_ACTION_FIELD_PARAMS_(params)                                       \
224028f6c2f2SEnji Cooper     };                                                                         \
224128f6c2f2SEnji Cooper     std::shared_ptr<const gmock_Impl> impl_;                                   \
224228f6c2f2SEnji Cooper   };                                                                           \
224328f6c2f2SEnji Cooper   template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \
224428f6c2f2SEnji Cooper   inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \
224528f6c2f2SEnji Cooper       GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_;        \
224628f6c2f2SEnji Cooper   template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \
224728f6c2f2SEnji Cooper   inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \
224828f6c2f2SEnji Cooper       GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) {                              \
224928f6c2f2SEnji Cooper     return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>(                       \
225028f6c2f2SEnji Cooper         GMOCK_ACTION_GVALUE_PARAMS_(params));                                  \
225128f6c2f2SEnji Cooper   }                                                                            \
225228f6c2f2SEnji Cooper   template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \
225328f6c2f2SEnji Cooper   template <typename function_type, typename return_type, typename args_type,  \
225428f6c2f2SEnji Cooper             GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                 \
225528f6c2f2SEnji Cooper   return_type                                                                  \
225628f6c2f2SEnji Cooper   full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl::gmock_PerformImpl( \
225728f6c2f2SEnji Cooper       GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
225828f6c2f2SEnji Cooper 
225928f6c2f2SEnji Cooper }  // namespace internal
226028f6c2f2SEnji Cooper 
226128f6c2f2SEnji Cooper // Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored.
226228f6c2f2SEnji Cooper #define ACTION(name)                                                          \
226328f6c2f2SEnji Cooper   class name##Action {                                                        \
226428f6c2f2SEnji Cooper    public:                                                                    \
226528f6c2f2SEnji Cooper     explicit name##Action() noexcept {}                                       \
226628f6c2f2SEnji Cooper     name##Action(const name##Action&) noexcept {}                             \
226728f6c2f2SEnji Cooper     template <typename F>                                                     \
226828f6c2f2SEnji Cooper     operator ::testing::Action<F>() const {                                   \
226928f6c2f2SEnji Cooper       return ::testing::internal::MakeAction<F, gmock_Impl>();                \
227028f6c2f2SEnji Cooper     }                                                                         \
227128f6c2f2SEnji Cooper                                                                               \
227228f6c2f2SEnji Cooper    private:                                                                   \
227328f6c2f2SEnji Cooper     class gmock_Impl {                                                        \
227428f6c2f2SEnji Cooper      public:                                                                  \
227528f6c2f2SEnji Cooper       template <typename function_type, typename return_type,                 \
227628f6c2f2SEnji Cooper                 typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>        \
227728f6c2f2SEnji Cooper       return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
227828f6c2f2SEnji Cooper     };                                                                        \
227928f6c2f2SEnji Cooper   };                                                                          \
228028f6c2f2SEnji Cooper   inline name##Action name() GTEST_MUST_USE_RESULT_;                          \
228128f6c2f2SEnji Cooper   inline name##Action name() { return name##Action(); }                       \
228228f6c2f2SEnji Cooper   template <typename function_type, typename return_type, typename args_type, \
228328f6c2f2SEnji Cooper             GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                \
228428f6c2f2SEnji Cooper   return_type name##Action::gmock_Impl::gmock_PerformImpl(                    \
228528f6c2f2SEnji Cooper       GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
228628f6c2f2SEnji Cooper 
228728f6c2f2SEnji Cooper #define ACTION_P(name, ...) \
228828f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__))
228928f6c2f2SEnji Cooper 
229028f6c2f2SEnji Cooper #define ACTION_P2(name, ...) \
229128f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__))
229228f6c2f2SEnji Cooper 
229328f6c2f2SEnji Cooper #define ACTION_P3(name, ...) \
229428f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__))
229528f6c2f2SEnji Cooper 
229628f6c2f2SEnji Cooper #define ACTION_P4(name, ...) \
229728f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__))
229828f6c2f2SEnji Cooper 
229928f6c2f2SEnji Cooper #define ACTION_P5(name, ...) \
230028f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__))
230128f6c2f2SEnji Cooper 
230228f6c2f2SEnji Cooper #define ACTION_P6(name, ...) \
230328f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__))
230428f6c2f2SEnji Cooper 
230528f6c2f2SEnji Cooper #define ACTION_P7(name, ...) \
230628f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__))
230728f6c2f2SEnji Cooper 
230828f6c2f2SEnji Cooper #define ACTION_P8(name, ...) \
230928f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__))
231028f6c2f2SEnji Cooper 
231128f6c2f2SEnji Cooper #define ACTION_P9(name, ...) \
231228f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__))
231328f6c2f2SEnji Cooper 
231428f6c2f2SEnji Cooper #define ACTION_P10(name, ...) \
231528f6c2f2SEnji Cooper   GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__))
231628f6c2f2SEnji Cooper 
2317b89a7cc2SEnji Cooper }  // namespace testing
2318b89a7cc2SEnji Cooper 
231928f6c2f2SEnji Cooper GTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100
232028f6c2f2SEnji Cooper 
232128f6c2f2SEnji Cooper #endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
2322