#ifndef KGR_KANGARU_INCLUDE_KANGARU_DETAIL_ERROR_HPP #define KGR_KANGARU_INCLUDE_KANGARU_DETAIL_ERROR_HPP #include "traits.hpp" #include "single.hpp" #include "service_traits.hpp" namespace kgr { namespace detail { template struct ServiceError { template::value && !is_override_convertible::value, int> = 0> ServiceError() { static_assert(false_t::value, "The service injected type cannot be converted to the overriding type. " "Check if the service is overriding the right service and if types are compatible." ); } template::value && !is_autocall_valid::value, int> = 0> ServiceError() { static_assert(false_t::value, "The service has problem with autocall. Injected services can be invalid, or the service map can be incoplete. " "Check if all required services are included and if every services are valid." ); } template::value && !is_autocall_valid::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The service has problem with autocall. Injected services can be invalid, or the service map can be incoplete. " "Check if all required services are included and if every services are valid." ); } template::value && is_service_constructible::value && is_autocall_valid::value && !dependency_trait::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "A dependency of this service has problem with autocall. Injected services can be invalid, or the service map can be incoplete. " "Check if all required services are included and if every services are valid." ); } template::value && is_service_constructible::value && is_autocall_valid::value && !dependency_trait::value, int> = 0> ServiceError() { static_assert(false_t::value, "A dependency of this service has problem with autocall. Injected services can be invalid, or the service map can be incoplete. " "Check if all required services are included and if every services are valid." ); } template::value && !is_override_convertible::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The service injected type cannot be converted to the overriding type. " "Check if the service is overriding the right service and if types are compatible." ); } template::value && dependency_trait::value && !dependency_trait::value && is_service_constructible::value, int> = 0> ServiceError() { static_assert(false_t::value, "One or more dependencies injected type cannot be converted to one of it's overriding type. " "Check if that service is overriding the right service and if types are compatible." ); } template::value && dependency_trait::value && !dependency_trait::value && is_service_constructible::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "One or more dependencies injected type cannot be converted to one of it's overriding type. " "Check if that service is overriding the right service and if types are compatible." ); } template::value && is_abstract_service::value && dependency_trait::value && !is_default_service_valid::value && is_default_convertible::value && is_default_overrides_abstract::value, int> = 0> ServiceError() { static_assert(false_t::value, "The default implementation of this abstract service is not a well defined service. " "Please check that types are complete and exposing a valid service definition interface." ); } template::value && is_abstract_service::value && dependency_trait::value && !is_default_service_valid::value && is_default_convertible::value && is_default_overrides_abstract::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The default implementation of this abstract service is not a well defined service. " "Please check that types are complete and exposing a valid service definition interface." ); } template::value && is_abstract_service::value && dependency_trait::value && !is_default_service_valid::value && !is_default_convertible::value && is_default_overrides_abstract::value, int> = 0> ServiceError() { static_assert(false_t::value, "The service type of the default implementation of this abstract service is not convertible to the abstract service type. " "Please check that the service type of the default implementation of that abstract service is a compatible type." ); } template::value && is_abstract_service::value && dependency_trait::value && !is_default_service_valid::value && !is_default_convertible::value && is_default_overrides_abstract::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The service type of the default implementation of this abstract service is not convertible to the abstract service type. " "Please check that the service type of the default implementation of that abstract service is a compatible type." ); } template::value && is_abstract_service::value && dependency_trait::value && !is_default_service_valid::value && !is_default_overrides_abstract::value, int> = 0> ServiceError() { static_assert(false_t::value, "The default implementation of this abstract service is not overriding that abstract service. " "Ensure that the default implementation really override this abstract service." ); } template::value && is_abstract_service::value && dependency_trait::value && !is_default_service_valid::value && !is_default_overrides_abstract::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The default implementation of this abstract service is not overriding that abstract service. " "Ensure that the default implementation really override this abstract service." ); } template::value && !is_abstract_service::value && !is_default_service_valid::value, int> = 0> ServiceError() { static_assert(false_t::value, "Non-abstract service cannot have a default implementation." ); } template::value && !is_abstract_service::value && !is_default_service_valid::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "Non-abstract service cannot have a default implementation." ); } template::value && dependency_trait::value && is_service_constructible::value && !dependency_trait::value, int> = 0> ServiceError() { static_assert(false_t::value, "The default implementation of a dependency is not valid. " "Ensure that every default implementation are valid services that override properly thier abstract services." ); } template::value && dependency_trait::value && is_service_constructible::value && !dependency_trait::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The default implementation of a dependency is not valid. " "Ensure that every default implementation are valid services that override properly thier abstract services." ); } template::value && dependency_trait::value && !dependency_trait::value && is_service_constructible::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "One or more dependencies are not constructible with it's dependencies as constructor argument. " "Please check that dependency's constructor and it's dependencies." ); } template::value && dependency_trait::value && !dependency_trait::value && is_service_constructible::value, int> = 0> ServiceError() { static_assert(false_t::value, "One or more dependencies are not constructible with it's dependencies as constructor argument. " "Please check that dependency's constructor and dependencies." ); } template::value && !dependency_trait::value && is_construct_function_callable::value && is_service_constructible::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "One or more dependencies construct function cannot be called when calling kgr::Container::service(). " "Please check that dependency's construct function and ensure that is well formed." ); } template::value && !dependency_trait::value && is_construct_function_callable::value && is_service_constructible::value, int> = 0> ServiceError() { static_assert(false_t::value, "One or more dependencies construct function cannot be called when calling kgr::Container::service(). " "Please check that dependency's construct function and ensure that is well formed." ); } template::value && !is_service_constructible::value && !is_service_constructible::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The service type is not constructible given it's dependencies and passed arguments. " "Ensure that dependencies are correctly configured and you pass the right set of parameters." ); } template::value && !is_service_constructible::value && is_service_constructible::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The service type is not constructible given passed arguments to kgr::Container::service(...)."); } template::value && is_construct_function_callable::value && !is_service_constructible::value, int> = 0> ServiceError() { static_assert(false_t::value, "The service type is not constructible given it's dependencies. " "Check if dependencies are configured correctly and if the service has the required constructor." ); } template::value && is_single::value && !is_construct_function_callable::value, int> = 0> ServiceError() { static_assert(false_t::value, "The service construct function cannot be called. " "Check if the construct function is well formed, receive injected arguments first and additional parameters at the end." ); } template::value && !is_single::value && dependency_trait::value && !is_construct_function_callable::value, int> = 0> ServiceError() { static_assert(false_t::value, "The service construct function cannot be called without arguments, or is not well formed. " "Check if the construct function is well formed, receive injected arguments first and additional parameters at the end." ); } template::value && !is_single::value && dependency_trait::value && !is_construct_function_callable::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "The service construct function cannot be called. " "Check if the construct function is well formed, receive injected arguments first and additional parameters at the end." ); } template::value && has_any_construct::value && !dependency_trait::value, int> = 0> ServiceError() { static_assert(false_t::value, "A dependency or one of their dependencies is not a service. Be sure to use the service definition in the list of dependencies of that service." ); } template::value && has_any_construct::value && !dependency_trait::value, int> = 0> ServiceError(Arg&&) { static_assert(false_t::value, "A dependency or one of their dependencies is not a service. Be sure to use the service definition in the list of dependencies of that service." ); } template::value && !has_forward::value, int> = 0> ServiceError() { static_assert(false_t::value, "The type sent to kgr::Container::service(...) is not a service."); } template::value && has_forward::value, int> = 0> ServiceError() { static_assert(false_t::value, "The service type must not not contain any virtual function or must be abstract."); } }; struct NotInvokableError { template NotInvokableError(...) { static_assert(false_t::value, "The function sent is not invokable. Ensure to include all services definitions " "you need and that received parameters are correct." ); } }; } // namespace detail } // namespace kgr #endif // KGR_KANGARU_INCLUDE_KANGARU_DETAIL_ERROR_HPP