diff options
author | Marco Poletti <poletti.marco@gmail.com> | 2020-09-20 12:04:41 -0700 |
---|---|---|
committer | Marco Poletti <poletti.marco@gmail.com> | 2020-09-20 12:04:41 -0700 |
commit | 928458857f4b85a0016c2d724486343b4660cb46 (patch) | |
tree | fe8ca51ef92c81b4055d0a5c9082b9b340eef3de | |
parent | c6d389dab4bcdb61ed1a3d9d0500f8d6feca1ecf (diff) | |
download | google-fruit-928458857f4b85a0016c2d724486343b4660cb46.tar.gz |
Support non-assignable (but movable) types in factory arguments when using registerFactory.
-rw-r--r-- | include/fruit/impl/component_functors.defn.h | 8 | ||||
-rwxr-xr-x | tests/test_register_factory.py | 73 |
2 files changed, 77 insertions, 4 deletions
diff --git a/include/fruit/impl/component_functors.defn.h b/include/fruit/impl/component_functors.defn.h index 83ef385..e6778b1 100644 --- a/include/fruit/impl/component_functors.defn.h +++ b/include/fruit/impl/component_functors.defn.h @@ -402,7 +402,7 @@ template <int numAssistedBefore, int numNonAssistedBefore, typename Arg> struct GetAssistedArg<numAssistedBefore, numNonAssistedBefore, Assisted<Arg>> { template <typename InjectedArgsTuple, typename UserProvidedArgsTuple> inline Arg operator()(InjectedArgsTuple&, UserProvidedArgsTuple& user_provided_args) { - return std::get<numAssistedBefore>(user_provided_args); + return std::move(std::get<numAssistedBefore>(user_provided_args)); } }; @@ -437,9 +437,9 @@ struct RegisterFactoryHelper { using Result = Eval<R>; void operator()(FixedSizeVector<ComponentStorageEntry>& entries) { auto function_provider = [](NakedInjectedArgs... args) { - auto injected_args = std::make_tuple(args...); - auto object_provider = [injected_args](NakedUserProvidedArgs... params) mutable { - auto user_provided_args = std::tie(params...); + std::tuple<NakedInjectedArgs...> injected_args{args...}; + auto object_provider = [=](NakedUserProvidedArgs... params) mutable { + std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...}; // These are unused if they are 0-arg tuples. Silence the unused-variable warnings anyway. (void)injected_args; (void)user_provided_args; diff --git a/tests/test_register_factory.py b/tests/test_register_factory.py index 202d18b..8f62946 100755 --- a/tests/test_register_factory.py +++ b/tests/test_register_factory.py @@ -2005,6 +2005,79 @@ class TestRegisterFactory(parameterized.TestCase): source, locals()) + @multiple_parameters([ + ('X()', 'X'), + ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), + ], [ + 'WithNoAnnotation', + 'WithAnnotation1', + ]) + def test_register_factory_with_non_assignable_injected_param_success(self, ConstructX, XPtr, WithAnnot): + source = ''' + struct Y { + Y(const Y&) = delete; + Y& operator=(const Y&) = delete; + + Y() = default; + Y(Y&&) = default; + Y& operator=(Y&&) = default; + }; + struct X {}; + + fruit::Component<WithAnnot<Y>> getYComponent() { + return fruit::createComponent() + .registerConstructor<WithAnnot<Y>()>(); + } + + fruit::Component<std::function<XPtr()>> getComponent() { + return fruit::createComponent() + .install(getYComponent) + .registerFactory<XPtr(WithAnnot<Y&>)>([](Y&){ return ConstructX; }); + } + + int main() { + fruit::Injector<std::function<XPtr()>> injector(getComponent); + XPtr x = injector.get<std::function<XPtr()>>()(); + (void) x; + } + ''' + expect_success( + COMMON_DEFINITIONS, + source, + locals()) + + @multiple_parameters([ + ('X()', 'X'), + ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), + ]) + def test_register_factory_with_non_assignable_assisted_param_success(self, ConstructX, XPtr): + source = ''' + struct Y { + Y(const Y&) = delete; + Y& operator=(const Y&) = delete; + + Y() = default; + Y(Y&&) = default; + Y& operator=(Y&&) = default; + }; + struct X {}; + + fruit::Component<std::function<XPtr(Y)>> getComponent() { + return fruit::createComponent() + .registerFactory<XPtr(fruit::Assisted<Y>)>([](Y){ return ConstructX; }); + } + + int main() { + fruit::Injector<std::function<XPtr(Y)>> injector(getComponent); + XPtr x = injector.get<std::function<XPtr(Y)>>()(Y()); + (void) x; + } + ''' + expect_success( + COMMON_DEFINITIONS, + source, + locals()) + def test_register_factory_requiring_nonconst_then_requiring_const_ok(self): source = ''' struct X {}; |