1#ifndef CREATIONAL_CONFIG_DISPATCHER_HPP_
2#define CREATIONAL_CONFIG_DISPATCHER_HPP_
19#include <boost/mp11.hpp>
36 : configs_tuple_ { std::move(configs)... }
37 , configs_dispatch_map_ {
38 populate_configs_map(this->configs_tuple_)
47 typename InputType = std::tuple<>
54 if constexpr (!
decltype(maybe_config)::has_value())
56 return std::expected<meta::RuntimeRef<Type>,
Error> {
63 auto configs_array_reference = maybe_config.value();
64 typename decltype(configs_array_reference)::ReferenceType configs_array = configs_array_reference;
65 auto input_tuple = context.input;
68 []<
typename... T>(T&&... input_args) {
70 std::forward<T>(input_args)...
73 std::move(input_tuple)
76 for (
auto& config_variant : configs_array)
78 auto resolution = std::visit([
this, &overrides, &context](
auto& config_reference)
mutable {
79 typename std::decay_t<
decltype(config_reference)>::ReferenceType config = config_reference;
82 auto maybe_dependencies_tuple = this->resolve_dependencies_tuple(
88 return maybe_dependencies_tuple
89 .and_then([&config, &overrides, &context](
auto&& dependencies_tuple)
mutable {
90 return config.do_resolve(KeyPack{}, dependencies_tuple, context, overrides);
95 if (!resolution.has_value()) [[unlikely]]
97 code = resolution.error();
101 if (!overrides.
validate()) [[unlikely]]
111 return std::expected<meta::RuntimeRef<Type>,
Error> {
112 std::unexpected { code }
119 template<
typename... Dependencies>
121 resolve_dependencies_tuple(
127 auto dependencies_tuple = [
this, &config, &context]<std::size_t... Idx>(std::index_sequence<Idx...>) {
129 [
this, &config, &context] {
130 auto dependencies_input = config.template get_dependencies_input<Idx>();
132 if (dependencies_input.has_value()) {
139 }(std::index_sequence_for<Dependencies...>{});
142 [](
auto&&... maybe_dependencies) {
143 using DependenciesTuple = std::tuple<
144 typename std::remove_reference_t<
decltype(maybe_dependencies)>::value_type...
147 if ((maybe_dependencies.has_value() && ...))
149 return std::expected<DependenciesTuple, Error> {
150 std::tuple { std::move(maybe_dependencies.value())... }
155 return std::expected<DependenciesTuple, Error> {
160 std::move(dependencies_tuple)
164 template<
typename UniqueType,
typename... NonUniqueConfigs>
165 static constexpr auto collect(NonUniqueConfigs&... args)
167 using namespace boost::mp11;
169 auto configs_tuple = std::tuple_cat(
175 return std::tuple<meta::RuntimeRef<NonUniqueConfigs>> {
176 meta::RuntimeRef<NonUniqueConfigs> { args }
180 return std::tuple<>{};
186 []<
typename... T>(T&&... configs) {
187 using UniqueTs = mp_unique<mp_list<T...>>;
189 return std::array<VariantType,
sizeof...(configs)> {
190 VariantType { std::forward<T>(configs) }...
193 std::move(configs_tuple)
197 template<meta::wrapped_with<std::tuple> ConfigsTuple>
198 static constexpr auto populate_configs_map(
199 ConfigsTuple& configs_tuple
201 using namespace boost::mp11;
203 using KeysList = mp_flatten<mp_list<
211 using UniqueKeysList = mp_unique<KeysList>;
213 return [&]<
typename... UniqueKeys>(mp_list<UniqueKeys...>&& list) {
214 return meta::MetaMap {
216 meta::Unit<UniqueKeys>{},
219 return collect<UniqueKeys>(args...);
229 using ConfigsTupleType = std::tuple<Configs...>;
230 using MapType =
decltype(populate_configs_map(std::declval<ConfigsTupleType&>()));
232 ConfigsTupleType configs_tuple_;
233 MapType configs_dispatch_map_;
Concept and utilities for creational (factory/constructor) configurations.
Error codes and diagnostics for dependency injection operations.
Compile-time type pack utilities and metaprogramming foundations.
Resolution concept and result type for dependency injection queries.
constexpr Resolution< Type, Error > auto resolve(meta::wrapped_with< ResolutionContext > auto &context) const
Definition CreationalConfigDispatcher.hpp:49
constexpr CreationalConfigDispatcher(Configs &&... configs)
Definition CreationalConfigDispatcher.hpp:33
Definition ResolutionOverrides.hpp:15
constexpr bool validate() const
Definition ResolutionOverrides.hpp:58
constexpr void reset() const
Definition ResolutionOverrides.hpp:65
Definition CreationalConfigDispatcher.hpp:27
Concept for configurations that handle dependency creation and instantiation.
Definition CreationalConfig.hpp:50
Definition Resolution.hpp:30
Definition Decorator.hpp:19
typename Config::DependenciesPack dependencies_pack_t
Definition CreationalConfig.hpp:82
typename Config::ResolutionKeysPack resolution_keys_pack_t
Helper alias to extract the resolution keys from a CreationalConfig.
Definition CreationalConfig.hpp:79
Error
Enumeration of possible errors during dependency injection resolution.
Definition Error.hpp:26
@ CANNOT_BE_RESOLVED
A dependency cannot be resolved because no suitable config was found.
Definition Error.hpp:28
@ DEPENDENCY_CANNOT_BE_RESOLVED
A dependency required by another dependency cannot be resolved. This indicates a missing transitive d...
Definition Error.hpp:32
@ NOT_ALL_INPUTS_RETRIEVED
Definition Error.hpp:43