From df6b75949b1efab7606ba60c0f0a0125ac95c5af Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 26 Aug 2020 14:36:31 -0400 Subject: [PATCH] Googletest export Replace uses of ACTION_TEMPLATE and ACTION_P with manually written functors. The latter provide better error diagnostics. This fixes https://github.com/google/googletest/issues/2729. PiperOrigin-RevId: 328573022 --- googlemock/include/gmock/gmock-actions.h | 176 ++++++++++++++++-- googlemock/include/gmock/gmock-more-actions.h | 162 ---------------- googlemock/include/gmock/gmock.h | 1 - googlemock/test/gmock-more-actions_test.cc | 6 +- 4 files changed, 162 insertions(+), 183 deletions(-) delete mode 100644 googlemock/include/gmock/gmock-more-actions.h diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 02356a40..d934dc9c 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -1063,6 +1063,105 @@ struct DoAllAction { } }; +template +struct ReturnNewAction { + T* operator()() const { + return internal::Apply( + [](const Params&... unpacked_params) { + return new T(unpacked_params...); + }, + params); + } + std::tuple params; +}; + +template +struct ReturnArgAction { + template + auto operator()(const Args&... args) const -> + typename std::tuple_element>::type { + return std::get(std::tie(args...)); + } +}; + +template +struct SaveArgAction { + Ptr pointer; + + template + void operator()(const Args&... args) const { + *pointer = std::get(std::tie(args...)); + } +}; + +template +struct SaveArgPointeeAction { + Ptr pointer; + + template + void operator()(const Args&... args) const { + *pointer = *std::get(std::tie(args...)); + } +}; + +template +struct SetArgRefereeAction { + T value; + + template + void operator()(Args&&... args) const { + using argk_type = + typename ::std::tuple_element>::type; + static_assert(std::is_lvalue_reference::value, + "Argument must be a reference type."); + std::get(std::tie(args...)) = value; + } +}; + +template +struct SetArrayArgumentAction { + I1 first; + I2 last; + + template + void operator()(const Args&... args) const { + auto value = std::get(std::tie(args...)); + for (auto it = first; it != last; ++it, (void)++value) { + *value = *it; + } + } +}; + +template +struct DeleteArgAction { + template + void operator()(const Args&... args) const { + delete std::get(std::tie(args...)); + } +}; + +template +struct ReturnPointeeAction { + Ptr pointer; + template + auto operator()(const Args&...) const -> decltype(*pointer) { + return *pointer; + } +}; + +#if GTEST_HAS_EXCEPTIONS +template +struct ThrowAction { + T exception; + // We use a conversion operator to adapt to any return type. + template + operator Action() const { // NOLINT + T copy = exception; + return [copy](Args...) -> R { throw copy; }; + } +}; +#endif // GTEST_HAS_EXCEPTIONS + } // namespace internal // An Unused object can be implicitly constructed from ANY value. @@ -1292,22 +1391,6 @@ inline ::std::reference_wrapper ByRef(T& l_value) { // NOLINT return ::std::reference_wrapper(l_value); } -namespace internal { - -template -struct ReturnNewAction { - T* operator()() const { - return internal::Apply( - [](const Params&... unpacked_params) { - return new T(unpacked_params...); - }, - params); - } - std::tuple params; -}; - -} // namespace internal - // The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new // instance of type T, constructed on the heap with constructor arguments // a1, a2, ..., and a_k. The caller assumes ownership of the returned value. @@ -1317,6 +1400,67 @@ internal::ReturnNewAction::type...> ReturnNew( return {std::forward_as_tuple(std::forward(params)...)}; } +// Action ReturnArg() returns the k-th argument of the mock function. +template +internal::ReturnArgAction ReturnArg() { + return {}; +} + +// Action SaveArg(pointer) saves the k-th (0-based) argument of the +// mock function to *pointer. +template +internal::SaveArgAction SaveArg(Ptr pointer) { + return {pointer}; +} + +// Action SaveArgPointee(pointer) saves the value pointed to +// by the k-th (0-based) argument of the mock function to *pointer. +template +internal::SaveArgPointeeAction SaveArgPointee(Ptr pointer) { + return {pointer}; +} + +// Action SetArgReferee(value) assigns 'value' to the variable +// referenced by the k-th (0-based) argument of the mock function. +template +internal::SetArgRefereeAction::type> SetArgReferee( + T&& value) { + return {std::forward(value)}; +} + +// Action SetArrayArgument(first, last) copies the elements in +// source range [first, last) to the array pointed to by the k-th +// (0-based) argument, which can be either a pointer or an +// iterator. The action does not take ownership of the elements in the +// source range. +template +internal::SetArrayArgumentAction SetArrayArgument(I1 first, + I2 last) { + return {first, last}; +} + +// Action DeleteArg() deletes the k-th (0-based) argument of the mock +// function. +template +internal::DeleteArgAction DeleteArg() { + return {}; +} + +// This action returns the value pointed to by 'pointer'. +template +internal::ReturnPointeeAction ReturnPointee(Ptr pointer) { + return {pointer}; +} + +// Action Throw(exception) can be used in a mock function of any type +// to throw the given exception. Any copyable value can be thrown. +#if GTEST_HAS_EXCEPTIONS +template +internal::ThrowAction::type> Throw(T&& exception) { + return {std::forward(exception)}; +} +#endif // GTEST_HAS_EXCEPTIONS + namespace internal { // A macro from the ACTION* family (defined later in gmock-generated-actions.h) diff --git a/googlemock/include/gmock/gmock-more-actions.h b/googlemock/include/gmock/gmock-more-actions.h deleted file mode 100644 index d42484ae..00000000 --- a/googlemock/include/gmock/gmock-more-actions.h +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some actions that depend on gmock-generated-actions.h. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ - -#include -#include - -#include "gmock/gmock-generated-actions.h" - -namespace testing { -namespace internal { - -// An internal replacement for std::copy which mimics its behavior. This is -// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996. -// However Visual Studio 2010 and later do not honor #pragmas which disable that -// warning. -template -inline OutputIterator CopyElements(InputIterator first, - InputIterator last, - OutputIterator output) { - for (; first != last; ++first, ++output) { - *output = *first; - } - return output; -} - -} // namespace internal - -// Various overloads for Invoke(). - -// The ACTION*() macros trigger warning C4100 (unreferenced formal -// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in -// the macro definition, as the warnings are generated when the macro -// is expanded and macro expansion cannot contain #pragma. Therefore -// we suppress them here. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif - -// Action ReturnArg() returns the k-th argument of the mock function. -ACTION_TEMPLATE(ReturnArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - return ::std::get(args); -} - -// Action SaveArg(pointer) saves the k-th (0-based) argument of the -// mock function to *pointer. -ACTION_TEMPLATE(SaveArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(pointer)) { - *pointer = ::std::get(args); -} - -// Action SaveArgPointee(pointer) saves the value pointed to -// by the k-th (0-based) argument of the mock function to *pointer. -ACTION_TEMPLATE(SaveArgPointee, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(pointer)) { - *pointer = *::std::get(args); -} - -// Action SetArgReferee(value) assigns 'value' to the variable -// referenced by the k-th (0-based) argument of the mock function. -ACTION_TEMPLATE(SetArgReferee, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(value)) { - typedef typename ::std::tuple_element::type argk_type; - // Ensures that argument #k is a reference. If you get a compiler - // error on the next line, you are using SetArgReferee(value) in - // a mock function whose k-th (0-based) argument is not a reference. - GTEST_COMPILE_ASSERT_(std::is_reference::value, - SetArgReferee_must_be_used_with_a_reference_argument); - ::std::get(args) = value; -} - -// Action SetArrayArgument(first, last) copies the elements in -// source range [first, last) to the array pointed to by the k-th -// (0-based) argument, which can be either a pointer or an -// iterator. The action does not take ownership of the elements in the -// source range. -ACTION_TEMPLATE(SetArrayArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_2_VALUE_PARAMS(first, last)) { - // Visual Studio deprecates ::std::copy, so we use our own copy in that case. -#ifdef _MSC_VER - internal::CopyElements(first, last, ::std::get(args)); -#else - ::std::copy(first, last, ::std::get(args)); -#endif -} - -// Action DeleteArg() deletes the k-th (0-based) argument of the mock -// function. -ACTION_TEMPLATE(DeleteArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - delete ::std::get(args); -} - -// This action returns the value pointed to by 'pointer'. -ACTION_P(ReturnPointee, pointer) { return *pointer; } - -// Action Throw(exception) can be used in a mock function of any type -// to throw the given exception. Any copyable value can be thrown. -#if GTEST_HAS_EXCEPTIONS - -// Suppresses the 'unreachable code' warning that VC generates in opt modes. -# ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4702) // Temporarily disables warning 4702. -# endif -ACTION_P(Throw, exception) { throw exception; } -# ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -# endif - -#endif // GTEST_HAS_EXCEPTIONS - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h index 3c317b6d..8a4aceae 100644 --- a/googlemock/include/gmock/gmock.h +++ b/googlemock/include/gmock/gmock.h @@ -61,7 +61,6 @@ #include "gmock/gmock-function-mocker.h" #include "gmock/gmock-generated-actions.h" #include "gmock/gmock-matchers.h" -#include "gmock/gmock-more-actions.h" #include "gmock/gmock-more-matchers.h" #include "gmock/gmock-nice-strict.h" #include "gmock/internal/gmock-internal-utils.h" diff --git a/googlemock/test/gmock-more-actions_test.cc b/googlemock/test/gmock-more-actions_test.cc index d6a078b4..4bcb5df6 100644 --- a/googlemock/test/gmock-more-actions_test.cc +++ b/googlemock/test/gmock-more-actions_test.cc @@ -27,18 +27,16 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Google Mock - a framework for writing C++ mock classes. // -// This file tests the built-in actions in gmock-more-actions.h. - -#include "gmock/gmock-more-actions.h" +// This file tests the built-in actions in gmock-actions.h. #include #include #include #include +#include "gmock/gmock-actions.h" #include "gmock/gmock.h" #include "gtest/gtest-spi.h" #include "gtest/gtest.h"