diff --git a/include/utempl/utils.hpp b/include/utempl/utils.hpp index 62b6fb3..1f09c06 100644 --- a/include/utempl/utils.hpp +++ b/include/utempl/utils.hpp @@ -40,6 +40,19 @@ struct kSeq { } // namespace impl +template +concept ImplicitConvertibleTo = std::same_as || requires(From from) { [](To) {}(from); }; + +template +concept Function = [](TypeList) { + if constexpr(std::invocable) { + return std::same_as || ImplicitConvertibleTo, R>; + }; + return false; +}(kType); + +static_assert(Function); + template inline constexpr impl::kSeq kSeq; @@ -425,12 +438,7 @@ struct LeftFold { template concept LeftFoldConcept = decltype(Unpack(std::declval(), [](Ts&&...) { - return kWrapper<([] { - if constexpr(std::invocable) { - return std::convertible_to, T>; - }; - return false; - }() && ...)>; + return kWrapper<(Function && ...)>; }))::kValue; } // namespace impl @@ -526,11 +534,7 @@ namespace impl { template concept FilterConcept = decltype(Unpack(std::declval(), [](Ts&&...) { - return kWrapper<([] { - if constexpr(std::invocable) { - return std::convertible_to, bool>; - }; - }() && ...)>; + return kWrapper<(Function && ...)>; }))::kValue; } // namespace impl @@ -673,27 +677,9 @@ concept ComparableSwitchConcept = decltype(Unpack(std::declval(), []< template concept CallableSwitchConcept = std::same_as || decltype(Unpack(std::declval(), [](Ts&&...) { - return kWrapper<([] { - if constexpr(std::invocable) { - if constexpr(!std::same_as, void>) { - return std::convertible_to, std::optional>; - }; - }; - return false; - }() && ...)>; + return kWrapper<(Function(Ts)> && ...)>; }))::kValue; -template -concept DefaultSwitchConcept = [] { - if constexpr(std::invocable) { - if constexpr(!std::same_as) { - return std::convertible_to, std::optional>; - }; - return true; - }; - return false; -}(); - } // namespace impl template Key, impl::CallableSwitchConcept F, - impl::DefaultSwitchConcept Default = decltype(kDefaultCreator)> + Function Default = decltype(kDefaultCreator)> constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& key, F&& f, Default&& def = {}) -> R requires(std::move_constructible || std::same_as) && (kTupleSize == kTupleSize) {