<commit_before>#ifndef KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_CHECK_HPP
#define KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_CHECK_HPP

#include "traits.hpp"
#include "function_traits.hpp"
#include "construct_function.hpp"
#include "override_traits.hpp"

namespace kgr {
namespace detail {

/*
 * Trait that check if the service definition can be constructed given the return type of it's construct function.
 */
template<typename T, typename... Args>
using is_service_constructible = bool_constant<
	is_abstract_service<T>::value || is_container_service<T>::value ||
	(is_tuple<detected_t<function_result_t, detected_t<construct_function_t, T, Args...>>>::value &&
	expand_all<
		to_meta_list_t<detected_or<std::tuple<>, function_result_t, detected_t<construct_function_t, T, Args...>>>,
		is_service_instantiable, T
	>::value)
>;

template<typename T, typename... Args>
using is_service_constructible_if_required = bool_constant<
	is_service_constructible<T, Args...>::value || is_supplied_service<T>::value
>;

/*
 * Meta trait that applies a trait recursively for each dependencies and thier dependencies.
 */
template<template<typename...> class Trait, typename T, typename... Args>
struct dependency_trait {
	// This subtrait recursively call dependency_trait for each dependencies
	template<typename... Service>
	struct service_check_dependencies {
		static constexpr bool value = conjunction<
			Trait<detected_t<injected_service_t, Service>>...,
			dependency_trait<Trait, detected_t<injected_service_t, Service>, Args...>...
		>::value;
	};
	
	static constexpr bool value =
		is_supplied_service<T>::value ||
		expand_minus_n<
			sizeof...(Args),
			detected_or<meta_list<>, function_arguments_t, detected_t<construct_function_t, T, Args...>>,
			service_check_dependencies
		>::value;
};

/*
 * Validity check for default services
 */
template<typename T>
using is_default_service_valid = std::integral_constant<bool,
	(is_abstract_service<T>::value || !has_default<T>::value) &&
	is_default_overrides_abstract<T>::value &&
	is_default_convertible<T>::value
>;

template<typename T><commit_msg>Removed unused Args... arguments<commit_after>#ifndef KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_CHECK_HPP
#define KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_CHECK_HPP

#include "traits.hpp"
#include "function_traits.hpp"
#include "construct_function.hpp"
#include "override_traits.hpp"

namespace kgr {
namespace detail {

/*
 * Trait that check if the service definition can be constructed given the return type of it's construct function.
 */
template<typename T, typename... Args>
using is_service_constructible = bool_constant<
	is_abstract_service<T>::value || is_container_service<T>::value ||
	(is_tuple<detected_t<function_result_t, detected_t<construct_function_t, T, Args...>>>::value &&
	expand_all<
		to_meta_list_t<detected_or<std::tuple<>, function_result_t, detected_t<construct_function_t, T, Args...>>>,
		is_service_instantiable, T
	>::value)
>;

template<typename T, typename... Args>
using is_service_constructible_if_required = bool_constant<
	is_service_constructible<T, Args...>::value || is_supplied_service<T>::value
>;

/*
 * Meta trait that applies a trait recursively for each dependencies and thier dependencies.
 */
template<template<typename...> class Trait, typename T, typename... Args>
struct dependency_trait {
	// This subtrait recursively call dependency_trait for each dependencies
	template<typename... Service>
	struct service_check_dependencies {
		static constexpr bool value = conjunction<
			Trait<detected_t<injected_service_t, Service>>...,
			dependency_trait<Trait, detected_t<injected_service_t, Service>>...
		>::value;
	};
	
	static constexpr bool value =
		is_supplied_service<T>::value ||
		expand_minus_n<
			sizeof...(Args),
			detected_or<meta_list<>, function_arguments_t, detected_t<construct_function_t, T, Args...>>,
			service_check_dependencies
		>::value;
};

/*
 * Validity check for default services
 */
template<typename T>
using is_default_service_valid = std::integral_constant<bool,
	(is_abstract_service<T>::value || !has_default<T>::value) &&
	is_default_overrides_abstract<T>::value &&
	is_default_convertible<T>::value
>;

template<typename T>
{'fraction_non_alphanumeric': 0.11766098484848485, 'fraction_numerical': 0.0, 'mean_word_length': 6.42530755711775, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5513031', 'n_tokens_mistral': 1408, 'n_tokens_neox': 1351, 'n_words': 285}