tint: Use utils::Vector for sem::Type::Common()

Instead of a C-style array.

Change-Id: Ieb3e9811cddf505bfd3b484b7f265459f7b0e66b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97583
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2022-07-29 14:15:01 +00:00 committed by Dawn LUCI CQ
parent 05a76183e0
commit 8e0368e554
5 changed files with 162 additions and 171 deletions

View File

@ -131,7 +131,7 @@ class TemplateState {
if (existing == ty) {
return ty;
}
ty = sem::Type::Common({existing, ty});
ty = sem::Type::Common(utils::Vector{existing, ty});
if (ty) {
res.first->second = ty;
}

View File

@ -896,9 +896,8 @@ bool Resolver::WorkgroupSize(const ast::Function* func) {
}
auto values = attr->Values();
std::array<const sem::Expression*, 3> args = {};
std::array<const sem::Type*, 3> arg_tys = {};
size_t arg_count = 0;
utils::Vector<const sem::Expression*, 3> args;
utils::Vector<const sem::Type*, 3> arg_tys;
constexpr const char* kErrBadExpr =
"workgroup_size argument must be either a literal, constant, or overridable of type "
@ -921,12 +920,11 @@ bool Resolver::WorkgroupSize(const ast::Function* func) {
return false;
}
args[i] = expr;
arg_tys[i] = ty;
arg_count++;
args.Push(expr);
arg_tys.Push(ty);
}
auto* common_ty = sem::Type::Common(arg_tys.data(), arg_count);
auto* common_ty = sem::Type::Common(arg_tys);
if (!common_ty) {
AddError("workgroup_size arguments must be of the same type, either i32 or u32",
attr->source);
@ -938,7 +936,7 @@ bool Resolver::WorkgroupSize(const ast::Function* func) {
common_ty = builder_->create<sem::I32>();
}
for (size_t i = 0; i < arg_count; i++) {
for (size_t i = 0; i < args.Length(); i++) {
auto* materialized = Materialize(args[i], common_ty);
if (!materialized) {
return false;
@ -2576,8 +2574,8 @@ sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt
auto* cond_ty = cond->Type()->UnwrapRef();
utils::UniqueVector<const sem::Type*> types;
types.add(cond_ty);
utils::Vector<const sem::Type*, 8> types;
types.Push(cond_ty);
std::vector<sem::CaseStatement*> cases;
cases.reserve(stmt->body.size());
@ -2588,7 +2586,7 @@ sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt
return false;
}
for (auto* expr : c->Selectors()) {
types.add(expr->Type()->UnwrapRef());
types.Push(expr->Type()->UnwrapRef());
}
cases.emplace_back(c);
behaviors.Add(c->Behaviors());
@ -2597,7 +2595,7 @@ sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt
// Determine the common type across all selectors and the switch expression
// This must materialize to an integer scalar (non-abstract).
auto* common_ty = sem::Type::Common(types.data(), types.size());
auto* common_ty = sem::Type::Common(types);
if (!common_ty || !common_ty->is_integer_scalar()) {
// No common type found or the common type was abstract.
// Pick i32 and let validation deal with any mismatches.

View File

@ -264,7 +264,8 @@ const Type* Type::DeepestElementOf(const Type* ty, uint32_t* count /* = nullptr
return el_ty;
}
const sem::Type* Type::Common(Type const* const* types, size_t count) {
const sem::Type* Type::Common(utils::ConstVectorRef<const Type*> types) {
const auto count = types.Length();
if (count == 0) {
return nullptr;
}

View File

@ -19,6 +19,7 @@
#include <string>
#include "src/tint/sem/node.h"
#include "src/tint/utils/vector.h"
// Forward declarations
namespace tint {
@ -156,20 +157,11 @@ class Type : public Castable<Type, Node> {
/// * `nullptr` if `ty` is none of the above
static const Type* DeepestElementOf(const Type* ty, uint32_t* count = nullptr);
/// @param types a pointer to a list of `const Type*`.
/// @param count the number of types in `types`.
/// @param types the list of types
/// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
/// or nullptr if there is no consistent common type across all types in `types`.
/// @see https://www.w3.org/TR/WGSL/#conversion-rank
static const sem::Type* Common(Type const* const* types, size_t count);
/// @param types an initializer_list of `const Type*`.
/// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
/// or nullptr if there is no consistent common type across all types in `types`.
/// @see https://www.w3.org/TR/WGSL/#conversion-rank
static const sem::Type* Common(std::initializer_list<const Type*> types) {
return Common(types.begin(), types.size());
}
static const sem::Type* Common(utils::ConstVectorRef<const Type*> types);
protected:
Type();

View File

@ -357,41 +357,41 @@ TEST_F(TypeTest, Common2) {
auto* i32 = create<I32>();
auto* u32 = create<U32>();
EXPECT_TYPE(Type::Common({ai, ai}), ai);
EXPECT_TYPE(Type::Common({af, af}), af);
EXPECT_TYPE(Type::Common({f32, f32}), f32);
EXPECT_TYPE(Type::Common({f16, f16}), f16);
EXPECT_TYPE(Type::Common({i32, i32}), i32);
EXPECT_TYPE(Type::Common({u32, u32}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, ai}), ai);
EXPECT_TYPE(Type::Common(utils::Vector{af, af}), af);
EXPECT_TYPE(Type::Common(utils::Vector{f32, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{f16, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{i32, i32}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{u32, u32}), u32);
EXPECT_TYPE(Type::Common({i32, u32}), nullptr);
EXPECT_TYPE(Type::Common({u32, f32}), nullptr);
EXPECT_TYPE(Type::Common({f32, f16}), nullptr);
EXPECT_TYPE(Type::Common({f16, i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{i32, u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{u32, f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{f32, f16}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{f16, i32}), nullptr);
EXPECT_TYPE(Type::Common({ai, af}), af);
EXPECT_TYPE(Type::Common({ai, f32}), f32);
EXPECT_TYPE(Type::Common({ai, f16}), f16);
EXPECT_TYPE(Type::Common({ai, i32}), i32);
EXPECT_TYPE(Type::Common({ai, u32}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af}), af);
EXPECT_TYPE(Type::Common(utils::Vector{ai, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{ai, i32}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, u32}), u32);
EXPECT_TYPE(Type::Common({af, ai}), af);
EXPECT_TYPE(Type::Common({f32, ai}), f32);
EXPECT_TYPE(Type::Common({f16, ai}), f16);
EXPECT_TYPE(Type::Common({i32, ai}), i32);
EXPECT_TYPE(Type::Common({u32, ai}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{af, ai}), af);
EXPECT_TYPE(Type::Common(utils::Vector{f32, ai}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{f16, ai}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{i32, ai}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{u32, ai}), u32);
EXPECT_TYPE(Type::Common({ai, af}), af);
EXPECT_TYPE(Type::Common({f32, af}), f32);
EXPECT_TYPE(Type::Common({f16, af}), f16);
EXPECT_TYPE(Type::Common({i32, af}), nullptr);
EXPECT_TYPE(Type::Common({u32, af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af}), af);
EXPECT_TYPE(Type::Common(utils::Vector{f32, af}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{f16, af}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{i32, af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{u32, af}), nullptr);
EXPECT_TYPE(Type::Common({af, ai}), af);
EXPECT_TYPE(Type::Common({af, f32}), f32);
EXPECT_TYPE(Type::Common({af, f16}), f16);
EXPECT_TYPE(Type::Common({af, i32}), nullptr);
EXPECT_TYPE(Type::Common({af, u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{af, ai}), af);
EXPECT_TYPE(Type::Common(utils::Vector{af, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{af, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{af, i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{af, u32}), nullptr);
auto* vec3_ai = create<Vector>(ai, 3u);
auto* vec3_af = create<Vector>(af, 3u);
@ -401,55 +401,55 @@ TEST_F(TypeTest, Common2) {
auto* vec3_u32 = create<Vector>(u32, 3u);
auto* vec3_i32 = create<Vector>(i32, 3u);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_ai}), vec3_ai);
EXPECT_TYPE(Type::Common({vec3_af, vec3_af}), vec3_af);
EXPECT_TYPE(Type::Common({vec3_f32, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_f16, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common({vec4_f32, vec4_f32}), vec4_f32);
EXPECT_TYPE(Type::Common({vec3_u32, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common({vec3_i32, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai}), vec3_ai);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af}), vec3_af);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec4_f32}), vec4_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common({vec3_ai, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common({vec3_f32, vec3_ai}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_f16, vec3_ai}), vec3_f16);
EXPECT_TYPE(Type::Common({vec4_f32, vec3_ai}), nullptr);
EXPECT_TYPE(Type::Common({vec3_u32, vec3_ai}), vec3_u32);
EXPECT_TYPE(Type::Common({vec3_i32, vec3_ai}), vec3_i32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_ai}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_ai}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_ai}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_ai}), vec3_u32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_ai}), vec3_i32);
EXPECT_TYPE(Type::Common({vec3_af, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_af, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common({vec3_af, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_af, vec3_u32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_af, vec3_i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_i32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_f32, vec3_af}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_f16, vec3_af}), vec3_f16);
EXPECT_TYPE(Type::Common({vec4_f32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common({vec3_u32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common({vec3_i32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_af}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_af}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_af}), nullptr);
auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_af}), mat4x3_af);
EXPECT_TYPE(Type::Common({mat3x4_f32, mat3x4_f32}), mat3x4_f32);
EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af}), mat4x3_af);
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32}), mat3x4_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common({mat4x3_af, mat3x4_f32}), nullptr);
EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat3x4_f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common({mat3x4_f32, mat4x3_af}), nullptr);
EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_af}), mat4x3_f32);
EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_af}), mat4x3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat4x3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_af}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_af}), mat4x3_f16);
}
TEST_F(TypeTest, Common3) {
@ -460,49 +460,49 @@ TEST_F(TypeTest, Common3) {
auto* i32 = create<I32>();
auto* u32 = create<U32>();
EXPECT_TYPE(Type::Common({ai, ai, ai}), ai);
EXPECT_TYPE(Type::Common({af, af, af}), af);
EXPECT_TYPE(Type::Common({f32, f32, f32}), f32);
EXPECT_TYPE(Type::Common({f16, f16, f16}), f16);
EXPECT_TYPE(Type::Common({i32, i32, i32}), i32);
EXPECT_TYPE(Type::Common({u32, u32, u32}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, ai, ai}), ai);
EXPECT_TYPE(Type::Common(utils::Vector{af, af, af}), af);
EXPECT_TYPE(Type::Common(utils::Vector{f32, f32, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{f16, f16, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{i32, i32, i32}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{u32, u32, u32}), u32);
EXPECT_TYPE(Type::Common({ai, af, ai}), af);
EXPECT_TYPE(Type::Common({ai, f32, ai}), f32);
EXPECT_TYPE(Type::Common({ai, f16, ai}), f16);
EXPECT_TYPE(Type::Common({ai, i32, ai}), i32);
EXPECT_TYPE(Type::Common({ai, u32, ai}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, ai}), af);
EXPECT_TYPE(Type::Common(utils::Vector{ai, f32, ai}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, f16, ai}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{ai, i32, ai}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, u32, ai}), u32);
EXPECT_TYPE(Type::Common({af, ai, af}), af);
EXPECT_TYPE(Type::Common({f32, ai, f32}), f32);
EXPECT_TYPE(Type::Common({f16, ai, f16}), f16);
EXPECT_TYPE(Type::Common({i32, ai, i32}), i32);
EXPECT_TYPE(Type::Common({u32, ai, u32}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{af, ai, af}), af);
EXPECT_TYPE(Type::Common(utils::Vector{f32, ai, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{f16, ai, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{i32, ai, i32}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{u32, ai, u32}), u32);
EXPECT_TYPE(Type::Common({ai, f32, ai}), f32);
EXPECT_TYPE(Type::Common({ai, f16, ai}), f16);
EXPECT_TYPE(Type::Common({ai, i32, ai}), i32);
EXPECT_TYPE(Type::Common({ai, u32, ai}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, f32, ai}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, f16, ai}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{ai, i32, ai}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, u32, ai}), u32);
EXPECT_TYPE(Type::Common({f32, ai, f32}), f32);
EXPECT_TYPE(Type::Common({f16, ai, f16}), f16);
EXPECT_TYPE(Type::Common({i32, ai, i32}), i32);
EXPECT_TYPE(Type::Common({u32, ai, u32}), u32);
EXPECT_TYPE(Type::Common(utils::Vector{f32, ai, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{f16, ai, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{i32, ai, i32}), i32);
EXPECT_TYPE(Type::Common(utils::Vector{u32, ai, u32}), u32);
EXPECT_TYPE(Type::Common({af, f32, af}), f32);
EXPECT_TYPE(Type::Common({af, f16, af}), f16);
EXPECT_TYPE(Type::Common({af, i32, af}), nullptr);
EXPECT_TYPE(Type::Common({af, u32, af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{af, f32, af}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{af, f16, af}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{af, i32, af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{af, u32, af}), nullptr);
EXPECT_TYPE(Type::Common({f32, af, f32}), f32);
EXPECT_TYPE(Type::Common({f16, af, f16}), f16);
EXPECT_TYPE(Type::Common({i32, af, i32}), nullptr);
EXPECT_TYPE(Type::Common({u32, af, u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{f32, af, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{f16, af, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{i32, af, i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{u32, af, u32}), nullptr);
EXPECT_TYPE(Type::Common({ai, af, f32}), f32);
EXPECT_TYPE(Type::Common({ai, af, f16}), f16);
EXPECT_TYPE(Type::Common({ai, af, i32}), nullptr);
EXPECT_TYPE(Type::Common({ai, af, u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, f32}), f32);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, f16}), f16);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, u32}), nullptr);
auto* vec3_ai = create<Vector>(ai, 3u);
auto* vec3_af = create<Vector>(af, 3u);
@ -512,61 +512,61 @@ TEST_F(TypeTest, Common3) {
auto* vec3_u32 = create<Vector>(u32, 3u);
auto* vec3_i32 = create<Vector>(i32, 3u);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_ai, vec3_ai}), vec3_ai);
EXPECT_TYPE(Type::Common({vec3_af, vec3_af, vec3_af}), vec3_af);
EXPECT_TYPE(Type::Common({vec3_f32, vec3_f32, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_f16, vec3_f16, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common({vec4_f32, vec4_f32, vec4_f32}), vec4_f32);
EXPECT_TYPE(Type::Common({vec3_u32, vec3_u32, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common({vec3_i32, vec3_i32, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai, vec3_ai}), vec3_ai);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af, vec3_af}), vec3_af);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_f16, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec4_f32, vec4_f32}), vec4_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_u32, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_i32, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common({vec3_f32, vec3_ai, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_f16, vec3_ai, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common({vec4_f32, vec3_ai, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_u32, vec3_ai, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common({vec3_i32, vec3_ai, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_ai, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_ai, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_ai, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_ai, vec3_u32}), vec3_u32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_ai, vec3_i32}), vec3_i32);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_f32, vec3_ai}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_f16, vec3_ai}), vec3_f16);
EXPECT_TYPE(Type::Common({vec3_ai, vec4_f32, vec3_ai}), nullptr);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_u32, vec3_ai}), vec3_u32);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_i32, vec3_ai}), vec3_i32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f32, vec3_ai}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f16, vec3_ai}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec4_f32, vec3_ai}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_u32, vec3_ai}), vec3_u32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_i32, vec3_ai}), vec3_i32);
EXPECT_TYPE(Type::Common({vec3_f32, vec3_af, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_f16, vec3_af, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common({vec4_f32, vec3_af, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_u32, vec3_af, vec3_u32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_i32, vec3_af, vec3_i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_af, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_af, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_af, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_af, vec3_u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_af, vec3_i32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_af, vec3_f32, vec3_af}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_af, vec3_f16, vec3_af}), vec3_f16);
EXPECT_TYPE(Type::Common({vec3_af, vec4_f32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common({vec3_af, vec3_u32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common({vec3_af, vec3_i32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f32, vec3_af}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f16, vec3_af}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec4_f32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_u32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_i32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_u32}), nullptr);
EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_f32}), vec3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_f16}), vec3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec4_f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_i32}), nullptr);
auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_af, mat4x3_af}), mat4x3_af);
EXPECT_TYPE(Type::Common({mat3x4_f32, mat3x4_f32, mat3x4_f32}), mat3x4_f32);
EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_f32, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_f16, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af, mat4x3_af}), mat4x3_af);
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32, mat3x4_f32}), mat3x4_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_f16, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common({mat3x4_f32, mat4x3_af, mat3x4_f32}), nullptr);
EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_af, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_af, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat4x3_af, mat3x4_f32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_af, mat4x3_f32}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_af, mat4x3_f16}), mat4x3_f16);
EXPECT_TYPE(Type::Common({mat4x3_af, mat3x4_f32, mat4x3_af}), nullptr);
EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f32, mat4x3_af}), mat4x3_f32);
EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f16, mat4x3_af}), mat4x3_f16);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat3x4_f32, mat4x3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f32, mat4x3_af}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f16, mat4x3_af}), mat4x3_f16);
}
} // namespace