summaryrefslogtreecommitdiff
path: root/asl/base/functional.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'asl/base/functional.hpp')
-rw-r--r--asl/base/functional.hpp61
1 files changed, 27 insertions, 34 deletions
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<typename... Args, typename C>
-constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args)
- -> decltype((self.*f)(std::forward<Args>(args)...))
- requires requires {
- (self.*f)(std::forward<Args>(args)...);
+template<typename F, typename... Args>
+constexpr auto invoke(F&& f, Args&&... args)
+ -> decltype(std::forward<F>(f)(std::forward<Args>(args)...))
+ requires (!is_member_ptr<un_cvref_t<F>>) && requires {
+ f(std::forward<Args>(args)...);
}
{
- return (std::forward<decltype(self)>(self).*f)(std::forward<Args>(args)...);
+ return std::forward<F>(f)(std::forward<Args>(args)...);
}
-template<typename... Args, typename C>
-constexpr auto invoke(is_func auto C::* f, auto* self, Args&&... args)
- -> decltype((self->*f)(std::forward<Args>(args)...))
- requires requires {
- (self->*f)(std::forward<Args>(args)...);
- }
+template<typename C>
+constexpr auto&& invoke(auto C::* f, same_or_derived_from<C> auto&& arg)
{
- return (self->*f)(std::forward<Args>(args)...);
+ return std::forward<decltype(arg)>(arg).*f;
}
-template<typename... Args, typename C>
-constexpr auto invoke(is_object auto C::* m, auto&& self, Args&&...)
- -> decltype(self.*m)
+template<typename C>
+constexpr auto&& invoke(auto C::* f, auto&& arg)
requires (
- sizeof...(Args) == 0 &&
- requires { self.*m; }
+ !same_or_derived_from<decltype(arg), C>
+ && requires { (*arg).*f; }
)
{
- return std::forward<decltype(self)>(self).*m;
+ return (*std::forward<decltype(arg)>(arg)).*f;
}
-template<typename... Args, typename C>
-constexpr auto invoke(is_object auto C::* m, auto* self, Args&&...)
- -> decltype(self->*m)
- requires (
- sizeof...(Args) == 0 &&
- requires { self->*m; }
- )
+template<typename C, typename... Args>
+constexpr auto invoke(is_func auto C::* f, same_or_derived_from<C> auto&& self, Args&&... args)
+ -> decltype((std::forward<decltype(self)>(self).*f)(std::forward<Args>(args)...))
+ requires requires { (self.*f)(std::forward<Args>(args)...); }
{
- return self->*m;
+ return (std::forward<decltype(self)>(self).*f)(std::forward<Args>(args)...);
}
-template<typename... Args>
-constexpr auto invoke(auto&& f, Args&&... args)
- -> decltype(f(std::forward<Args>(args)...))
- requires requires {
- f(std::forward<Args>(args)...);
- }
+template<typename C, typename... Args>
+constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args)
+ -> decltype(((*std::forward<decltype(self)>(self)).*f)(std::forward<Args>(args)...))
+ requires (
+ !same_or_derived_from<decltype(self), C>
+ && requires { ((*self).*f)(std::forward<Args>(args)...); }
+ )
{
- return std::forward<decltype(f)>(f)(std::forward<Args>(args)...);
+ return ((*std::forward<decltype(self)>(self)).*f)(std::forward<Args>(args)...);
}
template<typename Void, typename F, typename... Args>