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