summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2025-03-26 21:52:00 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2025-03-26 21:52:00 +0100
commit4f8cbd442a1b7805decaf4db7226075221655083 (patch)
tree7312b7e49e64a6f5bbba538cd5c5955c0a2fba0e
parent2d309a2cff4754c381353a73872a55b20b1a8019 (diff)
Add invoke_r & co
-rw-r--r--asl/base/functional.hpp17
-rw-r--r--asl/base/functional_tests.cpp9
-rw-r--r--todo.txt2
3 files changed, 27 insertions, 1 deletions
diff --git a/asl/base/functional.hpp b/asl/base/functional.hpp
index 5649bf8..7372001 100644
--- a/asl/base/functional.hpp
+++ b/asl/base/functional.hpp
@@ -54,6 +54,19 @@ constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args)
return ((*std::forward<decltype(self)>(self)).*f)(std::forward<Args>(args)...);
}
+template<typename R, typename F, typename... Args>
+constexpr R invoke_r(F&& f, Args&&... args)
+{
+ if constexpr (is_void<R>)
+ {
+ static_cast<void>(invoke(std::forward<F>(f), std::forward<Args>(args)...));
+ }
+ else
+ {
+ return invoke(std::forward<F>(f), std::forward<Args>(args)...);
+ }
+}
+
template<typename Void, typename F, typename... Args>
struct _invoke_result_helper;
@@ -72,4 +85,8 @@ concept invocable = requires (F&& f, Args&&... args)
invoke(std::forward<F>(f), std::forward<Args>(args)...);
};
+template<typename R, typename F, typename... Args>
+concept invocable_r = invocable<F, Args...>
+ && (is_void<R> || convertible_to<invoke_result_t<F, Args...>, R>);
+
} // namespace asl
diff --git a/asl/base/functional_tests.cpp b/asl/base/functional_tests.cpp
index 6332784..6645109 100644
--- a/asl/base/functional_tests.cpp
+++ b/asl/base/functional_tests.cpp
@@ -68,6 +68,9 @@ static_assert(asl::invocable<decltype(&HasMember::member), const HasMember2>);
static_assert(asl::invocable<decltype(&HasMember::member), const HasMember&>);
static_assert(asl::invocable<decltype(&HasMember::member), const HasMember2*>);
+static_assert(asl::invocable_r<void*, int*()>);
+static_assert(!asl::invocable_r<int*, void*()>);
+
ASL_TEST(invoke_member_function)
{
HasFunction c;
@@ -109,3 +112,9 @@ ASL_TEST(invoke_lambda)
ASL_TEST_EXPECT(asl::invoke([](){ return 35; }) == 35);
ASL_TEST_EXPECT(asl::invoke([](int x){ return x + 2; }, 6) == 8);
}
+
+ASL_TEST(invoke_r)
+{
+ ASL_TEST_EXPECT(asl::invoke_r<int>([]() { return 1ULL; }) == 1);
+ asl::invoke_r<void>([]() { return 1ULL; });
+}
diff --git a/todo.txt b/todo.txt
index 8a1d00b..8b13789 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1 +1 @@
-Add invoke_r & co
+