blob: 216efd77c31e54ffdf18a044acf695710773a023 [file] [log] [blame]
Marco Poletticf798fa2014-06-21 15:05:15 +01001/*
2 * Copyright 2014 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Marco Poletti7f35b652014-11-01 10:11:37 +000017#ifndef FRUIT_COMPONENT_DEFN_H
18#define FRUIT_COMPONENT_DEFN_H
Marco Poletticf798fa2014-06-21 15:05:15 +010019
Marco Polettif2895102016-01-30 13:38:37 +000020#include <fruit/component.h>
Marco Poletti103f6502014-10-04 09:48:09 +010021
Marco Polettif2895102016-01-30 13:38:37 +000022#include <fruit/impl/injection_errors.h>
23#include <fruit/impl/storage/component_storage.h>
Marco Poletti32381f62014-11-01 15:51:05 +000024
25#include <memory>
26
Marco Poletticf798fa2014-06-21 15:05:15 +010027namespace fruit {
Marco Poletti5d849292014-07-05 19:04:31 +010028
Marco Poletti4406e322014-10-04 10:53:59 +010029template <typename... Params>
Marco Poletticbe3c7a2016-02-07 09:52:02 +000030template <typename... Bindings>
31inline Component<Params...>::Component(PartialComponent<Bindings...> component)
32 : storage(std::move(component.storage)) {
Marco Polettib9c9cef2015-05-31 15:31:12 +010033 using namespace fruit::impl::meta;
34
Marco Poletti010daa62015-07-06 01:15:12 +010035 (void)typename CheckIfError<Comp>::type();
Marco Poletti36253c92015-07-19 17:12:47 +010036
Marco Poletti43637ba2015-03-07 19:45:41 +000037 // Keep in sync with the Op in PartialComponent::PartialComponent(PartialComponent&&).
Marco Poletticbe3c7a2016-02-07 09:52:02 +000038 using Op = Eval<Call(ComposeFunctors(Id<ProcessBinding(Bindings)>...,
39 ProcessDeferredBindings,
Marco Poletti3b95a512015-07-11 13:43:39 +010040 ComponentFunctor(ConvertComponent, Comp)),
Marco Poletticbe3c7a2016-02-07 09:52:02 +000041 ConstructComponentImpl())>;
Marco Poletti010daa62015-07-06 01:15:12 +010042 (void)typename CheckIfError<Op>::type();
Marco Poletti36253c92015-07-19 17:12:47 +010043
Marco Poletticbe3c7a2016-02-07 09:52:02 +000044 Op()(storage);
45
Marco Poletti36253c92015-07-19 17:12:47 +010046#ifndef FRUIT_NO_LOOP_CHECK
47 (void)typename CheckIfError<Eval<CheckNoLoopInDeps(typename Op::Result)>>::type();
Marco Polettie5c936b2015-07-25 11:24:27 +010048#endif // !FRUIT_NO_LOOP_CHECK
Marco Poletti4406e322014-10-04 10:53:59 +010049}
50
Marco Poletticbe3c7a2016-02-07 09:52:02 +000051template <typename... Params>
52template <typename... OtherParams>
53inline Component<Params...>::Component(Component<OtherParams...> component)
54 : Component(fruit::createComponent().install(component)) {
55}
56
57inline PartialComponent<> createComponent() {
Marco Poletti4406e322014-10-04 10:53:59 +010058 return {};
59}
60
Marco Poletticbe3c7a2016-02-07 09:52:02 +000061template <typename... Bindings>
62inline PartialComponent<Bindings...>::PartialComponent(fruit::impl::ComponentStorage&& storage)
Marco Polettib5cadcf2014-08-20 19:40:49 +020063 : storage(std::move(storage)) {
Marco Poletticf798fa2014-06-21 15:05:15 +010064}
65
Marco Poletticbe3c7a2016-02-07 09:52:02 +000066template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +010067template <typename AnnotatedI, typename AnnotatedC>
Marco Poletticbe3c7a2016-02-07 09:52:02 +000068inline PartialComponent<Bindings..., Bind<AnnotatedI, AnnotatedC>>
69PartialComponent<Bindings...>::bind() && {
Marco Poletti4406e322014-10-04 10:53:59 +010070 return {std::move(storage)};
71}
72
Marco Poletticbe3c7a2016-02-07 09:52:02 +000073template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +010074template <typename AnnotatedSignature>
Marco Poletticbe3c7a2016-02-07 09:52:02 +000075inline PartialComponent<Bindings..., RegisterConstructor<AnnotatedSignature>>
76PartialComponent<Bindings...>::registerConstructor() && {
Marco Poletti4406e322014-10-04 10:53:59 +010077 return {std::move(storage)};
78}
79
Marco Poletticbe3c7a2016-02-07 09:52:02 +000080template <typename... Bindings>
Marco Poletti4406e322014-10-04 10:53:59 +010081template <typename C>
Marco Poletticbe3c7a2016-02-07 09:52:02 +000082inline PartialComponent<Bindings..., BindInstance<C>>
83PartialComponent<Bindings...>::bindInstance(C& instance) && {
84 storage.addBinding(fruit::impl::InjectorStorage::createBindingDataForBindInstance<C, C>(instance));
Marco Poletti4406e322014-10-04 10:53:59 +010085 return {std::move(storage)};
86}
87
Marco Poletticbe3c7a2016-02-07 09:52:02 +000088template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +010089template <typename AnnotatedC, typename C>
Marco Poletticbe3c7a2016-02-07 09:52:02 +000090inline PartialComponent<Bindings..., BindInstance<AnnotatedC>>
91PartialComponent<Bindings...>::bindInstance(C& instance) && {
92 storage.addBinding(fruit::impl::InjectorStorage::createBindingDataForBindInstance<AnnotatedC, C>(instance));
Marco Poletti31f638a2015-05-10 21:21:25 +010093 return {std::move(storage)};
94}
95
Marco Poletticbe3c7a2016-02-07 09:52:02 +000096template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +010097template <typename Lambda>
Marco Poletticbe3c7a2016-02-07 09:52:02 +000098inline PartialComponent<Bindings..., RegisterProvider<Lambda>>
99PartialComponent<Bindings...>::registerProvider(Lambda) && {
Marco Poletti4406e322014-10-04 10:53:59 +0100100 return {std::move(storage)};
101}
102
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000103template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +0100104template <typename AnnotatedSignature, typename Lambda>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000105inline PartialComponent<Bindings..., RegisterProvider<AnnotatedSignature, Lambda>>
106PartialComponent<Bindings...>::registerProvider(Lambda) && {
Marco Poletti31f638a2015-05-10 21:21:25 +0100107 return {std::move(storage)};
108}
109
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000110template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +0100111template <typename AnnotatedI, typename AnnotatedC>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000112inline PartialComponent<Bindings..., AddMultibinding<AnnotatedI, AnnotatedC>>
113PartialComponent<Bindings...>::addMultibinding() && {
Marco Poletti4406e322014-10-04 10:53:59 +0100114 return {std::move(storage)};
115}
116
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000117template <typename... Bindings>
Marco Poletti4406e322014-10-04 10:53:59 +0100118template <typename C>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000119inline PartialComponent<Bindings...>
120PartialComponent<Bindings...>::addInstanceMultibinding(C& instance) && {
121 auto multibindingData = fruit::impl::InjectorStorage::createMultibindingDataForInstance<C, C>(instance);
122 storage.addMultibinding(multibindingData);
Marco Polettib9c9cef2015-05-31 15:31:12 +0100123
Marco Poletti31f638a2015-05-10 21:21:25 +0100124 return {std::move(storage)};
125}
126
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000127template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +0100128template <typename AnnotatedC, typename C>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000129inline PartialComponent<Bindings...>
130PartialComponent<Bindings...>::addInstanceMultibinding(C& instance) && {
131 auto multibindingData = fruit::impl::InjectorStorage::createMultibindingDataForInstance<AnnotatedC, C>(instance);
132 storage.addMultibinding(multibindingData);
Marco Poletti4406e322014-10-04 10:53:59 +0100133 return {std::move(storage)};
134}
135
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000136template <typename... Bindings>
Marco Polettie53b79e2015-01-28 06:23:48 +0000137template <typename C>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000138inline PartialComponent<Bindings...>
139PartialComponent<Bindings...>::addInstanceMultibindings(std::vector<C>& instances) && {
140 for (C& instance : instances) {
141 auto multibindingData = fruit::impl::InjectorStorage::createMultibindingDataForInstance<C, C>(instance);
142 storage.addMultibinding(multibindingData);
143 }
Marco Polettie53b79e2015-01-28 06:23:48 +0000144 return {std::move(storage)};
145}
146
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000147template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +0100148template <typename AnnotatedC, typename C>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000149inline PartialComponent<Bindings...>
150PartialComponent<Bindings...>::addInstanceMultibindings(std::vector<C>& instances) && {
151 for (C& instance : instances) {
152 auto multibindingData = fruit::impl::InjectorStorage::createMultibindingDataForInstance<AnnotatedC, C>(instance);
153 storage.addMultibinding(multibindingData);
154 }
Marco Poletti31f638a2015-05-10 21:21:25 +0100155 return {std::move(storage)};
156}
157
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000158template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +0100159template <typename Lambda>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000160inline PartialComponent<Bindings..., AddMultibindingProvider<Lambda>>
161PartialComponent<Bindings...>::addMultibindingProvider(Lambda) && {
Marco Poletti4406e322014-10-04 10:53:59 +0100162 return {std::move(storage)};
163}
Marco Poletti90367fd2014-09-07 19:53:06 +0100164
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000165template <typename... Bindings>
Marco Polettied4d62b2014-11-24 18:24:09 +0000166template <typename AnnotatedSignature, typename Lambda>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000167inline PartialComponent<Bindings..., AddMultibindingProvider<AnnotatedSignature, Lambda>>
168PartialComponent<Bindings...>::addMultibindingProvider(Lambda) && {
Marco Poletti31f638a2015-05-10 21:21:25 +0100169 return {std::move(storage)};
170}
171
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000172template <typename... Bindings>
Marco Poletti31f638a2015-05-10 21:21:25 +0100173template <typename DecoratedSignature, typename Lambda>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000174inline PartialComponent<Bindings..., RegisterFactory<DecoratedSignature, Lambda>>
175PartialComponent<Bindings...>::registerFactory(Lambda) && {
Marco Poletti4406e322014-10-04 10:53:59 +0100176 return {std::move(storage)};
177}
178
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000179template <typename... Bindings>
Marco Poletti4406e322014-10-04 10:53:59 +0100180template <typename... OtherCompParams>
Marco Poletticbe3c7a2016-02-07 09:52:02 +0000181inline PartialComponent<Bindings..., InstallComponent<Component<OtherCompParams...>>>
182PartialComponent<Bindings...>::install(Component<OtherCompParams...> component) && {
183 storage.install(std::move(component.storage));
Marco Poletti4406e322014-10-04 10:53:59 +0100184 return {std::move(storage)};
Marco Poletticf798fa2014-06-21 15:05:15 +0100185}
186
Marco Poletticf798fa2014-06-21 15:05:15 +0100187} // namespace fruit
188
189
Marco Poletti7f35b652014-11-01 10:11:37 +0000190#endif // FRUIT_COMPONENT_DEFN_H