diff --git a/.travis.yml b/.travis.yml
index 8913e89a..1200c676 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,13 +37,15 @@ matrix:
group: deprecated-2017Q4
compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
+ - os: linux
+ compiler: clang
+ env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 NO_EXCEPTION=ON NO_RTTI=ON COMPILER_IS_GNUCXX=ON
- os: osx
compiler: gcc
env: BUILD_TYPE=Debug VERBOSE=1
- os: osx
compiler: gcc
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
- if: type != pull_request
- os: osx
compiler: clang
env: BUILD_TYPE=Debug VERBOSE=1
diff --git a/ci/travis.sh b/ci/travis.sh
index 2dda68fd..9ff3bad3 100755
--- a/ci/travis.sh
+++ b/ci/travis.sh
@@ -24,11 +24,19 @@ export MAKEFLAGS
env | sort
+# Set default values to OFF for these variables if not specified.
+: "${NO_EXCEPTION:=OFF}"
+: "${NO_RTTI:=OFF}"
+: "${COMPILER_IS_GNUCXX:=OFF}"
+
mkdir build || true
cd build
cmake -Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
+ -Dcxx_no_exception=$NO_EXCEPTION \
+ -Dcxx_no_rtti=$NO_RTTI \
+ -DCMAKE_COMPILER_IS_GNUCXX=$COMPILER_IS_GNUCXX \
-DCMAKE_CXX_FLAGS=$CXX_FLAGS \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
..
diff --git a/googlemock/docs/CookBook.md b/googlemock/docs/CookBook.md
index c2565f1e..3737d030 100644
--- a/googlemock/docs/CookBook.md
+++ b/googlemock/docs/CookBook.md
@@ -2229,13 +2229,20 @@ versus
## Mocking Methods That Use Move-Only Types ##
-C++11 introduced move-only types. A move-only-typed value can be moved from one object to another, but cannot be copied. `std::unique_ptr` is probably the most commonly used move-only type.
+C++11 introduced *move-only types*. A move-only-typed value can be moved from
+one object to another, but cannot be copied. `std::unique_ptr` is
+probably the most commonly used move-only type.
-Mocking a method that takes and/or returns move-only types presents some challenges, but nothing insurmountable. This recipe shows you how you can do it.
+Mocking a method that takes and/or returns move-only types presents some
+challenges, but nothing insurmountable. This recipe shows you how you can do it.
+Note that the support for move-only method arguments was only introduced to
+gMock in April 2017; in older code, you may find more complex
+[workarounds](#LegacyMoveOnly) for lack of this feature.
-Let’s say we are working on a fictional project that lets one post and share snippets called “buzzes”. Your code uses these types:
+Let’s say we are working on a fictional project that lets one post and share
+snippets called “buzzes”. Your code uses these types:
-```
+```cpp
enum class AccessLevel { kInternal, kPublic };
class Buzz {
@@ -2247,59 +2254,46 @@ class Buzz {
class Buzzer {
public:
virtual ~Buzzer() {}
- virtual std::unique_ptr MakeBuzz(const std::string& text) = 0;
- virtual bool ShareBuzz(std::unique_ptr buzz, Time timestamp) = 0;
+ virtual std::unique_ptr MakeBuzz(StringPiece text) = 0;
+ virtual bool ShareBuzz(std::unique_ptr buzz, int64_t timestamp) = 0;
...
};
```
-A `Buzz` object represents a snippet being posted. A class that implements the `Buzzer` interface is capable of creating and sharing `Buzz`. Methods in `Buzzer` may return a `unique_ptr` or take a `unique_ptr`. Now we need to mock `Buzzer` in our tests.
+A `Buzz` object represents a snippet being posted. A class that implements the
+`Buzzer` interface is capable of creating and sharing `Buzz`es. Methods in
+`Buzzer` may return a `unique_ptr` or take a
+`unique_ptr`. Now we need to mock `Buzzer` in our tests.
-To mock a method that returns a move-only type, you just use the familiar `MOCK_METHOD` syntax as usual:
+To mock a method that accepts or returns move-only types, you just use the
+familiar `MOCK_METHOD` syntax as usual:
-```
+```cpp
class MockBuzzer : public Buzzer {
public:
- MOCK_METHOD1(MakeBuzz, std::unique_ptr(const std::string& text));
- …
+ MOCK_METHOD1(MakeBuzz, std::unique_ptr(StringPiece text));
+ MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr buzz, int64_t timestamp));
};
```
-However, if you attempt to use the same `MOCK_METHOD` pattern to mock a method that takes a move-only parameter, you’ll get a compiler error currently:
+Now that we have the mock class defined, we can use it in tests. In the
+following code examples, we assume that we have defined a `MockBuzzer` object
+named `mock_buzzer_`:
-```
- // Does NOT compile!
- MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr buzz, Time timestamp));
-```
-
-While it’s highly desirable to make this syntax just work, it’s not trivial and the work hasn’t been done yet. Fortunately, there is a trick you can apply today to get something that works nearly as well as this.
-
-The trick, is to delegate the `ShareBuzz()` method to a mock method (let’s call it `DoShareBuzz()`) that does not take move-only parameters:
-
-```
-class MockBuzzer : public Buzzer {
- public:
- MOCK_METHOD1(MakeBuzz, std::unique_ptr(const std::string& text));
- MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp));
- bool ShareBuzz(std::unique_ptr buzz, Time timestamp) {
- return DoShareBuzz(buzz.get(), timestamp);
- }
-};
-```
-
-Note that there's no need to define or declare `DoShareBuzz()` in a base class. You only need to define it as a `MOCK_METHOD` in the mock class.
-
-Now that we have the mock class defined, we can use it in tests. In the following code examples, we assume that we have defined a `MockBuzzer` object named `mock_buzzer_`:
-
-```
+```cpp
MockBuzzer mock_buzzer_;
```
-First let’s see how we can set expectations on the `MakeBuzz()` method, which returns a `unique_ptr`.
+First let’s see how we can set expectations on the `MakeBuzz()` method, which
+returns a `unique_ptr`.
-As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or `.WillRepeated()` clause), when that expectation fires, the default action for that method will be taken. Since `unique_ptr<>` has a default constructor that returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an action:
+As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or
+`.WillRepeated()` clause), when that expectation fires, the default action for
+that method will be taken. Since `unique_ptr<>` has a default constructor
+that returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an
+action:
-```
+```cpp
// Use the default action.
EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"));
@@ -2307,32 +2301,13 @@ As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or
EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello"));
```
-If you are not happy with the default action, you can tweak it. Depending on what you need, you may either tweak the default action for a specific (mock object, mock method) combination using `ON_CALL()`, or you may tweak the default action for all mock methods that return a specific type. The usage of `ON_CALL()` is similar to `EXPECT_CALL()`, so we’ll skip it and just explain how to do the latter (tweaking the default action for a specific return type). You do this via the `DefaultValue<>::SetFactory()` and `DefaultValue<>::Clear()` API:
+If you are not happy with the default action, you can tweak it as usual; see
+[Setting Default Actions](#OnCall).
-```
- // Sets the default action for return type std::unique_ptr to
- // creating a new Buzz every time.
- DefaultValue>::SetFactory(
- [] { return MakeUnique(AccessLevel::kInternal); });
+If you just need to return a pre-defined move-only value, you can use the
+`Return(ByMove(...))` action:
- // When this fires, the default action of MakeBuzz() will run, which
- // will return a new Buzz object.
- EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber());
-
- auto buzz1 = mock_buzzer_.MakeBuzz("hello");
- auto buzz2 = mock_buzzer_.MakeBuzz("hello");
- EXPECT_NE(nullptr, buzz1);
- EXPECT_NE(nullptr, buzz2);
- EXPECT_NE(buzz1, buzz2);
-
- // Resets the default action for return type std::unique_ptr,
- // to avoid interfere with other tests.
- DefaultValue>::Clear();
-```
-
-What if you want the method to do something other than the default action? If you just need to return a pre-defined move-only value, you can use the `Return(ByMove(...))` action:
-
-```
+```cpp
// When this fires, the unique_ptr<> specified by ByMove(...) will
// be returned.
EXPECT_CALL(mock_buzzer_, MakeBuzz("world"))
@@ -2343,81 +2318,87 @@ What if you want the method to do something other than the default action? If y
Note that `ByMove()` is essential here - if you drop it, the code won’t compile.
-Quiz time! What do you think will happen if a `Return(ByMove(...))` action is performed more than once (e.g. you write `….WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time the action runs, the source value will be consumed (since it’s a move-only value), so the next time around, there’s no value to move from -- you’ll get a run-time error that `Return(ByMove(...))` can only be run once.
+Quiz time! What do you think will happen if a `Return(ByMove(...))` action is
+performed more than once (e.g. you write
+`….WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first
+time the action runs, the source value will be consumed (since it’s a move-only
+value), so the next time around, there’s no value to move from -- you’ll get a
+run-time error that `Return(ByMove(...))` can only be run once.
-If you need your mock method to do more than just moving a pre-defined value, remember that you can always use `Invoke()` to call a lambda or a callable object, which can do pretty much anything you want:
+If you need your mock method to do more than just moving a pre-defined value,
+remember that you can always use a lambda or a callable object, which can do
+pretty much anything you want:
-```
+```cpp
EXPECT_CALL(mock_buzzer_, MakeBuzz("x"))
- .WillRepeatedly(Invoke([](const std::string& text) {
- return std::make_unique(AccessLevel::kInternal);
- }));
+ .WillRepeatedly([](StringPiece text) {
+ return MakeUnique(AccessLevel::kInternal);
+ });
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
```
-Every time this `EXPECT_CALL` fires, a new `unique_ptr` will be created and returned. You cannot do this with `Return(ByMove(...))`.
+Every time this `EXPECT_CALL` fires, a new `unique_ptr` will be
+created and returned. You cannot do this with `Return(ByMove(...))`.
-Now there’s one topic we haven’t covered: how do you set expectations on `ShareBuzz()`, which takes a move-only-typed parameter? The answer is you don’t. Instead, you set expectations on the `DoShareBuzz()` mock method (remember that we defined a `MOCK_METHOD` for `DoShareBuzz()`, not `ShareBuzz()`):
+That covers returning move-only values; but how do we work with methods
+accepting move-only arguments? The answer is that they work normally, although
+some actions will not compile when any of method's arguments are move-only. You
+can always use `Return`, or a [lambda or functor](#FunctionsAsActions):
+```cpp
+ using ::testing::Unused;
+
+ EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)) .WillOnce(Return(true));
+ EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal)),
+ 0);
+
+ EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)) .WillOnce(
+ [](std::unique_ptr buzz, Unused) { return buzz != nullptr; });
+ EXPECT_FALSE(mock_buzzer_.ShareBuzz(nullptr, 0));
```
+
+Many built-in actions (`WithArgs`, `WithoutArgs`,`DeleteArg`, `SaveArg`, ...)
+could in principle support move-only arguments, but the support for this is not
+implemented yet. If this is blocking you, please file a bug.
+
+A few actions (e.g. `DoAll`) copy their arguments internally, so they can never
+work with non-copyable objects; you'll have to use functors instead.
+
+##### Legacy workarounds for move-only types {#LegacyMoveOnly}
+
+Support for move-only function arguments was only introduced to gMock in April
+2017. In older code, you may encounter the following workaround for the lack of
+this feature (it is no longer necessary - we're including it just for
+reference):
+
+```cpp
+class MockBuzzer : public Buzzer {
+ public:
+ MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp));
+ bool ShareBuzz(std::unique_ptr buzz, Time timestamp) override {
+ return DoShareBuzz(buzz.get(), timestamp);
+ }
+};
+```
+
+The trick is to delegate the `ShareBuzz()` method to a mock method (let’s call
+it `DoShareBuzz()`) that does not take move-only parameters. Then, instead of
+setting expectations on `ShareBuzz()`, you set them on the `DoShareBuzz()` mock
+method:
+
+```cpp
+ MockBuzzer mock_buzzer_;
EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _));
// When one calls ShareBuzz() on the MockBuzzer like this, the call is
// forwarded to DoShareBuzz(), which is mocked. Therefore this statement
// will trigger the above EXPECT_CALL.
- mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal),
- ::base::Now());
+ mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal), 0);
```
-Some of you may have spotted one problem with this approach: the `DoShareBuzz()` mock method differs from the real `ShareBuzz()` method in that it cannot take ownership of the buzz parameter - `ShareBuzz()` will always delete buzz after `DoShareBuzz()` returns. What if you need to save the buzz object somewhere for later use when `ShareBuzz()` is called? Indeed, you'd be stuck.
-Another problem with the `DoShareBuzz()` we had is that it can surprise people reading or maintaining the test, as one would expect that `DoShareBuzz()` has (logically) the same contract as `ShareBuzz()`.
-
-Fortunately, these problems can be fixed with a bit more code. Let's try to get it right this time:
-
-```
-class MockBuzzer : public Buzzer {
- public:
- MockBuzzer() {
- // Since DoShareBuzz(buzz, time) is supposed to take ownership of
- // buzz, define a default behavior for DoShareBuzz(buzz, time) to
- // delete buzz.
- ON_CALL(*this, DoShareBuzz(_, _))
- .WillByDefault(Invoke([](Buzz* buzz, Time timestamp) {
- delete buzz;
- return true;
- }));
- }
-
- MOCK_METHOD1(MakeBuzz, std::unique_ptr(const std::string& text));
-
- // Takes ownership of buzz.
- MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp));
- bool ShareBuzz(std::unique_ptr buzz, Time timestamp) {
- return DoShareBuzz(buzz.release(), timestamp);
- }
-};
-```
-
-Now, the mock `DoShareBuzz()` method is free to save the buzz argument for later use if this is what you want:
-
-```
- std::unique_ptr intercepted_buzz;
- EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _))
- .WillOnce(Invoke([&intercepted_buzz](Buzz* buzz, Time timestamp) {
- // Save buzz in intercepted_buzz for analysis later.
- intercepted_buzz.reset(buzz);
- return false;
- }));
-
- mock_buzzer_.ShareBuzz(std::make_unique(AccessLevel::kInternal),
- Now());
- EXPECT_NE(nullptr, intercepted_buzz);
-```
-
-Using the tricks covered in this recipe, you are now able to mock methods that take and/or return move-only types. Put your newly-acquired power to good use - when you design a new API, you can now feel comfortable using `unique_ptrs` as appropriate, without fearing that doing so will compromise your tests.
## Making the Compilation Faster ##
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index 90fd2ea6..a2784f63 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -360,15 +360,21 @@ class Action {
// Constructs a null Action. Needed for storing Action objects in
// STL containers.
- Action() : impl_(NULL) {}
+ Action() {}
- // Constructs an Action from its implementation. A NULL impl is
- // used to represent the "do-default" 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).
+ template , G>::value>::type>
+ Action(G&& fun) : fun_(::std::forward(fun)) {} // NOLINT
+#endif
+
+ // Constructs an Action from its implementation.
explicit Action(ActionInterface* impl) : impl_(impl) {}
- // Copy constructor.
- Action(const Action& action) : impl_(action.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
@@ -377,7 +383,13 @@ class Action {
explicit Action(const Action& action);
// Returns true iff this is the DoDefault() action.
- bool IsDoDefault() const { return impl_.get() == NULL; }
+ 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
// the corresponding method in ActionInterface is not. The reason
@@ -385,14 +397,15 @@ class Action {
// another concrete action, not that the concrete action it binds to
// cannot change state. (Think of the difference between a const
// pointer and a pointer to const.)
- Result Perform(const ArgumentTuple& args) const {
- internal::Assert(
- !IsDoDefault(), __FILE__, __LINE__,
- "You are using DoDefault() inside a composite action like "
- "DoAll() or WithArgs(). This is not supported for technical "
- "reasons. Please instead spell out the default action, or "
- "assign the default action to an Action variable and use "
- "the variable in various places.");
+ Result Perform(ArgumentTuple args) const {
+ 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);
}
@@ -400,6 +413,18 @@ class Action {
template
friend class internal::ActionAdaptor;
+ 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
+ ::std::function fun_;
+#endif
internal::linked_ptr > impl_;
};
@@ -531,6 +556,9 @@ struct ByMoveWrapper {
// statement, and conversion of the result of Return to Action is a
// good place for that.
//
+// The real life example of the above scenario happens when an invocation
+// of gtl::Container() is passed into Return.
+//
template
class ReturnAction {
public:
@@ -750,7 +778,7 @@ class DoDefaultAction {
// This template type conversion operator allows DoDefault() to be
// used in any function.
template
- operator Action() const { return Action(NULL); }
+ operator Action() const { return Action(); } // NOLINT
};
// Implements the Assign action to set a given pointer referent to a
@@ -886,6 +914,28 @@ class InvokeMethodWithoutArgsAction {
GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction);
};
+// Implements the InvokeWithoutArgs(callback) action.
+template
+class InvokeCallbackWithoutArgsAction {
+ public:
+ // The c'tor takes ownership of the callback.
+ explicit InvokeCallbackWithoutArgsAction(CallbackType* callback)
+ : callback_(callback) {
+ callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
+ }
+
+ // This type conversion operator template allows Invoke(callback) to
+ // be used wherever the callback's return type can be implicitly
+ // converted to that of the mock function.
+ template
+ Result Perform(const ArgumentTuple&) const { return callback_->Run(); }
+
+ private:
+ const internal::linked_ptr callback_;
+
+ GTEST_DISALLOW_ASSIGN_(InvokeCallbackWithoutArgsAction);
+};
+
// Implements the IgnoreResult(action) action.
template
class IgnoreResultAction {
@@ -1053,7 +1103,13 @@ typedef internal::IgnoredValue Unused;
template
template
Action::Action(const Action& from)
- : impl_(new internal::ActionAdaptor(from)) {}
+ :
+#if GTEST_LANG_CXX11
+ fun_(from.fun_),
+#endif
+ impl_(from.impl_ == NULL ? NULL
+ : new internal::ActionAdaptor(from)) {
+}
// Creates an action that returns 'value'. 'value' is passed by value
// instead of const reference - otherwise Return("string literal")
diff --git a/googlemock/include/gmock/gmock-generated-actions.h b/googlemock/include/gmock/gmock-generated-actions.h
index be4ebe4f..7728d745 100644
--- a/googlemock/include/gmock/gmock-generated-actions.h
+++ b/googlemock/include/gmock/gmock-generated-actions.h
@@ -1,4 +1,6 @@
-// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+// This file was GENERATED by command:
+// pump.py gmock-generated-actions.h.pump
+// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
@@ -45,8 +47,8 @@ namespace testing {
namespace internal {
// InvokeHelper knows how to unpack an N-tuple and invoke an N-ary
-// function or method with the unpacked values, where F is a function
-// type that takes N arguments.
+// function, method, or callback with the unpacked values, where F is
+// a function type that takes N arguments.
template
class InvokeHelper;
@@ -64,6 +66,12 @@ class InvokeHelper > {
const ::testing::tuple<>&) {
return (obj_ptr->*method_ptr)();
}
+
+ template
+ static R InvokeCallback(CallbackType* callback,
+ const ::testing::tuple<>&) {
+ return callback->Run();
+ }
};
template
@@ -80,6 +88,12 @@ class InvokeHelper > {
const ::testing::tuple& args) {
return (obj_ptr->*method_ptr)(get<0>(args));
}
+
+ template
+ static R InvokeCallback(CallbackType* callback,
+ const ::testing::tuple& args) {
+ return callback->Run(get<0>(args));
+ }
};
template
@@ -96,6 +110,12 @@ class InvokeHelper > {
const ::testing::tuple& args) {
return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args));
}
+
+ template
+ static R InvokeCallback(CallbackType* callback,
+ const ::testing::tuple& args) {
+ return callback->Run(get<0>(args), get<1>(args));
+ }
};
template
@@ -113,6 +133,12 @@ class InvokeHelper > {
return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
get<2>(args));
}
+
+ template
+ static R InvokeCallback(CallbackType* callback,
+ const ::testing::tuple& args) {
+ return callback->Run(get<0>(args), get<1>(args), get<2>(args));
+ }
};
template
@@ -132,6 +158,13 @@ class InvokeHelper > {
return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
get<2>(args), get<3>(args));
}
+
+ template
+ static R InvokeCallback(CallbackType* callback,
+ const ::testing::tuple& args) {
+ return callback->Run(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args));
+ }
};
template > {
return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
get<2>(args), get<3>(args), get<4>(args));
}
+
+ template
+ static R InvokeCallback(CallbackType* callback,
+ const ::testing::tuple& args) {
+ return callback->Run(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args), get<4>(args));
+ }
};
template > {
return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
get<2>(args), get<3>(args), get<4>(args), get<5>(args));
}
+
+ // There is no InvokeCallback() for 6-tuples, as google3 callbacks
+ // support 5 arguments at most.
};
template > {
get<2>(args), get<3>(args), get<4>(args), get<5>(args),
get<6>(args));
}
+
+ // There is no InvokeCallback() for 7-tuples, as google3 callbacks
+ // support 5 arguments at most.
};
template > {
get<2>(args), get<3>(args), get<4>(args), get<5>(args),
get<6>(args), get<7>(args));
}
+
+ // There is no InvokeCallback() for 8-tuples, as google3 callbacks
+ // support 5 arguments at most.
};
template > {
get<2>(args), get<3>(args), get<4>(args), get<5>(args),
get<6>(args), get<7>(args), get<8>(args));
}
+
+ // There is no InvokeCallback() for 9-tuples, as google3 callbacks
+ // support 5 arguments at most.
};
template (args), get<3>(args), get<4>(args), get<5>(args),
get<6>(args), get<7>(args), get<8>(args), get<9>(args));
}
+
+ // There is no InvokeCallback() for 10-tuples, as google3 callbacks
+ // support 5 arguments at most.
+};
+
+// Implements the Invoke(callback) action.
+template
+class InvokeCallbackAction {
+ public:
+ // The c'tor takes ownership of the callback.
+ explicit InvokeCallbackAction(CallbackType* callback)
+ : callback_(callback) {
+ callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
+ }
+
+ // This type conversion operator template allows Invoke(callback) to
+ // be used wherever the callback's type is compatible with that of
+ // the mock function, i.e. if the mock function's arguments can be
+ // implicitly converted to the callback's arguments and the
+ // callback's result can be implicitly converted to the mock
+ // function's result.
+ template
+ Result Perform(const ArgumentTuple& args) const {
+ return InvokeHelper::InvokeCallback(
+ callback_.get(), args);
+ }
+ private:
+ const linked_ptr callback_;
};
// An INTERNAL macro for extracting the type of a tuple field. It's
@@ -1073,52 +1153,90 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
()
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
- (p0##_type gmock_p0) : p0(gmock_p0)
+ (p0##_type gmock_p0) : p0(::testing::internal::move(gmock_p0))
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
- (p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), p1(gmock_p1)
+ (p0##_type gmock_p0, \
+ p1##_type gmock_p1) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1))
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2)
+ p2##_type gmock_p2) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2))
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3)
+ p3##_type gmock_p3) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2)), \
+ p3(::testing::internal::move(gmock_p3))
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4)
+ p3##_type gmock_p3, \
+ p4##_type gmock_p4) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2)), \
+ p3(::testing::internal::move(gmock_p3)), \
+ p4(::testing::internal::move(gmock_p4))
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5)
+ p5##_type gmock_p5) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2)), \
+ p3(::testing::internal::move(gmock_p3)), \
+ p4(::testing::internal::move(gmock_p4)), \
+ p5(::testing::internal::move(gmock_p5))
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6)
+ p6##_type gmock_p6) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2)), \
+ p3(::testing::internal::move(gmock_p3)), \
+ p4(::testing::internal::move(gmock_p4)), \
+ p5(::testing::internal::move(gmock_p5)), \
+ p6(::testing::internal::move(gmock_p6))
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7)
+ p6##_type gmock_p6, \
+ p7##_type gmock_p7) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2)), \
+ p3(::testing::internal::move(gmock_p3)), \
+ p4(::testing::internal::move(gmock_p4)), \
+ p5(::testing::internal::move(gmock_p5)), \
+ p6(::testing::internal::move(gmock_p6)), \
+ p7(::testing::internal::move(gmock_p7))
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8)
+ p8##_type gmock_p8) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2)), \
+ p3(::testing::internal::move(gmock_p3)), \
+ p4(::testing::internal::move(gmock_p4)), \
+ p5(::testing::internal::move(gmock_p5)), \
+ p6(::testing::internal::move(gmock_p6)), \
+ p7(::testing::internal::move(gmock_p7)), \
+ p8(::testing::internal::move(gmock_p8))
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
- p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8), p9(gmock_p9)
+ p9##_type gmock_p9) : p0(::testing::internal::move(gmock_p0)), \
+ p1(::testing::internal::move(gmock_p1)), \
+ p2(::testing::internal::move(gmock_p2)), \
+ p3(::testing::internal::move(gmock_p3)), \
+ p4(::testing::internal::move(gmock_p4)), \
+ p5(::testing::internal::move(gmock_p5)), \
+ p6(::testing::internal::move(gmock_p6)), \
+ p7(::testing::internal::move(gmock_p7)), \
+ p8(::testing::internal::move(gmock_p8)), \
+ p9(::testing::internal::move(gmock_p9))
// Declares the fields for storing the value parameters.
#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()
@@ -1354,7 +1472,8 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
template \
class name##ActionP {\
public:\
- explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
+ explicit name##ActionP(p0##_type gmock_p0) : \
+ p0(::testing::internal::forward(gmock_p0)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1362,7 +1481,8 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
typedef typename ::testing::internal::Function::Result return_type;\
typedef typename ::testing::internal::Function::ArgumentTuple\
args_type;\
- explicit gmock_Impl(p0##_type gmock_p0) : p0(gmock_p0) {}\
+ explicit gmock_Impl(p0##_type gmock_p0) : \
+ p0(::testing::internal::forward(gmock_p0)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1404,8 +1524,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
template \
class name##ActionP2 {\
public:\
- name##ActionP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
- p1(gmock_p1) {}\
+ name##ActionP2(p0##_type gmock_p0, \
+ p1##_type gmock_p1) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1413,8 +1534,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
typedef typename ::testing::internal::Function::Result return_type;\
typedef typename ::testing::internal::Function::ArgumentTuple\
args_type;\
- gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
- p1(gmock_p1) {}\
+ gmock_Impl(p0##_type gmock_p0, \
+ p1##_type gmock_p1) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1460,7 +1582,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
class name##ActionP3 {\
public:\
name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+ p2##_type gmock_p2) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1469,7 +1593,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
typedef typename ::testing::internal::Function::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+ p2##_type gmock_p2) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1519,8 +1645,11 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
class name##ActionP4 {\
public:\
name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3) {}\
+ p2##_type gmock_p2, \
+ p3##_type gmock_p3) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1529,8 +1658,10 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
typedef typename ::testing::internal::Function::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3) {}\
+ p3##_type gmock_p3) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1587,8 +1718,11 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
public:\
name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, \
- p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4) {}\
+ p4##_type gmock_p4) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1597,8 +1731,12 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
typedef typename ::testing::internal::Function::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), \
- p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\
+ p3##_type gmock_p3, \
+ p4##_type gmock_p4) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1657,8 +1795,12 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
public:\
name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
+ p5##_type gmock_p5) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1668,8 +1810,12 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
+ p5##_type gmock_p5) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1731,9 +1877,14 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
public:\
name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
- p6(gmock_p6) {}\
+ p5##_type gmock_p5, \
+ p6##_type gmock_p6) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1743,8 +1894,13 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
+ p6##_type gmock_p6) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1813,9 +1969,14 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, \
- p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7) {}\
+ p7##_type gmock_p7) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)), \
+ p7(::testing::internal::forward(gmock_p7)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1825,9 +1986,15 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), \
- p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \
- p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
+ p6##_type gmock_p6, \
+ p7##_type gmock_p7) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)), \
+ p7(::testing::internal::forward(gmock_p7)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1900,9 +2067,15 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8) {}\
+ p8##_type gmock_p8) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)), \
+ p7(::testing::internal::forward(gmock_p7)), \
+ p8(::testing::internal::forward(gmock_p8)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -1913,9 +2086,15 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7), p8(gmock_p8) {}\
+ p8##_type gmock_p8) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)), \
+ p7(::testing::internal::forward(gmock_p7)), \
+ p8(::testing::internal::forward(gmock_p8)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -1992,9 +2171,17 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
+ p8##_type gmock_p8, \
+ p9##_type gmock_p9) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)), \
+ p7(::testing::internal::forward(gmock_p7)), \
+ p8(::testing::internal::forward(gmock_p8)), \
+ p9(::testing::internal::forward(gmock_p9)) {}\
template \
class gmock_Impl : public ::testing::ActionInterface {\
public:\
@@ -2005,9 +2192,16 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
- p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
+ p9##_type gmock_p9) : p0(::testing::internal::forward(gmock_p0)), \
+ p1(::testing::internal::forward(gmock_p1)), \
+ p2(::testing::internal::forward(gmock_p2)), \
+ p3(::testing::internal::forward(gmock_p3)), \
+ p4(::testing::internal::forward(gmock_p4)), \
+ p5(::testing::internal::forward(gmock_p5)), \
+ p6(::testing::internal::forward(gmock_p6)), \
+ p7(::testing::internal::forward(gmock_p7)), \
+ p8(::testing::internal::forward(gmock_p8)), \
+ p9(::testing::internal::forward(gmock_p9)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper::\
Perform(this, args);\
@@ -2369,7 +2563,7 @@ ACTION_TEMPLATE(ReturnNew,
} // namespace testing
-// Include any custom actions added by the local installation.
+// Include any custom callback actions added by the local installation.
// We must include this header at the end to make sure it can use the
// declarations from this file.
#include "gmock/internal/custom/gmock-generated-actions.h"
diff --git a/googlemock/include/gmock/gmock-generated-actions.h.pump b/googlemock/include/gmock/gmock-generated-actions.h.pump
index 712f65d6..8bafa478 100644
--- a/googlemock/include/gmock/gmock-generated-actions.h.pump
+++ b/googlemock/include/gmock/gmock-generated-actions.h.pump
@@ -1,5 +1,5 @@
$$ -*- mode: c++; -*-
-$$ This is a Pump source file. Please use Pump to convert it to
+$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
@@ -49,12 +49,13 @@ namespace testing {
namespace internal {
// InvokeHelper knows how to unpack an N-tuple and invoke an N-ary
-// function or method with the unpacked values, where F is a function
-// type that takes N arguments.
+// function, method, or callback with the unpacked values, where F is
+// a function type that takes N arguments.
template
class InvokeHelper;
+$var max_callback_arity = 5
$range i 0..n
$for i [[
$range j 1..i
@@ -76,10 +77,48 @@ class InvokeHelper > {
const ::testing::tuple<$as>&$args) {
return (obj_ptr->*method_ptr)($gets);
}
+
+
+$if i <= max_callback_arity [[
+ template
+ static R InvokeCallback(CallbackType* callback,
+ const ::testing::tuple<$as>&$args) {
+ return callback->Run($gets);
+ }
+]] $else [[
+ // There is no InvokeCallback() for $i-tuples, as google3 callbacks
+ // support $max_callback_arity arguments at most.
+]]
+
};
]]
+// Implements the Invoke(callback) action.
+template
+class InvokeCallbackAction {
+ public:
+ // The c'tor takes ownership of the callback.
+ explicit InvokeCallbackAction(CallbackType* callback)
+ : callback_(callback) {
+ callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
+ }
+
+ // This type conversion operator template allows Invoke(callback) to
+ // be used wherever the callback's type is compatible with that of
+ // the mock function, i.e. if the mock function's arguments can be
+ // implicitly converted to the callback's arguments and the
+ // callback's result can be implicitly converted to the mock
+ // function's result.
+ template
+ Result Perform(const ArgumentTuple& args) const {
+ return InvokeHelper::InvokeCallback(
+ callback_.get(), args);
+ }
+ private:
+ const linked_ptr callback_;
+};
+
// An INTERNAL macro for extracting the type of a tuple field. It's
// subject to change without notice - DO NOT USE IN USER CODE!
#define GMOCK_FIELD_(Tuple, N) \
@@ -486,7 +525,7 @@ _VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
- ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]]
+ ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::testing::internal::move(gmock_p$j))]]
]]
@@ -619,7 +658,7 @@ $var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
$range j 0..i-1
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
-$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
+$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::forward