Thunks: Simplify PackedArguments invocation code

This commit is contained in:
Tony Wasserka committed 2023-09-07 13:56:53 +02:00
1 parent 024fb268c0
commit 677b77f1bb
1 file changed
+59 -88
+59 -88
View File
@@ -2,6 +2,7 @@
#include <cstdint>
#include <type_traits>
#include <utility>
template<typename Result, typename... Args>
struct PackedArguments;
@@ -102,97 +103,67 @@ struct PackedArguments<void, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename A14, typename A15, typename A16, typename A17, typename A18>
struct PackedArguments<void, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18> { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; A9 a9; A10 a10; A11 a11; A12 a12; A13 a13; A14 a14; A15 a15; A16 a16; A17 a17; A18 a18; };
// Helper struct that allows assigning the result of a function to a variable, even if that result is a void type.
//
// For non-void result types, the overloaded the comma operator will always returns its left argument.
// For void types, the overloaded comma operator is *not* used. Instead, a dummy object is returned.
struct Regularize {};
template<typename T>
T&& operator,(T&& t, Regularize) {
return std::forward<T>(t);
}
template<typename Result, typename... Args>
void Invoke(Result(*func)(Args...), PackedArguments<Result, Args...>& args) {
constexpr auto NumArgs = sizeof...(Args);
static_assert(NumArgs <= 19 || NumArgs == 24);
if constexpr (std::is_void_v<Result>) {
if constexpr (NumArgs == 0) {
func();
} else if constexpr (NumArgs == 1) {
func(args.a0);
} else if constexpr (NumArgs == 2) {
func(args.a0, args.a1);
} else if constexpr (NumArgs == 3) {
func(args.a0, args.a1, args.a2);
} else if constexpr (NumArgs == 4) {
func(args.a0, args.a1, args.a2, args.a3);
} else if constexpr (NumArgs == 5) {
func(args.a0, args.a1, args.a2, args.a3, args.a4);
} else if constexpr (NumArgs == 6) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5);
} else if constexpr (NumArgs == 7) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6);
} else if constexpr (NumArgs == 8) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7);
} else if constexpr (NumArgs == 9) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8);
} else if constexpr (NumArgs == 10) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9);
} else if constexpr (NumArgs == 11) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10);
} else if constexpr (NumArgs == 12) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11);
} else if constexpr (NumArgs == 13) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12);
} else if constexpr (NumArgs == 14) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13);
} else if constexpr (NumArgs == 15) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14);
} else if constexpr (NumArgs == 16) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15);
} else if constexpr (NumArgs == 17) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16);
} else if constexpr (NumArgs == 18) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17);
} else if constexpr (NumArgs == 19) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17, args.a18);
} else if constexpr (NumArgs == 24) {
func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17, args.a18, args.a19, args.a20, args.a21, args.a22, args.a23);
}
} else {
if constexpr (NumArgs == 0) {
args.rv = func();
} else if constexpr (NumArgs == 1) {
args.rv = func(args.a0);
} else if constexpr (NumArgs == 2) {
args.rv = func(args.a0, args.a1);
} else if constexpr (NumArgs == 3) {
args.rv = func(args.a0, args.a1, args.a2);
} else if constexpr (NumArgs == 4) {
args.rv = func(args.a0, args.a1, args.a2, args.a3);
} else if constexpr (NumArgs == 5) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4);
} else if constexpr (NumArgs == 6) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5);
} else if constexpr (NumArgs == 7) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6);
} else if constexpr (NumArgs == 8) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7);
} else if constexpr (NumArgs == 9) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8);
} else if constexpr (NumArgs == 10) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9);
} else if constexpr (NumArgs == 11) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10);
} else if constexpr (NumArgs == 12) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11);
} else if constexpr (NumArgs == 13) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12);
} else if constexpr (NumArgs == 14) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13);
} else if constexpr (NumArgs == 15) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14);
} else if constexpr (NumArgs == 16) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15);
} else if constexpr (NumArgs == 17) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16);
} else if constexpr (NumArgs == 18) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17);
} else if constexpr (NumArgs == 19) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17, args.a18);
} else if constexpr (NumArgs == 24) {
args.rv = func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17, args.a18, args.a19, args.a20, args.a21, args.a22, args.a23);
}
std::conditional_t<std::is_void_v<Result>, Regularize, Result> rv;
if constexpr (NumArgs == 0) {
rv = (func(), Regularize{});
} else if constexpr (NumArgs == 1) {
rv = (func(args.a0), Regularize {});
} else if constexpr (NumArgs == 2) {
rv = (func(args.a0, args.a1), Regularize{});
} else if constexpr (NumArgs == 3) {
rv = (func(args.a0, args.a1, args.a2), Regularize{});
} else if constexpr (NumArgs == 4) {
rv = (func(args.a0, args.a1, args.a2, args.a3), Regularize{});
} else if constexpr (NumArgs == 5) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4), Regularize{});
} else if constexpr (NumArgs == 6) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5), Regularize{});
} else if constexpr (NumArgs == 7) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6), Regularize{});
} else if constexpr (NumArgs == 8) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7), Regularize{});
} else if constexpr (NumArgs == 9) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8), Regularize{});
} else if constexpr (NumArgs == 10) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9), Regularize{});
} else if constexpr (NumArgs == 11) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10), Regularize{});
} else if constexpr (NumArgs == 12) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11), Regularize{});
} else if constexpr (NumArgs == 13) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12), Regularize{});
} else if constexpr (NumArgs == 14) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13), Regularize{});
} else if constexpr (NumArgs == 15) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14), Regularize{});
} else if constexpr (NumArgs == 16) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15), Regularize{});
} else if constexpr (NumArgs == 17) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16), Regularize{});
} else if constexpr (NumArgs == 18) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17), Regularize{});
} else if constexpr (NumArgs == 19) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17, args.a18), Regularize{});
} else if constexpr (NumArgs == 24) {
rv = (func(args.a0, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6, args.a7, args.a8, args.a9, args.a10, args.a11, args.a12, args.a13, args.a14, args.a15, args.a16, args.a17, args.a18, args.a19, args.a20, args.a21, args.a22, args.a23), Regularize{});
}
if constexpr (!std::is_void_v<Result>) {
args.rv = rv;
}
}