From 096fb37a1976bbddde136c9db5fa88ac4332b802 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 14 Dec 2018 15:24:21 -0500 Subject: Googletest export Replace pump'd code for DoAll with variadic templates. PiperOrigin-RevId: 225584656 --- googlemock/include/gmock/gmock-actions.h | 86 +++++++++++++++----------------- 1 file changed, 40 insertions(+), 46 deletions(-) (limited to 'googlemock/include/gmock/gmock-actions.h') diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 7105830d..e0437f3f 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -574,7 +574,7 @@ class ReturnAction { // This template type conversion operator allows Return(x) to be // used in ANY function that returns x's type. template - operator Action() const { + operator Action() const { // NOLINT // Assert statement belongs here because this is the best place to verify // conditions on F. It produces the clearest error messages // in most compilers. @@ -587,6 +587,8 @@ class ReturnAction { GTEST_COMPILE_ASSERT_( !is_reference::value, use_ReturnRef_instead_of_Return_to_return_a_reference); + static_assert(!std::is_void::value, + "Can't use Return() on an action expected to return `void`."); return Action(new Impl(value_)); } @@ -1017,51 +1019,6 @@ void PrintTo(const ReferenceWrapper& ref, ::std::ostream* os) { UniversalPrinter::Print(value, os); } -// Does two actions sequentially. Used for implementing the DoAll(a1, -// a2, ...) action. -template -class DoBothAction { - public: - DoBothAction(Action1 action1, Action2 action2) - : action1_(action1), action2_(action2) {} - - // This template type conversion operator allows DoAll(a1, ..., a_n) - // to be used in ANY function of compatible type. - template - operator Action() const { - return Action(new Impl(action1_, action2_)); - } - - private: - // Implements the DoAll(...) action for a particular function type F. - template - class Impl : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - typedef typename Function::MakeResultVoid VoidResult; - - Impl(const Action& action1, const Action& action2) - : action1_(action1), action2_(action2) {} - - Result Perform(const ArgumentTuple& args) override { - action1_.Perform(args); - return action2_.Perform(args); - } - - private: - const Action action1_; - const Action action2_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; - - Action1 action1_; - Action2 action2_; - - GTEST_DISALLOW_ASSIGN_(DoBothAction); -}; - template struct WithArgsAction { InnerAction action; @@ -1080,6 +1037,35 @@ struct WithArgsAction { } }; +template +struct DoAllAction { + private: + template + std::vector> Convert(IndexSequence) const { + return {std::get(actions)...}; + } + + public: + std::tuple actions; + + template + operator Action() const { // NOLINT + struct Op { + std::vector> converted; + Action last; + R operator()(Args... args) const { + auto tuple_args = std::forward_as_tuple(std::forward(args)...); + for (auto& a : converted) { + a.Perform(tuple_args); + } + return last.Perform(tuple_args); + } + }; + return Op{Convert(MakeIndexSequence()), + std::get(actions)}; + } +}; + } // namespace internal // An Unused object can be implicitly constructed from ANY value. @@ -1130,6 +1116,14 @@ Action::Action(const Action& from) : new internal::ActionAdaptor(from)) { } +// Creates an action that does actions a1, a2, ..., sequentially in +// each invocation. +template +internal::DoAllAction::type...> DoAll( + Action&&... action) { + return {std::forward_as_tuple(std::forward(action)...)}; +} + // WithArg(an_action) creates an action that passes the k-th // (0-based) argument of the mock function to an_action and performs // it. It adapts an action accepting one argument to one that accepts -- cgit v1.2.3 From e26a3fa13ca21500773293946e92ec72f8d8c9ea Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 17 Dec 2018 18:59:00 -0500 Subject: Googletest export Unifdef c++11-related macros from googletest now that it requires C++11. PiperOrigin-RevId: 225905601 --- googlemock/include/gmock/gmock-actions.h | 50 +++++--------------------------- 1 file changed, 7 insertions(+), 43 deletions(-) (limited to 'googlemock/include/gmock/gmock-actions.h') diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index e0437f3f..4fd3400f 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -42,18 +42,15 @@ #endif #include +#include #include #include +#include #include #include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-port.h" -#if GTEST_LANG_CXX11 // Defined by gtest-port.h via gmock-port.h. -#include -#include -#endif // GTEST_LANG_CXX11 - #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable:4100) @@ -105,7 +102,6 @@ struct BuiltInDefaultValueGetter { template class BuiltInDefaultValue { public: -#if GTEST_LANG_CXX11 // This function returns true iff type T has a built-in default value. static bool Exists() { return ::std::is_default_constructible::value; @@ -115,18 +111,6 @@ class BuiltInDefaultValue { return BuiltInDefaultValueGetter< T, ::std::is_default_constructible::value>::Get(); } - -#else // GTEST_LANG_CXX11 - // This function returns true iff type T has a built-in default value. - static bool Exists() { - return false; - } - - static T Get() { - return BuiltInDefaultValueGetter::Get(); - } - -#endif // GTEST_LANG_CXX11 }; // This partial specialization says that we use the same built-in @@ -366,7 +350,6 @@ class Action { // STL containers. Action() {} -#if GTEST_LANG_CXX11 // Construct an Action from a specified callable. // This cannot take std::function directly, because then Action would not be // directly constructible from lambda (it would require two conversions). @@ -374,7 +357,6 @@ class Action { typename = typename ::std::enable_if< ::std::is_constructible<::std::function, G>::value>::type> Action(G&& fun) : fun_(::std::forward(fun)) {} // NOLINT -#endif // Constructs an Action from its implementation. explicit Action(ActionInterface* impl) : impl_(impl) {} @@ -388,11 +370,7 @@ class Action { // Returns true iff this is the DoDefault() action. bool IsDoDefault() const { -#if GTEST_LANG_CXX11 return impl_ == nullptr && fun_ == nullptr; -#else - return impl_ == NULL; -#endif } // Performs the action. Note that this method is const even though @@ -405,11 +383,9 @@ class Action { if (IsDoDefault()) { internal::IllegalDoDefault(__FILE__, __LINE__); } -#if GTEST_LANG_CXX11 if (fun_ != nullptr) { return internal::Apply(fun_, ::std::move(args)); } -#endif return impl_->Perform(args); } @@ -420,16 +396,12 @@ class Action { template friend class Action; - // In C++11, Action can be implemented either as a generic functor (through - // std::function), or legacy ActionInterface. In C++98, only ActionInterface - // is available. The invariants are as follows: - // * in C++98, impl_ is null iff this is the default action - // * in C++11, at most one of fun_ & impl_ may be nonnull; both are null iff - // this is the default action -#if GTEST_LANG_CXX11 + // Action can be implemented either as a generic functor (via std::function), + // or legacy ActionInterface. The invariant is that at most one of fun_ and + // impl_ may be nonnull; both are null iff this is the default action. + // FIXME: Fold the ActionInterface into std::function. ::std::function fun_; -#endif - std::shared_ptr> impl_; + ::std::shared_ptr> impl_; }; // The PolymorphicAction class template makes it easy to implement a @@ -662,13 +634,7 @@ class ReturnNullAction { // pointer type on compile time. template static Result Perform(const ArgumentTuple&) { -#if GTEST_LANG_CXX11 return nullptr; -#else - GTEST_COMPILE_ASSERT_(internal::is_pointer::value, - ReturnNull_can_be_used_to_return_a_pointer_only); - return NULL; -#endif // GTEST_LANG_CXX11 } }; @@ -1108,9 +1074,7 @@ template template Action::Action(const Action& from) : -#if GTEST_LANG_CXX11 fun_(from.fun_), -#endif impl_(from.impl_ == nullptr ? nullptr : new internal::ActionAdaptor(from)) { -- cgit v1.2.3 From 9494c45e75a55547f3f183a1161fbd39d29b994e Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 19 Dec 2018 03:16:02 -0500 Subject: Googletest export Use std::function to implement type erasure in Action, wrapping the legacy ActionInterface if necessary. This makes functors / std::function the primary way to implement Action; the existing ActionInterface implementations are handled through ActionAdaptor. The existing actions are not (yet) migrated though; they'll pay the cost of one additional indirection - but that should be negligible. PiperOrigin-RevId: 226126137 --- googlemock/include/gmock/gmock-actions.h | 76 +++++++++----------------------- 1 file changed, 20 insertions(+), 56 deletions(-) (limited to 'googlemock/include/gmock/gmock-actions.h') diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 4fd3400f..8b3c03b0 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -69,9 +69,6 @@ namespace testing { namespace internal { -template -class ActionAdaptor; - // BuiltInDefaultValueGetter::Get() returns a // default-constructed T value. BuiltInDefaultValueGetter::Get() crashes with an error. @@ -342,6 +339,19 @@ class ActionInterface { // object as a handle to it. template class Action { + // Adapter class to allow constructing Action from a legacy ActionInterface. + // New code should create Actions from functors instead. + struct ActionAdapter { + // Adapter must be copyable to satisfy std::function requirements. + ::std::shared_ptr> impl_; + + template + typename internal::Function::Result operator()(Args&&... args) { + return impl_->Perform( + ::std::forward_as_tuple(::std::forward(args)...)); + } + }; + public: typedef typename internal::Function::Result Result; typedef typename internal::Function::ArgumentTuple ArgumentTuple; @@ -359,19 +369,17 @@ class Action { Action(G&& fun) : fun_(::std::forward(fun)) {} // NOLINT // Constructs an Action from its implementation. - explicit Action(ActionInterface* impl) : impl_(impl) {} + explicit Action(ActionInterface* impl) + : fun_(ActionAdapter{::std::shared_ptr>(impl)}) {} // This constructor allows us to turn an Action object into an // Action, as long as F's arguments can be implicitly converted - // to Func's and Func's return type can be implicitly converted to - // F's. + // to Func's and Func's return type can be implicitly converted to F's. template - explicit Action(const Action& action); + explicit Action(const Action& action) : fun_(action.fun_) {} // Returns true iff this is the DoDefault() action. - bool IsDoDefault() const { - return impl_ == nullptr && fun_ == nullptr; - } + bool IsDoDefault() const { return fun_ == nullptr; } // Performs the action. Note that this method is const even though // the corresponding method in ActionInterface is not. The reason @@ -383,25 +391,15 @@ class Action { if (IsDoDefault()) { internal::IllegalDoDefault(__FILE__, __LINE__); } - if (fun_ != nullptr) { - return internal::Apply(fun_, ::std::move(args)); - } - return impl_->Perform(args); + return internal::Apply(fun_, ::std::move(args)); } private: - template - friend class internal::ActionAdaptor; - template friend class Action; - // Action can be implemented either as a generic functor (via std::function), - // or legacy ActionInterface. The invariant is that at most one of fun_ and - // impl_ may be nonnull; both are null iff this is the default action. - // FIXME: Fold the ActionInterface into std::function. + // fun_ is an empty function iff this is the DoDefault() action. ::std::function fun_; - ::std::shared_ptr> impl_; }; // The PolymorphicAction class template makes it easy to implement a @@ -480,26 +478,6 @@ inline PolymorphicAction MakePolymorphicAction(const Impl& impl) { namespace internal { -// Allows an Action object to pose as an Action, as long as F2 -// and F1 are compatible. -template -class ActionAdaptor : public ActionInterface { - public: - typedef typename internal::Function::Result Result; - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - explicit ActionAdaptor(const Action& from) : impl_(from.impl_) {} - - Result Perform(const ArgumentTuple& args) override { - return impl_->Perform(args); - } - - private: - const std::shared_ptr> impl_; - - GTEST_DISALLOW_ASSIGN_(ActionAdaptor); -}; - // Helper struct to specialize ReturnAction to execute a move instead of a copy // on return. Useful for move-only types, but could be used on any type. template @@ -1066,20 +1044,6 @@ struct DoAllAction { // EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); typedef internal::IgnoredValue Unused; -// This constructor allows us to turn an Action object into an -// Action, as long as To's arguments can be implicitly converted -// to From's and From's return type cann be implicitly converted to -// To's. -template -template -Action::Action(const Action& from) - : - fun_(from.fun_), - impl_(from.impl_ == nullptr - ? nullptr - : new internal::ActionAdaptor(from)) { -} - // Creates an action that does actions a1, a2, ..., sequentially in // each invocation. template -- cgit v1.2.3 From f8b1c1af17750189b83c58f360c85268c0d95105 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 28 Dec 2018 06:03:51 -0500 Subject: Googletest export Remove the #ifs for old, unsupported and buggy compilers: * old versions of GCC & MSVC * Symbian PiperOrigin-RevId: 227116941 --- googlemock/include/gmock/gmock-actions.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'googlemock/include/gmock/gmock-actions.h') diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 8b3c03b0..28141257 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -1140,10 +1140,6 @@ SetArgPointee(const T& x) { N, T, internal::IsAProtocolMessage::value>(x)); } -#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN) -// This overload allows SetArgPointee() to accept a string literal. -// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish -// this overload from the templated version and emit a compile error. template PolymorphicAction< internal::SetArgumentPointeeAction > @@ -1159,7 +1155,6 @@ SetArgPointee(const wchar_t* p) { return MakePolymorphicAction(internal::SetArgumentPointeeAction< N, const wchar_t*, false>(p)); } -#endif // The following version is DEPRECATED. template -- cgit v1.2.3