From f19d93a69a0ec5c7a89dcb4c064c984aac90ba71 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Wed, 26 Mar 2025 18:54:54 +0100 Subject: Improve implementation of invoke --- asl/base/functional.hpp | 61 ++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'asl/base/functional.hpp') diff --git a/asl/base/functional.hpp b/asl/base/functional.hpp index 509a2b2..5649bf8 100644 --- a/asl/base/functional.hpp +++ b/asl/base/functional.hpp @@ -9,56 +9,49 @@ namespace asl { -template -constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args) - -> decltype((self.*f)(std::forward(args)...)) - requires requires { - (self.*f)(std::forward(args)...); +template +constexpr auto invoke(F&& f, Args&&... args) + -> decltype(std::forward(f)(std::forward(args)...)) + requires (!is_member_ptr>) && requires { + f(std::forward(args)...); } { - return (std::forward(self).*f)(std::forward(args)...); + return std::forward(f)(std::forward(args)...); } -template -constexpr auto invoke(is_func auto C::* f, auto* self, Args&&... args) - -> decltype((self->*f)(std::forward(args)...)) - requires requires { - (self->*f)(std::forward(args)...); - } +template +constexpr auto&& invoke(auto C::* f, same_or_derived_from auto&& arg) { - return (self->*f)(std::forward(args)...); + return std::forward(arg).*f; } -template -constexpr auto invoke(is_object auto C::* m, auto&& self, Args&&...) - -> decltype(self.*m) +template +constexpr auto&& invoke(auto C::* f, auto&& arg) requires ( - sizeof...(Args) == 0 && - requires { self.*m; } + !same_or_derived_from + && requires { (*arg).*f; } ) { - return std::forward(self).*m; + return (*std::forward(arg)).*f; } -template -constexpr auto invoke(is_object auto C::* m, auto* self, Args&&...) - -> decltype(self->*m) - requires ( - sizeof...(Args) == 0 && - requires { self->*m; } - ) +template +constexpr auto invoke(is_func auto C::* f, same_or_derived_from auto&& self, Args&&... args) + -> decltype((std::forward(self).*f)(std::forward(args)...)) + requires requires { (self.*f)(std::forward(args)...); } { - return self->*m; + return (std::forward(self).*f)(std::forward(args)...); } -template -constexpr auto invoke(auto&& f, Args&&... args) - -> decltype(f(std::forward(args)...)) - requires requires { - f(std::forward(args)...); - } +template +constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args) + -> decltype(((*std::forward(self)).*f)(std::forward(args)...)) + requires ( + !same_or_derived_from + && requires { ((*self).*f)(std::forward(args)...); } + ) { - return std::forward(f)(std::forward(args)...); + return ((*std::forward(self)).*f)(std::forward(args)...); } template -- cgit