diff --git a/include/kangaru/detail/injector.hpp b/include/kangaru/detail/injector.hpp index ed88570..9c2e9bb 100644 --- a/include/kangaru/detail/injector.hpp +++ b/include/kangaru/detail/injector.hpp @@ -149,6 +149,68 @@ namespace kangaru { template inline constexpr auto make_fixed_injector = make_fixed_injector_function{}; + + template + struct strict_fixed_injector { + explicit constexpr strict_fixed_injector(Source source) noexcept : source{std::move(source)} {} + + constexpr auto operator()(auto&& function) & -> decltype(auto) + requires detail::injector::invocable_with_strict_deducer_sequence, std::make_index_sequence> + { + return expand_deducers(std::make_index_sequence{}, KANGARU5_FWD(function), source); + } + + constexpr auto operator()(callable> auto&& function) const& -> decltype(auto) + requires detail::injector::invocable_with_strict_deducer_sequence, std::make_index_sequence> + { + return expand_deducers(std::make_index_sequence{}, KANGARU5_FWD(function), source); + } + + constexpr auto operator()(callable> auto&& function) && -> decltype(auto) + requires detail::injector::invocable_with_strict_deducer_sequence, std::make_index_sequence> + { + return expand_deducers(std::make_index_sequence{}, KANGARU5_FWD(function), std::move(source)); + } + + constexpr auto operator()(callable> auto&& function) const&& -> decltype(auto) + requires detail::injector::invocable_with_strict_deducer_sequence, std::make_index_sequence> + { + return expand_deducers(std::make_index_sequence{}, KANGARU5_FWD(function), std::move(source)); + } + + private: + template + static constexpr auto expand_deducers(std::index_sequence, auto&& function, auto&& source) -> decltype(auto) { + using Deducer = basic_deducer; + return kangaru::invoke_with_strict_deducers(KANGARU5_FWD(function), (void(s), Deducer{KANGARU5_FWD(source)})...); + } + + Source source; + }; + + template + using strict_simple_injector = strict_fixed_injector; + + struct make_strict_simple_injector_function { + template requires kangaru::source> + inline constexpr auto operator()(Source&& source) const { + return strict_simple_injector>{KANGARU5_FWD(source)}; + } + }; + + inline constexpr auto make_strict_simple_injector = make_strict_simple_injector_function{}; + + template + struct make_strict_fixed_injector_function { + template requires kangaru::source> + inline constexpr auto operator()(Source&& source) const { + return strict_fixed_injector, N>{KANGARU5_FWD(source)}; + } + }; + + template + inline constexpr auto make_strict_fixed_injector = make_strict_fixed_injector_function{}; + template struct basic_spread_injector {