#pragma once #include #include #include template struct __attribute__((packed)) PackedArguments; template struct __attribute__((packed)) PackedArguments { R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; A9 a9; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; A9 a9; A10 a10; R rv; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; A9 a9; A10 a10; A11 a11; R rv; }; template struct __attribute__((packed)) PackedArguments { 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; R rv; }; template struct __attribute__((packed)) PackedArguments { 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; R rv; }; template struct __attribute__((packed)) PackedArguments { 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; R rv; }; template struct __attribute__(( packed)) PackedArguments { 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; A19 a19; A20 a20; A21 a21; A22 a22; R rv; }; template struct __attribute__(( packed)) PackedArguments { 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; A19 a19; A20 a20; A21 a21; A22 a22; A23 a23; R rv; }; template<> struct __attribute__((packed)) PackedArguments {}; template struct __attribute__((packed)) PackedArguments { A0 a0; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; A9 a9; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; A9 a9; A10 a10; }; template struct __attribute__((packed)) PackedArguments { A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; A7 a7; A8 a8; A9 a9; A10 a10; A11 a11; }; template struct __attribute__((packed)) PackedArguments { 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; }; template struct __attribute__((packed)) PackedArguments { 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; }; template struct __attribute__((packed)) PackedArguments { 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; }; template struct __attribute__((packed)) PackedArguments { 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; }; template struct __attribute__((packed)) PackedArguments { 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; }; template struct __attribute__((packed)) PackedArguments { 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; }; template struct __attribute__((packed)) PackedArguments { 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 T&& operator,(T&& t, Regularize) { return std::forward(t); } template void Invoke(Func&& func, PackedArguments& args) requires (std::is_invocable_r_v) { constexpr auto NumArgs = sizeof...(Args); static_assert(NumArgs <= 19 || NumArgs == 24); std::conditional_t, 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) { args.rv = rv; } }