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.hpp19
1 files changed, 16 insertions, 3 deletions
diff --git a/asl/base/functional.hpp b/asl/base/functional.hpp
index d820bce..b4b5312 100644
--- a/asl/base/functional.hpp
+++ b/asl/base/functional.hpp
@@ -7,6 +7,7 @@ namespace asl {
template<typename... Args, typename C>
constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args)
+ -> decltype((self.*f)(ASL_FWD(args)...))
requires requires {
(self.*f)(ASL_FWD(args)...);
}
@@ -16,6 +17,7 @@ constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args)
template<typename... Args, typename C>
constexpr auto invoke(is_func auto C::* f, auto* self, Args&&... args)
+ -> decltype((self->*f)(ASL_FWD(args)...))
requires requires {
(self->*f)(ASL_FWD(args)...);
}
@@ -25,6 +27,7 @@ constexpr auto invoke(is_func auto C::* f, auto* self, Args&&... args)
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; }
@@ -35,6 +38,7 @@ constexpr auto invoke(is_object auto C::* m, auto&& self, Args&&...)
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; }
@@ -45,6 +49,7 @@ constexpr auto invoke(is_object auto C::* m, auto* self, Args&&...)
template<typename... Args>
constexpr auto invoke(auto&& f, Args&&... args)
+ -> decltype(f(ASL_FWD(args)...))
requires requires {
f(ASL_FWD(args)...);
}
@@ -52,14 +57,22 @@ constexpr auto invoke(auto&& f, Args&&... args)
return ASL_FWD(f)(ASL_FWD(args)...);
}
-template<typename F> struct _result_of_helper;
+template<typename Void, typename F, typename... Args>
+struct _invoke_result_helper;
template<typename R, typename... Args>
-struct _result_of_helper<R(Args...)>
+struct _invoke_result_helper<void, R, Args...>
{
using type = decltype(invoke(declval<R>(), declval<Args>()...));
};
-template<typename F> using result_of_t = _result_of_helper<F>::type;
+template<typename F, typename... Args>
+using invoke_result_t = _invoke_result_helper<void, F, Args...>::type;
+
+template<typename F, typename... Args>
+concept invocable = requires (F&& f, Args&&... args)
+{
+ invoke(ASL_FWD(f), ASL_FWD(args)...);
+};
} // namespace asl