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_INJECTION_ERRORS_H 18 #define FRUIT_INJECTION_ERRORS_H 19 20 #include <fruit/impl/fruit_assert.h> 21 #include <fruit/impl/meta/set.h> 22 23 namespace fruit { 24 namespace impl { 25 26 template <typename... Ts> 27 struct AlwaysFalse { 28 static constexpr bool value = false; 29 }; 30 31 template <typename T> 32 struct NoBindingFoundError { 33 static_assert(AlwaysFalse<T>::value, "No explicit binding nor C::Inject definition was found for T."); 34 }; 35 36 template <typename T, typename C> 37 struct NoBindingFoundForAbstractClassError { 38 static_assert(AlwaysFalse<T>::value, 39 "No explicit binding was found for T, and note that C is an abstract class (so Fruit can't auto-inject " 40 "this type, " 41 "even if it has an Inject typedef or an INJECT annotation that will be ignored)."); 42 }; 43 44 template <typename... Ts> 45 struct RepeatedTypesError { 46 static_assert(AlwaysFalse<Ts...>::value, 47 "A type was specified more than once. Requirements and provided types should be unique."); 48 }; 49 50 template <typename... TypesInLoop> 51 struct SelfLoopError { 52 static_assert(AlwaysFalse<TypesInLoop...>::value, 53 "Found a loop in the dependencies! The types in TypesInLoop all depend on the next, and the " 54 "last one depends on the first."); 55 }; 56 57 template <typename T, typename C> 58 struct NonClassTypeError { 59 static_assert(AlwaysFalse<T>::value, "A non-class type T was specified. Use C instead."); 60 }; 61 62 template <typename AnnotatedT, typename T> 63 struct AnnotatedTypeError { 64 static_assert(AlwaysFalse<T>::value, "An annotated type was specified where a non-annotated type was expected."); 65 }; 66 67 template <typename C> 68 struct TypeAlreadyBoundError { 69 static_assert(AlwaysFalse<C>::value, "Trying to bind C but it is already bound."); 70 }; 71 72 template <typename RequiredSignature, typename SignatureInInjectTypedef> 73 struct RequiredFactoryWithDifferentSignatureError { 74 static_assert(AlwaysFalse<RequiredSignature>::value, 75 "The required C factory doesn't have the same signature as the Inject annotation in C."); 76 }; 77 78 template <typename Signature, typename SignatureInLambda> 79 struct AnnotatedSignatureDifferentFromLambdaSignatureError { 80 static_assert(AlwaysFalse<Signature>::value, 81 "The annotated signature specified is not the same as the lambda's signature (after removing " 82 "annotations)."); 83 }; 84 85 template <typename... DuplicatedTypes> 86 struct DuplicateTypesInComponentError { 87 static_assert(AlwaysFalse<DuplicatedTypes...>::value, 88 "The installed component provides some types that are already provided by the current " 89 "component."); 90 }; 91 92 template <typename... Requirements> 93 struct InjectorWithRequirementsError { 94 static_assert(AlwaysFalse<Requirements...>::value, 95 "Injectors can't have requirements. If you want Fruit to try auto-resolving the requirements " 96 "in the injector's scope, cast the component to a component with no requirements before " 97 "constructing the injector with it."); 98 }; 99 100 template <typename C, typename CandidateSignature> 101 struct InjectTypedefNotASignatureError { 102 static_assert(AlwaysFalse<C>::value, "C::Inject should be a typedef to a signature, e.g. C(int)"); 103 }; 104 105 template <typename C, typename SignatureReturnType> 106 struct InjectTypedefForWrongClassError { 107 static_assert(AlwaysFalse<C>::value, 108 "C::Inject is a signature, but does not return a C. Maybe the class C has no Inject typedef " 109 "and inherited the base class' one? If that's not the case, make sure it returns just C, not " 110 "C* or other types."); 111 }; 112 113 template <typename C> 114 struct InjectTypedefWithAnnotationError { 115 static_assert(AlwaysFalse<C>::value, 116 "C::Inject is a signature that returns an annotated type. The annotation must be removed, " 117 "Fruit will deduce the correct annotation based on how the required binding."); 118 }; 119 120 template <typename CandidateSignature> 121 struct NotASignatureError { 122 static_assert(AlwaysFalse<CandidateSignature>::value, 123 "CandidateSignature was specified as parameter, but it's not a signature. Signatures are of " 124 "the form MyClass(int, float)."); 125 }; 126 127 template <typename CandidateSignature> 128 struct AssistedParamInRegisterConstructorSignatureError { 129 static_assert(AlwaysFalse<CandidateSignature>::value, 130 "CandidateSignature was used as signature for a registerConstructor() (explicit or implicit via the " 131 "INJECT macro / Inject typedef) but it contains an assisted parameter. When using assisted parameters" 132 "You need to inject a factory like std::function<std::unique_ptr<MyClass>(int, float)> instead of " 133 "injecting MyClass directly. If you used an explicit registerConstructor(), you also need to switch " 134 "that to registerFactory()."); 135 }; 136 137 template <typename CandidateLambda> 138 struct NotALambdaError { 139 static_assert(AlwaysFalse<CandidateLambda>::value, 140 "CandidateLambda was specified as parameter, but it's not a lambda."); 141 }; 142 143 template <typename Signature> 144 struct ConstructorDoesNotExistError { 145 static_assert(AlwaysFalse<Signature>::value, "The specified constructor does not exist."); 146 }; 147 148 template <typename I, typename C> 149 struct NotABaseClassOfError { 150 static_assert(AlwaysFalse<I>::value, "I is not a base class of C."); 151 }; 152 153 template <typename ProviderType> 154 struct FunctorUsedAsProviderError { 155 static_assert(AlwaysFalse<ProviderType>::value, 156 "A stateful lambda or a non-lambda functor was used as provider. Only functions and stateless " 157 "lambdas can be used as providers."); 158 }; 159 160 template <typename... ComponentRequirements> 161 struct ComponentWithRequirementsInInjectorError { 162 static_assert(AlwaysFalse<ComponentRequirements...>::value, 163 "When using the two-argument constructor of Injector, the component used as second parameter " 164 "must not have requirements (while the normalized component can), but the specified component " 165 "requires ComponentRequirements."); 166 }; 167 168 template <typename... UnsatisfiedRequirements> 169 struct UnsatisfiedRequirementsInNormalizedComponentError { 170 static_assert(AlwaysFalse<UnsatisfiedRequirements...>::value, 171 "The requirements in UnsatisfiedRequirements are required by the NormalizedComponent but are " 172 "not provided by the Component (second parameter of the Injector constructor)."); 173 }; 174 175 template <typename... TypesNotProvided> 176 struct TypesInInjectorNotProvidedError { 177 static_assert(AlwaysFalse<TypesNotProvided...>::value, 178 "The types in TypesNotProvided are declared as provided by the injector, but none of the two " 179 "components passed to the Injector constructor provides them."); 180 }; 181 182 template <typename... TypesProvidedAsConstOnly> 183 struct TypesInInjectorProvidedAsConstOnlyError { 184 static_assert( 185 AlwaysFalse<TypesProvidedAsConstOnly...>::value, 186 "The types in TypesProvidedAsConstOnly are declared as non-const provided types by the injector, but the " 187 "components passed to the Injector constructor provide them as const only. You should mark them as const in the " 188 "injector (e.g., switching from Injector<T> to Injector<const T>) or mark them as non-const in the " 189 "Component/NormalizedComponent (e.g. switching from [Normalized]Component<const T> to " 190 "[Normalized]Component<T>)."); 191 }; 192 193 template <typename T> 194 struct TypeNotProvidedError { 195 static_assert(AlwaysFalse<T>::value, 196 "Trying to get an instance of T, but it is not provided by this Provider/Injector."); 197 }; 198 199 template <typename T> 200 struct TypeProvidedAsConstOnlyError { 201 static_assert( 202 AlwaysFalse<T>::value, 203 "Trying to get an instance of T, but it is only provided as a constant by this Provider/Injector and a non-const " 204 "pointer/reference/Provider was requested. You should either switch to injecting a const value (e.g. switching " 205 "from" 206 " injecting T*, T&, std::unique_ptr<T> or Provider<T> to injecting a T, const T*, const T& or Provider<const T>) " 207 "or get the value from an Injector/Provider that provides it as a non-const type (e.g. switching from calling " 208 "get " 209 "on an Injector<const T> or on a Provider<const T> to calling get on an Injector<T> or a Provider<T>)."); 210 }; 211 212 template <typename T> 213 struct NonConstBindingRequiredButConstBindingProvidedError { 214 static_assert( 215 AlwaysFalse<T>::value, 216 "The type T was provided as constant, however one of the constructors/providers/factories in this component " 217 "requires it as a non-constant (or this Component declares it as a non-const provided/required type). " 218 "If you want to only have a const binding for this type, you should change the places that use the type to " 219 "inject " 220 "a constant value (e.g. T, const T*, const T& and Provider<const T> are ok while you should avoid injecting T*, " 221 "T&," 222 " std::unique_ptr<T> and Provider<T>) and if the type is in Component<...> make sure that it's marked as const " 223 "there" 224 " (e.g. Component<const T> and Component<Required<const T>> are ok while Component<T> and Component<Required<T>> " 225 "are " 226 "not. " 227 "On the other hand, if you want to have a non-const binding for this type, you should switch to a non-const " 228 "bindInstance (if you're binding an instance) or changing any installed component functions to declare the type " 229 "as " 230 "non-const, e.g. Component<T> or Component<Required<T>> instead of Component<const T> and " 231 "Component<Required<const T>>."); 232 }; 233 234 template <typename C, typename InjectSignature> 235 struct NoConstructorMatchingInjectSignatureError { 236 static_assert(AlwaysFalse<C>::value, 237 "C contains an Inject typedef but it's not constructible with the specified types"); 238 }; 239 240 template <typename ExpectedSignature, typename FunctorSignature> 241 struct FunctorSignatureDoesNotMatchError { 242 static_assert(AlwaysFalse<ExpectedSignature>::value, 243 "Unexpected functor signature (it should be the same as ExpectedSignature minus any Assisted " 244 "types)."); 245 }; 246 247 template <typename Signature> 248 struct FactoryReturningPointerError { 249 static_assert(AlwaysFalse<Signature>::value, 250 "The specified factory returns a pointer. This is not supported; return a value or an " 251 "std::unique_ptr instead."); 252 }; 253 254 template <typename Lambda> 255 struct LambdaWithCapturesError { 256 // It's not guaranteed by the standard, but it's reasonable to expect lambdas with no captures 257 // to be empty. This is always the case in GCC and Clang, but is not guaranteed to work in all 258 // conforming C++ compilers. If this error happens for a lambda with no captures, please file a 259 // bug at https://github.com/google/fruit/issues and indicate the compiler (with version) that 260 // you're using. 261 static_assert(AlwaysFalse<Lambda>::value, "Only lambdas with no captures are supported."); 262 }; 263 264 template <typename Lambda> 265 struct NonTriviallyCopyableLambdaError { 266 // It's not guaranteed by the standard, but it's reasonable to expect lambdas with no captures 267 // to be trivially copyable. This is always the case in GCC and Clang, but is not guaranteed to 268 // work in all conforming C++ compilers. If this error happens for a lambda with no captures, 269 // please file a bug at https://github.com/google/fruit/issues and indicate the compiler (with 270 // version) that you're using. 271 static_assert(AlwaysFalse<Lambda>::value, 272 "Only trivially copyable lambdas are supported. Make sure that your lambda has no captures."); 273 }; 274 275 template <typename C> 276 struct CannotConstructAbstractClassError { 277 static_assert(AlwaysFalse<C>::value, "The specified class can't be constructed because it's an abstract class."); 278 }; 279 280 template <typename C> 281 struct InterfaceBindingToSelfError { 282 static_assert(AlwaysFalse<C>::value, 283 "The type C was bound to itself. If this was intentional, to \"tell Fruit to inject the type" 284 " C\", this binding is unnecessary, just remove it. bind<I,C>() is to tell Fruit about" 285 " base-derived class relationships."); 286 }; 287 288 template <typename TypeParameter, typename TypeOfValue> 289 struct TypeMismatchInBindInstanceError { 290 static_assert(AlwaysFalse<TypeParameter>::value, 291 "A type parameter was specified in bindInstance() but it doesn't match the value type" 292 " (even after removing the fruit::Annotation<>, if any). Please change the type parameter" 293 " to be the same as the type of the value (or a subclass)."); 294 }; 295 296 template <typename RequiredType> 297 struct RequiredTypesInComponentArgumentsError { 298 static_assert(AlwaysFalse<RequiredType>::value, 299 "A Required<...> type was passed as a non-first template parameter to fruit::Component or " 300 "fruit::NormalizedComponent. " 301 "All required types (if any) should be passed together as a single Required<> type passed as the first " 302 "type argument of fruit::Component (and fruit::NormalizedComponent). For example, write " 303 "fruit::Component<fruit::Required<Foo, Bar>, Baz> instead of " 304 "fruit::Component<fruit::Required<Foo>, fruit::Required<Bar>, Baz>."); 305 }; 306 307 template <typename T> 308 struct NonInjectableTypeError { 309 static_assert( 310 AlwaysFalse<T>::value, 311 "The type T is not injectable. Injectable types are of the form X, X*, X&, const X, const X*, const X&, " 312 "std::shared_ptr<X>, or Provider<X> where X is a fundamental type (excluding void), a class, a struct or " 313 "an enum."); 314 }; 315 316 template <typename T> 317 struct ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError { 318 static_assert( 319 AlwaysFalse<T>::value, 320 "The type T was declared as a const Required type in the returned Component, however a non-const binding is " 321 "required. You should either change all the usages of this type so that they no longer require a non-const " 322 "binding " 323 "(i.e., you shouldn't inject T*, T& or std::shared_ptr<T>) or you should remove the 'const' in the type of the " 324 "returned Component, e.g. changing fruit::Component<fruit::Required<const T, ...>, ...> to " 325 "fruit::Component<fruit::Required<T, ...>, ...>."); 326 }; 327 328 template <typename T> 329 struct ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError { 330 static_assert( 331 AlwaysFalse<T>::value, 332 "registerProvider() was called with a lambda that returns a pointer to T, but T is an abstract class with no " 333 "virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor (the one " 334 "of " 335 "the concrete class that was then casted to T). You must either add a virtual destructor to T or change the " 336 "registerProvider() call to return a pointer to the concrete class (and then add a bind<T, TImpl>() so that T is " 337 "bound)."); 338 }; 339 340 template <typename T> 341 struct MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError { 342 static_assert( 343 AlwaysFalse<T>::value, 344 "registerMultibindingProvider() was called with a lambda that returns a pointer to T, but T is an abstract class " 345 "with no virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor " 346 "(the " 347 "one of the concrete class that was then casted to T). You must add a virtual destructor to T or replace the " 348 "registerMultibindingProvider() with a registerProvider() for the concrete class and an addMultibinding() for T. " 349 "Note that with the latter, if you end up with multiple addMultibinding() calls for the same concrete class, " 350 "there will be only one instance of the concrete class in the injector, not one per addMultibdinding() call; if " 351 "you want separate instances you might want to use annotated injection for the concrete class (so that there's " 352 "one " 353 "instance per annotation)."); 354 }; 355 356 template <typename T> 357 struct RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError { 358 static_assert(AlwaysFalse<T>::value, 359 "registerFactory() was called with a lambda that returns a std::unique_ptr<T>, but T is an abstract " 360 "class with no " 361 "virtual destructor so when the returned std::unique_ptr<T> object is deleted the wrong destructor " 362 "will be called " 363 "(T's destructor instead of the one of the concrete class that was then casted to T). You must add a " 364 "virtual destructor to T."); 365 }; 366 367 template <typename BaseFactory, typename DerivedFactory> 368 struct FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError { 369 static_assert( 370 AlwaysFalse<BaseFactory>::value, 371 "Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr " 372 "of " 373 "a class with no virtual destructor, so when the std::unique_ptr object is destroyed the wrong destructor would " 374 "be " 375 "called (the one in the base class instead of the derived class). To avoid this, you must add a virtual " 376 "destructor to the base class."); 377 }; 378 379 template <typename Arg> 380 struct IncorrectArgTypePassedToInstallComponentFuntionsError { 381 static_assert( 382 AlwaysFalse<Arg>::value, 383 "All arguments passed to installComponentFunctions() must be fruit::ComponentFunction<...> objects but an " 384 "argument with type Arg was passed instead."); 385 }; 386 387 struct LambdaWithCapturesErrorTag { 388 template <typename Lambda> 389 using apply = LambdaWithCapturesError<Lambda>; 390 }; 391 392 struct NonTriviallyCopyableLambdaErrorTag { 393 template <typename Lambda> 394 using apply = NonTriviallyCopyableLambdaError<Lambda>; 395 }; 396 397 struct FactoryReturningPointerErrorTag { 398 template <typename Signature> 399 using apply = FactoryReturningPointerError<Signature>; 400 }; 401 402 struct NoBindingFoundErrorTag { 403 template <typename T> 404 using apply = NoBindingFoundError<T>; 405 }; 406 407 struct RepeatedTypesErrorTag { 408 template <typename... Ts> 409 using apply = RepeatedTypesError<Ts...>; 410 }; 411 412 struct SelfLoopErrorTag { 413 template <typename... TypesInLoop> 414 using apply = SelfLoopError<TypesInLoop...>; 415 }; 416 417 struct NonClassTypeErrorTag { 418 template <typename T, typename C> 419 using apply = NonClassTypeError<T, C>; 420 }; 421 422 struct AnnotatedTypeErrorTag { 423 template <typename T, typename C> 424 using apply = AnnotatedTypeError<T, C>; 425 }; 426 427 struct TypeAlreadyBoundErrorTag { 428 template <typename C> 429 using apply = TypeAlreadyBoundError<C>; 430 }; 431 432 struct RequiredFactoryWithDifferentSignatureErrorTag { 433 template <typename RequiredSignature, typename SignatureInInjectTypedef> 434 using apply = RequiredFactoryWithDifferentSignatureError<RequiredSignature, SignatureInInjectTypedef>; 435 }; 436 437 struct AnnotatedSignatureDifferentFromLambdaSignatureErrorTag { 438 template <typename Signature, typename SignatureInLambda> 439 using apply = AnnotatedSignatureDifferentFromLambdaSignatureError<Signature, SignatureInLambda>; 440 }; 441 442 struct DuplicateTypesInComponentErrorTag { 443 template <typename... DuplicatedTypes> 444 using apply = DuplicateTypesInComponentError<DuplicatedTypes...>; 445 }; 446 447 struct InjectorWithRequirementsErrorTag { 448 template <typename... Requirements> 449 using apply = InjectorWithRequirementsError<Requirements...>; 450 }; 451 452 struct ComponentWithRequirementsInInjectorErrorTag { 453 template <typename... ComponentRequirements> 454 using apply = ComponentWithRequirementsInInjectorError<ComponentRequirements...>; 455 }; 456 457 struct InjectTypedefNotASignatureErrorTag { 458 template <typename C, typename TypeInInjectTypedef> 459 using apply = InjectTypedefNotASignatureError<C, TypeInInjectTypedef>; 460 }; 461 462 struct InjectTypedefForWrongClassErrorTag { 463 template <typename C, typename ReturnTypeOfInjectTypedef> 464 using apply = InjectTypedefForWrongClassError<C, ReturnTypeOfInjectTypedef>; 465 }; 466 467 struct InjectTypedefWithAnnotationErrorTag { 468 template <typename C> 469 using apply = InjectTypedefWithAnnotationError<C>; 470 }; 471 472 struct UnsatisfiedRequirementsInNormalizedComponentErrorTag { 473 template <typename... UnsatisfiedRequirements> 474 using apply = UnsatisfiedRequirementsInNormalizedComponentError<UnsatisfiedRequirements...>; 475 }; 476 477 struct TypesInInjectorNotProvidedErrorTag { 478 template <typename... TypesNotProvided> 479 using apply = TypesInInjectorNotProvidedError<TypesNotProvided...>; 480 }; 481 482 struct TypesInInjectorProvidedAsConstOnlyErrorTag { 483 template <typename... TypesProvidedAsConstOnly> 484 using apply = TypesInInjectorProvidedAsConstOnlyError<TypesProvidedAsConstOnly...>; 485 }; 486 487 struct FunctorUsedAsProviderErrorTag { 488 template <typename ProviderType> 489 using apply = FunctorUsedAsProviderError<ProviderType>; 490 }; 491 492 struct ConstructorDoesNotExistErrorTag { 493 template <typename Signature> 494 using apply = ConstructorDoesNotExistError<Signature>; 495 }; 496 497 struct NotABaseClassOfErrorTag { 498 template <typename I, typename C> 499 using apply = NotABaseClassOfError<I, C>; 500 }; 501 502 struct NotASignatureErrorTag { 503 template <typename CandidateSignature> 504 using apply = NotASignatureError<CandidateSignature>; 505 }; 506 507 struct AssistedParamInRegisterConstructorSignatureErrorTag { 508 template <typename CandidateSignature> 509 using apply = AssistedParamInRegisterConstructorSignatureError<CandidateSignature>; 510 }; 511 512 struct NotALambdaErrorTag { 513 template <typename CandidateLambda> 514 using apply = NotALambdaError<CandidateLambda>; 515 }; 516 517 struct TypeNotProvidedErrorTag { 518 template <typename T> 519 using apply = TypeNotProvidedError<T>; 520 }; 521 522 struct TypeProvidedAsConstOnlyErrorTag { 523 template <typename T> 524 using apply = TypeProvidedAsConstOnlyError<T>; 525 }; 526 527 struct NonConstBindingRequiredButConstBindingProvidedErrorTag { 528 template <typename T> 529 using apply = NonConstBindingRequiredButConstBindingProvidedError<T>; 530 }; 531 532 struct NoConstructorMatchingInjectSignatureErrorTag { 533 template <typename C, typename InjectSignature> 534 using apply = NoConstructorMatchingInjectSignatureError<C, InjectSignature>; 535 }; 536 537 struct FunctorSignatureDoesNotMatchErrorTag { 538 template <typename ExpectedSignature, typename FunctorSignature> 539 using apply = FunctorSignatureDoesNotMatchError<ExpectedSignature, FunctorSignature>; 540 }; 541 542 struct CannotConstructAbstractClassErrorTag { 543 template <typename C> 544 using apply = CannotConstructAbstractClassError<C>; 545 }; 546 547 struct NoBindingFoundForAbstractClassErrorTag { 548 template <typename T, typename C> 549 using apply = NoBindingFoundForAbstractClassError<T, C>; 550 }; 551 552 struct InterfaceBindingToSelfErrorTag { 553 template <typename C> 554 using apply = InterfaceBindingToSelfError<C>; 555 }; 556 557 struct TypeMismatchInBindInstanceErrorTag { 558 template <typename TypeParameter, typename TypeOfValue> 559 using apply = TypeMismatchInBindInstanceError<TypeParameter, TypeOfValue>; 560 }; 561 562 struct RequiredTypesInComponentArgumentsErrorTag { 563 template <typename RequiredType> 564 using apply = RequiredTypesInComponentArgumentsError<RequiredType>; 565 }; 566 567 struct NonInjectableTypeErrorTag { 568 template <typename T> 569 using apply = NonInjectableTypeError<T>; 570 }; 571 572 struct ConstBindingDeclaredAsRequiredButNonConstBindingRequiredErrorTag { 573 template <typename T> 574 using apply = ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<T>; 575 }; 576 577 struct ProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag { 578 template <typename T> 579 using apply = ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<T>; 580 }; 581 582 struct MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag { 583 template <typename T> 584 using apply = MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<T>; 585 }; 586 587 struct RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorErrorTag { 588 template <typename T> 589 using apply = RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError<T>; 590 }; 591 592 struct FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorErrorTag { 593 template <typename BaseFactory, typename DerivedFactory> 594 using apply = FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<BaseFactory, DerivedFactory>; 595 }; 596 597 struct IncorrectArgTypePassedToInstallComponentFuntionsErrorTag { 598 template <typename Arg> 599 using apply = IncorrectArgTypePassedToInstallComponentFuntionsError<Arg>; 600 }; 601 602 } // namespace impl 603 } // namespace fruit 604 605 #endif // FRUIT_INJECTION_ERRORS_H 606