Add curry
This commit is contained in:
parent
956c3bfa05
commit
a3f060b5c3
1 changed files with 27 additions and 0 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue