mirror of
https://github.com/google/googletest.git
synced 2025-03-20 10:53:47 +00:00
Add SaveArgByMove
Allows capture of move-only argument types (e.g. AnyInvocable) PiperOrigin-RevId: 725262899 Change-Id: Idcd46e333a42d99ff05d58a1bc57d8791f6d45a6
This commit is contained in:
parent
a866428a78
commit
4a00a24fff
@ -24,7 +24,8 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
|
||||
| :--------------------------------- | :-------------------------------------- |
|
||||
| `Assign(&variable, value)` | Assign `value` to variable. |
|
||||
| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. |
|
||||
| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. |
|
||||
| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by copy-assignment. |
|
||||
| `SaveArgByMove<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by move-assignment. |
|
||||
| `SaveArgPointee<N>(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. |
|
||||
| `SetArgReferee<N>(value)` | Assign `value` to the variable referenced by the `N`-th (0-based) argument. |
|
||||
| `SetArgPointee<N>(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. |
|
||||
|
@ -1720,6 +1720,16 @@ struct SaveArgAction {
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgByMoveAction {
|
||||
Ptr pointer;
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(Args&&... args) const {
|
||||
*pointer = std::move(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgPointeeAction {
|
||||
Ptr pointer;
|
||||
@ -2070,6 +2080,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgByMove<k>(pointer) moves the k-th (0-based) argument of the
|
||||
// mock function into *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
|
@ -59,6 +59,7 @@ using testing::Invoke;
|
||||
using testing::ReturnArg;
|
||||
using testing::ReturnPointee;
|
||||
using testing::SaveArg;
|
||||
using testing::SaveArgByMove;
|
||||
using testing::SaveArgPointee;
|
||||
using testing::SetArgReferee;
|
||||
using testing::Unused;
|
||||
@ -492,6 +493,34 @@ TEST(SaveArgActionTest, WorksForCompatibleType) {
|
||||
EXPECT_EQ('a', result);
|
||||
}
|
||||
|
||||
struct MoveOnly {
|
||||
explicit MoveOnly(int v) : i(v) {}
|
||||
MoveOnly(MoveOnly&& o) {
|
||||
i = o.i;
|
||||
o.i = -1;
|
||||
}
|
||||
MoveOnly& operator=(MoveOnly&& o) {
|
||||
i = o.i;
|
||||
o.i = -1;
|
||||
return *this;
|
||||
}
|
||||
int i;
|
||||
};
|
||||
|
||||
TEST(SaveArgByMoveActionTest, WorksForSameType) {
|
||||
MoveOnly result{0};
|
||||
const Action<void(MoveOnly v)> a1 = SaveArgByMove<0>(&result);
|
||||
a1.Perform(std::make_tuple(MoveOnly{5}));
|
||||
EXPECT_EQ(5, result.i);
|
||||
}
|
||||
|
||||
TEST(SaveArgByMoveActionTest, WorksForCompatibleType) {
|
||||
MoveOnly result{0};
|
||||
const Action<void(bool, MoveOnly)> a1 = SaveArgByMove<1>(&result);
|
||||
a1.Perform(std::make_tuple(true, MoveOnly{7}));
|
||||
EXPECT_EQ(7, result.i);
|
||||
}
|
||||
|
||||
TEST(SaveArgPointeeActionTest, WorksForSameType) {
|
||||
int result = 0;
|
||||
const int value = 5;
|
||||
@ -756,34 +785,34 @@ TEST(InvokeArgumentTest, Functor6) {
|
||||
|
||||
// Tests using InvokeArgument with a 7-ary function.
|
||||
TEST(InvokeArgumentTest, Function7) {
|
||||
Action<std::string(std::string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*))>
|
||||
Action<std::string(std::string (*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
|
||||
EXPECT_EQ("1234567", a.Perform(std::make_tuple(&Concat7)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 8-ary function.
|
||||
TEST(InvokeArgumentTest, Function8) {
|
||||
Action<std::string(std::string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*))>
|
||||
Action<std::string(std::string (*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
|
||||
EXPECT_EQ("12345678", a.Perform(std::make_tuple(&Concat8)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 9-ary function.
|
||||
TEST(InvokeArgumentTest, Function9) {
|
||||
Action<std::string(std::string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*, const char*))>
|
||||
Action<std::string(std::string (*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*, const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||
EXPECT_EQ("123456789", a.Perform(std::make_tuple(&Concat9)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 10-ary function.
|
||||
TEST(InvokeArgumentTest, Function10) {
|
||||
Action<std::string(std::string(*)(
|
||||
Action<std::string(std::string (*)(
|
||||
const char*, const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*, const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
|
||||
|
Loading…
x
Reference in New Issue
Block a user