Skip to content

Commit 4a00a24

Browse files
Abseil Teamcopybara-github
authored andcommitted
Add SaveArgByMove
Allows capture of move-only argument types (e.g. AnyInvocable) PiperOrigin-RevId: 725262899 Change-Id: Idcd46e333a42d99ff05d58a1bc57d8791f6d45a6
1 parent a866428 commit 4a00a24

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

docs/reference/actions.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
2424
| :--------------------------------- | :-------------------------------------- |
2525
| `Assign(&variable, value)` | Assign `value` to variable. |
2626
| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. |
27-
| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. |
27+
| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by copy-assignment. |
28+
| `SaveArgByMove<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by move-assignment. |
2829
| `SaveArgPointee<N>(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. |
2930
| `SetArgReferee<N>(value)` | Assign `value` to the variable referenced by the `N`-th (0-based) argument. |
3031
| `SetArgPointee<N>(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. |

googlemock/include/gmock/gmock-actions.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,16 @@ struct SaveArgAction {
17201720
}
17211721
};
17221722

1723+
template <size_t k, typename Ptr>
1724+
struct SaveArgByMoveAction {
1725+
Ptr pointer;
1726+
1727+
template <typename... Args>
1728+
void operator()(Args&&... args) const {
1729+
*pointer = std::move(std::get<k>(std::tie(args...)));
1730+
}
1731+
};
1732+
17231733
template <size_t k, typename Ptr>
17241734
struct SaveArgPointeeAction {
17251735
Ptr pointer;
@@ -2070,6 +2080,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
20702080
return {pointer};
20712081
}
20722082

2083+
// Action SaveArgByMove<k>(pointer) moves the k-th (0-based) argument of the
2084+
// mock function into *pointer.
2085+
template <size_t k, typename Ptr>
2086+
internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(Ptr pointer) {
2087+
return {pointer};
2088+
}
2089+
20732090
// Action SaveArgPointee<k>(pointer) saves the value pointed to
20742091
// by the k-th (0-based) argument of the mock function to *pointer.
20752092
template <size_t k, typename Ptr>

googlemock/test/gmock-more-actions_test.cc

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ using testing::Invoke;
5959
using testing::ReturnArg;
6060
using testing::ReturnPointee;
6161
using testing::SaveArg;
62+
using testing::SaveArgByMove;
6263
using testing::SaveArgPointee;
6364
using testing::SetArgReferee;
6465
using testing::Unused;
@@ -492,6 +493,34 @@ TEST(SaveArgActionTest, WorksForCompatibleType) {
492493
EXPECT_EQ('a', result);
493494
}
494495

496+
struct MoveOnly {
497+
explicit MoveOnly(int v) : i(v) {}
498+
MoveOnly(MoveOnly&& o) {
499+
i = o.i;
500+
o.i = -1;
501+
}
502+
MoveOnly& operator=(MoveOnly&& o) {
503+
i = o.i;
504+
o.i = -1;
505+
return *this;
506+
}
507+
int i;
508+
};
509+
510+
TEST(SaveArgByMoveActionTest, WorksForSameType) {
511+
MoveOnly result{0};
512+
const Action<void(MoveOnly v)> a1 = SaveArgByMove<0>(&result);
513+
a1.Perform(std::make_tuple(MoveOnly{5}));
514+
EXPECT_EQ(5, result.i);
515+
}
516+
517+
TEST(SaveArgByMoveActionTest, WorksForCompatibleType) {
518+
MoveOnly result{0};
519+
const Action<void(bool, MoveOnly)> a1 = SaveArgByMove<1>(&result);
520+
a1.Perform(std::make_tuple(true, MoveOnly{7}));
521+
EXPECT_EQ(7, result.i);
522+
}
523+
495524
TEST(SaveArgPointeeActionTest, WorksForSameType) {
496525
int result = 0;
497526
const int value = 5;
@@ -756,34 +785,34 @@ TEST(InvokeArgumentTest, Functor6) {
756785

757786
// Tests using InvokeArgument with a 7-ary function.
758787
TEST(InvokeArgumentTest, Function7) {
759-
Action<std::string(std::string(*)(const char*, const char*, const char*,
760-
const char*, const char*, const char*,
761-
const char*))>
788+
Action<std::string(std::string (*)(const char*, const char*, const char*,
789+
const char*, const char*, const char*,
790+
const char*))>
762791
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
763792
EXPECT_EQ("1234567", a.Perform(std::make_tuple(&Concat7)));
764793
}
765794

766795
// Tests using InvokeArgument with a 8-ary function.
767796
TEST(InvokeArgumentTest, Function8) {
768-
Action<std::string(std::string(*)(const char*, const char*, const char*,
769-
const char*, const char*, const char*,
770-
const char*, const char*))>
797+
Action<std::string(std::string (*)(const char*, const char*, const char*,
798+
const char*, const char*, const char*,
799+
const char*, const char*))>
771800
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
772801
EXPECT_EQ("12345678", a.Perform(std::make_tuple(&Concat8)));
773802
}
774803

775804
// Tests using InvokeArgument with a 9-ary function.
776805
TEST(InvokeArgumentTest, Function9) {
777-
Action<std::string(std::string(*)(const char*, const char*, const char*,
778-
const char*, const char*, const char*,
779-
const char*, const char*, const char*))>
806+
Action<std::string(std::string (*)(const char*, const char*, const char*,
807+
const char*, const char*, const char*,
808+
const char*, const char*, const char*))>
780809
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
781810
EXPECT_EQ("123456789", a.Perform(std::make_tuple(&Concat9)));
782811
}
783812

784813
// Tests using InvokeArgument with a 10-ary function.
785814
TEST(InvokeArgumentTest, Function10) {
786-
Action<std::string(std::string(*)(
815+
Action<std::string(std::string (*)(
787816
const char*, const char*, const char*, const char*, const char*,
788817
const char*, const char*, const char*, const char*, const char*))>
789818
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");

0 commit comments

Comments
 (0)