mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-16 04:11:25 +00:00
tint/resolver: Further simplify test const eval framework
Replace ScalarArgs struct with Scalar variant and vector. Fold ValueBase and ConcreteValue into Value. Change-Id: I5cc5811a87f1aae162feb65fb6b1ecdac033d0fe Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/111761 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
c572df265d
commit
95d174a118
@ -94,12 +94,12 @@ TEST_P(ResolverConstEvalConvTest, Test) {
|
|||||||
ASSERT_NE(sem->ConstantValue(), nullptr);
|
ASSERT_NE(sem->ConstantValue(), nullptr);
|
||||||
EXPECT_TYPE(sem->ConstantValue()->Type(), target_sem_ty);
|
EXPECT_TYPE(sem->ConstantValue()->Type(), target_sem_ty);
|
||||||
|
|
||||||
auto expected_values = expected.Args();
|
auto expected_values = expected.args;
|
||||||
if (kind == Kind::kVector) {
|
if (kind == Kind::kVector) {
|
||||||
expected_values.values.Push(expected_values.values[0]);
|
expected_values.Push(expected_values[0]);
|
||||||
expected_values.values.Push(expected_values.values[0]);
|
expected_values.Push(expected_values[0]);
|
||||||
}
|
}
|
||||||
auto got_values = ScalarArgsFrom(sem->ConstantValue());
|
auto got_values = ScalarsFrom(sem->ConstantValue());
|
||||||
EXPECT_EQ(expected_values, got_values);
|
EXPECT_EQ(expected_values, got_values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,28 +37,29 @@ template <typename T>
|
|||||||
inline const auto k3PiOver4 = T(UnwrapNumber<T>(2.356194490192344928846));
|
inline const auto k3PiOver4 = T(UnwrapNumber<T>(2.356194490192344928846));
|
||||||
|
|
||||||
/// Walks the sem::Constant @p c, accumulating all the inner-most scalar values into @p args
|
/// Walks the sem::Constant @p c, accumulating all the inner-most scalar values into @p args
|
||||||
inline void CollectScalarArgs(const sem::Constant* c, builder::ScalarArgs& args) {
|
template <size_t N>
|
||||||
|
inline void CollectScalars(const sem::Constant* c, utils::Vector<builder::Scalar, N>& scalars) {
|
||||||
Switch(
|
Switch(
|
||||||
c->Type(), //
|
c->Type(), //
|
||||||
[&](const sem::AbstractInt*) { args.values.Push(c->As<AInt>()); },
|
[&](const sem::AbstractInt*) { scalars.Push(c->As<AInt>()); },
|
||||||
[&](const sem::AbstractFloat*) { args.values.Push(c->As<AFloat>()); },
|
[&](const sem::AbstractFloat*) { scalars.Push(c->As<AFloat>()); },
|
||||||
[&](const sem::Bool*) { args.values.Push(c->As<bool>()); },
|
[&](const sem::Bool*) { scalars.Push(c->As<bool>()); },
|
||||||
[&](const sem::I32*) { args.values.Push(c->As<i32>()); },
|
[&](const sem::I32*) { scalars.Push(c->As<i32>()); },
|
||||||
[&](const sem::U32*) { args.values.Push(c->As<u32>()); },
|
[&](const sem::U32*) { scalars.Push(c->As<u32>()); },
|
||||||
[&](const sem::F32*) { args.values.Push(c->As<f32>()); },
|
[&](const sem::F32*) { scalars.Push(c->As<f32>()); },
|
||||||
[&](const sem::F16*) { args.values.Push(c->As<f16>()); },
|
[&](const sem::F16*) { scalars.Push(c->As<f16>()); },
|
||||||
[&](Default) {
|
[&](Default) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (auto* child = c->Index(i++)) {
|
while (auto* child = c->Index(i++)) {
|
||||||
CollectScalarArgs(child, args);
|
CollectScalars(child, scalars);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walks the sem::Constant @p c, returning all the inner-most scalar values.
|
/// Walks the sem::Constant @p c, returning all the inner-most scalar values.
|
||||||
inline builder::ScalarArgs ScalarArgsFrom(const sem::Constant* c) {
|
inline utils::Vector<builder::Scalar, 16> ScalarsFrom(const sem::Constant* c) {
|
||||||
builder::ScalarArgs out;
|
utils::Vector<builder::Scalar, 16> out;
|
||||||
CollectScalarArgs(c, out);
|
CollectScalars(c, out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,14 +91,14 @@ struct CheckConstantFlags {
|
|||||||
inline void CheckConstant(const sem::Constant* got_constant,
|
inline void CheckConstant(const sem::Constant* got_constant,
|
||||||
const builder::Value& expected_value,
|
const builder::Value& expected_value,
|
||||||
CheckConstantFlags flags = {}) {
|
CheckConstantFlags flags = {}) {
|
||||||
auto values_flat = ScalarArgsFrom(got_constant);
|
auto values_flat = ScalarsFrom(got_constant);
|
||||||
auto expected_values_flat = expected_value.Args();
|
auto expected_values_flat = expected_value.args;
|
||||||
ASSERT_EQ(values_flat.values.Length(), expected_values_flat.values.Length());
|
ASSERT_EQ(values_flat.Length(), expected_values_flat.Length());
|
||||||
for (size_t i = 0; i < values_flat.values.Length(); ++i) {
|
for (size_t i = 0; i < values_flat.Length(); ++i) {
|
||||||
auto& got_scalar = values_flat.values[i];
|
auto& got_scalar = values_flat[i];
|
||||||
auto& expected_scalar = expected_values_flat.values[i];
|
auto& expected_scalar = expected_values_flat[i];
|
||||||
std::visit(
|
std::visit(
|
||||||
[&](auto&& expected) {
|
[&](const auto& expected) {
|
||||||
using T = std::decay_t<decltype(expected)>;
|
using T = std::decay_t<decltype(expected)>;
|
||||||
|
|
||||||
ASSERT_TRUE(std::holds_alternative<T>(got_scalar));
|
ASSERT_TRUE(std::holds_alternative<T>(got_scalar));
|
||||||
|
@ -61,14 +61,14 @@ TEST_P(ResolverConstEvalUnaryOpTest, Test) {
|
|||||||
ASSERT_NE(value, nullptr);
|
ASSERT_NE(value, nullptr);
|
||||||
EXPECT_TYPE(value->Type(), sem->Type());
|
EXPECT_TYPE(value->Type(), sem->Type());
|
||||||
|
|
||||||
auto values_flat = ScalarArgsFrom(value);
|
auto values_flat = ScalarsFrom(value);
|
||||||
auto expected_values_flat = expected.Args();
|
auto expected_values_flat = expected.args;
|
||||||
ASSERT_EQ(values_flat.values.Length(), expected_values_flat.values.Length());
|
ASSERT_EQ(values_flat.Length(), expected_values_flat.Length());
|
||||||
for (size_t i = 0; i < values_flat.values.Length(); ++i) {
|
for (size_t i = 0; i < values_flat.Length(); ++i) {
|
||||||
auto& a = values_flat.values[i];
|
auto& a = values_flat[i];
|
||||||
auto& b = expected_values_flat.values[i];
|
auto& b = expected_values_flat[i];
|
||||||
EXPECT_EQ(a, b);
|
EXPECT_EQ(a, b);
|
||||||
if (expected.IsIntegral()) {
|
if (expected.is_integral) {
|
||||||
// Check that the constant's integer doesn't contain unexpected
|
// Check that the constant's integer doesn't contain unexpected
|
||||||
// data in the MSBs that are outside of the bit-width of T.
|
// data in the MSBs that are outside of the bit-width of T.
|
||||||
EXPECT_EQ(builder::As<AInt>(a), builder::As<AInt>(b));
|
EXPECT_EQ(builder::As<AInt>(a), builder::As<AInt>(b));
|
||||||
|
@ -180,63 +180,18 @@ using alias3 = alias<TO, 3>;
|
|||||||
template <typename TO>
|
template <typename TO>
|
||||||
struct ptr {};
|
struct ptr {};
|
||||||
|
|
||||||
/// Type used to accept scalars as arguments. Can be either a single value that gets splatted for
|
/// A scalar value
|
||||||
/// composite types, or all values required by the composite type.
|
using Scalar = std::variant<i32, u32, f32, f16, AInt, AFloat, bool>;
|
||||||
struct ScalarArgs {
|
|
||||||
/// Constructor
|
|
||||||
ScalarArgs() = default;
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
/// @param single_value single value to initialize with
|
|
||||||
template <typename T>
|
|
||||||
explicit ScalarArgs(T single_value) : values(utils::Vector<Storage, 1>{single_value}) {}
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
/// @param all_values all values to initialize the composite type with
|
|
||||||
template <typename T>
|
|
||||||
ScalarArgs(utils::VectorRef<T> all_values) // NOLINT: implicit on purpose
|
|
||||||
{
|
|
||||||
for (auto& v : all_values) {
|
|
||||||
values.Push(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @param other the other ScalarArgs to compare against
|
|
||||||
/// @returns true if all values are equal to the values in @p other
|
|
||||||
bool operator==(const ScalarArgs& other) const { return values == other.values; }
|
|
||||||
|
|
||||||
/// Valid scalar types for args
|
|
||||||
using Storage = std::variant<i32, u32, f32, f16, AInt, AFloat, bool>;
|
|
||||||
|
|
||||||
/// The vector of values
|
|
||||||
utils::Vector<Storage, 16> values;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Returns current variant value in `s` cast to type `T`
|
/// Returns current variant value in `s` cast to type `T`
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T As(ScalarArgs::Storage& s) {
|
T As(Scalar& s) {
|
||||||
return std::visit([](auto&& v) { return static_cast<T>(v); }, s);
|
return std::visit([](auto&& v) { return static_cast<T>(v); }, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param o the std::ostream to write to
|
|
||||||
/// @param args the ScalarArgs
|
|
||||||
/// @return the std::ostream so calls can be chained
|
|
||||||
inline std::ostream& operator<<(std::ostream& o, const ScalarArgs& args) {
|
|
||||||
o << "[";
|
|
||||||
bool first = true;
|
|
||||||
for (auto& val : args.values) {
|
|
||||||
if (!first) {
|
|
||||||
o << ", ";
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
std::visit([&](auto&& v) { o << v; }, val);
|
|
||||||
}
|
|
||||||
o << "]";
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
using ast_type_func_ptr = const ast::Type* (*)(ProgramBuilder& b);
|
using ast_type_func_ptr = const ast::Type* (*)(ProgramBuilder& b);
|
||||||
using ast_expr_func_ptr = const ast::Expression* (*)(ProgramBuilder& b, ScalarArgs args);
|
using ast_expr_func_ptr = const ast::Expression* (*)(ProgramBuilder& b,
|
||||||
|
utils::VectorRef<Scalar> args);
|
||||||
using ast_expr_from_double_func_ptr = const ast::Expression* (*)(ProgramBuilder& b, double v);
|
using ast_expr_from_double_func_ptr = const ast::Expression* (*)(ProgramBuilder& b, double v);
|
||||||
using sem_type_func_ptr = const sem::Type* (*)(ProgramBuilder& b);
|
using sem_type_func_ptr = const sem::Type* (*)(ProgramBuilder& b);
|
||||||
using type_name_func_ptr = std::string (*)();
|
using type_name_func_ptr = std::string (*)();
|
||||||
@ -280,14 +235,14 @@ struct DataType<bool> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the boolean value to init with
|
/// @param args args of size 1 with the boolean value to init with
|
||||||
/// @return a new AST expression of the bool type
|
/// @return a new AST expression of the bool type
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Expr(std::get<bool>(args.values[0]));
|
return b.Expr(std::get<bool>(args[0]));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param v arg of type double that will be cast to bool.
|
/// @param v arg of type double that will be cast to bool.
|
||||||
/// @return a new AST expression of the bool type
|
/// @return a new AST expression of the bool type
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() { return "bool"; }
|
static inline std::string Name() { return "bool"; }
|
||||||
@ -311,14 +266,14 @@ struct DataType<i32> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the i32 value to init with
|
/// @param args args of size 1 with the i32 value to init with
|
||||||
/// @return a new AST i32 literal value expression
|
/// @return a new AST i32 literal value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Expr(std::get<i32>(args.values[0]));
|
return b.Expr(std::get<i32>(args[0]));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param v arg of type double that will be cast to i32.
|
/// @param v arg of type double that will be cast to i32.
|
||||||
/// @return a new AST i32 literal value expression
|
/// @return a new AST i32 literal value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() { return "i32"; }
|
static inline std::string Name() { return "i32"; }
|
||||||
@ -342,14 +297,14 @@ struct DataType<u32> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the u32 value to init with
|
/// @param args args of size 1 with the u32 value to init with
|
||||||
/// @return a new AST u32 literal value expression
|
/// @return a new AST u32 literal value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Expr(std::get<u32>(args.values[0]));
|
return b.Expr(std::get<u32>(args[0]));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param v arg of type double that will be cast to u32.
|
/// @param v arg of type double that will be cast to u32.
|
||||||
/// @return a new AST u32 literal value expression
|
/// @return a new AST u32 literal value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() { return "u32"; }
|
static inline std::string Name() { return "u32"; }
|
||||||
@ -373,14 +328,14 @@ struct DataType<f32> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the f32 value to init with
|
/// @param args args of size 1 with the f32 value to init with
|
||||||
/// @return a new AST f32 literal value expression
|
/// @return a new AST f32 literal value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Expr(std::get<f32>(args.values[0]));
|
return b.Expr(std::get<f32>(args[0]));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param v arg of type double that will be cast to f32.
|
/// @param v arg of type double that will be cast to f32.
|
||||||
/// @return a new AST f32 literal value expression
|
/// @return a new AST f32 literal value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<f32>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<f32>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() { return "f32"; }
|
static inline std::string Name() { return "f32"; }
|
||||||
@ -404,14 +359,14 @@ struct DataType<f16> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the f16 value to init with
|
/// @param args args of size 1 with the f16 value to init with
|
||||||
/// @return a new AST f16 literal value expression
|
/// @return a new AST f16 literal value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Expr(std::get<f16>(args.values[0]));
|
return b.Expr(std::get<f16>(args[0]));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param v arg of type double that will be cast to f16.
|
/// @param v arg of type double that will be cast to f16.
|
||||||
/// @return a new AST f16 literal value expression
|
/// @return a new AST f16 literal value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() { return "f16"; }
|
static inline std::string Name() { return "f16"; }
|
||||||
@ -434,14 +389,14 @@ struct DataType<AFloat> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the abstract-float value to init with
|
/// @param args args of size 1 with the abstract-float value to init with
|
||||||
/// @return a new AST abstract-float literal value expression
|
/// @return a new AST abstract-float literal value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Expr(std::get<AFloat>(args.values[0]));
|
return b.Expr(std::get<AFloat>(args[0]));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param v arg of type double that will be cast to AFloat.
|
/// @param v arg of type double that will be cast to AFloat.
|
||||||
/// @return a new AST abstract-float literal value expression
|
/// @return a new AST abstract-float literal value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() { return "abstract-float"; }
|
static inline std::string Name() { return "abstract-float"; }
|
||||||
@ -464,14 +419,14 @@ struct DataType<AInt> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 with the abstract-int value to init with
|
/// @param args args of size 1 with the abstract-int value to init with
|
||||||
/// @return a new AST abstract-int literal value expression
|
/// @return a new AST abstract-int literal value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Expr(std::get<AInt>(args.values[0]));
|
return b.Expr(std::get<AInt>(args[0]));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param v arg of type double that will be cast to AInt.
|
/// @param v arg of type double that will be cast to AInt.
|
||||||
/// @return a new AST abstract-int literal value expression
|
/// @return a new AST abstract-int literal value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() { return "abstract-int"; }
|
static inline std::string Name() { return "abstract-int"; }
|
||||||
@ -499,17 +454,17 @@ struct DataType<vec<N, T>> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 or N with values of type T to initialize with
|
/// @param args args of size 1 or N with values of type T to initialize with
|
||||||
/// @return a new AST vector value expression
|
/// @return a new AST vector value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Construct(AST(b), ExprArgs(b, std::move(args)));
|
return b.Construct(AST(b), ExprArgs(b, std::move(args)));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 or N with values of type T to initialize with
|
/// @param args args of size 1 or N with values of type T to initialize with
|
||||||
/// @return the list of expressions that are used to construct the vector
|
/// @return the list of expressions that are used to construct the vector
|
||||||
static inline auto ExprArgs(ProgramBuilder& b, ScalarArgs args) {
|
static inline auto ExprArgs(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
const bool one_value = args.values.Length() == 1;
|
const bool one_value = args.Length() == 1;
|
||||||
utils::Vector<const ast::Expression*, N> r;
|
utils::Vector<const ast::Expression*, N> r;
|
||||||
for (size_t i = 0; i < N; ++i) {
|
for (size_t i = 0; i < N; ++i) {
|
||||||
r.Push(DataType<T>::Expr(b, ScalarArgs{one_value ? args.values[0] : args.values[i]}));
|
r.Push(DataType<T>::Expr(b, utils::Vector<Scalar, 1>{one_value ? args[0] : args[i]}));
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -517,7 +472,7 @@ struct DataType<vec<N, T>> {
|
|||||||
/// @param v arg of type double that will be cast to ElementType
|
/// @param v arg of type double that will be cast to ElementType
|
||||||
/// @return a new AST vector value expression
|
/// @return a new AST vector value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() {
|
static inline std::string Name() {
|
||||||
@ -548,25 +503,25 @@ struct DataType<mat<N, M, T>> {
|
|||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 or N*M with values of type T to initialize with
|
/// @param args args of size 1 or N*M with values of type T to initialize with
|
||||||
/// @return a new AST matrix value expression
|
/// @return a new AST matrix value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Construct(AST(b), ExprArgs(b, std::move(args)));
|
return b.Construct(AST(b), ExprArgs(b, std::move(args)));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 or N*M with values of type T to initialize with
|
/// @param args args of size 1 or N*M with values of type T to initialize with
|
||||||
/// @return a new AST matrix value expression
|
/// @return a new AST matrix value expression
|
||||||
static inline auto ExprArgs(ProgramBuilder& b, ScalarArgs args) {
|
static inline auto ExprArgs(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
const bool one_value = args.values.Length() == 1;
|
const bool one_value = args.Length() == 1;
|
||||||
size_t next = 0;
|
size_t next = 0;
|
||||||
utils::Vector<const ast::Expression*, N> r;
|
utils::Vector<const ast::Expression*, N> r;
|
||||||
for (uint32_t i = 0; i < N; ++i) {
|
for (uint32_t i = 0; i < N; ++i) {
|
||||||
if (one_value) {
|
if (one_value) {
|
||||||
r.Push(DataType<vec<M, T>>::Expr(b, ScalarArgs{args.values[0]}));
|
r.Push(DataType<vec<M, T>>::Expr(b, utils::Vector<Scalar, 1>{args[0]}));
|
||||||
} else {
|
} else {
|
||||||
utils::Vector<T, M> v;
|
utils::Vector<Scalar, M> v;
|
||||||
for (size_t j = 0; j < M; ++j) {
|
for (size_t j = 0; j < M; ++j) {
|
||||||
v.Push(std::get<T>(args.values[next++]));
|
v.Push(args[next++]);
|
||||||
}
|
}
|
||||||
r.Push(DataType<vec<M, T>>::Expr(b, utils::VectorRef<T>{v}));
|
r.Push(DataType<vec<M, T>>::Expr(b, std::move(v)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
@ -575,7 +530,7 @@ struct DataType<mat<N, M, T>> {
|
|||||||
/// @param v arg of type double that will be cast to ElementType
|
/// @param v arg of type double that will be cast to ElementType
|
||||||
/// @return a new AST matrix value expression
|
/// @return a new AST matrix value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() {
|
static inline std::string Name() {
|
||||||
@ -611,8 +566,9 @@ struct DataType<alias<T, ID>> {
|
|||||||
/// @param args the value nested elements will be initialized with
|
/// @param args the value nested elements will be initialized with
|
||||||
/// @return a new AST expression of the alias type
|
/// @return a new AST expression of the alias type
|
||||||
template <bool IS_COMPOSITE = is_composite>
|
template <bool IS_COMPOSITE = is_composite>
|
||||||
static inline traits::EnableIf<!IS_COMPOSITE, const ast::Expression*> Expr(ProgramBuilder& b,
|
static inline traits::EnableIf<!IS_COMPOSITE, const ast::Expression*> Expr(
|
||||||
ScalarArgs args) {
|
ProgramBuilder& b,
|
||||||
|
utils::VectorRef<Scalar> args) {
|
||||||
// Cast
|
// Cast
|
||||||
return b.Construct(AST(b), DataType<T>::Expr(b, std::move(args)));
|
return b.Construct(AST(b), DataType<T>::Expr(b, std::move(args)));
|
||||||
}
|
}
|
||||||
@ -621,8 +577,9 @@ struct DataType<alias<T, ID>> {
|
|||||||
/// @param args the value nested elements will be initialized with
|
/// @param args the value nested elements will be initialized with
|
||||||
/// @return a new AST expression of the alias type
|
/// @return a new AST expression of the alias type
|
||||||
template <bool IS_COMPOSITE = is_composite>
|
template <bool IS_COMPOSITE = is_composite>
|
||||||
static inline traits::EnableIf<IS_COMPOSITE, const ast::Expression*> Expr(ProgramBuilder& b,
|
static inline traits::EnableIf<IS_COMPOSITE, const ast::Expression*> Expr(
|
||||||
ScalarArgs args) {
|
ProgramBuilder& b,
|
||||||
|
utils::VectorRef<Scalar> args) {
|
||||||
// Construct
|
// Construct
|
||||||
return b.Construct(AST(b), DataType<T>::ExprArgs(b, std::move(args)));
|
return b.Construct(AST(b), DataType<T>::ExprArgs(b, std::move(args)));
|
||||||
}
|
}
|
||||||
@ -631,7 +588,7 @@ struct DataType<alias<T, ID>> {
|
|||||||
/// @param v arg of type double that will be cast to ElementType
|
/// @param v arg of type double that will be cast to ElementType
|
||||||
/// @return a new AST expression of the alias type
|
/// @return a new AST expression of the alias type
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
@ -662,7 +619,8 @@ struct DataType<ptr<T>> {
|
|||||||
|
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @return a new AST expression of the pointer type
|
/// @return a new AST expression of the pointer type
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs /*unused*/) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b,
|
||||||
|
utils::VectorRef<Scalar> /*unused*/) {
|
||||||
auto sym = b.Symbols().New("global_for_ptr");
|
auto sym = b.Symbols().New("global_for_ptr");
|
||||||
b.GlobalVar(sym, DataType<T>::AST(b), ast::AddressSpace::kPrivate);
|
b.GlobalVar(sym, DataType<T>::AST(b), ast::AddressSpace::kPrivate);
|
||||||
return b.AddressOf(sym);
|
return b.AddressOf(sym);
|
||||||
@ -672,7 +630,7 @@ struct DataType<ptr<T>> {
|
|||||||
/// @param v arg of type double that will be cast to ElementType
|
/// @param v arg of type double that will be cast to ElementType
|
||||||
/// @return a new AST expression of the pointer type
|
/// @return a new AST expression of the pointer type
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
@ -716,17 +674,17 @@ struct DataType<array<N, T>> {
|
|||||||
/// @param args args of size 1 or N with values of type T to initialize with
|
/// @param args args of size 1 or N with values of type T to initialize with
|
||||||
/// with
|
/// with
|
||||||
/// @return a new AST array value expression
|
/// @return a new AST array value expression
|
||||||
static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs args) {
|
static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
return b.Construct(AST(b), ExprArgs(b, std::move(args)));
|
return b.Construct(AST(b), ExprArgs(b, std::move(args)));
|
||||||
}
|
}
|
||||||
/// @param b the ProgramBuilder
|
/// @param b the ProgramBuilder
|
||||||
/// @param args args of size 1 or N with values of type T to initialize with
|
/// @param args args of size 1 or N with values of type T to initialize with
|
||||||
/// @return the list of expressions that are used to construct the array
|
/// @return the list of expressions that are used to construct the array
|
||||||
static inline auto ExprArgs(ProgramBuilder& b, ScalarArgs args) {
|
static inline auto ExprArgs(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
|
||||||
const bool one_value = args.values.Length() == 1;
|
const bool one_value = args.Length() == 1;
|
||||||
utils::Vector<const ast::Expression*, N> r;
|
utils::Vector<const ast::Expression*, N> r;
|
||||||
for (uint32_t i = 0; i < N; i++) {
|
for (uint32_t i = 0; i < N; i++) {
|
||||||
r.Push(DataType<T>::Expr(b, ScalarArgs{one_value ? args.values[0] : args.values[i]}));
|
r.Push(DataType<T>::Expr(b, utils::Vector<Scalar, 1>{one_value ? args[0] : args[i]}));
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -734,7 +692,7 @@ struct DataType<array<N, T>> {
|
|||||||
/// @param v arg of type double that will be cast to ElementType
|
/// @param v arg of type double that will be cast to ElementType
|
||||||
/// @return a new AST array value expression
|
/// @return a new AST array value expression
|
||||||
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
static inline const ast::Expression* ExprFromDouble(ProgramBuilder& b, double v) {
|
||||||
return Expr(b, ScalarArgs{static_cast<ElementType>(v)});
|
return Expr(b, utils::Vector<Scalar, 1>{static_cast<ElementType>(v)});
|
||||||
}
|
}
|
||||||
/// @returns the WGSL name for the type
|
/// @returns the WGSL name for the type
|
||||||
static inline std::string Name() {
|
static inline std::string Name() {
|
||||||
@ -776,80 +734,34 @@ template <typename T>
|
|||||||
const bool IsDataTypeSpecializedFor =
|
const bool IsDataTypeSpecializedFor =
|
||||||
!std::is_same_v<typename DataType<T>::ElementType, UnspecializedElementType>;
|
!std::is_same_v<typename DataType<T>::ElementType, UnspecializedElementType>;
|
||||||
|
|
||||||
namespace detail {
|
/// Value is used to create Values with a Scalar vector initializer.
|
||||||
/// ValueBase is a base class of ConcreteValue<T>
|
struct Value {
|
||||||
struct ValueBase {
|
/// Creates a Value for type T initialized with `args`
|
||||||
/// Constructor
|
|
||||||
ValueBase() = default;
|
|
||||||
/// Destructor
|
|
||||||
virtual ~ValueBase() = default;
|
|
||||||
/// Move constructor
|
|
||||||
ValueBase(ValueBase&&) = default;
|
|
||||||
/// Copy constructor
|
|
||||||
ValueBase(const ValueBase&) = default;
|
|
||||||
/// Copy assignment operator
|
|
||||||
/// @returns this instance
|
|
||||||
ValueBase& operator=(const ValueBase&) = default;
|
|
||||||
/// Creates an `ast::Expression` for the type T passing in previously stored args
|
|
||||||
/// @param b the ProgramBuilder
|
|
||||||
/// @returns an expression node
|
|
||||||
virtual const ast::Expression* Expr(ProgramBuilder& b) const = 0;
|
|
||||||
/// @returns args used to create expression via `Expr`
|
|
||||||
virtual const ScalarArgs& Args() const = 0;
|
|
||||||
/// @returns true if element type is abstract
|
|
||||||
virtual bool IsAbstract() const = 0;
|
|
||||||
/// @returns true if element type is an integral
|
|
||||||
virtual bool IsIntegral() const = 0;
|
|
||||||
/// @returns element type name
|
|
||||||
virtual std::string TypeName() const = 0;
|
|
||||||
/// Prints this value to the output stream
|
|
||||||
/// @param o the output stream
|
|
||||||
/// @returns input argument `o`
|
|
||||||
virtual std::ostream& Print(std::ostream& o) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ConcreteValue<T> is used to create Values of type DataType<T> with a ScalarArgs initializer.
|
|
||||||
template <typename T>
|
|
||||||
struct ConcreteValue : ValueBase {
|
|
||||||
/// Constructor
|
|
||||||
/// @param args the scalar args
|
/// @param args the scalar args
|
||||||
explicit ConcreteValue(ScalarArgs args) : args_(std::move(args)) {}
|
/// @returns Value
|
||||||
|
template <typename T>
|
||||||
/// Alias to T
|
static Value Create(utils::VectorRef<Scalar> args) {
|
||||||
using Type = T;
|
static_assert(IsDataTypeSpecializedFor<T>, "No DataType<T> specialization exists");
|
||||||
/// Alias to DataType<T>
|
using EL_TY = typename builder::DataType<T>::ElementType;
|
||||||
using DataType = builder::DataType<T>;
|
return Value{
|
||||||
/// Alias to DataType::ElementType
|
std::move(args), CreatePtrsFor<T>().expr, tint::IsAbstract<EL_TY>,
|
||||||
using ElementType = typename DataType::ElementType;
|
tint::IsIntegral<EL_TY>, tint::FriendlyName<EL_TY>(),
|
||||||
|
};
|
||||||
/// Creates an `ast::Expression` for the type T passing in previously stored args
|
|
||||||
/// @param b the ProgramBuilder
|
|
||||||
/// @returns an expression node
|
|
||||||
const ast::Expression* Expr(ProgramBuilder& b) const override {
|
|
||||||
auto create = CreatePtrsFor<T>();
|
|
||||||
return (*create.expr)(b, args_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns args used to create expression via `Expr`
|
/// Creates an `ast::Expression` for the type T passing in previously stored args
|
||||||
const ScalarArgs& Args() const override { return args_; }
|
/// @param b the ProgramBuilder
|
||||||
|
/// @returns an expression node
|
||||||
/// @returns true if element type is abstract
|
const ast::Expression* Expr(ProgramBuilder& b) const { return (*create)(b, args); }
|
||||||
bool IsAbstract() const override { return tint::IsAbstract<ElementType>; }
|
|
||||||
|
|
||||||
/// @returns true if element type is an integral
|
|
||||||
bool IsIntegral() const override { return tint::IsIntegral<ElementType>; }
|
|
||||||
|
|
||||||
/// @returns element type name
|
|
||||||
std::string TypeName() const override { return tint::FriendlyName<ElementType>(); }
|
|
||||||
|
|
||||||
/// Prints this value to the output stream
|
/// Prints this value to the output stream
|
||||||
/// @param o the output stream
|
/// @param o the output stream
|
||||||
/// @returns input argument `o`
|
/// @returns input argument `o`
|
||||||
std::ostream& Print(std::ostream& o) const override {
|
std::ostream& Print(std::ostream& o) const {
|
||||||
o << TypeName() << "(";
|
o << type_name << "(";
|
||||||
for (auto& a : args_.values) {
|
for (auto& a : args) {
|
||||||
o << std::get<ElementType>(a);
|
std::visit([&](auto& v) { o << v; }, a);
|
||||||
if (&a != &args_.values.Back()) {
|
if (&a != &args.Back()) {
|
||||||
o << ", ";
|
o << ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -857,54 +769,16 @@ struct ConcreteValue : ValueBase {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
/// The arguments used to construct the value
|
||||||
/// args to create expression with
|
utils::Vector<Scalar, 4> args;
|
||||||
ScalarArgs args_;
|
/// Function used to construct an expression with the given value
|
||||||
};
|
builder::ast_expr_func_ptr create;
|
||||||
} // namespace detail
|
/// True if the element type is abstract
|
||||||
|
bool is_abstract = false;
|
||||||
/// A Value represents a value of type DataType<T> created with ScalarArgs. Useful for storing
|
/// True if the element type is an integer
|
||||||
/// values for unit tests.
|
bool is_integral = false;
|
||||||
class Value {
|
/// The name of the type.
|
||||||
public:
|
const char* type_name = "<invalid>";
|
||||||
/// Creates a Value for type T initialized with `args`
|
|
||||||
/// @param args the scalar args
|
|
||||||
/// @returns Value
|
|
||||||
template <typename T>
|
|
||||||
static Value Create(ScalarArgs args) {
|
|
||||||
static_assert(IsDataTypeSpecializedFor<T>, "No DataType<T> specialization exists");
|
|
||||||
return Value{std::make_shared<detail::ConcreteValue<T>>(std::move(args))};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates an `ast::Expression` for the type T passing in previously stored args
|
|
||||||
/// @param b the ProgramBuilder
|
|
||||||
/// @returns an expression node
|
|
||||||
const ast::Expression* Expr(ProgramBuilder& b) const { return value_->Expr(b); }
|
|
||||||
|
|
||||||
/// @returns args used to create expression via `Expr`
|
|
||||||
const ScalarArgs& Args() const { return value_->Args(); }
|
|
||||||
|
|
||||||
/// @returns true if element type is abstract
|
|
||||||
bool IsAbstract() const { return value_->IsAbstract(); }
|
|
||||||
|
|
||||||
/// @returns true if element type is an integral
|
|
||||||
bool IsIntegral() const { return value_->IsIntegral(); }
|
|
||||||
|
|
||||||
/// @returns element type name
|
|
||||||
std::string TypeName() const { return value_->TypeName(); }
|
|
||||||
|
|
||||||
/// Prints this value to the output stream
|
|
||||||
/// @param o the output stream
|
|
||||||
/// @returns input argument `o`
|
|
||||||
std::ostream& Print(std::ostream& o) const { return value_->Print(o); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Private constructor
|
|
||||||
explicit Value(std::shared_ptr<const detail::ValueBase> value) : value_(std::move(value)) {}
|
|
||||||
|
|
||||||
/// Shared pointer to an immutable value. This type-erasure pattern allows Value to wrap a
|
|
||||||
/// polymorphic type, while being used like a value-type (i.e. copyable).
|
|
||||||
std::shared_ptr<const detail::ValueBase> value_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Prints Value to ostream
|
/// Prints Value to ostream
|
||||||
@ -919,7 +793,7 @@ constexpr bool IsValue = std::is_same_v<T, Value>;
|
|||||||
/// Creates a Value of DataType<T> from a scalar `v`
|
/// Creates a Value of DataType<T> from a scalar `v`
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Value Val(T v) {
|
Value Val(T v) {
|
||||||
return Value::Create<T>(ScalarArgs{v});
|
return Value::Create<T>(utils::Vector<Scalar, 1>{v});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Value of DataType<vec<N, T>> from N scalar `args`
|
/// Creates a Value of DataType<vec<N, T>> from N scalar `args`
|
||||||
@ -927,41 +801,41 @@ template <typename... T>
|
|||||||
Value Vec(T... args) {
|
Value Vec(T... args) {
|
||||||
using FirstT = std::tuple_element_t<0, std::tuple<T...>>;
|
using FirstT = std::tuple_element_t<0, std::tuple<T...>>;
|
||||||
constexpr size_t N = sizeof...(args);
|
constexpr size_t N = sizeof...(args);
|
||||||
utils::Vector v{args...};
|
utils::Vector<Scalar, sizeof...(args)> v{args...};
|
||||||
return Value::Create<vec<N, FirstT>>(utils::VectorRef<FirstT>{v});
|
return Value::Create<vec<N, FirstT>>(std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Value of DataType<mat<C,R,T> from C*R scalar `args`
|
/// Creates a Value of DataType<mat<C,R,T> from C*R scalar `args`
|
||||||
template <size_t C, size_t R, typename T>
|
template <size_t C, size_t R, typename T>
|
||||||
Value Mat(const T (&m_in)[C][R]) {
|
Value Mat(const T (&m_in)[C][R]) {
|
||||||
utils::Vector<T, C * R> m;
|
utils::Vector<Scalar, C * R> m;
|
||||||
for (uint32_t i = 0; i < C; ++i) {
|
for (uint32_t i = 0; i < C; ++i) {
|
||||||
for (size_t j = 0; j < R; ++j) {
|
for (size_t j = 0; j < R; ++j) {
|
||||||
m.Push(m_in[i][j]);
|
m.Push(m_in[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Value::Create<mat<C, R, T>>(utils::VectorRef<T>{m});
|
return Value::Create<mat<C, R, T>>(std::move(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Value of DataType<mat<2,R,T> from column vectors `c0` and `c1`
|
/// Creates a Value of DataType<mat<2,R,T> from column vectors `c0` and `c1`
|
||||||
template <typename T, size_t R>
|
template <typename T, size_t R>
|
||||||
Value Mat(const T (&c0)[R], const T (&c1)[R]) {
|
Value Mat(const T (&c0)[R], const T (&c1)[R]) {
|
||||||
constexpr size_t C = 2;
|
constexpr size_t C = 2;
|
||||||
utils::Vector<T, C * R> m;
|
utils::Vector<Scalar, C * R> m;
|
||||||
for (auto v : c0) {
|
for (auto v : c0) {
|
||||||
m.Push(v);
|
m.Push(v);
|
||||||
}
|
}
|
||||||
for (auto v : c1) {
|
for (auto v : c1) {
|
||||||
m.Push(v);
|
m.Push(v);
|
||||||
}
|
}
|
||||||
return Value::Create<mat<C, R, T>>(utils::VectorRef<T>{m});
|
return Value::Create<mat<C, R, T>>(std::move(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Value of DataType<mat<3,R,T> from column vectors `c0`, `c1`, and `c2`
|
/// Creates a Value of DataType<mat<3,R,T> from column vectors `c0`, `c1`, and `c2`
|
||||||
template <typename T, size_t R>
|
template <typename T, size_t R>
|
||||||
Value Mat(const T (&c0)[R], const T (&c1)[R], const T (&c2)[R]) {
|
Value Mat(const T (&c0)[R], const T (&c1)[R], const T (&c2)[R]) {
|
||||||
constexpr size_t C = 3;
|
constexpr size_t C = 3;
|
||||||
utils::Vector<T, C * R> m;
|
utils::Vector<Scalar, C * R> m;
|
||||||
for (auto v : c0) {
|
for (auto v : c0) {
|
||||||
m.Push(v);
|
m.Push(v);
|
||||||
}
|
}
|
||||||
@ -971,14 +845,14 @@ Value Mat(const T (&c0)[R], const T (&c1)[R], const T (&c2)[R]) {
|
|||||||
for (auto v : c2) {
|
for (auto v : c2) {
|
||||||
m.Push(v);
|
m.Push(v);
|
||||||
}
|
}
|
||||||
return Value::Create<mat<C, R, T>>(utils::VectorRef<T>{m});
|
return Value::Create<mat<C, R, T>>(std::move(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Value of DataType<mat<4,R,T> from column vectors `c0`, `c1`, `c2`, and `c3`
|
/// Creates a Value of DataType<mat<4,R,T> from column vectors `c0`, `c1`, `c2`, and `c3`
|
||||||
template <typename T, size_t R>
|
template <typename T, size_t R>
|
||||||
Value Mat(const T (&c0)[R], const T (&c1)[R], const T (&c2)[R], const T (&c3)[R]) {
|
Value Mat(const T (&c0)[R], const T (&c1)[R], const T (&c2)[R], const T (&c3)[R]) {
|
||||||
constexpr size_t C = 4;
|
constexpr size_t C = 4;
|
||||||
utils::Vector<T, C * R> m;
|
utils::Vector<Scalar, C * R> m;
|
||||||
for (auto v : c0) {
|
for (auto v : c0) {
|
||||||
m.Push(v);
|
m.Push(v);
|
||||||
}
|
}
|
||||||
@ -991,7 +865,7 @@ Value Mat(const T (&c0)[R], const T (&c1)[R], const T (&c2)[R], const T (&c3)[R]
|
|||||||
for (auto v : c3) {
|
for (auto v : c3) {
|
||||||
m.Push(v);
|
m.Push(v);
|
||||||
}
|
}
|
||||||
return Value::Create<mat<C, R, T>>(utils::VectorRef<T>{m});
|
return Value::Create<mat<C, R, T>>(std::move(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace builder
|
} // namespace builder
|
||||||
|
Loading…
x
Reference in New Issue
Block a user