1#ifndef CHAINABLE_CONFIG_DISPATCHER_HPP_
2#define CHAINABLE_CONFIG_DISPATCHER_HPP_
13#include <boost/mp11.hpp>
29 : configs_tuple_ { std::move(configs)... }
30 , configs_dispatch_map_ {
31 populate_configs_map(this->configs_tuple_)
36 template<
typename RelatedKey,
typename RelatedEntity>
46 auto maybe_configs_array = this->configs_dispatch_map_
49 if constexpr (!maybe_configs_array.has_value()) [[unlikely]]
51 return std::expected<meta::RuntimeRef<RelatedEntity>,
Error> {
57 auto configs_array_reference = maybe_configs_array.value();
58 typename decltype(configs_array_reference)::ReferenceType configs_array = configs_array_reference;
63 template<
typename RelatedEntity>
69 const auto& configs_array,
72 std::size_t current_index
75 if (current_index >= configs_array.size())
77 return std::expected<meta::RuntimeRef<RelatedEntity>,
Error> {
84 [&entity, &context](
const auto& config_reference) {
85 typename std::decay_t<
decltype(config_reference)>::ReferenceType config = config_reference;
86 return config.pipe(entity, context);
88 configs_array[current_index]
90 .and_then([
this, &configs_array, current_index, &context](
103 template<
typename UniqueType,
typename... NonUniqueConfigs>
104 static constexpr auto collect(NonUniqueConfigs&... args)
106 using namespace boost::mp11;
108 auto configs_tuple = std::tuple_cat(
114 return std::tuple<meta::RuntimeRef<NonUniqueConfigs>> {
119 return std::tuple<>{};
125 []<
typename... T>(T&&... configs) {
126 using UniqueTs = mp_unique<mp_list<std::decay_t<T>...>>;
132 return std::array<VariantType,
sizeof...(configs)> {
133 VariantType { std::forward<T>(configs) }...
136 std::move(configs_tuple)
140 template<meta::wrapped_with<std::tuple> ConfigsTuple>
141 static constexpr auto populate_configs_map(
142 ConfigsTuple& configs_tuple
144 using namespace boost::mp11;
146 using KeysList = mp_flatten<mp_list<
154 using UniqueKeysList = mp_unique<KeysList>;
156 return [&]<
typename... UniqueKeys>(mp_list<UniqueKeys...>&& list) {
157 return meta::MetaMap {
159 meta::Unit<UniqueKeys>{},
162 return collect<UniqueKeys>(args...);
172 using ConfigsTupleType = std::tuple<Configs...>;
173 using MapType =
decltype(populate_configs_map(std::declval<ConfigsTupleType&>()));
175 ConfigsTupleType configs_tuple_;
176 MapType configs_dispatch_map_;
Concept and utilities for chainable (decorator/pipeline) 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 ChainableConfigDispatcher(Configs &&... configs)
Definition ChainableConfigDispatcher.hpp:26
constexpr Resolution< RelatedEntity, Error > auto apply_configs_chain(meta::Reference< RelatedEntity > auto entity, meta::wrapped_with< ResolutionContext > auto &context) const
Definition ChainableConfigDispatcher.hpp:41
constexpr Resolution< RelatedEntity, Error > auto perform_piping(const auto &configs_array, meta::wrapped_with< ResolutionContext > auto &context, meta::Reference< RelatedEntity > auto entity, std::size_t current_index) const
Definition ChainableConfigDispatcher.hpp:68
Concept for configuration objects that transform/decorate dependencies.
Definition ChainableConfig.hpp:58
Definition Resolution.hpp:30
Definition Decorator.hpp:19
typename Config::RelatedKeysPack get_related_keys_pack_t
Helper alias to extract the key type from a ChainableConfig.
Definition ChainableConfig.hpp:96
Error
Enumeration of possible errors during dependency injection resolution.
Definition Error.hpp:26