summaryrefslogtreecommitdiffstats
path: root/googlemock/include/gmock/gmock-spec-builders.h
diff options
context:
space:
mode:
authorAaron Jacobs <jacobsa@google.com>2022-04-26 15:05:01 (GMT)
committerCopybara-Service <copybara-worker@google.com>2022-04-26 15:05:34 (GMT)
commit0498660ea575bfeb4b3b0879fa6aa6904d1df373 (patch)
tree555b8f3add5a2ceae42409040ecec37c0ca28810 /googlemock/include/gmock/gmock-spec-builders.h
parentb53547bf01ee6d5c547bc539a498c49bc6027169 (diff)
downloadgoogletest-0498660ea575bfeb4b3b0879fa6aa6904d1df373.zip
googletest-0498660ea575bfeb4b3b0879fa6aa6904d1df373.tar.gz
googletest-0498660ea575bfeb4b3b0879fa6aa6904d1df373.tar.bz2
Support move-only and &&-qualified actions in DoAll.
This is necessary for generic support of these actions, since `DoAll` is a frequently-used action wrapper. PiperOrigin-RevId: 444561964 Change-Id: I02edb55e35ab4207fbd71e371255a319c8253136
Diffstat (limited to 'googlemock/include/gmock/gmock-spec-builders.h')
-rw-r--r--googlemock/include/gmock/gmock-spec-builders.h41
1 files changed, 36 insertions, 5 deletions
diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h
index a3e32a4..835e518 100644
--- a/googlemock/include/gmock/gmock-spec-builders.h
+++ b/googlemock/include/gmock/gmock-spec-builders.h
@@ -878,9 +878,15 @@ class GTEST_API_ ExpectationBase {
mutable Mutex mutex_; // Protects action_count_checked_.
}; // class ExpectationBase
-// Implements an expectation for the given function type.
template <typename F>
-class TypedExpectation : public ExpectationBase {
+class TypedExpectation;
+
+// Implements an expectation for the given function type.
+template <typename R, typename... Args>
+class TypedExpectation<R(Args...)> : public ExpectationBase {
+ private:
+ using F = R(Args...);
+
public:
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
@@ -993,15 +999,30 @@ class TypedExpectation : public ExpectationBase {
return After(s1, s2, s3, s4).After(s5);
}
- // Implements the .WillOnce() clause for copyable actions.
+ // Preferred, type-safe overload: consume anything that can be directly
+ // converted to a OnceAction, except for Action<F> objects themselves.
TypedExpectation& WillOnce(OnceAction<F> once_action) {
+ // Call the overload below, smuggling the OnceAction as a copyable callable.
+ // We know this is safe because a WillOnce action will not be called more
+ // than once.
+ return WillOnce(Action<F>(ActionAdaptor{
+ std::make_shared<OnceAction<F>>(std::move(once_action)),
+ }));
+ }
+
+ // Fallback overload: accept Action<F> objects and those actions that define
+ // `operator Action<F>` but not `operator OnceAction<F>`.
+ //
+ // This is templated in order to cause the overload above to be preferred
+ // when the input is convertible to either type.
+ template <int&... ExplicitArgumentBarrier, typename = void>
+ TypedExpectation& WillOnce(Action<F> action) {
ExpectSpecProperty(last_clause_ <= kWillOnce,
".WillOnce() cannot appear after "
".WillRepeatedly() or .RetiresOnSaturation().");
last_clause_ = kWillOnce;
- untyped_actions_.push_back(
- new Action<F>(std::move(once_action).ReleaseAction()));
+ untyped_actions_.push_back(new Action<F>(std::move(action)));
if (!cardinality_specified()) {
set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));
@@ -1074,6 +1095,16 @@ class TypedExpectation : public ExpectationBase {
template <typename Function>
friend class FunctionMocker;
+ // An adaptor that turns a OneAction<F> into something compatible with
+ // Action<F>. Must be called at most once.
+ struct ActionAdaptor {
+ std::shared_ptr<OnceAction<R(Args...)>> once_action;
+
+ R operator()(Args&&... args) const {
+ return std::move(*once_action).Call(std::forward<Args>(args)...);
+ }
+ };
+
// Returns an Expectation object that references and co-owns this
// expectation.
Expectation GetHandle() override { return owner_->GetHandleOf(this); }