diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-03-26 21:52:00 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-03-26 21:52:00 +0100 |
commit | 4f8cbd442a1b7805decaf4db7226075221655083 (patch) | |
tree | 7312b7e49e64a6f5bbba538cd5c5955c0a2fba0e | |
parent | 2d309a2cff4754c381353a73872a55b20b1a8019 (diff) |
Add invoke_r & co
-rw-r--r-- | asl/base/functional.hpp | 17 | ||||
-rw-r--r-- | asl/base/functional_tests.cpp | 9 | ||||
-rw-r--r-- | todo.txt | 2 |
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; }); +} @@ -1 +1 @@ -Add invoke_r & co + |