diff --git a/ffi/include/tvm/ffi/base_details.h b/ffi/include/tvm/ffi/base_details.h index d078a5963ab7..fb7be1a955ba 100644 --- a/ffi/include/tvm/ffi/base_details.h +++ b/ffi/include/tvm/ffi/base_details.h @@ -29,7 +29,6 @@ #include #include -#include #include #if defined(_MSC_VER) @@ -136,32 +135,14 @@ namespace tvm { namespace ffi { namespace details { -// a dependent-name version of false, for static_assert -template -inline constexpr bool always_false = false; - // for each iterator struct for_each_dispatcher { template static void run(std::index_sequence, const F& f, Args&&... args) { // NOLINT(*) - if constexpr (std::conjunction_v< - std::is_invocable, Args>...>) { - (f(std::integral_constant{}, std::forward(args)), ...); - } else if constexpr (std::conjunction_v...>) { - (f(I, std::forward(args)), ...); - } else if constexpr (std::conjunction_v...>) { - (f(std::forward(args)), ...); - } else { - static_assert(always_false, "The function is not invocable with the provided arguments"); - } + (f(I, std::forward(args)), ...); } }; -// Three kinds of function F are acceptable in `for_each`: -// 1. F(size_t, Arg): argument with its index -// 2. F(Arg): just the argument -// 3. F(std::integral_constant, Arg): argument with its constexpr index -// The third one can make the index available in template arguments and `if constexpr`. template void for_each(const F& f, Args&&... args) { // NOLINT(*) for_each_dispatcher::run(std::index_sequence_for{}, f, std::forward(args)...); diff --git a/ffi/include/tvm/ffi/function_details.h b/ffi/include/tvm/ffi/function_details.h index 34e9979d5d56..d029c19dd107 100644 --- a/ffi/include/tvm/ffi/function_details.h +++ b/ffi/include/tvm/ffi/function_details.h @@ -36,6 +36,23 @@ namespace tvm { namespace ffi { namespace details { +template +struct Arg2Str { + template + TVM_FFI_INLINE static void Apply(std::ostream& os) { + using Arg = std::tuple_element_t; + if constexpr (i != 0) { + os << ", "; + } + os << i << ": " << Type2Str::v(); + } + template + TVM_FFI_INLINE static void Run(std::ostream& os, std::index_sequence) { + using TExpander = int[]; + (void)TExpander{0, (Apply(os), 0)...}; + } +}; + template static constexpr bool ArgSupported = (std::is_same_v>, Any> || @@ -61,16 +78,10 @@ struct FuncFunctorImpl { #endif TVM_FFI_INLINE static std::string Sig() { + using IdxSeq = std::make_index_sequence; std::ostringstream ss; ss << "("; - for_each( - [&ss](auto i, const auto& v) { - if constexpr (i() != 0) { - ss << ", "; - } - ss << i() << ": " << v; - }, - Type2Str::v()...); + Arg2Str>::Run(ss, IdxSeq{}); ss << ") -> " << Type2Str::v(); return ss.str(); }