🐙
CppでCライクなほとんど全ての関数をvoid**引数の形式に変換するメタ関数
#include <cstring>
#include <tuple>
#include <type_traits>
template <typename T>
struct Func_type : Func_type<decltype(+std::declval<T>())> {};
template <typename R, typename... A> struct Func_type<R (*)(A...)> {
using Return_type = R;
using Args_tuple = std::tuple<A...>;
};
template <const auto kernel_impl>
constexpr auto wrap_kernel() -> void (*)(void **) {
using args_t = typename Func_type<decltype(kernel_impl)>::Args_tuple;
constexpr size_t nargs = std::tuple_size_v<args_t>;
return +[](void **args_ptr) {
args_t args;
[&]<std::size_t... I>(std::index_sequence<I...>) {
((std::memcpy(&std::get<I>(args), args_ptr[I],
sizeof(std::tuple_element_t<I, args_t>))),
...);
}(std::make_index_sequence<nargs>{});
std::apply(kernel_impl, args);
};
}
// 例
void kernel_X(int n, int *arr, int val) {
// Do something
}
auto stub_kernel_X = wrap_kernel<kernel_X>();
static_assert(std::is_same<decltype(stub_kernel_X), void (*)(void**)>::value);
Discussion