12 #include <type_traits>
19 template<
typename F,
typename... PrevArgs>
24 std::tuple<PrevArgs...> m_prevArgs;
26 template<
typename CF,
typename CT>
28 : m_f { std::forward<CF> (
f) }
29 , m_prevArgs { std::forward<CT> (prev) }
36 return run (*
this, std::forward<T> (arg));
42 return run (std::as_const (*
this), std::forward<T> (arg));
48 return run (std::move (*
this), std::forward<T> (arg));
51 template<
typename This,
typename T>
52 static auto run (This&& refThis, T&& arg)
54 if constexpr (std::is_invocable_v<F, PrevArgs..., T>)
56 auto wrapper = [&refThis, &arg] (
auto&&... args)
58 return std::invoke (std::move (refThis.m_f), std::forward<decltype (args)> (args)..., std::forward<T> (arg));
60 return std::apply (std::move (wrapper), std::move (refThis.m_prevArgs));
65 std::move (refThis.m_f),
66 std::tuple_cat (std::move (refThis.m_prevArgs), std::forward_as_tuple (std::forward<T> (arg)))
71 template<
typename F,
typename... Args>
72 CurryImpl<std::decay_t<F>, Args...>
Curry (F&&
f, Args&&... args)
74 return { std::forward<F> (
f), std::forward_as_tuple (std::forward<Args> (args)...) };