diff --git a/include/fu/basic.h b/include/fu/basic.h index 3859ff4..4f5f6ed 100644 --- a/include/fu/basic.h +++ b/include/fu/basic.h @@ -188,40 +188,36 @@ constexpr auto part = ForwardT{}; /// A function that takes `n` or more arguments. If given only one argument, it /// will return a partial application. -template -struct multary_n_f : ToFunctor<_F> { - using F = ToFunctor<_F>; - - constexpr multary_n_f(F f) : F(std::move(f)) { } - +template +struct multary_n_f { // The result of applying this m arguments where m <= n. - template - using Partial = multary_n_f>; + template + using Partial = Part, Part>; /// Too few arguments: Return another multary function. - template> - constexpr Partial operator() (X...x) const & { - return Partial(closure(F(*this), std::move(x)...)); + template> + constexpr auto operator() (F f, X...x) const { + return part(multary_n_f{}, + closure(std::move(f), std::move(x)...)); } /// Exactly n arguments: Partially apply. - template> - constexpr Part operator() (X...x) const & { - return closure(F(*this), std::move(x)...); + template> + constexpr auto operator() (F&& f, X...x) const { + return closure(std::forward(f), std::move(x)...); } /// More than n arguments: invoke. - template n)>> - constexpr decltype(auto) operator() (X&&...x) const & + template n)>> + constexpr decltype(auto) operator() (F&& f, X&&...x) const { - return static_cast(*this)(std::forward(x)...); + return fu::invoke(std::forward(f), std::forward(x)...); } }; -template -struct multary_n_f<0, F> : ToFunctor { - using Fn = ToFunctor; - using Fn::operator(); +template<> +struct multary_n_f<0> : invoke_f { + using invoke_f::operator(); }; /// A function that takes two or more arguments. If given only one argument, it @@ -231,8 +227,8 @@ constexpr struct multary_f { // basic_multary = MakeT{}; // multary = part(basic_multary, Int<0>{}) template - constexpr multary_n_f<1, F> operator() (F f) const { - return multary_n_f<1, F>(std::move(f)); + constexpr auto operator() (F f) const { + return closure(multary_n_f<1>{}, std::move(f)); } } multary{}; @@ -244,16 +240,13 @@ constexpr struct multary_f { template struct make_multary_n_f { template - constexpr auto operator() (F f) const -> multary_n_f - { - return {std::move(f)}; + constexpr auto operator() (F f) const { + return closure(multary_n_f{}, std::move(f)); } template - constexpr auto operator() (std::reference_wrapper f) const - -> multary_n_f - { - return {std::move(f)}; + constexpr auto operator() (std::reference_wrapper f) const { + return part(multary_n_f{}, f.get()); } }; @@ -261,8 +254,8 @@ template constexpr auto multary_n = make_multary_n_f{}; #else template -constexpr multary_n_f multary_n(F f) { - return multary_n_f(std::move(f)); +constexpr auto multary_n(F f) { + return closure(multary_n_f{}, std::move(f)); } #endif // __clang__