diff options
author | Marco Poletti <poletti.marco@gmail.com> | 2014-08-19 22:03:17 +0200 |
---|---|---|
committer | Marco Poletti <poletti.marco@gmail.com> | 2014-08-19 22:03:17 +0200 |
commit | 80cfec6c278066d7758cc1d46475af9f5db01589 (patch) | |
tree | cd44c522366e639b47fa2b0214e057c3c03abc9f /include | |
parent | 09fa583bbe4ac587818f1673e6b2dd9bd3459d8a (diff) | |
download | google-fruit-80cfec6c278066d7758cc1d46475af9f5db01589.tar.gz |
Add injection support for unique_ptr for non-movable types.
Diffstat (limited to 'include')
-rw-r--r-- | include/fruit/component.h | 46 | ||||
-rw-r--r-- | include/fruit/fruit_forward_decls.h | 10 | ||||
-rw-r--r-- | include/fruit/impl/component.templates.h | 63 | ||||
-rw-r--r-- | include/fruit/impl/component.utils.h | 27 | ||||
-rw-r--r-- | include/fruit/impl/component_impl.h | 10 | ||||
-rw-r--r-- | include/fruit/impl/component_storage.h | 11 | ||||
-rw-r--r-- | include/fruit/impl/component_storage.templates.h | 90 |
7 files changed, 203 insertions, 54 deletions
diff --git a/include/fruit/component.h b/include/fruit/component.h index ff838f9..ee5eb64 100644 --- a/include/fruit/component.h +++ b/include/fruit/component.h @@ -102,9 +102,9 @@ public: } /** - * Registers `provider' as a provider of C, where provider is a function - * returning either C or C* (returning C* is preferable). A lambda with no captures - * can be used as a function. + * Registers `provider' as a provider of C, where provider is a function returning either C or C* + * (prefer returning a C by value instead of allocating a C using `new C', if possible). + * A lambda with no captures can be used as a function. * When an instance of C is needed, the arguments of the provider will be injected * and the provider will be called to create the instance of C, that will then be * stored in the injector. @@ -115,9 +115,9 @@ public: * Example: * * registerProvider([](U* u, V* v) { - * C* c = new C(u, v); - * c->initialize(); - * return c; + * C c(u, v); + * c.initialize(); + * return std::move(c); * }) * * As in the previous example, it's not necessary to specify the signature, it will @@ -185,8 +185,8 @@ public: } /** - * Registers `factory' as a factory of C, where `factory' is a function returning either C or C* - * (returning C* is preferable). A lambda with no captures can be used as a function. + * Registers `factory' as a factory of C, where `factory' is a function returning C. + * A lambda with no captures can be used as a function. * * Returns a PartialComponent (usually with different type arguments). * @@ -199,10 +199,10 @@ public: * As in the previous example, this is usually used for assisted injection. Unlike * registerProvider, where the signature is inferred, for this method the signature * must be specified explicitly. - * This is usually used for assisted injection: some parameters are marked as Assisted + * This can be used for assisted injection: some parameters are marked as Assisted * and are not injected. Instead of calling injector.get<C*>(), in this example we will - * call injector.get<std::function<C(U*)>() (or we will declare std::function<C(U*)> as - * an injected parameter to another provider or class). + * call injector.get<std::function<C(U*)>(), or we will declare std::function<C(U*)> as + * an injected parameter to another provider or class. * * If the only thing that the factory does is to call the constructor of C, it's usually * more convenient to use an Inject typedef or INJECT macro instead, e.g.: @@ -232,11 +232,27 @@ public: * and returns a C*. */ template <typename AnnotatedSignature> - fruit::impl::FunctorResult<fruit::impl::RegisterFactory<This, AnnotatedSignature>, + fruit::impl::FunctorResult<fruit::impl::RegisterFactoryForValue<This, AnnotatedSignature>, This&&, - fruit::impl::RequiredSignatureForAssistedFactory<AnnotatedSignature>*> - registerFactory(fruit::impl::RequiredSignatureForAssistedFactory<AnnotatedSignature>* factory) && { - return fruit::impl::RegisterFactory<This, AnnotatedSignature>()(std::move(*this), factory); + fruit::impl::ConstructSignature<fruit::impl::SignatureType<AnnotatedSignature>, + fruit::impl::RequiredArgsForAssistedFactory<AnnotatedSignature>>> + registerFactory(fruit::impl::ConstructSignature<fruit::impl::SignatureType<AnnotatedSignature>, + fruit::impl::RequiredArgsForAssistedFactory<AnnotatedSignature>>* factory) && { + return fruit::impl::RegisterFactoryForValue<This, AnnotatedSignature>()(std::move(*this), factory); + } + + /** + * Similar to the previous one, but takes a provider that returns a unique_ptr<C>, and injects + * an std::function that also returns unique_ptr<C>. + */ + template <typename AnnotatedSignature> + fruit::impl::FunctorResult<fruit::impl::RegisterFactoryForPointer<This, AnnotatedSignature>, + This&&, + fruit::impl::ConstructSignature<std::unique_ptr<fruit::impl::SignatureType<AnnotatedSignature>>, + fruit::impl::RequiredArgsForAssistedFactory<AnnotatedSignature>>> + registerFactory(fruit::impl::ConstructSignature<std::unique_ptr<fruit::impl::SignatureType<AnnotatedSignature>>, + fruit::impl::RequiredArgsForAssistedFactory<AnnotatedSignature>>* factory) && { + return fruit::impl::RegisterFactoryForPointer<This, AnnotatedSignature>()(std::move(*this), factory); } /** diff --git a/include/fruit/fruit_forward_decls.h b/include/fruit/fruit_forward_decls.h index b4531a5..011f929 100644 --- a/include/fruit/fruit_forward_decls.h +++ b/include/fruit/fruit_forward_decls.h @@ -58,7 +58,10 @@ template <typename Comp, typename Signature> struct RegisterMultibindingProvider; template <typename Comp, typename AnnotatedSignature> -struct RegisterFactory; +struct RegisterFactoryForValue; + +template <typename Comp, typename AnnotatedSignature> +struct RegisterFactoryForPointer; template <typename Comp, typename C> struct RegisterInstance; @@ -70,7 +73,10 @@ template <typename Comp, typename Signature> struct RegisterConstructor; template <typename Comp, typename AnnotatedSignature> -struct RegisterConstructorAsFactory; +struct RegisterConstructorAsValueFactory; + +template <typename Comp, typename AnnotatedSignature> +struct RegisterConstructorAsPointerFactory; template <typename Comp, typename OtherComp> struct InstallComponent; diff --git a/include/fruit/impl/component.templates.h b/include/fruit/impl/component.templates.h index 4d20970..dab54fa 100644 --- a/include/fruit/impl/component.templates.h +++ b/include/fruit/impl/component.templates.h @@ -209,7 +209,26 @@ struct AutoRegisterFactoryHelper<Comp, TargetRequirements, false, false, std::un } }; -// C has an Inject typedef, use it. +// C has an Inject typedef, use it. unique_ptr case. +// TODO: Doesn't work after renaming Argz->Args, consider minimizing the test case and filing a bug. +template <typename Comp, typename TargetRequirements, typename C, typename... Argz> +struct AutoRegisterFactoryHelper<Comp, TargetRequirements, false, true, std::unique_ptr<C>, Argz...> { + using AnnotatedSignature = typename GetInjectAnnotation<C>::Signature; + FruitDelegateCheck(CheckSameParametersInInjectionAnnotation< + std::unique_ptr<C>, + List<Argz...>, + RemoveNonAssisted<SignatureArgs<AnnotatedSignature>>>); + using NonAssistedArgs = RemoveAssisted<SignatureArgs<AnnotatedSignature>>; + using RegisterC = RegisterConstructorAsPointerFactory<Comp, AnnotatedSignature>; + using Comp1 = FunctorResult<RegisterC, Comp&&>; + using AutoRegisterArgs = EnsureProvidedTypes<Comp1, TargetRequirements, ExpandProvidersInParams<NonAssistedArgs>>; + using Comp2 = FunctorResult<AutoRegisterArgs, Comp1&&>; + Comp2 operator()(Comp&& m) { + return AutoRegisterArgs()(RegisterC()(std::move(m))); + } +}; + +// C has an Inject typedef, use it. Value (not unique_ptr) case. // TODO: Doesn't work after renaming Argz->Args, consider minimizing the test case and filing a bug. template <typename Comp, typename TargetRequirements, typename C, typename... Argz> struct AutoRegisterFactoryHelper<Comp, TargetRequirements, false, true, C, Argz...> { @@ -219,7 +238,7 @@ struct AutoRegisterFactoryHelper<Comp, TargetRequirements, false, true, C, Argz. List<Argz...>, RemoveNonAssisted<SignatureArgs<AnnotatedSignature>>>); using NonAssistedArgs = RemoveAssisted<SignatureArgs<AnnotatedSignature>>; - using RegisterC = RegisterConstructorAsFactory<Comp, AnnotatedSignature>; + using RegisterC = RegisterConstructorAsValueFactory<Comp, AnnotatedSignature>; using Comp1 = FunctorResult<RegisterC, Comp&&>; using AutoRegisterArgs = EnsureProvidedTypes<Comp1, TargetRequirements, ExpandProvidersInParams<NonAssistedArgs>>; using Comp2 = FunctorResult<AutoRegisterArgs, Comp1&&>; @@ -338,9 +357,22 @@ struct RegisterMultibindingProvider<Comp, T(Args...)> { }; template <typename Comp, typename AnnotatedSignature> -struct RegisterFactory { - using InjectedFunctionType = InjectedFunctionTypeForAssistedFactory<AnnotatedSignature>; - using RequiredSignature = RequiredSignatureForAssistedFactory<AnnotatedSignature>; +struct RegisterFactoryForValue { + using InjectedFunctionType = ConstructSignature<SignatureType<AnnotatedSignature>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>; + using RequiredSignature = ConstructSignature<SignatureType<AnnotatedSignature>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; + using NewRequirements = ExpandProvidersInParams<ExtractRequirementsFromAssistedParams<SignatureArgs<AnnotatedSignature>>>; + using Comp1 = AddRequirements<Comp, NewRequirements>; + using Comp2 = AddProvide<Comp1, std::function<InjectedFunctionType>, NewRequirements>; + Comp2 operator()(Comp&& m, RequiredSignature* factory) { + m.storage.template registerFactory<AnnotatedSignature>(factory); + return std::move(m.storage); + } +}; + +template <typename Comp, typename AnnotatedSignature> +struct RegisterFactoryForPointer { + using InjectedFunctionType = ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>; + using RequiredSignature = ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; using NewRequirements = ExpandProvidersInParams<ExtractRequirementsFromAssistedParams<SignatureArgs<AnnotatedSignature>>>; using Comp1 = AddRequirements<Comp, NewRequirements>; using Comp2 = AddProvide<Comp1, std::function<InjectedFunctionType>, NewRequirements>; @@ -383,13 +415,24 @@ struct AddInstanceMultibinding { }; template <typename Comp, typename AnnotatedSignature> -struct RegisterConstructorAsFactory { - using RequiredSignature = RequiredSignatureForAssistedFactory<AnnotatedSignature>; - using Provider = decltype(ConstructorFactoryProvider<RequiredSignature>::f); - using RegisterFactoryOperation = RegisterFactory<Comp, AnnotatedSignature>; +struct RegisterConstructorAsValueFactory { + using RequiredSignature = ConstructSignature<SignatureType<AnnotatedSignature>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; + using Provider = decltype(ConstructorFactoryValueProvider<RequiredSignature>::f); + using RegisterFactoryOperation = RegisterFactoryForValue<Comp, AnnotatedSignature>; + using Comp1 = FunctorResult<RegisterFactoryOperation, Comp&&, Provider*>; + Comp1 operator()(Comp&& m) { + return RegisterFactoryOperation()(std::move(m), ConstructorFactoryValueProvider<RequiredSignature>::f); + }; +}; + +template <typename Comp, typename AnnotatedSignature> +struct RegisterConstructorAsPointerFactory { + using RequiredSignature = ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; + using Provider = decltype(ConstructorFactoryPointerProvider<RequiredSignature>::f); + using RegisterFactoryOperation = RegisterFactoryForPointer<Comp, AnnotatedSignature>; using Comp1 = FunctorResult<RegisterFactoryOperation, Comp&&, Provider*>; Comp1 operator()(Comp&& m) { - return RegisterFactoryOperation()(std::move(m), ConstructorFactoryProvider<RequiredSignature>::f); + return RegisterFactoryOperation()(std::move(m), ConstructorFactoryPointerProvider<RequiredSignature>::f); }; }; diff --git a/include/fruit/impl/component.utils.h b/include/fruit/impl/component.utils.h index 2a4fbdb..f17d8f4 100644 --- a/include/fruit/impl/component.utils.h +++ b/include/fruit/impl/component.utils.h @@ -155,10 +155,10 @@ template <typename L> using UnlabelAssisted = typename UnlabelAssistedHelper<L>::type; template <typename AnnotatedSignature> -using RequiredSignatureForAssistedFactory = ConstructSignature<SignatureType<AnnotatedSignature>, UnlabelAssisted<SignatureArgs<AnnotatedSignature>>>; +using RequiredArgsForAssistedFactory = UnlabelAssisted<SignatureArgs<AnnotatedSignature>>; template <typename AnnotatedSignature> -using InjectedFunctionTypeForAssistedFactory = ConstructSignature<SignatureType<AnnotatedSignature>, RemoveNonAssisted<SignatureArgs<AnnotatedSignature>>>; +using InjectedFunctionArgsForAssistedFactory = RemoveNonAssisted<SignatureArgs<AnnotatedSignature>>; template <int index, typename L> class NumAssistedBefore {}; // Not used. Instantiated only if index is out of bounds. @@ -403,10 +403,10 @@ static inline void standardDeleter(void* p) { } template <typename Signature> -struct ConstructorFactoryProvider {}; +struct ConstructorFactoryValueProviderHelper {}; template <typename C, typename... Args> -struct ConstructorFactoryProvider<C(Args...)> { +struct ConstructorFactoryValueProviderHelper<C(Args...)> { static C f(Args... args) { static_assert(!std::is_pointer<C>::value, "Error, C should not be a pointer"); static_assert(std::is_constructible<C, Args...>::value, "Error, C should be constructible with Args..."); @@ -414,6 +414,25 @@ struct ConstructorFactoryProvider<C(Args...)> { } }; +template <typename Signature> +struct ConstructorFactoryValueProvider : public ConstructorFactoryValueProviderHelper<Signature> {}; + +template <typename Signature> +struct ConstructorFactoryPointerProviderHelper {}; + +template <typename C, typename... Args> +struct ConstructorFactoryPointerProviderHelper<C(Args...)> { + static std::unique_ptr<C> f(Args... args) { + static_assert(!std::is_pointer<C>::value, "Error, C should not be a pointer"); + static_assert(std::is_constructible<C, Args...>::value, "Error, C should be constructible with Args..."); + return std::unique_ptr<C>(std::forward<Args>(args)...); + } +}; + +template <typename Signature> +struct ConstructorFactoryPointerProvider : public ConstructorFactoryPointerProviderHelper<Signature> {}; + + } // namespace impl } // namespace fruit diff --git a/include/fruit/impl/component_impl.h b/include/fruit/impl/component_impl.h index 336287e..eec7b2e 100644 --- a/include/fruit/impl/component_impl.h +++ b/include/fruit/impl/component_impl.h @@ -100,13 +100,19 @@ public: friend struct fruit::impl::RegisterMultibindingProvider; template <typename Comp, typename AnnotatedSignature> - friend struct fruit::impl::RegisterFactory; + friend struct fruit::impl::RegisterFactoryForValue; + + template <typename Comp, typename AnnotatedSignature> + friend struct fruit::impl::RegisterFactoryForPointer; template <typename Comp, typename Signature> friend struct fruit::impl::RegisterConstructor; template <typename Comp, typename AnnotatedSignature> - friend struct fruit::impl::RegisterConstructorAsFactory; + friend struct fruit::impl::RegisterConstructorAsPointerFactory; + + template <typename Comp, typename AnnotatedSignature> + friend struct fruit::impl::RegisterConstructorAsValueFactory; template <typename Comp, typename OtherM> friend struct fruit::impl::InstallComponent; diff --git a/include/fruit/impl/component_storage.h b/include/fruit/impl/component_storage.h index c78e793..af9107f 100644 --- a/include/fruit/impl/component_storage.h +++ b/include/fruit/impl/component_storage.h @@ -181,7 +181,7 @@ private: void becomeInjector(); template <typename C, typename... Args> - C* constructSingleton(Args... args); + C* constructSingleton(Args&&... args); template <typename T> friend struct GetHelper; @@ -224,8 +224,13 @@ public: template <typename C, typename... Args> void registerConstructor(); - template <typename AnnotatedSignature> - void registerFactory(RequiredSignatureForAssistedFactory<AnnotatedSignature>* factory); + // List<Args...> must be equal to RequiredArgsForAssistedFactory<AnnotatedSignature>. + template <typename AnnotatedSignature, typename... Args> + void registerFactory(SignatureType<AnnotatedSignature>(*factory)(Args...)); + + // List<Args...> must be equal to RequiredArgsForAssistedFactory<AnnotatedSignature>. + template <typename AnnotatedSignature, typename... Args> + void registerFactory(std::unique_ptr<SignatureType<AnnotatedSignature>>(*factory)(Args...)); template <typename I, typename C> void addMultibinding(); diff --git a/include/fruit/impl/component_storage.templates.h b/include/fruit/impl/component_storage.templates.h index 6006f53..c2f5dca 100644 --- a/include/fruit/impl/component_storage.templates.h +++ b/include/fruit/impl/component_storage.templates.h @@ -108,19 +108,19 @@ template <int index, typename AnnotatedArgs, typename ParamTuple> struct GetAssistedArg : public GetAssistedArgHelper<NumAssistedBefore<index, AnnotatedArgs>::value, GetNthType<index, AnnotatedArgs>, ParamTuple> {}; template <typename AnnotatedSignature, typename InjectedFunctionType, typename Sequence> -class BindAssistedFactoryHelper {}; +class BindAssistedFactoryHelperForValue {}; template <typename AnnotatedSignature, typename C, typename... Params, int... indexes> -class BindAssistedFactoryHelper<AnnotatedSignature, C(Params...), IntList<indexes...>> { +class BindAssistedFactoryHelperForValue<AnnotatedSignature, C(Params...), IntList<indexes...>> { private: /* std::function<C(Params...)>, C(Args...) */ - using RequiredSignature = RequiredSignatureForAssistedFactory<AnnotatedSignature>; + using RequiredSignature = ConstructSignature<SignatureType<AnnotatedSignature>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; ComponentStorage& storage; RequiredSignature* factory; public: - BindAssistedFactoryHelper(ComponentStorage& storage, RequiredSignature* factory) + BindAssistedFactoryHelperForValue(ComponentStorage& storage, RequiredSignature* factory) :storage(storage), factory(factory) {} C operator()(Params... params) { @@ -128,26 +128,66 @@ public: } }; +template <typename AnnotatedSignature, typename InjectedFunctionType, typename Sequence> +class BindAssistedFactoryHelperForPointer {}; + +template <typename AnnotatedSignature, typename C, typename... Params, int... indexes> +class BindAssistedFactoryHelperForPointer<AnnotatedSignature, std::unique_ptr<C>(Params...), IntList<indexes...>> { +private: + /* std::function<std::unique_ptr<C>(Params...)>, std::unique_ptr<C>(Args...) */ + using RequiredSignature = ConstructSignature<std::unique_ptr<C>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; + + ComponentStorage& storage; + RequiredSignature* factory; + +public: + BindAssistedFactoryHelperForPointer(ComponentStorage& storage, RequiredSignature* factory) + :storage(storage), factory(factory) {} + + std::unique_ptr<C> operator()(Params... params) { + return factory(GetAssistedArg<indexes, SignatureArgs<AnnotatedSignature>, decltype(std::tie(params...))>()(storage, std::tie(params...))...); + } +}; + template <typename AnnotatedSignature> -struct BindAssistedFactory : public BindAssistedFactoryHelper< +struct BindAssistedFactoryForValue : public BindAssistedFactoryHelperForValue< AnnotatedSignature, - InjectedFunctionTypeForAssistedFactory<AnnotatedSignature>, + ConstructSignature<SignatureType<AnnotatedSignature>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>, GenerateIntSequence< list_size< - SignatureArgs<RequiredSignatureForAssistedFactory<AnnotatedSignature>> + RequiredArgsForAssistedFactory<AnnotatedSignature> >::value >> { - BindAssistedFactory(ComponentStorage& storage, RequiredSignatureForAssistedFactory<AnnotatedSignature>* factory) - : BindAssistedFactoryHelper< + BindAssistedFactoryForValue(ComponentStorage& storage, ConstructSignature<SignatureType<AnnotatedSignature>, RequiredArgsForAssistedFactory<AnnotatedSignature>>* factory) + : BindAssistedFactoryHelperForValue< AnnotatedSignature, - InjectedFunctionTypeForAssistedFactory<AnnotatedSignature>, + ConstructSignature<SignatureType<AnnotatedSignature>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>, GenerateIntSequence< list_size< - SignatureArgs<RequiredSignatureForAssistedFactory<AnnotatedSignature>> + RequiredArgsForAssistedFactory<AnnotatedSignature> >::value >>(storage, factory) {} }; +template <typename AnnotatedSignature> +struct BindAssistedFactoryForPointer : public BindAssistedFactoryHelperForPointer< + AnnotatedSignature, + ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>, + GenerateIntSequence< + list_size< + RequiredArgsForAssistedFactory<AnnotatedSignature> + >::value + >> { + BindAssistedFactoryForPointer(ComponentStorage& storage, ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, RequiredArgsForAssistedFactory<AnnotatedSignature>>* factory) + : BindAssistedFactoryHelperForPointer< + AnnotatedSignature, + ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>, + GenerateIntSequence< + list_size< + RequiredArgsForAssistedFactory<AnnotatedSignature> + >::value + >>(storage, factory) {} +}; template <typename MessageGenerator> inline void ComponentStorage::check(bool b, MessageGenerator messageGenerator) { @@ -240,13 +280,13 @@ inline void ComponentStorage::bindInstance(C& instance) { } template <typename C, typename... Args> -inline C* ComponentStorage::constructSingleton(Args... args) { +inline C* ComponentStorage::constructSingleton(Args&&... args) { size_t misalignment = (singletonStorageNumUsedBytes % alignof(C)); if (misalignment != 0) { singletonStorageNumUsedBytes += alignof(C) - misalignment; } C* c = reinterpret_cast<C*>(singletonStorageBegin + singletonStorageNumUsedBytes); - new (c) C(args...); + new (c) C(std::forward<Args>(args)...); singletonStorageNumUsedBytes += sizeof(C); return c; } @@ -361,15 +401,29 @@ inline void ComponentStorage::registerMultibindingProvider(C (*provider)(Args... createBindingDataForMultibinding<C>(create, reinterpret_cast<void*>(provider), destroy); } -template <typename AnnotatedSignature> -inline void ComponentStorage::registerFactory(RequiredSignatureForAssistedFactory<AnnotatedSignature>* factory) { +template <typename AnnotatedSignature, typename... Argz> +inline void ComponentStorage::registerFactory(SignatureType<AnnotatedSignature>(*factory)(Argz...)) { + check(factory != nullptr, "attempting to register nullptr as factory"); + using Signature = ConstructSignature<SignatureType<AnnotatedSignature>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; + using InjectedFunctionType = ConstructSignature<SignatureType<AnnotatedSignature>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>; + auto create = [](ComponentStorage& m, void* arg) { + Signature* factory = reinterpret_cast<Signature*>(arg); + std::function<InjectedFunctionType>* fPtr = + new std::function<InjectedFunctionType>(BindAssistedFactoryForValue<AnnotatedSignature>(m, factory)); + return reinterpret_cast<void*>(fPtr); + }; + createBindingData<std::function<InjectedFunctionType>>(create, reinterpret_cast<void*>(factory), standardDeleter<std::function<InjectedFunctionType>>); +} + +template <typename AnnotatedSignature, typename... Argz> +inline void ComponentStorage::registerFactory(std::unique_ptr<SignatureType<AnnotatedSignature>>(*factory)(Argz...)) { check(factory != nullptr, "attempting to register nullptr as factory"); - using Signature = RequiredSignatureForAssistedFactory<AnnotatedSignature>; - using InjectedFunctionType = InjectedFunctionTypeForAssistedFactory<AnnotatedSignature>; + using Signature = ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, RequiredArgsForAssistedFactory<AnnotatedSignature>>; + using InjectedFunctionType = ConstructSignature<std::unique_ptr<SignatureType<AnnotatedSignature>>, InjectedFunctionArgsForAssistedFactory<AnnotatedSignature>>; auto create = [](ComponentStorage& m, void* arg) { Signature* factory = reinterpret_cast<Signature*>(arg); std::function<InjectedFunctionType>* fPtr = - new std::function<InjectedFunctionType>(BindAssistedFactory<AnnotatedSignature>(m, factory)); + new std::function<InjectedFunctionType>(BindAssistedFactoryForPointer<AnnotatedSignature>(m, factory)); return reinterpret_cast<void*>(fPtr); }; createBindingData<std::function<InjectedFunctionType>>(create, reinterpret_cast<void*>(factory), standardDeleter<std::function<InjectedFunctionType>>); |