Marco Poletti | cf798fa | 2014-06-21 15:05:15 +0100 | [diff] [blame] | 1 | /* |
| 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 Poletti | 7f35b65 | 2014-11-01 10:11:37 +0000 | [diff] [blame] | 17 | #ifndef FRUIT_COMPONENT_DEFN_H |
| 18 | #define FRUIT_COMPONENT_DEFN_H |
Marco Poletti | cf798fa | 2014-06-21 15:05:15 +0100 | [diff] [blame] | 19 | |
Marco Poletti | f289510 | 2016-01-30 13:38:37 +0000 | [diff] [blame] | 20 | #include <fruit/component.h> |
Marco Poletti | 103f650 | 2014-10-04 09:48:09 +0100 | [diff] [blame] | 21 | |
Marco Poletti | f289510 | 2016-01-30 13:38:37 +0000 | [diff] [blame] | 22 | #include <fruit/impl/injection_errors.h> |
| 23 | #include <fruit/impl/storage/component_storage.h> |
Marco Poletti | 32381f6 | 2014-11-01 15:51:05 +0000 | [diff] [blame] | 24 | |
| 25 | #include <memory> |
| 26 | |
Marco Poletti | cf798fa | 2014-06-21 15:05:15 +0100 | [diff] [blame] | 27 | namespace fruit { |
Marco Poletti | 5d84929 | 2014-07-05 19:04:31 +0100 | [diff] [blame] | 28 | |
Marco Poletti | 6cf268f | 2016-03-25 11:45:08 +0000 | [diff] [blame] | 29 | namespace impl { |
| 30 | namespace meta { |
| 31 | // This is a helper class used in the implementation of Component and PartialComponent. |
| 32 | // It's in fruit::impl::meta so that we don't need to qualify everything with fruit::impl::meta. |
| 33 | template <typename... PreviousBindings> |
| 34 | struct OpForComponent { |
| 35 | template <typename Comp> |
| 36 | using ConvertTo = Eval< |
Marco Poletti | 905dc09 | 2017-03-12 15:54:31 +0000 | [diff] [blame] | 37 | Call(ReverseComposeFunctors(Id<ComponentFunctor(ConvertComponent, Comp)>, |
| 38 | ProcessDeferredBindings, |
| 39 | Id<ProcessBinding(PreviousBindings)>...), |
| 40 | ConstructComponentImpl())>; |
Marco Poletti | 6cf268f | 2016-03-25 11:45:08 +0000 | [diff] [blame] | 41 | |
| 42 | template <typename Binding> |
| 43 | using AddBinding = Eval< |
Marco Poletti | 905dc09 | 2017-03-12 15:54:31 +0000 | [diff] [blame] | 44 | Call(ReverseComposeFunctors(Id<ProcessBinding(Binding)>, |
| 45 | Id<ProcessBinding(PreviousBindings)>...), |
| 46 | ConstructComponentImpl())>; |
Marco Poletti | 6cf268f | 2016-03-25 11:45:08 +0000 | [diff] [blame] | 47 | }; |
| 48 | } // namespace meta |
| 49 | } // namespace impl |
| 50 | |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 51 | template <typename... Params> |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 52 | template <typename... Bindings> |
Marco Poletti | 04cf924 | 2016-08-29 19:31:12 +0100 | [diff] [blame] | 53 | inline Component<Params...>::Component(PartialComponent<Bindings...> component) |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 54 | : storage() { |
| 55 | |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 56 | (void)typename fruit::impl::meta::CheckIfError<Comp>::type(); |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 57 | |
Marco Poletti | 6cf268f | 2016-03-25 11:45:08 +0000 | [diff] [blame] | 58 | using Op = typename fruit::impl::meta::OpForComponent<Bindings...>::template ConvertTo<Comp>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 59 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 60 | |
Marco Poletti | 36253c9 | 2015-07-19 17:12:47 +0100 | [diff] [blame] | 61 | #ifndef FRUIT_NO_LOOP_CHECK |
Marco Poletti | 6cf268f | 2016-03-25 11:45:08 +0000 | [diff] [blame] | 62 | (void)typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNoLoopInDeps(typename Op::Result)>>::type(); |
Marco Poletti | e5c936b | 2015-07-25 11:24:27 +0100 | [diff] [blame] | 63 | #endif // !FRUIT_NO_LOOP_CHECK |
Marco Poletti | 6cf268f | 2016-03-25 11:45:08 +0000 | [diff] [blame] | 64 | |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 65 | component.storage.addBindings(storage); |
| 66 | |
| 67 | // TODO: re-enable this check somehow. |
| 68 | // component.component.already_converted_to_component = true; |
Marco Poletti | 04cf924 | 2016-08-29 19:31:12 +0100 | [diff] [blame] | 69 | |
Marco Poletti | 6cf268f | 2016-03-25 11:45:08 +0000 | [diff] [blame] | 70 | Op()(storage); |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 71 | } |
| 72 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 73 | template <typename... Params> |
| 74 | template <typename... OtherParams> |
| 75 | inline Component<Params...>::Component(Component<OtherParams...> component) |
Marco Poletti | c9e7a0b | 2017-06-11 20:04:03 +0100 | [diff] [blame] | 76 | : storage(std::move(component.storage)) { |
| 77 | (void)typename fruit::impl::meta::CheckIfError<Comp>::type(); |
| 78 | |
| 79 | using InstallBinding = fruit::impl::InstallComponent<Component<OtherParams...>>; |
| 80 | |
| 81 | using Op1 = typename fruit::impl::meta::OpForComponent<>::template AddBinding<InstallBinding>; |
| 82 | (void)typename fruit::impl::meta::CheckIfError<Op1>::type(); |
| 83 | |
| 84 | using Op2 = typename fruit::impl::meta::OpForComponent<InstallBinding>::template ConvertTo<Comp>; |
| 85 | (void)typename fruit::impl::meta::CheckIfError<Op2>::type(); |
| 86 | |
| 87 | Op2()(storage); |
| 88 | |
| 89 | #ifndef FRUIT_NO_LOOP_CHECK |
| 90 | (void)typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNoLoopInDeps(typename Op2::Result)>>::type(); |
| 91 | #endif // !FRUIT_NO_LOOP_CHECK |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 92 | } |
| 93 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 94 | template <typename... Bindings> |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 95 | inline PartialComponent<Bindings...>::~PartialComponent() { |
| 96 | } |
| 97 | |
| 98 | template <> |
| 99 | inline PartialComponent<>::~PartialComponent() { |
| 100 | |
| 101 | } |
| 102 | |
| 103 | inline PartialComponent<> createComponent() { |
| 104 | return {{}}; |
Marco Poletti | cf798fa | 2014-06-21 15:05:15 +0100 | [diff] [blame] | 105 | } |
| 106 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 107 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 108 | template <typename AnnotatedI, typename AnnotatedC> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 109 | inline PartialComponent<fruit::impl::Bind<AnnotatedI, AnnotatedC>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 110 | PartialComponent<Bindings...>::bind() { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 111 | using Op = OpFor<fruit::impl::Bind<AnnotatedI, AnnotatedC>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 112 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
| 113 | |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 114 | return {{storage}}; |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 115 | } |
| 116 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 117 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 118 | template <typename AnnotatedSignature> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 119 | inline PartialComponent<fruit::impl::RegisterConstructor<AnnotatedSignature>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 120 | PartialComponent<Bindings...>::registerConstructor() { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 121 | using Op = OpFor<fruit::impl::RegisterConstructor<AnnotatedSignature>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 122 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
| 123 | |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 124 | return {{storage}}; |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 125 | } |
| 126 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 127 | template <typename... Bindings> |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 128 | template <typename C> |
Marco Poletti | 0acba69 | 2016-12-10 17:44:38 +0000 | [diff] [blame] | 129 | inline PartialComponent<fruit::impl::BindInstance<C, C>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 130 | PartialComponent<Bindings...>::bindInstance(C& instance) { |
Marco Poletti | 0acba69 | 2016-12-10 17:44:38 +0000 | [diff] [blame] | 131 | using Op = OpFor<fruit::impl::BindInstance<C, C>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 132 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 133 | return {{storage, instance}}; |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 134 | } |
| 135 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 136 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 137 | template <typename AnnotatedC, typename C> |
Marco Poletti | 0acba69 | 2016-12-10 17:44:38 +0000 | [diff] [blame] | 138 | inline PartialComponent<fruit::impl::BindInstance<AnnotatedC, C>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 139 | PartialComponent<Bindings...>::bindInstance(C& instance) { |
Marco Poletti | 0acba69 | 2016-12-10 17:44:38 +0000 | [diff] [blame] | 140 | using Op = OpFor<fruit::impl::BindInstance<AnnotatedC, C>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 141 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 142 | return {{storage, instance}}; |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 143 | } |
| 144 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 145 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 146 | template <typename Lambda> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 147 | inline PartialComponent<fruit::impl::RegisterProvider<Lambda>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 148 | PartialComponent<Bindings...>::registerProvider(Lambda) { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 149 | using Op = OpFor<fruit::impl::RegisterProvider<Lambda>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 150 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 151 | return {{storage}}; |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 152 | } |
| 153 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 154 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 155 | template <typename AnnotatedSignature, typename Lambda> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 156 | inline PartialComponent<fruit::impl::RegisterProvider<AnnotatedSignature, Lambda>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 157 | PartialComponent<Bindings...>::registerProvider(Lambda) { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 158 | using Op = OpFor<fruit::impl::RegisterProvider<AnnotatedSignature, Lambda>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 159 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 160 | return {{storage}}; |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 161 | } |
| 162 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 163 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 164 | template <typename AnnotatedI, typename AnnotatedC> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 165 | inline PartialComponent<fruit::impl::AddMultibinding<AnnotatedI, AnnotatedC>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 166 | PartialComponent<Bindings...>::addMultibinding() { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 167 | using Op = OpFor<fruit::impl::AddMultibinding<AnnotatedI, AnnotatedC>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 168 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
| 169 | |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 170 | return {{storage}}; |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 171 | } |
| 172 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 173 | template <typename... Bindings> |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 174 | template <typename C> |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 175 | inline PartialComponent<fruit::impl::AddInstanceMultibinding<C>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 176 | PartialComponent<Bindings...>::addInstanceMultibinding(C& instance) { |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 177 | return {{storage, instance}}; |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 178 | } |
| 179 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 180 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 181 | template <typename AnnotatedC, typename C> |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 182 | inline PartialComponent<fruit::impl::AddInstanceMultibinding<AnnotatedC>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 183 | PartialComponent<Bindings...>::addInstanceMultibinding(C& instance) { |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 184 | return {{storage, instance}}; |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 185 | } |
| 186 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 187 | template <typename... Bindings> |
Marco Poletti | e53b79e | 2015-01-28 06:23:48 +0000 | [diff] [blame] | 188 | template <typename C> |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 189 | inline PartialComponent<fruit::impl::AddInstanceVectorMultibindings<C>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 190 | PartialComponent<Bindings...>::addInstanceMultibindings(std::vector<C>& instances) { |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 191 | return {{storage, instances}}; |
Marco Poletti | e53b79e | 2015-01-28 06:23:48 +0000 | [diff] [blame] | 192 | } |
| 193 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 194 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 195 | template <typename AnnotatedC, typename C> |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 196 | inline PartialComponent<fruit::impl::AddInstanceVectorMultibindings<AnnotatedC>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 197 | PartialComponent<Bindings...>::addInstanceMultibindings(std::vector<C>& instances) { |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 198 | return {{storage, instances}}; |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 199 | } |
| 200 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 201 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 202 | template <typename Lambda> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 203 | inline PartialComponent<fruit::impl::AddMultibindingProvider<Lambda>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 204 | PartialComponent<Bindings...>::addMultibindingProvider(Lambda) { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 205 | using Op = OpFor<fruit::impl::AddMultibindingProvider<Lambda>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 206 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
| 207 | |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 208 | return {{storage}}; |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 209 | } |
Marco Poletti | 90367fd | 2014-09-07 19:53:06 +0100 | [diff] [blame] | 210 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 211 | template <typename... Bindings> |
Marco Poletti | ed4d62b | 2014-11-24 18:24:09 +0000 | [diff] [blame] | 212 | template <typename AnnotatedSignature, typename Lambda> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 213 | inline PartialComponent<fruit::impl::AddMultibindingProvider<AnnotatedSignature, Lambda>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 214 | PartialComponent<Bindings...>::addMultibindingProvider(Lambda) { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 215 | using Op = OpFor<fruit::impl::AddMultibindingProvider<AnnotatedSignature, Lambda>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 216 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
| 217 | |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 218 | return {{storage}}; |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 219 | } |
| 220 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 221 | template <typename... Bindings> |
Marco Poletti | 31f638a | 2015-05-10 21:21:25 +0100 | [diff] [blame] | 222 | template <typename DecoratedSignature, typename Lambda> |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 223 | inline PartialComponent<fruit::impl::RegisterFactory<DecoratedSignature, Lambda>, Bindings...> |
Marco Poletti | cf5c9f1 | 2016-08-28 20:43:00 +0100 | [diff] [blame] | 224 | PartialComponent<Bindings...>::registerFactory(Lambda) { |
Marco Poletti | 0109baa | 2016-03-25 13:04:47 +0000 | [diff] [blame] | 225 | using Op = OpFor<fruit::impl::RegisterFactory<DecoratedSignature, Lambda>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 226 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
| 227 | |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 228 | return {{storage}}; |
| 229 | } |
| 230 | |
| 231 | template <typename... Bindings> |
| 232 | inline PartialComponent<Bindings...>::PartialComponent(fruit::impl::PartialComponentStorage<Bindings...> storage) |
| 233 | : storage(std::move(storage)) { |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 234 | } |
| 235 | |
Marco Poletti | cbe3c7a | 2016-02-07 09:52:02 +0000 | [diff] [blame] | 236 | template <typename... Bindings> |
Marco Poletti | 4406e32 | 2014-10-04 10:53:59 +0100 | [diff] [blame] | 237 | template <typename... OtherCompParams> |
Marco Poletti | 3e21dcf | 2017-06-17 15:58:00 +0100 | [diff] [blame^] | 238 | FRUIT_DEPRECATED_DEFINITION( |
Marco Poletti | 09843e0 | 2017-06-11 11:48:37 +0100 | [diff] [blame] | 239 | inline PartialComponent<fruit::impl::OldStyleInstallComponent<Component<OtherCompParams...>>, Bindings...> |
Marco Poletti | 3e21dcf | 2017-06-17 15:58:00 +0100 | [diff] [blame^] | 240 | PartialComponent<Bindings...>::install(const Component<OtherCompParams...>& other_component)) { |
Marco Poletti | 09843e0 | 2017-06-11 11:48:37 +0100 | [diff] [blame] | 241 | using Op = OpFor<fruit::impl::OldStyleInstallComponent<Component<OtherCompParams...>>>; |
Marco Poletti | e844355 | 2016-02-07 10:25:39 +0000 | [diff] [blame] | 242 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
Marco Poletti | 0316a00 | 2016-08-29 16:43:10 +0100 | [diff] [blame] | 243 | return {{storage, other_component.storage}}; |
Marco Poletti | cf798fa | 2014-06-21 15:05:15 +0100 | [diff] [blame] | 244 | } |
| 245 | |
Marco Poletti | 09843e0 | 2017-06-11 11:48:37 +0100 | [diff] [blame] | 246 | template <typename T> |
| 247 | FRUIT_ALWAYS_INLINE |
| 248 | inline int checkAcceptableComponentInstallArg() { |
| 249 | // This lambda checks that the required operations on T exist. |
| 250 | // Note that the lambda is never actually executed. |
| 251 | auto checkRequirements = [](const T& constRef, T value) { |
| 252 | T x1(constRef); |
| 253 | T x2(std::move(value)); |
| 254 | x1 = constRef; |
| 255 | x2 = std::move(value); |
| 256 | bool b = (constRef == constRef); |
| 257 | std::size_t h = std::hash<T>()(constRef); |
| 258 | (void)x1; |
| 259 | (void)x2; |
| 260 | (void)b; |
| 261 | (void)h; |
| 262 | }; |
| 263 | (void)checkRequirements; |
| 264 | return 0; |
| 265 | } |
| 266 | |
| 267 | template <typename... Bindings> |
| 268 | template <typename OtherComponent, typename... Args> |
| 269 | inline PartialComponent<fruit::impl::InstallComponent<OtherComponent, Args...>, Bindings...> |
Marco Poletti | 5de0d4f | 2017-06-11 12:47:52 +0100 | [diff] [blame] | 270 | PartialComponent<Bindings...>::install(OtherComponent(*fun)(Args...), Args... args) { |
Marco Poletti | 09843e0 | 2017-06-11 11:48:37 +0100 | [diff] [blame] | 271 | using IntCollector = int[]; |
| 272 | (void)(IntCollector{0, checkAcceptableComponentInstallArg<Args>()...}); |
| 273 | |
| 274 | using Op = OpFor<fruit::impl::InstallComponent<OtherComponent, Args...>>; |
| 275 | (void)typename fruit::impl::meta::CheckIfError<Op>::type(); |
| 276 | |
| 277 | return {{storage, fun, std::move(args)...}}; |
| 278 | } |
| 279 | |
Marco Poletti | 09843e0 | 2017-06-11 11:48:37 +0100 | [diff] [blame] | 280 | |
Marco Poletti | cf798fa | 2014-06-21 15:05:15 +0100 | [diff] [blame] | 281 | } // namespace fruit |
| 282 | |
Marco Poletti | 7f35b65 | 2014-11-01 10:11:37 +0000 | [diff] [blame] | 283 | #endif // FRUIT_COMPONENT_DEFN_H |