| /* |
| * Copyright 2014 Google Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef FRUIT_INJECTION_ERRORS_H |
| #define FRUIT_INJECTION_ERRORS_H |
| |
| #include <fruit/impl/fruit_assert.h> |
| #include <fruit/impl/meta/set.h> |
| |
| namespace fruit { |
| namespace impl { |
| |
| template <typename... Ts> |
| struct AlwaysFalse { |
| static constexpr bool value = false; |
| }; |
| |
| template <typename T> |
| struct NoBindingFoundError { |
| static_assert(AlwaysFalse<T>::value, "No explicit binding nor C::Inject definition was found for T."); |
| }; |
| |
| template <typename T, typename C> |
| struct NoBindingFoundForAbstractClassError { |
| static_assert(AlwaysFalse<T>::value, |
| "No explicit binding was found for T, and note that C is an abstract class (so Fruit can't auto-inject " |
| "this type, " |
| "even if it has an Inject typedef or an INJECT annotation that will be ignored)."); |
| }; |
| |
| template <typename... Ts> |
| struct RepeatedTypesError { |
| static_assert(AlwaysFalse<Ts...>::value, |
| "A type was specified more than once. Requirements and provided types should be unique."); |
| }; |
| |
| template <typename... TypesInLoop> |
| struct SelfLoopError { |
| static_assert(AlwaysFalse<TypesInLoop...>::value, |
| "Found a loop in the dependencies! The types in TypesInLoop all depend on the next, and the " |
| "last one depends on the first."); |
| }; |
| |
| template <typename T, typename C> |
| struct NonClassTypeError { |
| static_assert(AlwaysFalse<T>::value, "A non-class type T was specified. Use C instead."); |
| }; |
| |
| template <typename AnnotatedT, typename T> |
| struct AnnotatedTypeError { |
| static_assert(AlwaysFalse<T>::value, "An annotated type was specified where a non-annotated type was expected."); |
| }; |
| |
| template <typename C> |
| struct TypeAlreadyBoundError { |
| static_assert(AlwaysFalse<C>::value, "Trying to bind C but it is already bound."); |
| }; |
| |
| template <typename RequiredSignature, typename SignatureInInjectTypedef> |
| struct RequiredFactoryWithDifferentSignatureError { |
| static_assert(AlwaysFalse<RequiredSignature>::value, |
| "The required C factory doesn't have the same signature as the Inject annotation in C."); |
| }; |
| |
| template <typename Signature, typename SignatureInLambda> |
| struct AnnotatedSignatureDifferentFromLambdaSignatureError { |
| static_assert(AlwaysFalse<Signature>::value, |
| "The annotated signature specified is not the same as the lambda's signature (after removing " |
| "annotations)."); |
| }; |
| |
| template <typename... DuplicatedTypes> |
| struct DuplicateTypesInComponentError { |
| static_assert(AlwaysFalse<DuplicatedTypes...>::value, |
| "The installed component provides some types that are already provided by the current " |
| "component."); |
| }; |
| |
| template <typename... Requirements> |
| struct InjectorWithRequirementsError { |
| static_assert(AlwaysFalse<Requirements...>::value, |
| "Injectors can't have requirements. If you want Fruit to try auto-resolving the requirements " |
| "in the injector's scope, cast the component to a component with no requirements before " |
| "constructing the injector with it."); |
| }; |
| |
| template <typename C, typename CandidateSignature> |
| struct InjectTypedefNotASignatureError { |
| static_assert(AlwaysFalse<C>::value, "C::Inject should be a typedef to a signature, e.g. C(int)"); |
| }; |
| |
| template <typename C, typename SignatureReturnType> |
| struct InjectTypedefForWrongClassError { |
| static_assert(AlwaysFalse<C>::value, |
| "C::Inject is a signature, but does not return a C. Maybe the class C has no Inject typedef " |
| "and inherited the base class' one? If that's not the case, make sure it returns just C, not " |
| "C* or other types."); |
| }; |
| |
| template <typename C> |
| struct InjectTypedefWithAnnotationError { |
| static_assert(AlwaysFalse<C>::value, |
| "C::Inject is a signature that returns an annotated type. The annotation must be removed, " |
| "Fruit will deduce the correct annotation based on how the required binding."); |
| }; |
| |
| template <typename CandidateSignature> |
| struct NotASignatureError { |
| static_assert(AlwaysFalse<CandidateSignature>::value, |
| "CandidateSignature was specified as parameter, but it's not a signature. Signatures are of " |
| "the form MyClass(int, float)."); |
| }; |
| |
| template <typename CandidateSignature> |
| struct AssistedParamInRegisterConstructorSignatureError { |
| static_assert(AlwaysFalse<CandidateSignature>::value, |
| "CandidateSignature was used as signature for a registerConstructor() (explicit or implicit via the " |
| "INJECT macro / Inject typedef) but it contains an assisted parameter. When using assisted parameters" |
| "You need to inject a factory like std::function<std::unique_ptr<MyClass>(int, float)> instead of " |
| "injecting MyClass directly. If you used an explicit registerConstructor(), you also need to switch " |
| "that to registerFactory()."); |
| }; |
| |
| template <typename CandidateLambda> |
| struct NotALambdaError { |
| static_assert(AlwaysFalse<CandidateLambda>::value, |
| "CandidateLambda was specified as parameter, but it's not a lambda."); |
| }; |
| |
| template <typename Signature> |
| struct ConstructorDoesNotExistError { |
| static_assert(AlwaysFalse<Signature>::value, "The specified constructor does not exist."); |
| }; |
| |
| template <typename I, typename C> |
| struct NotABaseClassOfError { |
| static_assert(AlwaysFalse<I>::value, "I is not a base class of C."); |
| }; |
| |
| template <typename ProviderType> |
| struct FunctorUsedAsProviderError { |
| static_assert(AlwaysFalse<ProviderType>::value, |
| "A stateful lambda or a non-lambda functor was used as provider. Only functions and stateless " |
| "lambdas can be used as providers."); |
| }; |
| |
| template <typename... ComponentRequirements> |
| struct ComponentWithRequirementsInInjectorError { |
| static_assert(AlwaysFalse<ComponentRequirements...>::value, |
| "When using the two-argument constructor of Injector, the component used as second parameter " |
| "must not have requirements (while the normalized component can), but the specified component " |
| "requires ComponentRequirements."); |
| }; |
| |
| template <typename... UnsatisfiedRequirements> |
| struct UnsatisfiedRequirementsInNormalizedComponentError { |
| static_assert(AlwaysFalse<UnsatisfiedRequirements...>::value, |
| "The requirements in UnsatisfiedRequirements are required by the NormalizedComponent but are " |
| "not provided by the Component (second parameter of the Injector constructor)."); |
| }; |
| |
| template <typename... TypesNotProvided> |
| struct TypesInInjectorNotProvidedError { |
| static_assert(AlwaysFalse<TypesNotProvided...>::value, |
| "The types in TypesNotProvided are declared as provided by the injector, but none of the two " |
| "components passed to the Injector constructor provides them."); |
| }; |
| |
| template <typename... TypesProvidedAsConstOnly> |
| struct TypesInInjectorProvidedAsConstOnlyError { |
| static_assert( |
| AlwaysFalse<TypesProvidedAsConstOnly...>::value, |
| "The types in TypesProvidedAsConstOnly are declared as non-const provided types by the injector, but the " |
| "components passed to the Injector constructor provide them as const only. You should mark them as const in the " |
| "injector (e.g., switching from Injector<T> to Injector<const T>) or mark them as non-const in the " |
| "Component/NormalizedComponent (e.g. switching from [Normalized]Component<const T> to " |
| "[Normalized]Component<T>)."); |
| }; |
| |
| template <typename T> |
| struct TypeNotProvidedError { |
| static_assert(AlwaysFalse<T>::value, |
| "Trying to get an instance of T, but it is not provided by this Provider/Injector."); |
| }; |
| |
| template <typename T> |
| struct TypeProvidedAsConstOnlyError { |
| static_assert( |
| AlwaysFalse<T>::value, |
| "Trying to get an instance of T, but it is only provided as a constant by this Provider/Injector and a non-const " |
| "pointer/reference/Provider was requested. You should either switch to injecting a const value (e.g. switching " |
| "from" |
| " injecting T*, T&, std::unique_ptr<T> or Provider<T> to injecting a T, const T*, const T& or Provider<const T>) " |
| "or get the value from an Injector/Provider that provides it as a non-const type (e.g. switching from calling " |
| "get " |
| "on an Injector<const T> or on a Provider<const T> to calling get on an Injector<T> or a Provider<T>)."); |
| }; |
| |
| template <typename T> |
| struct NonConstBindingRequiredButConstBindingProvidedError { |
| static_assert( |
| AlwaysFalse<T>::value, |
| "The type T was provided as constant, however one of the constructors/providers/factories in this component " |
| "requires it as a non-constant (or this Component declares it as a non-const provided/required type). " |
| "If you want to only have a const binding for this type, you should change the places that use the type to " |
| "inject " |
| "a constant value (e.g. T, const T*, const T& and Provider<const T> are ok while you should avoid injecting T*, " |
| "T&," |
| " std::unique_ptr<T> and Provider<T>) and if the type is in Component<...> make sure that it's marked as const " |
| "there" |
| " (e.g. Component<const T> and Component<Required<const T>> are ok while Component<T> and Component<Required<T>> " |
| "are " |
| "not. " |
| "On the other hand, if you want to have a non-const binding for this type, you should switch to a non-const " |
| "bindInstance (if you're binding an instance) or changing any installed component functions to declare the type " |
| "as " |
| "non-const, e.g. Component<T> or Component<Required<T>> instead of Component<const T> and " |
| "Component<Required<const T>>."); |
| }; |
| |
| template <typename C, typename InjectSignature> |
| struct NoConstructorMatchingInjectSignatureError { |
| static_assert(AlwaysFalse<C>::value, |
| "C contains an Inject typedef but it's not constructible with the specified types"); |
| }; |
| |
| template <typename ExpectedSignature, typename FunctorSignature> |
| struct FunctorSignatureDoesNotMatchError { |
| static_assert(AlwaysFalse<ExpectedSignature>::value, |
| "Unexpected functor signature (it should be the same as ExpectedSignature minus any Assisted " |
| "types)."); |
| }; |
| |
| template <typename Signature> |
| struct FactoryReturningPointerError { |
| static_assert(AlwaysFalse<Signature>::value, |
| "The specified factory returns a pointer. This is not supported; return a value or an " |
| "std::unique_ptr instead."); |
| }; |
| |
| template <typename Lambda> |
| struct LambdaWithCapturesError { |
| // It's not guaranteed by the standard, but it's reasonable to expect lambdas with no captures |
| // to be empty. This is always the case in GCC and Clang, but is not guaranteed to work in all |
| // conforming C++ compilers. If this error happens for a lambda with no captures, please file a |
| // bug at https://github.com/google/fruit/issues and indicate the compiler (with version) that |
| // you're using. |
| static_assert(AlwaysFalse<Lambda>::value, "Only lambdas with no captures are supported."); |
| }; |
| |
| template <typename Lambda> |
| struct NonTriviallyCopyableLambdaError { |
| // It's not guaranteed by the standard, but it's reasonable to expect lambdas with no captures |
| // to be trivially copyable. This is always the case in GCC and Clang, but is not guaranteed to |
| // work in all conforming C++ compilers. If this error happens for a lambda with no captures, |
| // please file a bug at https://github.com/google/fruit/issues and indicate the compiler (with |
| // version) that you're using. |
| static_assert(AlwaysFalse<Lambda>::value, |
| "Only trivially copyable lambdas are supported. Make sure that your lambda has no captures."); |
| }; |
| |
| template <typename C> |
| struct CannotConstructAbstractClassError { |
| static_assert(AlwaysFalse<C>::value, "The specified class can't be constructed because it's an abstract class."); |
| }; |
| |
| template <typename C> |
| struct InterfaceBindingToSelfError { |
| static_assert(AlwaysFalse<C>::value, |
| "The type C was bound to itself. If this was intentional, to \"tell Fruit to inject the type" |
| " C\", this binding is unnecessary, just remove it. bind<I,C>() is to tell Fruit about" |
| " base-derived class relationships."); |
| }; |
| |
| template <typename TypeParameter, typename TypeOfValue> |
| struct TypeMismatchInBindInstanceError { |
| static_assert(AlwaysFalse<TypeParameter>::value, |
| "A type parameter was specified in bindInstance() but it doesn't match the value type" |
| " (even after removing the fruit::Annotation<>, if any). Please change the type parameter" |
| " to be the same as the type of the value (or a subclass)."); |
| }; |
| |
| template <typename RequiredType> |
| struct RequiredTypesInComponentArgumentsError { |
| static_assert(AlwaysFalse<RequiredType>::value, |
| "A Required<...> type was passed as a non-first template parameter to fruit::Component or " |
| "fruit::NormalizedComponent. " |
| "All required types (if any) should be passed together as a single Required<> type passed as the first " |
| "type argument of fruit::Component (and fruit::NormalizedComponent). For example, write " |
| "fruit::Component<fruit::Required<Foo, Bar>, Baz> instead of " |
| "fruit::Component<fruit::Required<Foo>, fruit::Required<Bar>, Baz>."); |
| }; |
| |
| template <typename T> |
| struct NonInjectableTypeError { |
| static_assert( |
| AlwaysFalse<T>::value, |
| "The type T is not injectable. Injectable types are of the form X, X*, X&, const X, const X*, const X&, " |
| "std::shared_ptr<X>, or Provider<X> where X is a fundamental type (excluding void), a class, a struct or " |
| "an enum."); |
| }; |
| |
| template <typename T> |
| struct ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError { |
| static_assert( |
| AlwaysFalse<T>::value, |
| "The type T was declared as a const Required type in the returned Component, however a non-const binding is " |
| "required. You should either change all the usages of this type so that they no longer require a non-const " |
| "binding " |
| "(i.e., you shouldn't inject T*, T& or std::shared_ptr<T>) or you should remove the 'const' in the type of the " |
| "returned Component, e.g. changing fruit::Component<fruit::Required<const T, ...>, ...> to " |
| "fruit::Component<fruit::Required<T, ...>, ...>."); |
| }; |
| |
| template <typename T> |
| struct ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError { |
| static_assert( |
| AlwaysFalse<T>::value, |
| "registerProvider() was called with a lambda that returns a pointer to T, but T is an abstract class with no " |
| "virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor (the one " |
| "of " |
| "the concrete class that was then casted to T). You must either add a virtual destructor to T or change the " |
| "registerProvider() call to return a pointer to the concrete class (and then add a bind<T, TImpl>() so that T is " |
| "bound)."); |
| }; |
| |
| template <typename T> |
| struct MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError { |
| static_assert( |
| AlwaysFalse<T>::value, |
| "registerMultibindingProvider() was called with a lambda that returns a pointer to T, but T is an abstract class " |
| "with no virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor " |
| "(the " |
| "one of the concrete class that was then casted to T). You must add a virtual destructor to T or replace the " |
| "registerMultibindingProvider() with a registerProvider() for the concrete class and an addMultibinding() for T. " |
| "Note that with the latter, if you end up with multiple addMultibinding() calls for the same concrete class, " |
| "there will be only one instance of the concrete class in the injector, not one per addMultibdinding() call; if " |
| "you want separate instances you might want to use annotated injection for the concrete class (so that there's " |
| "one " |
| "instance per annotation)."); |
| }; |
| |
| template <typename T> |
| struct RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError { |
| static_assert(AlwaysFalse<T>::value, |
| "registerFactory() was called with a lambda that returns a std::unique_ptr<T>, but T is an abstract " |
| "class with no " |
| "virtual destructor so when the returned std::unique_ptr<T> object is deleted the wrong destructor " |
| "will be called " |
| "(T's destructor instead of the one of the concrete class that was then casted to T). You must add a " |
| "virtual destructor to T."); |
| }; |
| |
| template <typename BaseFactory, typename DerivedFactory> |
| struct FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError { |
| static_assert( |
| AlwaysFalse<BaseFactory>::value, |
| "Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr " |
| "of " |
| "a class with no virtual destructor, so when the std::unique_ptr object is destroyed the wrong destructor would " |
| "be " |
| "called (the one in the base class instead of the derived class). To avoid this, you must add a virtual " |
| "destructor to the base class."); |
| }; |
| |
| template <typename Arg> |
| struct IncorrectArgTypePassedToInstallComponentFuntionsError { |
| static_assert( |
| AlwaysFalse<Arg>::value, |
| "All arguments passed to installComponentFunctions() must be fruit::ComponentFunction<...> objects but an " |
| "argument with type Arg was passed instead."); |
| }; |
| |
| struct LambdaWithCapturesErrorTag { |
| template <typename Lambda> |
| using apply = LambdaWithCapturesError<Lambda>; |
| }; |
| |
| struct NonTriviallyCopyableLambdaErrorTag { |
| template <typename Lambda> |
| using apply = NonTriviallyCopyableLambdaError<Lambda>; |
| }; |
| |
| struct FactoryReturningPointerErrorTag { |
| template <typename Signature> |
| using apply = FactoryReturningPointerError<Signature>; |
| }; |
| |
| struct NoBindingFoundErrorTag { |
| template <typename T> |
| using apply = NoBindingFoundError<T>; |
| }; |
| |
| struct RepeatedTypesErrorTag { |
| template <typename... Ts> |
| using apply = RepeatedTypesError<Ts...>; |
| }; |
| |
| struct SelfLoopErrorTag { |
| template <typename... TypesInLoop> |
| using apply = SelfLoopError<TypesInLoop...>; |
| }; |
| |
| struct NonClassTypeErrorTag { |
| template <typename T, typename C> |
| using apply = NonClassTypeError<T, C>; |
| }; |
| |
| struct AnnotatedTypeErrorTag { |
| template <typename T, typename C> |
| using apply = AnnotatedTypeError<T, C>; |
| }; |
| |
| struct TypeAlreadyBoundErrorTag { |
| template <typename C> |
| using apply = TypeAlreadyBoundError<C>; |
| }; |
| |
| struct RequiredFactoryWithDifferentSignatureErrorTag { |
| template <typename RequiredSignature, typename SignatureInInjectTypedef> |
| using apply = RequiredFactoryWithDifferentSignatureError<RequiredSignature, SignatureInInjectTypedef>; |
| }; |
| |
| struct AnnotatedSignatureDifferentFromLambdaSignatureErrorTag { |
| template <typename Signature, typename SignatureInLambda> |
| using apply = AnnotatedSignatureDifferentFromLambdaSignatureError<Signature, SignatureInLambda>; |
| }; |
| |
| struct DuplicateTypesInComponentErrorTag { |
| template <typename... DuplicatedTypes> |
| using apply = DuplicateTypesInComponentError<DuplicatedTypes...>; |
| }; |
| |
| struct InjectorWithRequirementsErrorTag { |
| template <typename... Requirements> |
| using apply = InjectorWithRequirementsError<Requirements...>; |
| }; |
| |
| struct ComponentWithRequirementsInInjectorErrorTag { |
| template <typename... ComponentRequirements> |
| using apply = ComponentWithRequirementsInInjectorError<ComponentRequirements...>; |
| }; |
| |
| struct InjectTypedefNotASignatureErrorTag { |
| template <typename C, typename TypeInInjectTypedef> |
| using apply = InjectTypedefNotASignatureError<C, TypeInInjectTypedef>; |
| }; |
| |
| struct InjectTypedefForWrongClassErrorTag { |
| template <typename C, typename ReturnTypeOfInjectTypedef> |
| using apply = InjectTypedefForWrongClassError<C, ReturnTypeOfInjectTypedef>; |
| }; |
| |
| struct InjectTypedefWithAnnotationErrorTag { |
| template <typename C> |
| using apply = InjectTypedefWithAnnotationError<C>; |
| }; |
| |
| struct UnsatisfiedRequirementsInNormalizedComponentErrorTag { |
| template <typename... UnsatisfiedRequirements> |
| using apply = UnsatisfiedRequirementsInNormalizedComponentError<UnsatisfiedRequirements...>; |
| }; |
| |
| struct TypesInInjectorNotProvidedErrorTag { |
| template <typename... TypesNotProvided> |
| using apply = TypesInInjectorNotProvidedError<TypesNotProvided...>; |
| }; |
| |
| struct TypesInInjectorProvidedAsConstOnlyErrorTag { |
| template <typename... TypesProvidedAsConstOnly> |
| using apply = TypesInInjectorProvidedAsConstOnlyError<TypesProvidedAsConstOnly...>; |
| }; |
| |
| struct FunctorUsedAsProviderErrorTag { |
| template <typename ProviderType> |
| using apply = FunctorUsedAsProviderError<ProviderType>; |
| }; |
| |
| struct ConstructorDoesNotExistErrorTag { |
| template <typename Signature> |
| using apply = ConstructorDoesNotExistError<Signature>; |
| }; |
| |
| struct NotABaseClassOfErrorTag { |
| template <typename I, typename C> |
| using apply = NotABaseClassOfError<I, C>; |
| }; |
| |
| struct NotASignatureErrorTag { |
| template <typename CandidateSignature> |
| using apply = NotASignatureError<CandidateSignature>; |
| }; |
| |
| struct AssistedParamInRegisterConstructorSignatureErrorTag { |
| template <typename CandidateSignature> |
| using apply = AssistedParamInRegisterConstructorSignatureError<CandidateSignature>; |
| }; |
| |
| struct NotALambdaErrorTag { |
| template <typename CandidateLambda> |
| using apply = NotALambdaError<CandidateLambda>; |
| }; |
| |
| struct TypeNotProvidedErrorTag { |
| template <typename T> |
| using apply = TypeNotProvidedError<T>; |
| }; |
| |
| struct TypeProvidedAsConstOnlyErrorTag { |
| template <typename T> |
| using apply = TypeProvidedAsConstOnlyError<T>; |
| }; |
| |
| struct NonConstBindingRequiredButConstBindingProvidedErrorTag { |
| template <typename T> |
| using apply = NonConstBindingRequiredButConstBindingProvidedError<T>; |
| }; |
| |
| struct NoConstructorMatchingInjectSignatureErrorTag { |
| template <typename C, typename InjectSignature> |
| using apply = NoConstructorMatchingInjectSignatureError<C, InjectSignature>; |
| }; |
| |
| struct FunctorSignatureDoesNotMatchErrorTag { |
| template <typename ExpectedSignature, typename FunctorSignature> |
| using apply = FunctorSignatureDoesNotMatchError<ExpectedSignature, FunctorSignature>; |
| }; |
| |
| struct CannotConstructAbstractClassErrorTag { |
| template <typename C> |
| using apply = CannotConstructAbstractClassError<C>; |
| }; |
| |
| struct NoBindingFoundForAbstractClassErrorTag { |
| template <typename T, typename C> |
| using apply = NoBindingFoundForAbstractClassError<T, C>; |
| }; |
| |
| struct InterfaceBindingToSelfErrorTag { |
| template <typename C> |
| using apply = InterfaceBindingToSelfError<C>; |
| }; |
| |
| struct TypeMismatchInBindInstanceErrorTag { |
| template <typename TypeParameter, typename TypeOfValue> |
| using apply = TypeMismatchInBindInstanceError<TypeParameter, TypeOfValue>; |
| }; |
| |
| struct RequiredTypesInComponentArgumentsErrorTag { |
| template <typename RequiredType> |
| using apply = RequiredTypesInComponentArgumentsError<RequiredType>; |
| }; |
| |
| struct NonInjectableTypeErrorTag { |
| template <typename T> |
| using apply = NonInjectableTypeError<T>; |
| }; |
| |
| struct ConstBindingDeclaredAsRequiredButNonConstBindingRequiredErrorTag { |
| template <typename T> |
| using apply = ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<T>; |
| }; |
| |
| struct ProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag { |
| template <typename T> |
| using apply = ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<T>; |
| }; |
| |
| struct MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag { |
| template <typename T> |
| using apply = MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<T>; |
| }; |
| |
| struct RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorErrorTag { |
| template <typename T> |
| using apply = RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError<T>; |
| }; |
| |
| struct FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorErrorTag { |
| template <typename BaseFactory, typename DerivedFactory> |
| using apply = FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<BaseFactory, DerivedFactory>; |
| }; |
| |
| struct IncorrectArgTypePassedToInstallComponentFuntionsErrorTag { |
| template <typename Arg> |
| using apply = IncorrectArgTypePassedToInstallComponentFuntionsError<Arg>; |
| }; |
| |
| } // namespace impl |
| } // namespace fruit |
| |
| #endif // FRUIT_INJECTION_ERRORS_H |