blob: 6f65bbfcb26f9c9d781dbd2eddeb630302deab8c [file] [log] [blame]
Marco Polettia5f49d42014-06-29 10:41:12 +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
Marco Poletti1b959ab2017-12-27 09:23:44 +00007 *
Marco Polettia5f49d42014-06-29 10:41:12 +01008 * http://www.apache.org/licenses/LICENSE-2.0
Marco Poletti1b959ab2017-12-27 09:23:44 +00009 *
Marco Polettia5f49d42014-06-29 10:41:12 +010010 * 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_PROVIDER_DEFN_H
18#define FRUIT_PROVIDER_DEFN_H
Marco Polettia5f49d42014-06-29 10:41:12 +010019
Marco Polettic5635122017-07-01 20:15:20 +010020#include <fruit/impl/injector/injector_storage.h>
Marco Polettia5f49d42014-06-29 10:41:12 +010021
22// Redundant, but makes KDevelop happy.
Marco Polettif2895102016-01-30 13:38:37 +000023#include <fruit/provider.h>
Marco Polettia5f49d42014-06-29 10:41:12 +010024
25namespace fruit {
26
Marco Poletti9250dea2014-11-09 09:10:53 +000027template <typename C>
Marco Poletti1b959ab2017-12-27 09:23:44 +000028inline Provider<C>::Provider(fruit::impl::InjectorStorage* storage,
29 fruit::impl::InjectorStorage::Graph::node_iterator itr)
30 : storage(storage), itr(itr) {}
Marco Polettia5f49d42014-06-29 10:41:12 +010031
Marco Poletti9250dea2014-11-09 09:10:53 +000032template <typename C>
33inline C* Provider<C>::get() {
Marco Poletti418e9bf2017-07-30 20:51:10 +010034 return get<C*>();
Marco Poletti9250dea2014-11-09 09:10:53 +000035}
36
Marco Poletti79b01d62016-03-25 12:25:30 +000037namespace impl {
38namespace meta {
39
40template <typename C>
41struct ProviderImplHelper {
Marco Poletti905dc092017-03-12 15:54:31 +000042
Marco Poletti79b01d62016-03-25 12:25:30 +000043 template <typename T>
Marco Poletti1b959ab2017-12-27 09:23:44 +000044 using CheckGet = Eval<PropagateError(
45 CheckInjectableType(RemoveAnnotations(Type<T>)),
46 If(Not(IsSame(GetClassForType(Type<T>), RemoveConstFromType(Type<C>))),
47 ConstructError(Id<TypeNotProvidedErrorTag>, Type<T>),
48 If(And(TypeInjectionRequiresNonConstBinding(Type<T>), Not(IsSame(Id<GetClassForType(Type<T>)>, Type<C>))),
49 ConstructError(TypeProvidedAsConstOnlyErrorTag, Type<T>), None)))>;
Marco Poletti79b01d62016-03-25 12:25:30 +000050};
51
52} // namespace meta
53} // namespace impl
54
Marco Poletti9250dea2014-11-09 09:10:53 +000055template <typename C>
Marco Polettia5f49d42014-06-29 10:41:12 +010056template <typename T>
Marco Poletti9250dea2014-11-09 09:10:53 +000057inline T Provider<C>::get() {
Marco Poletti79b01d62016-03-25 12:25:30 +000058 using E = typename fruit::impl::meta::ProviderImplHelper<C>::template CheckGet<T>;
59 (void)typename fruit::impl::meta::CheckIfError<E>::type();
Marco Poletti31f638a2015-05-10 21:21:25 +010060 return storage->template get<T>(itr);
Marco Polettia5f49d42014-06-29 10:41:12 +010061}
62
Marco Poletti9250dea2014-11-09 09:10:53 +000063template <typename C>
Marco Polettia5f49d42014-06-29 10:41:12 +010064template <typename T>
Marco Poletti9250dea2014-11-09 09:10:53 +000065inline Provider<C>::operator T() {
Marco Polettia5f49d42014-06-29 10:41:12 +010066 return get<T>();
67}
68
Marco Polettia5f49d42014-06-29 10:41:12 +010069} // namespace fruit
70
Marco Poletti7f35b652014-11-01 10:11:37 +000071#endif // FRUIT_PROVIDER_DEFN_H