xref: /aosp_15_r20/external/google-fruit/include/fruit/provider.h (revision a65addddcf69f38db5b288d787b6b7571a57bb8f)
1*a65addddSAndroid Build Coastguard Worker /*
2*a65addddSAndroid Build Coastguard Worker  * Copyright 2014 Google Inc. All rights reserved.
3*a65addddSAndroid Build Coastguard Worker  *
4*a65addddSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*a65addddSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*a65addddSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*a65addddSAndroid Build Coastguard Worker  *
8*a65addddSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*a65addddSAndroid Build Coastguard Worker  *
10*a65addddSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*a65addddSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*a65addddSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*a65addddSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*a65addddSAndroid Build Coastguard Worker  * limitations under the License.
15*a65addddSAndroid Build Coastguard Worker  */
16*a65addddSAndroid Build Coastguard Worker 
17*a65addddSAndroid Build Coastguard Worker #ifndef FRUIT_PROVIDER_H
18*a65addddSAndroid Build Coastguard Worker #define FRUIT_PROVIDER_H
19*a65addddSAndroid Build Coastguard Worker 
20*a65addddSAndroid Build Coastguard Worker // This include is not required here, but having it here shortens the include trace in error messages.
21*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/injection_errors.h>
22*a65addddSAndroid Build Coastguard Worker 
23*a65addddSAndroid Build Coastguard Worker #include <fruit/component.h>
24*a65addddSAndroid Build Coastguard Worker 
25*a65addddSAndroid Build Coastguard Worker namespace fruit {
26*a65addddSAndroid Build Coastguard Worker 
27*a65addddSAndroid Build Coastguard Worker /**
28*a65addddSAndroid Build Coastguard Worker  * A Provider is a class that allows access to instances of the types used as parameters of the Provider template.
29*a65addddSAndroid Build Coastguard Worker  * It's possible to inject a Provider<MyClass> instead of MyClass itself, and this allows lazy injection.
30*a65addddSAndroid Build Coastguard Worker  * For example:
31*a65addddSAndroid Build Coastguard Worker  *
32*a65addddSAndroid Build Coastguard Worker  * class S {
33*a65addddSAndroid Build Coastguard Worker  * private:
34*a65addddSAndroid Build Coastguard Worker  *   Bar* bar = nullptr;
35*a65addddSAndroid Build Coastguard Worker  *
36*a65addddSAndroid Build Coastguard Worker  * public:
37*a65addddSAndroid Build Coastguard Worker  *   INJECT(S(Foo* foo, Provider<Bar> barProvider)) {
38*a65addddSAndroid Build Coastguard Worker  *     if (foo->needsBar()) {
39*a65addddSAndroid Build Coastguard Worker  *       bar = barProvider.get();
40*a65addddSAndroid Build Coastguard Worker  *     }
41*a65addddSAndroid Build Coastguard Worker  *   }
42*a65addddSAndroid Build Coastguard Worker  * };
43*a65addddSAndroid Build Coastguard Worker  *
44*a65addddSAndroid Build Coastguard Worker  * In the example above, Bar will only be created if get<Bar*> is called.
45*a65addddSAndroid Build Coastguard Worker  * This can be useful if Bar is expensive to create (or some other types that need to be injected when a Bar is injected
46*a65addddSAndroid Build Coastguard Worker  * are) or if there are other side effects of the Bar constructor that are undesirable when !foo->needsBar().
47*a65addddSAndroid Build Coastguard Worker  * It's also possible to store the Provider object in a field, and create the Bar instance when the first method that
48*a65addddSAndroid Build Coastguard Worker  * needs it is called:
49*a65addddSAndroid Build Coastguard Worker  *
50*a65addddSAndroid Build Coastguard Worker  * class S {
51*a65addddSAndroid Build Coastguard Worker  * private:
52*a65addddSAndroid Build Coastguard Worker  *   Provider<Bar> barProvider;
53*a65addddSAndroid Build Coastguard Worker  *
54*a65addddSAndroid Build Coastguard Worker  * public:
55*a65addddSAndroid Build Coastguard Worker  *   INJECT(S(Provider<Bar> barProvider))
56*a65addddSAndroid Build Coastguard Worker  *   : barProvider(barProvider) {
57*a65addddSAndroid Build Coastguard Worker  *   }
58*a65addddSAndroid Build Coastguard Worker  *
59*a65addddSAndroid Build Coastguard Worker  *   void execute() {
60*a65addddSAndroid Build Coastguard Worker  *     if (...) {
61*a65addddSAndroid Build Coastguard Worker  *       Bar* bar = barProvider.get();
62*a65addddSAndroid Build Coastguard Worker  *       ...
63*a65addddSAndroid Build Coastguard Worker  *     }
64*a65addddSAndroid Build Coastguard Worker  *   }
65*a65addddSAndroid Build Coastguard Worker  * };
66*a65addddSAndroid Build Coastguard Worker  *
67*a65addddSAndroid Build Coastguard Worker  * As usual, Fruit ensures that (at most) one instance is ever created in a given injector; so if the Bar object was
68*a65addddSAndroid Build Coastguard Worker  * already constructed, the get() will simply return it.
69*a65addddSAndroid Build Coastguard Worker  *
70*a65addddSAndroid Build Coastguard Worker  * Note that you can inject a Provider<Foo> whenever you could have injected a Foo.
71*a65addddSAndroid Build Coastguard Worker  * It doesn't matter if Foo was bound using PartialComponent::registerProvider() or not.
72*a65addddSAndroid Build Coastguard Worker  */
73*a65addddSAndroid Build Coastguard Worker template <typename C>
74*a65addddSAndroid Build Coastguard Worker class Provider {
75*a65addddSAndroid Build Coastguard Worker private:
76*a65addddSAndroid Build Coastguard Worker   using Check1 =
77*a65addddSAndroid Build Coastguard Worker       typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
78*a65addddSAndroid Build Coastguard Worker           fruit::impl::meta::RemoveConstFromTypes(fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>))>>::type;
79*a65addddSAndroid Build Coastguard Worker   // Force instantiation of Check1.
80*a65addddSAndroid Build Coastguard Worker   static_assert(true || sizeof(Check1), "");
81*a65addddSAndroid Build Coastguard Worker 
82*a65addddSAndroid Build Coastguard Worker   using Check2 =
83*a65addddSAndroid Build Coastguard Worker       typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNotAnnotatedTypes(
84*a65addddSAndroid Build Coastguard Worker           fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>)>>::type;
85*a65addddSAndroid Build Coastguard Worker   // Force instantiation of Check2.
86*a65addddSAndroid Build Coastguard Worker   static_assert(true || sizeof(Check2), "");
87*a65addddSAndroid Build Coastguard Worker 
88*a65addddSAndroid Build Coastguard Worker public:
89*a65addddSAndroid Build Coastguard Worker   /**
90*a65addddSAndroid Build Coastguard Worker    * Returns an instance of the specified type. The following variations are allowed:
91*a65addddSAndroid Build Coastguard Worker    *
92*a65addddSAndroid Build Coastguard Worker    * On a Provider<Foo>, you can call:
93*a65addddSAndroid Build Coastguard Worker    *
94*a65addddSAndroid Build Coastguard Worker    * - provider.get<Foo>()
95*a65addddSAndroid Build Coastguard Worker    * - provider.get<Foo*>()
96*a65addddSAndroid Build Coastguard Worker    * - provider.get<Foo&>()
97*a65addddSAndroid Build Coastguard Worker    * - provider.get<const Foo*>()
98*a65addddSAndroid Build Coastguard Worker    * - provider.get<const Foo&>()
99*a65addddSAndroid Build Coastguard Worker    * - provider.get<std::shared_ptr<Foo>>()
100*a65addddSAndroid Build Coastguard Worker    * - provider.get<Provider<Foo>>()
101*a65addddSAndroid Build Coastguard Worker    * - provider.get<Provider<const Foo>>()
102*a65addddSAndroid Build Coastguard Worker    *
103*a65addddSAndroid Build Coastguard Worker    * On a Provider<const Foo>, you can call:
104*a65addddSAndroid Build Coastguard Worker    *
105*a65addddSAndroid Build Coastguard Worker    * - provider.get<Foo>()
106*a65addddSAndroid Build Coastguard Worker    * - provider.get<const Foo*>()
107*a65addddSAndroid Build Coastguard Worker    * - provider.get<const Foo&>()
108*a65addddSAndroid Build Coastguard Worker    * - provider.get<Provider<const Foo>>()
109*a65addddSAndroid Build Coastguard Worker    *
110*a65addddSAndroid Build Coastguard Worker    * The shared_ptr version is slightly slower than the ones returning a reference/pointer, use those if possible.
111*a65addddSAndroid Build Coastguard Worker    *
112*a65addddSAndroid Build Coastguard Worker    * Calling get<> repeatedly for the same class with the same injector will return the same instance (except for the
113*a65addddSAndroid Build Coastguard Worker    * first variation above, that returns a value; in that case, another copy of the same instance will be returned).
114*a65addddSAndroid Build Coastguard Worker    */
115*a65addddSAndroid Build Coastguard Worker   template <typename T>
116*a65addddSAndroid Build Coastguard Worker   T get();
117*a65addddSAndroid Build Coastguard Worker 
118*a65addddSAndroid Build Coastguard Worker   /**
119*a65addddSAndroid Build Coastguard Worker    * This is a convenient way to call get(). E.g.:
120*a65addddSAndroid Build Coastguard Worker    *
121*a65addddSAndroid Build Coastguard Worker    * C& x(provider);
122*a65addddSAndroid Build Coastguard Worker    *
123*a65addddSAndroid Build Coastguard Worker    * is equivalent to:
124*a65addddSAndroid Build Coastguard Worker    *
125*a65addddSAndroid Build Coastguard Worker    * C& x = provider.get<C&>();
126*a65addddSAndroid Build Coastguard Worker    */
127*a65addddSAndroid Build Coastguard Worker   template <typename T>
128*a65addddSAndroid Build Coastguard Worker   explicit operator T();
129*a65addddSAndroid Build Coastguard Worker 
130*a65addddSAndroid Build Coastguard Worker   /**
131*a65addddSAndroid Build Coastguard Worker    * This is equivalent to get<C*>(), it's provided for convenience.
132*a65addddSAndroid Build Coastguard Worker    */
133*a65addddSAndroid Build Coastguard Worker   C* get();
134*a65addddSAndroid Build Coastguard Worker 
135*a65addddSAndroid Build Coastguard Worker private:
136*a65addddSAndroid Build Coastguard Worker   // This is NOT owned by the provider object. It is not deleted on destruction.
137*a65addddSAndroid Build Coastguard Worker   // This is never nullptr.
138*a65addddSAndroid Build Coastguard Worker   fruit::impl::InjectorStorage* storage;
139*a65addddSAndroid Build Coastguard Worker   fruit::impl::InjectorStorage::Graph::node_iterator itr;
140*a65addddSAndroid Build Coastguard Worker 
141*a65addddSAndroid Build Coastguard Worker   Provider(fruit::impl::InjectorStorage* storage, fruit::impl::InjectorStorage::Graph::node_iterator itr);
142*a65addddSAndroid Build Coastguard Worker 
143*a65addddSAndroid Build Coastguard Worker   friend class fruit::impl::InjectorStorage;
144*a65addddSAndroid Build Coastguard Worker 
145*a65addddSAndroid Build Coastguard Worker   template <typename T>
146*a65addddSAndroid Build Coastguard Worker   friend struct fruit::impl::GetFirstStage;
147*a65addddSAndroid Build Coastguard Worker 
148*a65addddSAndroid Build Coastguard Worker   template <typename... OtherPs>
149*a65addddSAndroid Build Coastguard Worker   friend class Injector;
150*a65addddSAndroid Build Coastguard Worker };
151*a65addddSAndroid Build Coastguard Worker 
152*a65addddSAndroid Build Coastguard Worker } // namespace fruit
153*a65addddSAndroid Build Coastguard Worker 
154*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/provider.defn.h>
155*a65addddSAndroid Build Coastguard Worker 
156*a65addddSAndroid Build Coastguard Worker #endif // FRUIT_PROVIDER_H
157