aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMarco Poletti <poletti.marco@gmail.com>2014-08-19 22:03:17 +0200
committerMarco Poletti <poletti.marco@gmail.com>2014-08-19 22:03:17 +0200
commit80cfec6c278066d7758cc1d46475af9f5db01589 (patch)
treecd44c522366e639b47fa2b0214e057c3c03abc9f /include
parent09fa583bbe4ac587818f1673e6b2dd9bd3459d8a (diff)
downloadgoogle-fruit-80cfec6c278066d7758cc1d46475af9f5db01589.tar.gz
Add injection support for unique_ptr for non-movable types.
Diffstat (limited to 'include')
-rw-r--r--include/fruit/component.h46
-rw-r--r--include/fruit/fruit_forward_decls.h10
-rw-r--r--include/fruit/impl/component.templates.h63
-rw-r--r--include/fruit/impl/component.utils.h27
-rw-r--r--include/fruit/impl/component_impl.h10
-rw-r--r--include/fruit/impl/component_storage.h11
-rw-r--r--include/fruit/impl/component_storage.templates.h90
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>>);