Add GetDependencyGraph method to ServiceContextBuilder

This commit is contained in:
sha512sum 2024-03-24 17:21:17 +00:00
parent 18365b6386
commit f2db8a222a

View file

@ -69,7 +69,7 @@ struct ServiceContext {
storage{ storage{
[&]<auto... Is>(std::index_sequence<Is...>) -> utempl::Tuple<Ts...> { [&]<auto... Is>(std::index_sequence<Is...>) -> utempl::Tuple<Ts...> {
return {[&]<auto I>(utempl::Wrapper<I>) { return {[&]<auto I>(utempl::Wrapper<I>) {
return [&]() -> std::remove_cvref_t<decltype(Get<I>(storage))> { return [&] -> std::remove_cvref_t<decltype(Get<I>(storage))> {
return {utempl::Wrapper<Get<I>(names)>{}, *this}; return {utempl::Wrapper<Get<I>(names)>{}, *this};
}; };
}(utempl::Wrapper<Is>{})...}; }(utempl::Wrapper<Is>{})...};
@ -202,12 +202,16 @@ public:
static constexpr auto FindComponent() -> T&; static constexpr auto FindComponent() -> T&;
template <std::size_t I = 0, typename... TTs> template <std::size_t I = 0, typename... TTs>
static consteval auto GetDependencies() requires static consteval auto GetDependencies() requires (I == 0 ||
requires {Magic(loopholes::Getter<DependencyInfoKey<Current, I>{}>{});} { requires {Magic(loopholes::Getter<DependencyInfoKey<Current, I>{}>{});}) {
if constexpr(requires{GetDependencies<I + 1, TTs...>();}) { if constexpr(I == 0 && !requires {Magic(loopholes::Getter<DependencyInfoKey<Current, I>{}>{});}) {
return GetDependencies<I + 1, TTs..., typename decltype(Magic(loopholes::Getter<DependencyInfoKey<Current, I>{}>{}))::Type>(); return utempl::TypeList{};
} else { } else {
return utempl::kTypeList<TTs..., typename decltype(Magic(loopholes::Getter<DependencyInfoKey<Current, I>{}>{}))::Type>; if constexpr(requires{GetDependencies<I + 1, TTs...>();}) {
return GetDependencies<I + 1, TTs..., typename decltype(Magic(loopholes::Getter<DependencyInfoKey<Current, I>{}>{}))::Type>();
} else {
return utempl::kTypeList<TTs..., typename decltype(Magic(loopholes::Getter<DependencyInfoKey<Current, I>{}>{}))::Type>;
};
}; };
}; };
@ -219,6 +223,16 @@ public:
} // namespace impl } // namespace impl
template <typename T, utempl::TypeList Dependencies>
struct DependencyGraphElement {};
template <typename... Ts>
struct DependencyGraph {
static constexpr auto kValue = utempl::TypeList<Ts...>{};
};
template <ConstexprConfig config = {}, typename... Ts> template <ConstexprConfig config = {}, typename... Ts>
struct ServiceContextBuilder { struct ServiceContextBuilder {
static constexpr auto kList = utempl::kTypeList<Ts...>; static constexpr auto kList = utempl::kTypeList<Ts...>;
@ -257,6 +271,20 @@ struct ServiceContextBuilder {
return config; return config;
}; };
static consteval auto GetDependencyGraph() {
return [&]<utempl::ConstexprString... names, typename... TTs, Options... Options>
(ComponentConfig<names, TTs, Options>...){
return DependencyGraph<DependencyGraphElement<TTs,
[]<utempl::ConstexprString name, typename T, ::cserver::Options OOptions>
(ComponentConfig<name, T, OOptions>) {
impl::DependencyInfoInjector<T, config, Ts...> injector;
injector.template Inject<name>();
return injector.GetDependencies();
}(Ts{})>...>{};
}(Ts{}...);
};
static constexpr auto Run() -> void { static constexpr auto Run() -> void {
[]<utempl::ConstexprString... names, typename... TTs, Options... Options> []<utempl::ConstexprString... names, typename... TTs, Options... Options>
(utempl::TypeList<ComponentConfig<names, TTs, Options>...>) { (utempl::TypeList<ComponentConfig<names, TTs, Options>...>) {