tint: Fix ProgramBuilder::WrapInFunction overload not being picked up
Before this change, the variadic function template version of WrapInFunction would be selected when passing a utils::VectorRef<const ast::Statement*>, even though an overload exists for that type. The reason is that during type deduction, the compiler will select templates over non-templates in its overload set. The only way around this was to avoid type-deduction by explicitly casting the argument to utils::VectorRef<const ast::Statement*>. This CL adds a CanWrapInStatement metafunction that evaluates to true if the arg type is one that could be passed to ProgramBuilder::WrapInStatement. This is used to SFINAE in the variadic args version of WrapInFunction. Change-Id: I8aa3d69e2ce7324fd60b1b2a5906a51d51b549a3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/115502 Reviewed-by: David Neto <dneto@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
16024a982d
commit
dfa92a9cb6
|
@ -149,6 +149,10 @@ struct IsVectorLike<utils::VectorRef<T>> {
|
|||
};
|
||||
} // namespace detail
|
||||
|
||||
// Forward declare metafunction that evaluates to true iff T can be wrapped in a statement.
|
||||
template <typename T, typename = void>
|
||||
struct CanWrapInStatement;
|
||||
|
||||
/// ProgramBuilder is a mutable builder for a Program.
|
||||
/// To construct a Program, populate the builder and then `std::move` it to a
|
||||
/// Program.
|
||||
|
@ -3326,12 +3330,13 @@ class ProgramBuilder {
|
|||
/// by the Resolver.
|
||||
/// @param args a mix of ast::Expression, ast::Statement, ast::Variables.
|
||||
/// @returns the function
|
||||
template <typename... ARGS>
|
||||
template <typename... ARGS,
|
||||
typename = traits::EnableIf<(CanWrapInStatement<ARGS>::value && ...)>>
|
||||
const ast::Function* WrapInFunction(ARGS&&... args) {
|
||||
utils::Vector stmts{
|
||||
WrapInStatement(std::forward<ARGS>(args))...,
|
||||
};
|
||||
return WrapInFunction(utils::VectorRef<const ast::Statement*>{std::move(stmts)});
|
||||
return WrapInFunction(std::move(stmts));
|
||||
}
|
||||
/// @param stmts a list of ast::Statement that will be wrapped by a function,
|
||||
/// so that each statement is reachable by the Resolver.
|
||||
|
@ -3411,6 +3416,17 @@ inline ProgramID ProgramIDOf(const ProgramBuilder* builder) {
|
|||
return builder->ID();
|
||||
}
|
||||
|
||||
// Primary template for metafunction that evaluates to true iff T can be wrapped in a statement.
|
||||
template <typename T, typename /* = void */>
|
||||
struct CanWrapInStatement : std::false_type {};
|
||||
|
||||
// Specialization of CanWrapInStatement
|
||||
template <typename T>
|
||||
struct CanWrapInStatement<
|
||||
T,
|
||||
std::void_t<decltype(std::declval<ProgramBuilder>().WrapInStatement(std::declval<T>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_PROGRAM_BUILDER_H_
|
||||
|
|
Loading…
Reference in New Issue