From 4deaddc0e15d4b94b02b069b5bc0a1eb7cc7141e Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 21 Jun 2022 09:08:59 +1000 Subject: [PATCH 1/9] Take copy or return value if explicit by value used, when mocking return for return by ref or const ref function. --- include/fakeit/ActionSequence.hpp | 4 ++++ include/fakeit/StubbingProgress.hpp | 2 +- tests/referece_types_tests.cpp | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/fakeit/ActionSequence.hpp b/include/fakeit/ActionSequence.hpp index fb43808a..d7efe56b 100644 --- a/include/fakeit/ActionSequence.hpp +++ b/include/fakeit/ActionSequence.hpp @@ -44,7 +44,10 @@ namespace fakeit { Action &action = dynamic_cast &>(destructable); std::function finallyClause = [&]() -> void { if (action.isDone()) + { _recordedActions.erase(_recordedActions.begin()); + _usedActions.push_back(destructablePtr); + } }; Finally onExit(finallyClause); return action.invoke(args); @@ -81,6 +84,7 @@ namespace fakeit { } std::vector> _recordedActions; + std::vector> _usedActions; }; } diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index f4981695..885c78ec 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -50,7 +50,7 @@ namespace fakeit { template typename std::enable_if::value, MethodStubbingProgress &>::type Return(const R &r) { - return Do([r](const typename fakeit::test_arg::type...) -> R { return r; }); + return Do([r](const typename fakeit::test_arg::type...) mutable -> R { return r; }); } template diff --git a/tests/referece_types_tests.cpp b/tests/referece_types_tests.cpp index 31e6852e..140e4b1e 100644 --- a/tests/referece_types_tests.cpp +++ b/tests/referece_types_tests.cpp @@ -40,6 +40,8 @@ struct ReferenceTypesTests: tpunit::TestFixture { virtual int& returnIntByRef() = 0; virtual AbstractType& returnAbstractTypeByRef() = 0; virtual ConcreteType& returnConcreteTypeByRef() = 0; + virtual const std::string& returnStringByConstRef() = 0; + }; ReferenceTypesTests() : @@ -47,6 +49,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { // TEST(ReferenceTypesTests::implicitStubbingDefaultReturnValues), TEST(ReferenceTypesTests::explicitStubbingDefualtReturnValues), + TEST(ReferenceTypesTests::explicitStubbingReturnValuesForceCopyForConstRef), TEST(ReferenceTypesTests::explicitStubbingDefualtReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_by_assignment), @@ -121,6 +124,30 @@ struct ReferenceTypesTests: tpunit::TestFixture { ASSERT_EQUAL(&c, &i.returnAbstractTypeByRef()); } + void explicitStubbingReturnValuesForceCopyForConstRef() { + Mock mock; + + // add scope so we know we are copying + { + std::string a_string{"myString"}; + int num{ 1 }; + + // explicit copy here + When(Method(mock, returnStringByConstRef)).Return(a_string); + When(Method(mock, returnIntByRef)).Return(num); + + // modify now so know whether or not is was copied + a_string = "modified"; + num = 2; + } + + ReferenceInterface& i = mock.get(); + + // Fundamental types are initiated to 0. + ASSERT_EQUAL("myString", i.returnStringByConstRef()); + ASSERT_EQUAL(1, i.returnIntByRef()); + } + void explicitStubbingReturnValues_with_AlwaysReturn() { Mock mock; // From f4004430d48c83495a1caee93b9c1681ad19e64a Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 21 Jun 2022 17:36:40 +1000 Subject: [PATCH 2/9] fix typos --- tests/referece_types_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/referece_types_tests.cpp b/tests/referece_types_tests.cpp index 140e4b1e..428b3324 100644 --- a/tests/referece_types_tests.cpp +++ b/tests/referece_types_tests.cpp @@ -48,9 +48,9 @@ struct ReferenceTypesTests: tpunit::TestFixture { tpunit::TestFixture( // TEST(ReferenceTypesTests::implicitStubbingDefaultReturnValues), - TEST(ReferenceTypesTests::explicitStubbingDefualtReturnValues), + TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues), TEST(ReferenceTypesTests::explicitStubbingReturnValuesForceCopyForConstRef), - TEST(ReferenceTypesTests::explicitStubbingDefualtReturnValues_with_AlwaysReturn), + TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_by_assignment), TEST(ReferenceTypesTests::explicitStubbingReturnValues) @@ -80,7 +80,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { ASSERT_EQUAL(nullptr, &i.returnAbstractTypeByRef()); } - void explicitStubbingDefualtReturnValues() { + void explicitStubbingDefaultReturnValues() { Mock mock; // When(Method(mock,returnIntByRef)).Return(); // When(Method(mock,returnAbstractTypeByRef)).Return(); // @@ -196,7 +196,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { ASSERT_EQUAL(&c, &i.returnAbstractTypeByRef()); } - void explicitStubbingDefualtReturnValues_with_AlwaysReturn() { + void explicitStubbingDefaultReturnValues_with_AlwaysReturn() { Mock mock; When(Method(mock,returnIntByRef)).AlwaysReturn(); When(Method(mock,returnAbstractTypeByRef)).AlwaysReturn(); // From 6820aeb1a4fdc2adccef42e33dc6e2342850ca3d Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Wed, 22 Jun 2022 22:31:40 +1000 Subject: [PATCH 3/9] Handle automatically for temporaries --- include/fakeit/StubbingProgress.hpp | 9 ++++++++ tests/referece_types_tests.cpp | 33 +++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index 885c78ec..0bbd7f5b 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -53,6 +53,15 @@ namespace fakeit { return Do([r](const typename fakeit::test_arg::type...) mutable -> R { return r; }); } + template + typename std::enable_if::value&& std::is_copy_constructible::value, MethodStubbingProgress&>::type + Return(T&& t) { + auto store = std::make_shared(std::move(t)); + return Do([store = std::move(store)](const typename fakeit::test_arg::type...) mutable->R + { + return *store; + }); + } template typename std::enable_if::value, MethodStubbingProgress &>::type Return(const R &r) { diff --git a/tests/referece_types_tests.cpp b/tests/referece_types_tests.cpp index 428b3324..10f3941a 100644 --- a/tests/referece_types_tests.cpp +++ b/tests/referece_types_tests.cpp @@ -24,8 +24,8 @@ struct ReferenceTypesTests: tpunit::TestFixture { class ConcreteType: public AbstractType { public: int state; - ConcreteType() : - state(10) { + ConcreteType(int value = 10) : + state(value) { } virtual void foo() override { } @@ -41,7 +41,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { virtual AbstractType& returnAbstractTypeByRef() = 0; virtual ConcreteType& returnConcreteTypeByRef() = 0; virtual const std::string& returnStringByConstRef() = 0; - + virtual std::string& returnStringByRef() = 0; }; ReferenceTypesTests() : @@ -49,7 +49,8 @@ struct ReferenceTypesTests: tpunit::TestFixture { // TEST(ReferenceTypesTests::implicitStubbingDefaultReturnValues), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues), - TEST(ReferenceTypesTests::explicitStubbingReturnValuesForceCopyForConstRef), + TEST(ReferenceTypesTests::explicitStubbingReturnValuesForceCopyForRef), + TEST(ReferenceTypesTests::explicitStubbingReturnValuesCopyForRRef), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_by_assignment), @@ -124,7 +125,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { ASSERT_EQUAL(&c, &i.returnAbstractTypeByRef()); } - void explicitStubbingReturnValuesForceCopyForConstRef() { + void explicitStubbingReturnValuesForceCopyForRef() { Mock mock; // add scope so we know we are copying @@ -144,8 +145,26 @@ struct ReferenceTypesTests: tpunit::TestFixture { ReferenceInterface& i = mock.get(); // Fundamental types are initiated to 0. - ASSERT_EQUAL("myString", i.returnStringByConstRef()); - ASSERT_EQUAL(1, i.returnIntByRef()); + EXPECT_EQUAL("myString", i.returnStringByConstRef()); + EXPECT_EQUAL(1, i.returnIntByRef()); + } + + void explicitStubbingReturnValuesCopyForRRef() { + Mock mock; + + { + When(Method(mock, returnStringByConstRef)).Return(std::string{ "myConstRefString" }); + When(Method(mock, returnStringByRef)).Return(std::string{ "myRefString" }); + When(Method(mock, returnConcreteTypeByRef)).Return(ConcreteType(20)); + When(Method(mock, returnIntByRef)).Return(1); + } + + ReferenceInterface& i = mock.get(); + + EXPECT_EQUAL("myConstRefString", i.returnStringByConstRef()); + EXPECT_EQUAL("myRefString", i.returnStringByRef()); + EXPECT_EQUAL(ConcreteType(20), i.returnConcreteTypeByRef()); + EXPECT_EQUAL(1, i.returnIntByRef()); } void explicitStubbingReturnValues_with_AlwaysReturn() { From fce1dd8249dd9cfd736556f5da6b5759e18f30e4 Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 28 Jun 2022 09:13:52 +1000 Subject: [PATCH 4/9] Remove optional move (which was just an optimisation), so we can support C++11 --- include/fakeit/StubbingProgress.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index 0bbd7f5b..6b6a9ea2 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -57,7 +57,7 @@ namespace fakeit { typename std::enable_if::value&& std::is_copy_constructible::value, MethodStubbingProgress&>::type Return(T&& t) { auto store = std::make_shared(std::move(t)); - return Do([store = std::move(store)](const typename fakeit::test_arg::type...) mutable->R + return Do([store](const typename fakeit::test_arg::type...) mutable->R { return *store; }); From 4e91eef19e5a020caff53106037f416e6f19a121 Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 19 Jul 2022 09:43:38 +1000 Subject: [PATCH 5/9] Add ReturnCopy --- include/fakeit/StubbingProgress.hpp | 8 +++++++- tests/referece_types_tests.cpp | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index 6b6a9ea2..1fea493b 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -54,7 +54,7 @@ namespace fakeit { } template - typename std::enable_if::value&& std::is_copy_constructible::value, MethodStubbingProgress&>::type + typename std::enable_if::value && std::is_copy_constructible::value, MethodStubbingProgress&>::type Return(T&& t) { auto store = std::make_shared(std::move(t)); return Do([store](const typename fakeit::test_arg::type...) mutable->R @@ -62,12 +62,18 @@ namespace fakeit { return *store; }); } + template typename std::enable_if::value, MethodStubbingProgress &>::type Return(const R &r) { return Do([&r](const typename fakeit::test_arg::type...) -> R { return r; }); } + typename std::enable_if::value, MethodStubbingProgress&>::type + ReturnCopy(const R& r) { + return Do([r](const typename fakeit::test_arg::type...) mutable -> R { return r; }); + } + MethodStubbingProgress & Return(const Quantifier &q) { const R &value = q.value; diff --git a/tests/referece_types_tests.cpp b/tests/referece_types_tests.cpp index 10f3941a..0a35b932 100644 --- a/tests/referece_types_tests.cpp +++ b/tests/referece_types_tests.cpp @@ -49,7 +49,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { // TEST(ReferenceTypesTests::implicitStubbingDefaultReturnValues), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues), - TEST(ReferenceTypesTests::explicitStubbingReturnValuesForceCopyForRef), + TEST(ReferenceTypesTests::explicitStubbingReturnCopyValuesForRef), TEST(ReferenceTypesTests::explicitStubbingReturnValuesCopyForRRef), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_with_AlwaysReturn), @@ -125,7 +125,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { ASSERT_EQUAL(&c, &i.returnAbstractTypeByRef()); } - void explicitStubbingReturnValuesForceCopyForRef() { + void explicitStubbingReturnCopyValuesForRef() { Mock mock; // add scope so we know we are copying @@ -134,8 +134,8 @@ struct ReferenceTypesTests: tpunit::TestFixture { int num{ 1 }; // explicit copy here - When(Method(mock, returnStringByConstRef)).Return(a_string); - When(Method(mock, returnIntByRef)).Return(num); + When(Method(mock, returnStringByConstRef)).ReturnCopy(a_string); + When(Method(mock, returnIntByRef)).ReturnCopy(num); // modify now so know whether or not is was copied a_string = "modified"; From e856beef9c720f3713bb3d1c463a7a2ad1141d2d Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 19 Jul 2022 10:20:45 +1000 Subject: [PATCH 6/9] Always Return Copy --- include/fakeit/StubbingProgress.hpp | 5 +++++ tests/referece_types_tests.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index 1fea493b..44941d92 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -101,6 +101,11 @@ namespace fakeit { return AlwaysDo([&r](const typename fakeit::test_arg::type...) -> R { return r; }); } + typename std::enable_if::value, void>::type + AlwaysReturnCopy(const R& r) { + return AlwaysDo([r](const typename fakeit::test_arg::type...) mutable -> R { return r; }); + } + MethodStubbingProgress & Return() { return Do([](const typename fakeit::test_arg::type...) -> R { return DefaultValue::value(); }); diff --git a/tests/referece_types_tests.cpp b/tests/referece_types_tests.cpp index 0a35b932..1bc21e89 100644 --- a/tests/referece_types_tests.cpp +++ b/tests/referece_types_tests.cpp @@ -53,6 +53,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { TEST(ReferenceTypesTests::explicitStubbingReturnValuesCopyForRRef), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_with_AlwaysReturn), + TEST(ReferenceTypesTests::explicitStubbingReturnCopyValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_by_assignment), TEST(ReferenceTypesTests::explicitStubbingReturnValues) // @@ -190,6 +191,33 @@ struct ReferenceTypesTests: tpunit::TestFixture { // For abstract types return a reference to nullptr. ASSERT_EQUAL(&c, &i.returnAbstractTypeByRef()); } + + void explicitStubbingReturnCopyValues_with_AlwaysReturn() { + Mock mock; + + // add scope so we know we are copying + { + std::string a_string{ "myString" }; + int num{ 1 }; + + // explicit copy here + When(Method(mock, returnStringByConstRef)).AlwaysReturnCopy(a_string); + When(Method(mock, returnIntByRef)).AlwaysReturnCopy(num); + + // modify now so know whether or not is was copied + a_string = "modified"; + num = 2; + } + + ReferenceInterface& i = mock.get(); + + // Fundamental types are initiated to 0. + EXPECT_EQUAL("myString", i.returnStringByConstRef()); + EXPECT_EQUAL("myString", i.returnStringByConstRef()); + + EXPECT_EQUAL(1, i.returnIntByRef()); + EXPECT_EQUAL(1, i.returnIntByRef()); + } void explicitStubbingReturnValues_by_assignment() { Mock mock; // From deb971448d35a65bc1ab6e01dd494efad20ba937 Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 19 Jul 2022 11:24:25 +1000 Subject: [PATCH 7/9] All RRef for AlwaysReturn for Ref args --- include/fakeit/StubbingProgress.hpp | 10 ++++++++++ tests/referece_types_tests.cpp | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index 44941d92..bd785b2d 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -95,6 +95,16 @@ namespace fakeit { return AlwaysDo([r](const typename fakeit::test_arg::type...) -> R { return r; }); } + template + typename std::enable_if::value&& std::is_copy_constructible::value, MethodStubbingProgress&>::type + AlwaysReturn(T&& t) { + auto store = std::make_shared(std::move(t)); + return Do([store](const typename fakeit::test_arg::type...) mutable->R + { + return *store; + }); + } + template typename std::enable_if::value, void>::type AlwaysReturn(const R &r) { diff --git a/tests/referece_types_tests.cpp b/tests/referece_types_tests.cpp index 1bc21e89..457ce225 100644 --- a/tests/referece_types_tests.cpp +++ b/tests/referece_types_tests.cpp @@ -53,6 +53,7 @@ struct ReferenceTypesTests: tpunit::TestFixture { TEST(ReferenceTypesTests::explicitStubbingReturnValuesCopyForRRef), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_with_AlwaysReturn), + TEST(ReferenceTypesTests::explicitStubbingReturnCopyValuesForRef_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnCopyValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_by_assignment), TEST(ReferenceTypesTests::explicitStubbingReturnValues) @@ -168,6 +169,24 @@ struct ReferenceTypesTests: tpunit::TestFixture { EXPECT_EQUAL(1, i.returnIntByRef()); } + void explicitStubbingReturnCopyValuesForRef_with_AlwaysReturn() { + Mock mock; + + { + When(Method(mock, returnStringByConstRef)).AlwaysReturn(std::string{ "myConstRefString" }); + When(Method(mock, returnStringByRef)).AlwaysReturn(std::string{ "myRefString" }); + When(Method(mock, returnConcreteTypeByRef)).AlwaysReturn(ConcreteType(20)); + When(Method(mock, returnIntByRef)).AlwaysReturn(1); + } + + ReferenceInterface& i = mock.get(); + + EXPECT_EQUAL("myConstRefString", i.returnStringByConstRef()); + EXPECT_EQUAL("myRefString", i.returnStringByRef()); + EXPECT_EQUAL(ConcreteType(20), i.returnConcreteTypeByRef()); + EXPECT_EQUAL(1, i.returnIntByRef()); + } + void explicitStubbingReturnValues_with_AlwaysReturn() { Mock mock; // From a3b6b2d67c5d124effee1c2771af8807b2ea650b Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 19 Jul 2022 11:40:11 +1000 Subject: [PATCH 8/9] Fix up to work with newer move only return tests. --- include/fakeit/StubbingProgress.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index f09291d0..bc157e97 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -55,7 +55,7 @@ namespace fakeit { template typename std::enable_if::value && std::is_copy_constructible::value, MethodStubbingProgress&>::type - Return(T&& t) { + Return(T&& t) { auto store = std::make_shared(std::move(t)); return Do([store](const typename fakeit::test_arg::type...) mutable->R { @@ -71,14 +71,15 @@ namespace fakeit { template typename std::enable_if::value, MethodStubbingProgress&>::type - Return(R&& r) { + Return(R&& r) { auto store = std::make_shared(std::move(r)); // work around for lack of move_only_funciton( C++23) - move into a shared_ptr which we can copy. return Do([store](const typename fakeit::test_arg::type...) mutable -> R { return std::move(*store); - }); + }); } - typename std::enable_if::value, MethodStubbingProgress&>::type + template + typename std::enable_if::value, MethodStubbingProgress&>::type ReturnCopy(const R& r) { return Do([r](const typename fakeit::test_arg::type...) mutable -> R { return r; }); } @@ -120,7 +121,8 @@ namespace fakeit { return AlwaysDo([&r](const typename fakeit::test_arg::type...) -> R { return r; }); } - typename std::enable_if::value, void>::type + template + typename std::enable_if::value, void>::type AlwaysReturnCopy(const R& r) { return AlwaysDo([r](const typename fakeit::test_arg::type...) mutable -> R { return r; }); } From 36ad3e6a6ca4520714b6a927ae0196e773587fe0 Mon Sep 17 00:00:00 2001 From: Malcolm Davey Date: Tue, 19 Jul 2022 12:25:53 +1000 Subject: [PATCH 9/9] Fix mistake in new AlwaysReturn --- include/fakeit/StubbingProgress.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index bc157e97..266f23f2 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -106,10 +106,10 @@ namespace fakeit { } template - typename std::enable_if::value&& std::is_copy_constructible::value, MethodStubbingProgress&>::type + typename std::enable_if::value && std::is_copy_constructible::value, void>::type AlwaysReturn(T&& t) { auto store = std::make_shared(std::move(t)); - return Do([store](const typename fakeit::test_arg::type...) mutable->R + return AlwaysDo([store](const typename fakeit::test_arg::type...) mutable -> R { return *store; });