Add curry

This commit is contained in:
sha512sum 2024-02-29 22:29:44 +00:00
parent 956c3bfa05
commit a3f060b5c3

View file

@ -221,4 +221,31 @@ inline constexpr auto Filter(Tuple&& tuple, auto&& f) {
);
};
template <typename F, typename... Ts>
struct Curryer {
F f;
Tuple<Ts...> data;
inline constexpr operator decltype(f(std::declval<Ts>()...))() && {
return [&]<auto... Is>(std::index_sequence<Is...>){
return this->f(std::move(Get<Is>(this->data))...);
}(std::index_sequence_for<Ts...>());
};
inline constexpr operator decltype(f(std::declval<Ts>()...))() const {
return [&]<auto... Is>(std::index_sequence<Is...>){
return this->f(Get<Is>(this->data)...);
}(std::index_sequence_for<Ts...>());
};
template <typename T>
inline constexpr auto operator()(T&& arg) const -> Curryer<F, Ts..., std::remove_cvref_t<T>>{
return {.f = this->f, .data = this->data + Tuple{std::forward<T>(arg)}};
};
};
template <typename F>
inline constexpr auto Curry(F&& f) -> Curryer<std::remove_cvref_t<F>> {
return {.f = std::forward<F>(f), .data = Tuple{}};
};
static_assert(Curry([](auto... args) {return (0 + ... + args);})(1)(2)(3) == 6);
} // namespace utempl