aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Poletti <poletti.marco@gmail.com>2020-09-20 12:04:41 -0700
committerMarco Poletti <poletti.marco@gmail.com>2020-09-20 12:04:41 -0700
commit928458857f4b85a0016c2d724486343b4660cb46 (patch)
treefe8ca51ef92c81b4055d0a5c9082b9b340eef3de
parentc6d389dab4bcdb61ed1a3d9d0500f8d6feca1ecf (diff)
downloadgoogle-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.h8
-rwxr-xr-xtests/test_register_factory.py73
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 {};