Skip to content

Commit

Permalink
Deprecate the old Injector and NormalizedComponent constructors and i…
Browse files Browse the repository at this point in the history
…ntroduce the new Fruit 3.x variants. Also change PartialComponent::install to allow implicit conversions in the arguments (as in Fruit 3.x).
  • Loading branch information
poletti-marco committed Jul 31, 2017
1 parent 30db886 commit 8ba907a
Show file tree
Hide file tree
Showing 41 changed files with 570 additions and 192 deletions.
2 changes: 1 addition & 1 deletion examples/annotated_injection/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
using fruit::Injector;

int main() {
Injector<Car> injector(getCarComponent());
Injector<Car> injector(getCarComponent);
Car* car(injector);

car->brake();
Expand Down
2 changes: 1 addition & 1 deletion examples/hello_world/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Component<Greeter> getGreeterComponent() {

int main() {

Injector<Greeter> injector(getGreeterComponent());
Injector<Greeter> injector(getGreeterComponent);
Greeter* greeter = injector.get<Greeter*>();

greeter->greet();
Expand Down
2 changes: 1 addition & 1 deletion examples/multibindings/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Component<> getListenersComponent() {
}

int main() {
Injector<> injector(getListenersComponent());
Injector<> injector(getListenersComponent);
std::vector<Listener*> listeners = injector.getMultibindings<Listener>();

// The order of the returned listeners is unspecified, so the lines in output may have any order.
Expand Down
2 changes: 1 addition & 1 deletion examples/scaling_doubles/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
using fruit::Injector;

int main() {
Injector<ScalerFactory> injector(getScalerComponent());
Injector<ScalerFactory> injector(getScalerComponent);
ScalerFactory scalerFactory(injector);

std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
Expand Down
2 changes: 1 addition & 1 deletion examples/server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
using namespace fruit;

int main() {
Injector<Server> injector(getServerComponent());
Injector<Server> injector(getServerComponent);

Server* server(injector);
server->run(getRequestDispatcherComponent);
Expand Down
20 changes: 14 additions & 6 deletions examples/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ class ServerImpl : public Server {
serverContext.startupTime = getTime();

const NormalizedComponent<Required<Request>, RequestDispatcher> requestDispatcherNormalizedComponent(
createComponent()
.install(requestDispatcherComponent)
.bindInstance(serverContext));
getRequestDispatcherNormalizedComponent,
requestDispatcherComponent,
&serverContext);

cerr << "Server started." << endl;

Expand All @@ -68,7 +68,7 @@ class ServerImpl : public Server {
private:
static void worker_thread_main(const NormalizedComponent<Required<Request>, RequestDispatcher>& requestDispatcherNormalizedComponent,
Request request) {
Injector<RequestDispatcher> injector(requestDispatcherNormalizedComponent, getRequestComponent(request));
Injector<RequestDispatcher> injector(requestDispatcherNormalizedComponent, getRequestComponent, &request);

RequestDispatcher* requestDispatcher(injector);
requestDispatcher->handleRequest();
Expand All @@ -84,9 +84,17 @@ class ServerImpl : public Server {
return result;
}

static Component<Request> getRequestComponent(Request request) {
static Component<Request> getRequestComponent(Request* request) {
return createComponent()
.bindInstance(request);
.bindInstance(*request);
}

static Component<Required<Request>, RequestDispatcher> getRequestDispatcherNormalizedComponent(
Component<Required<Request, ServerContext>, RequestDispatcher>(*requestDispatcherComponent)(),
ServerContext* server_context) {
return createComponent()
.install(requestDispatcherComponent)
.bindInstance(*server_context);
}
};

Expand Down
2 changes: 1 addition & 1 deletion examples/simple_injection/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int main(int argc, const char* argv[]) {
if (argc == 2 && std::string(argv[1]) == "--checked")
checked = true;

Injector<Incrementer> injector(getIncrementerComponent(checked));
Injector<Incrementer> injector(getIncrementerComponent, checked);
Incrementer* incrementer(injector);

int x;
Expand Down
2 changes: 1 addition & 1 deletion examples/simple_injection/main_v1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ using fruit::Injector;
// echo 2147483647 | ./incrementer
int main() {

Injector<Incrementer> injector(getSimpleIncrementerComponent());
Injector<Incrementer> injector(getSimpleIncrementerComponent);
Incrementer* incrementer = injector.get<Incrementer*>();

int x;
Expand Down
8 changes: 4 additions & 4 deletions include/fruit/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ class PartialComponent {
*
* and then, e.g. in main():
*
* Injector<std::function<std::unique_ptr<MyClass>(int)>> injector(getMyClassComponent());
* Injector<std::function<std::unique_ptr<MyClass>(int)>> injector(getMyClassComponent);
*
* std::function<std::unique_ptr<MyClass>(int)> factory(injector);
* std::unique_ptr<MyClass> x = factory(42);
Expand Down Expand Up @@ -510,10 +510,10 @@ class PartialComponent {
* As in the example, the template parameters for this method will be inferred by the compiler, it's not necessary to
* specify them explicitly.
*/
template <typename OtherComponent, typename... Args>
template <typename OtherComponent, typename... FormalArgs, typename... Args>
PartialComponent<fruit::impl::InstallComponent<OtherComponent>, Bindings...> install(
OtherComponent(*)(Args...),
Args... args) &&;
OtherComponent(*)(FormalArgs...),
Args&&... args) &&;

private:
template <typename... OtherBindings>
Expand Down
10 changes: 5 additions & 5 deletions include/fruit/impl/component.defn.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,18 +256,18 @@ inline int checkAcceptableComponentInstallArg() {
}

template <typename... Bindings>
template <typename OtherComponent, typename... Args>
template <typename OtherComponent, typename... FormalArgs, typename... Args>
inline PartialComponent<fruit::impl::InstallComponent<OtherComponent>, Bindings...>
PartialComponent<Bindings...>::install(
OtherComponent(*f)(Args...),
Args... args) && {
OtherComponent(*f)(FormalArgs...),
Args&&... args) && {
using IntCollector = int[];
(void)(IntCollector{0, checkAcceptableComponentInstallArg<Args>()...});
(void)(IntCollector{0, checkAcceptableComponentInstallArg<FormalArgs>()...});

using Op = OpFor<fruit::impl::InstallComponent<OtherComponent>>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();

OtherComponent component = f(std::move(args)...);
OtherComponent component = f(std::forward<Args>(args)...);

storage.install(std::move(component.storage));
return {std::move(storage)};
Expand Down
49 changes: 45 additions & 4 deletions include/fruit/impl/injector.defn.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,23 @@
namespace fruit {

template <typename... P>
inline Injector<P...>::Injector(Component<P...> component)
inline FRUIT_DEPRECATED_DEFINITION(Injector<P...>::Injector(Component<P...> component))
: storage(new fruit::impl::InjectorStorage(std::move(component.storage),
std::initializer_list<fruit::impl::TypeId>{fruit::impl::getTypeId<P>()...})) {
};
}

template <typename... P>
template <typename... FormalArgs, typename... Args>
inline Injector<P...>::Injector(Component<P...>(*getComponent)(FormalArgs...), Args&&... args)
: storage(
new fruit::impl::InjectorStorage(
std::move(
fruit::Component<P...>(
fruit::createComponent().install(getComponent, std::forward<Args>(args)...))
.storage),
std::initializer_list<fruit::impl::TypeId>{fruit::impl::getTypeId<P>()...})) {
}


namespace impl {
namespace meta {
Expand Down Expand Up @@ -75,8 +88,9 @@ struct InjectorImplHelper {

template <typename... P>
template <typename... NormalizedComponentParams, typename... ComponentParams>
inline Injector<P...>::Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
Component<ComponentParams...> component)
inline FRUIT_DEPRECATED_DEFINITION(
Injector<P...>::Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
Component<ComponentParams...> component))
: storage(new fruit::impl::InjectorStorage(normalized_component.storage,
std::move(component.storage),
fruit::impl::getTypeIdsForList<fruit::impl::meta::Eval<
Expand All @@ -94,6 +108,33 @@ inline Injector<P...>::Injector(const NormalizedComponent<NormalizedComponentPar
(void)typename fruit::impl::meta::CheckIfError<E>::type();
}

template <typename... P>
template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs, typename... Args>
inline Injector<P...>::Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
Component<ComponentParams...>(*getComponent)(FormalArgs...), Args&&... args)
: storage(
new fruit::impl::InjectorStorage(
normalized_component.storage,
std::move(
fruit::Component<ComponentParams...>(
fruit::createComponent().install(getComponent, std::forward<Args>(args)...))
.storage),
fruit::impl::getTypeIdsForList<
fruit::impl::meta::Eval<
fruit::impl::meta::ConcatVectors(
fruit::impl::meta::SetToVector(fruit::impl::meta::GetComponentPs(fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<ComponentParams>...))),
fruit::impl::meta::SetToVector(fruit::impl::meta::GetComponentPs(fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<NormalizedComponentParams>...))))
>>())) {

using NormalizedComp = fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<NormalizedComponentParams>...);
using Comp = fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<ComponentParams>...);
// We don't check whether the construction of NormalizedComp or Comp resulted in errors here; if they did, the instantiation
// of NormalizedComponent<NormalizedComponentParams...> or Component<ComponentParams...> would have resulted in an error already.

using E = typename fruit::impl::meta::InjectorImplHelper<P...>::template CheckConstructionFromNormalizedComponent<NormalizedComp, Comp>::type;
(void)typename fruit::impl::meta::CheckIfError<E>::type();
}

template <typename... P>
template <typename T>
inline Injector<P...>::RemoveAnnotations<T> Injector<P...>::get() {
Expand Down
18 changes: 17 additions & 1 deletion include/fruit/impl/normalized_component.defn.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,30 @@
namespace fruit {

template <typename... Params>
inline NormalizedComponent<Params...>::NormalizedComponent(Component<Params...>&& component)
inline FRUIT_DEPRECATED_DEFINITION(
NormalizedComponent<Params...>::NormalizedComponent(Component<Params...>&& component))
: storage(std::move(component.storage), fruit::impl::getTypeIdsForList<
typename fruit::impl::meta::Eval<fruit::impl::meta::SetToVector(
typename fruit::impl::meta::Eval<
fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<Params>...)
>::Ps)>>()) {
}

template <typename... Params>
template <typename... FormalArgs, typename... Args>
inline NormalizedComponent<Params...>::NormalizedComponent(Component<Params...>(*getComponent)(FormalArgs...), Args&&... args)
: storage(
std::move(
fruit::Component<Params...>(
fruit::createComponent().install(getComponent, std::forward<Args>(args)...))
.storage),
fruit::impl::getTypeIdsForList<
typename fruit::impl::meta::Eval<fruit::impl::meta::SetToVector(
typename fruit::impl::meta::Eval<
fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<Params>...)
>::Ps)>>()) {
}

} // namespace fruit

#endif // FRUIT_NORMALIZED_COMPONENT_INLINES_H
41 changes: 35 additions & 6 deletions include/fruit/injector.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace fruit {
*
* Example usage:
*
* Injector<Foo, Bar> injector(getFooBarComponent());
* Injector<Foo, Bar> injector(getFooBarComponent);
* Foo* foo = injector.get<Foo*>();
* Bar* bar(injector); // Equivalent to: Bar* bar = injector.get<Bar*>();
*/
Expand All @@ -58,11 +58,19 @@ class Injector {
*
* Example usage:
*
* Injector<Foo, Bar> injector(getFooBarComponent());
* Injector<Foo, Bar> injector(getFooBarComponent);
* Foo* foo = injector.get<Foo*>();
* Bar* bar(injector); // Equivalent to: Bar* bar = injector.get<Bar*>();
*/
Injector(Component<P...> component);
FRUIT_DEPRECATED_DECLARATION(Injector(Component<P...> component));

/**
* Similar to the previous constructor, but takes a component function and arguments instead.
* This constructor replaces the previous in Fruit 3.x.
* The (formal) argument types have the same constraints as the ones for PartialComponent::install.
*/
template <typename... FormalArgs, typename... Args>
Injector(Component<P...>(*)(FormalArgs...), Args&&... args);

/**
* Creation of an injector from a normalized component and a component.
Expand Down Expand Up @@ -100,16 +108,37 @@ class Injector {
* }
*/
template <typename... NormalizedComponentParams, typename... ComponentParams>
Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component, Component<ComponentParams...> component);
FRUIT_DEPRECATED_DECLARATION(
Injector(
const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
Component<ComponentParams...> component)
);

/**
* Similar to the previous constructor, but takes a component function and arguments instead.
* This constructor replaces the previous in Fruit 3.x.
* The (formal) argument types have the same constraints as the ones for PartialComponent::install.
*/
template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs, typename... Args>
Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
Component<ComponentParams...>(*)(FormalArgs...), Args&&... args);

/**
* Deleted constructor, to ensure that constructing an Injector from a temporary NormalizedComponent doesn't compile.
* The NormalizedComponent must remain valid during the lifetime of any Injector object constructed with it.
*/
template <typename... NormalizedComponentParams, typename... ComponentParams>
Injector(NormalizedComponent<NormalizedComponentParams...>&& normalized_component,
Injector(NormalizedComponent<NormalizedComponentParams...>&& normalized_component,
Component<ComponentParams...> component) = delete;


/**
* Deleted constructor, to ensure that constructing an Injector from a temporary NormalizedComponent doesn't compile.
* The NormalizedComponent must remain valid during the lifetime of any Injector object constructed with it.
*/
template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs, typename... Args>
Injector(NormalizedComponent<NormalizedComponentParams...>&& normalized_component,
Component<ComponentParams...>(*)(FormalArgs...), Args&&... args) = delete;

/**
* Returns an instance of the specified type. For any class C in the Injector's template parameters, the following variations
* are allowed:
Expand Down
10 changes: 9 additions & 1 deletion include/fruit/normalized_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ class NormalizedComponent {
public:
// The Component used as parameter can have (and usually has) unsatisfied requirements, so it's usually of the form
// Component<Required<...>, ...>.
NormalizedComponent(Component<Params...>&& component);
FRUIT_DEPRECATED_DECLARATION(NormalizedComponent(Component<Params...>&& component));

/**
* Similar to the previous constructor, but takes a component function and arguments instead.
* This constructor replaces the previous in Fruit 3.x.
* The (formal) argument types have the same constraints as the ones for PartialComponent::install.
*/
template <typename... FormalArgs, typename... Args>
NormalizedComponent(Component<Params...>(*)(FormalArgs...), Args&&... args);

NormalizedComponent(NormalizedComponent&&) = default;
NormalizedComponent(const NormalizedComponent&) = delete;
Expand Down
Loading

0 comments on commit 8ba907a

Please sign in to comment.