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
17 #ifndef FRUIT_PROVIDER_DEFN_H
18 #define FRUIT_PROVIDER_DEFN_H
19
20 #include <fruit/impl/injector/injector_storage.h>
21
22 // Redundant, but makes KDevelop happy.
23 #include <fruit/provider.h>
24
25 namespace fruit {
26
27 template <typename C>
Provider(fruit::impl::InjectorStorage * storage,fruit::impl::InjectorStorage::Graph::node_iterator itr)28 inline Provider<C>::Provider(fruit::impl::InjectorStorage* storage,
29 fruit::impl::InjectorStorage::Graph::node_iterator itr)
30 : storage(storage), itr(itr) {}
31
32 template <typename C>
get()33 inline C* Provider<C>::get() {
34 return get<C*>();
35 }
36
37 namespace impl {
38 namespace meta {
39
40 template <typename C>
41 struct ProviderImplHelper {
42
43 template <typename T>
44 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)))>;
50 };
51
52 } // namespace meta
53 } // namespace impl
54
55 template <typename C>
56 template <typename T>
get()57 inline T Provider<C>::get() {
58 using E = typename fruit::impl::meta::ProviderImplHelper<C>::template CheckGet<T>;
59 (void)typename fruit::impl::meta::CheckIfError<E>::type();
60 return storage->template get<T>(itr);
61 }
62
63 template <typename C>
64 template <typename T>
T()65 inline Provider<C>::operator T() {
66 return get<T>();
67 }
68
69 } // namespace fruit
70
71 #endif // FRUIT_PROVIDER_DEFN_H
72