From 9e3f6959b521b15e06d78349d8d5a7fc44096cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Sun, 16 Oct 2022 22:21:39 +0200 Subject: [PATCH] Improves usability by providing accessor methods, index traits and conversion traits implementations. --- codegen/src/rust.rs | 226 ++++++++++++++++++++++++++++++++++++++++++-- src/lib.rs | 144 ++++++++-------------------- src/simd.rs | 34 +++---- 3 files changed, 269 insertions(+), 135 deletions(-) diff --git a/codegen/src/rust.rs b/codegen/src/rust.rs index d23b60d..fd10560 100644 --- a/codegen/src/rust.rs +++ b/codegen/src/rust.rs @@ -25,7 +25,7 @@ fn emit_expression(collector: &mut W, expression: &Expression } ExpressionContent::InvokeClassMethod(class, _, _) => { if *method_name == "Constructor" { - collector.write_fmt(format_args!("{} {{ ", class.class_name))?; + collector.write_fmt(format_args!("{} {{ groups: {}Groups {{ ", class.class_name, class.class_name))?; } else { collector.write_fmt(format_args!("{}::", class.class_name))?; } @@ -46,7 +46,7 @@ fn emit_expression(collector: &mut W, expression: &Expression emit_expression(collector, &argument)?; } if *method_name == "Constructor" { - collector.write_all(b" }")?; + collector.write_all(b" } }")?; } else { collector.write_all(b")")?; } @@ -66,7 +66,7 @@ fn emit_expression(collector: &mut W, expression: &Expression } ExpressionContent::Access(inner_expression, array_index) => { emit_expression(collector, &inner_expression)?; - collector.write_fmt(format_args!(".g{}", array_index))?; + collector.write_fmt(format_args!(".group{}()", array_index))?; } ExpressionContent::Swizzle(inner_expression, indices) => { if expression.size == 1 { @@ -99,7 +99,7 @@ fn emit_expression(collector: &mut W, expression: &Expression collector.write_all(b", ")?; } emit_expression(collector, &inner_expression)?; - collector.write_fmt(format_args!(".g{}", array_index))?; + collector.write_fmt(format_args!(".group{}()", array_index))?; if inner_expression.size > 1 { collector.write_fmt(format_args!("[{}]", *component_index))?; } @@ -193,8 +193,11 @@ pub fn emit_code(collector: &mut W, ast_node: &AstNode, inden .write_all(b"use crate::{simd::*, *};\nuse std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};\n\n")?; } AstNode::ClassDefinition { class } => { - collector.write_fmt(format_args!("#[derive(Clone, Copy, Debug)]\npub struct {} {{\n", class.class_name))?; - for (i, group) in class.grouped_basis.iter().enumerate() { + let element_count = class.grouped_basis.iter().fold(0, |a, b| a + b.len()); + let mut simd_widths = Vec::new(); + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!("#[derive(Clone, Copy)]\nstruct {}Groups {{\n", class.class_name))?; + for (j, group) in class.grouped_basis.iter().enumerate() { emit_indentation(collector, indentation + 1)?; collector.write_all(b"/// ")?; for (i, element) in group.iter().enumerate() { @@ -205,13 +208,216 @@ pub fn emit_code(collector: &mut W, ast_node: &AstNode, inden } collector.write_all(b"\n")?; emit_indentation(collector, indentation + 1)?; - collector.write_fmt(format_args!("pub g{}: ", i))?; - if group.len() == 1 { - collector.write_all(b"f32,\n")?; + collector.write_fmt(format_args!("g{}: ", j))?; + simd_widths.push(if group.len() == 1 { + collector.write_all(b"f32")?; + 1 } else { - collector.write_fmt(format_args!("Simd32x{},\n", group.len()))?; + collector.write_fmt(format_args!("Simd32x{}", group.len()))?; + 4 + }); + collector.write_all(b",\n")?; + } + collector.write_all(b"}\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!("#[derive(Clone, Copy)]\npub union {} {{\n", class.class_name))?; + emit_indentation(collector, indentation + 1)?; + collector.write_fmt(format_args!("groups: {}Groups,\n", class.class_name))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"/// ")?; + for (j, group) in class.grouped_basis.iter().enumerate() { + for (i, element) in group.iter().enumerate() { + if j > 0 || i > 0 { + collector.write_all(b", ")?; + } + collector.write_fmt(format_args!("{}", element))?; + } + for _ in group.len()..simd_widths[j] { + collector.write_all(b", 0")?; } } + collector.write_all(b"\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_fmt(format_args!("elements: [f32; {}],\n", simd_widths.iter().fold(0, |a, b| a + b)))?; + emit_indentation(collector, indentation)?; + collector.write_all(b"}\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!("impl {} {{\n", class.class_name))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"pub const fn new(")?; + for i in 0..element_count { + if i > 0 { + collector.write_all(b", ")?; + } + collector.write_fmt(format_args!("element{}: f32", i))?; + } + collector.write_all(b") -> Self {\n")?; + emit_indentation(collector, indentation + 2)?; + collector.write_all(b"Self { elements: [")?; + let mut element_index = 0; + for (j, group) in class.grouped_basis.iter().enumerate() { + for _ in 0..group.len() { + if element_index > 0 { + collector.write_all(b", ")?; + } + collector.write_fmt(format_args!("element{}", element_index))?; + element_index += 1; + } + for _ in group.len()..simd_widths[j] { + collector.write_all(b", 0.0")?; + } + } + collector.write_all(b"] }\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + for (j, group) in class.grouped_basis.iter().enumerate() { + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"#[inline(always)]\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_fmt(format_args!("pub fn group{}(&self) -> ", j))?; + if group.len() == 1 { + collector.write_all(b"f32")?; + } else { + collector.write_fmt(format_args!("Simd32x{}", group.len()))?; + } + collector.write_all(b" {\n")?; + emit_indentation(collector, indentation + 2)?; + collector.write_fmt(format_args!("unsafe {{ self.groups.g{} }}\n", j))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"#[inline(always)]\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_fmt(format_args!("pub fn group{}_mut(&mut self) -> &mut ", j))?; + if group.len() == 1 { + collector.write_all(b"f32")?; + } else { + collector.write_fmt(format_args!("Simd32x{}", group.len()))?; + } + collector.write_all(b" {\n")?; + emit_indentation(collector, indentation + 2)?; + collector.write_fmt(format_args!("unsafe {{ &mut self.groups.g{} }}\n", j))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + } + emit_indentation(collector, indentation)?; + collector.write_all(b"}\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!( + "const {}_INDEX_REMAP: [usize; {}] = [", + class.class_name.to_uppercase(), + element_count + ))?; + let mut element_index = 0; + let mut index_remap = Vec::new(); + for (j, group) in class.grouped_basis.iter().enumerate() { + for _ in 0..group.len() { + if element_index > 0 { + collector.write_all(b", ")?; + } + collector.write_fmt(format_args!("{}", element_index))?; + index_remap.push(element_index); + element_index += 1; + } + element_index += simd_widths[j].saturating_sub(group.len()); + } + collector.write_all(b"];\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!("impl std::ops::Index for {} {{\n", class.class_name))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"type Output = f32;\n\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"fn index(&self, index: usize) -> &Self::Output {\n")?; + emit_indentation(collector, indentation + 2)?; + collector.write_fmt(format_args!( + "unsafe {{ &self.elements[{}_INDEX_REMAP[index]] }}\n", + class.class_name.to_uppercase() + ))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + emit_indentation(collector, indentation)?; + collector.write_all(b"}\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!("impl std::ops::IndexMut for {} {{\n", class.class_name))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"fn index_mut(&mut self, index: usize) -> &mut Self::Output {\n")?; + emit_indentation(collector, indentation + 2)?; + collector.write_fmt(format_args!( + "unsafe {{ &mut self.elements[{}_INDEX_REMAP[index]] }}\n", + class.class_name.to_uppercase() + ))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + emit_indentation(collector, indentation)?; + collector.write_all(b"}\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!( + "impl std::convert::From<{}> for [f32; {}] {{\n", + class.class_name, element_count + ))?; + emit_indentation(collector, indentation + 1)?; + collector.write_fmt(format_args!("fn from(vector: {}) -> Self {{\n", class.class_name))?; + emit_indentation(collector, indentation + 2)?; + collector.write_all(b"unsafe { [")?; + for i in 0..element_count { + if i > 0 { + collector.write_all(b", ")?; + } + collector.write_fmt(format_args!("vector.elements[{}]", index_remap[i]))?; + } + collector.write_all(b"] }\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + emit_indentation(collector, indentation)?; + collector.write_all(b"}\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!( + "impl std::convert::From<[f32; {}]> for {} {{\n", + element_count, class.class_name + ))?; + emit_indentation(collector, indentation + 1)?; + collector.write_fmt(format_args!("fn from(array: [f32; {}]) -> Self {{\n", element_count))?; + emit_indentation(collector, indentation + 2)?; + collector.write_all(b"Self { elements: [")?; + let mut element_index = 0; + for (j, group) in class.grouped_basis.iter().enumerate() { + for _ in 0..group.len() { + if element_index > 0 { + collector.write_all(b", ")?; + } + collector.write_fmt(format_args!("array[{}]", element_index))?; + element_index += 1; + } + for _ in group.len()..simd_widths[j] { + collector.write_all(b", 0.0")?; + } + } + collector.write_all(b"] }\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + emit_indentation(collector, indentation)?; + collector.write_all(b"}\n\n")?; + emit_indentation(collector, indentation)?; + collector.write_fmt(format_args!("impl std::fmt::Debug for {} {{\n", class.class_name))?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {\n")?; + emit_indentation(collector, indentation + 2)?; + collector.write_all(b"formatter\n")?; + emit_indentation(collector, indentation + 3)?; + collector.write_fmt(format_args!(".debug_struct(\"{}\")\n", class.class_name))?; + let mut element_index = 0; + for group in class.grouped_basis.iter() { + for element in group.iter() { + emit_indentation(collector, indentation + 3)?; + collector.write_fmt(format_args!(".field(\"{}\", &self[{}])\n", element, element_index))?; + element_index += 1; + } + } + emit_indentation(collector, indentation + 3)?; + collector.write_all(b".finish()\n")?; + emit_indentation(collector, indentation + 1)?; + collector.write_all(b"}\n")?; + emit_indentation(collector, indentation)?; collector.write_all(b"}\n\n")?; } AstNode::ReturnStatement { expression } => { diff --git a/src/lib.rs b/src/lib.rs index cd83903..0a86ce7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,42 +12,30 @@ pub mod hpga3d; pub mod simd; impl epga1d::Scalar { - pub const fn new(real: f32) -> Self { - Self { g0: real } - } - pub fn real(self) -> f32 { - self.g0 + self[0] } pub fn sqrt(self) -> epga1d::ComplexNumber { - if self.g0 < 0.0 { - epga1d::ComplexNumber::new(0.0, (-self.g0).sqrt()) + if self[0] < 0.0 { + epga1d::ComplexNumber::from([0.0, (-self[0]).sqrt()]) } else { - epga1d::ComplexNumber::new(self.g0.sqrt(), 0.0) + epga1d::ComplexNumber::from([self[0].sqrt(), 0.0]) } } } impl epga1d::ComplexNumber { - pub const fn new(real: f32, imaginary: f32) -> Self { - Self { - g0: simd::Simd32x2 { - f32x2: [real, imaginary], - }, - } - } - pub fn real(self) -> f32 { - self.g0[0] + self[0] } pub fn imaginary(self) -> f32 { - self.g0[1] + self[1] } pub fn from_polar(magnitude: f32, argument: f32) -> Self { - Self::new(magnitude * argument.cos(), magnitude * argument.sin()) + Self::from([magnitude * argument.cos(), magnitude * argument.sin()]) } pub fn arg(self) -> f32 { @@ -59,7 +47,7 @@ impl Exp for epga1d::ComplexNumber { type Output = Self; fn exp(self) -> Self { - Self::from_polar(self.g0[0].exp(), self.g0[1]) + Self::from_polar(self[0].exp(), self[1]) } } @@ -67,7 +55,7 @@ impl Ln for epga1d::ComplexNumber { type Output = Self; fn ln(self) -> Self { - Self::new(self.magnitude().g0.ln(), self.arg()) + Self::from([self.magnitude()[0].ln(), self.arg()]) } } @@ -75,7 +63,7 @@ impl Powf for epga1d::ComplexNumber { type Output = Self; fn powf(self, exponent: f32) -> Self { - Self::from_polar(self.magnitude().g0.powf(exponent), self.arg() * exponent) + Self::from_polar(self.magnitude()[0].powf(exponent), self.arg() * exponent) } } @@ -83,11 +71,7 @@ impl Exp for ppga2d::IdealPoint { type Output = ppga2d::Translator; fn exp(self) -> ppga2d::Translator { - ppga2d::Translator { - g0: simd::Simd32x3 { - f32x3: [1.0, self.g0[0], self.g0[1]], - }, - } + ppga2d::Translator::from([1.0, self[0], self[1]]) } } @@ -96,7 +80,7 @@ impl Ln for ppga2d::Translator { fn ln(self) -> ppga2d::IdealPoint { let result: ppga2d::IdealPoint = self.into(); - result / ppga2d::Scalar { g0: self.g0[0] } + result / ppga2d::Scalar::from([self[0]]) } } @@ -104,7 +88,7 @@ impl Powf for ppga2d::Translator { type Output = Self; fn powf(self, exponent: f32) -> Self { - (ppga2d::Scalar { g0: exponent } * self.ln()).exp() + (ppga2d::Scalar::from([exponent]) * self.ln()).exp() } } @@ -112,23 +96,15 @@ impl Exp for ppga2d::Point { type Output = ppga2d::Motor; fn exp(self) -> ppga2d::Motor { - let det = self.g0[0] * self.g0[0]; + let det = self[0] * self[0]; if det <= 0.0 { - return ppga2d::Motor { - g0: simd::Simd32x4 { - f32x4: [1.0, 0.0, self.g0[1], self.g0[2]], - }, - }; + return ppga2d::Motor::from([1.0, 0.0, self[1], self[2]]); } let a = det.sqrt(); let c = a.cos(); let s = a.sin() / a; - let g0 = simd::Simd32x3::from(s) * self.g0; - ppga2d::Motor { - g0: simd::Simd32x4 { - f32x4: [c, g0[0], g0[1], g0[2]], - }, - } + let g0 = simd::Simd32x3::from(s) * self.group0(); + ppga2d::Motor::from([c, g0[0], g0[1], g0[2]]) } } @@ -136,22 +112,14 @@ impl Ln for ppga2d::Motor { type Output = ppga2d::Point; fn ln(self) -> ppga2d::Point { - let det = 1.0 - self.g0[0] * self.g0[0]; + let det = 1.0 - self[0] * self[0]; if det <= 0.0 { - return ppga2d::Point { - g0: simd::Simd32x3 { - f32x3: [0.0, self.g0[2], self.g0[3]], - }, - }; + return ppga2d::Point::from([0.0, self[2], self[3]]); } let a = 1.0 / det; - let b = self.g0[0].acos() * a.sqrt(); - let g0 = simd::Simd32x4::from(b) * self.g0; - return ppga2d::Point { - g0: simd::Simd32x3 { - f32x3: [g0[1], g0[2], g0[3]], - }, - }; + let b = self[0].acos() * a.sqrt(); + let g0 = simd::Simd32x4::from(b) * self.group0(); + return ppga2d::Point::from([g0[1], g0[2], g0[3]]); } } @@ -159,7 +127,7 @@ impl Powf for ppga2d::Motor { type Output = Self; fn powf(self, exponent: f32) -> Self { - (ppga2d::Scalar { g0: exponent } * self.ln()).exp() + (ppga2d::Scalar::from([exponent]) * self.ln()).exp() } } @@ -167,11 +135,7 @@ impl Exp for ppga3d::IdealPoint { type Output = ppga3d::Translator; fn exp(self) -> ppga3d::Translator { - ppga3d::Translator { - g0: simd::Simd32x4 { - f32x4: [1.0, self.g0[0], self.g0[1], self.g0[2]], - }, - } + ppga3d::Translator::from([1.0, self[0], self[1], self[2]]) } } @@ -180,7 +144,7 @@ impl Ln for ppga3d::Translator { fn ln(self) -> ppga3d::IdealPoint { let result: ppga3d::IdealPoint = self.into(); - result / ppga3d::Scalar { g0: self.g0[0] } + result / ppga3d::Scalar::from([self[0]]) } } @@ -188,7 +152,7 @@ impl Powf for ppga3d::Translator { type Output = Self; fn powf(self, exponent: f32) -> Self { - (ppga3d::Scalar { g0: exponent } * self.ln()).exp() + (ppga3d::Scalar::from([exponent]) * self.ln()).exp() } } @@ -196,32 +160,18 @@ impl Exp for ppga3d::Line { type Output = ppga3d::Motor; fn exp(self) -> ppga3d::Motor { - let det = self.g1[0] * self.g1[0] + self.g1[1] * self.g1[1] + self.g1[2] * self.g1[2]; + let det = self[3] * self[3] + self[4] * self[4] + self[5] * self[5]; if det <= 0.0 { - return ppga3d::Motor { - g0: simd::Simd32x4 { - f32x4: [1.0, 0.0, 0.0, 0.0], - }, - g1: simd::Simd32x4 { - f32x4: [0.0, self.g0[0], self.g0[1], self.g0[2]], - }, - }; + return ppga3d::Motor::from([1.0, 0.0, 0.0, 0.0, 0.0, self[0], self[1], self[2]]); } let a = det.sqrt(); let c = a.cos(); let s = a.sin() / a; - let m = self.g0[0] * self.g1[0] + self.g0[1] * self.g1[1] + self.g0[2] * self.g1[2]; + let m = self[0] * self[3] + self[1] * self[4] + self[2] * self[5]; let t = m / det * (c - s); - let g0 = simd::Simd32x3::from(s) * self.g1; - let g1 = simd::Simd32x3::from(s) * self.g0 + simd::Simd32x3::from(t) * self.g1; - ppga3d::Motor { - g0: simd::Simd32x4 { - f32x4: [c, g0[0], g0[1], g0[2]], - }, - g1: simd::Simd32x4 { - f32x4: [s * m, g1[0], g1[1], g1[2]], - }, - } + let g0 = simd::Simd32x3::from(s) * self.group1(); + let g1 = simd::Simd32x3::from(s) * self.group0() + simd::Simd32x3::from(t) * self.group1(); + ppga3d::Motor::from([c, g0[0], g0[1], g0[2], s * m, g1[0], g1[1], g1[2]]) } } @@ -229,30 +179,16 @@ impl Ln for ppga3d::Motor { type Output = ppga3d::Line; fn ln(self) -> ppga3d::Line { - let det = 1.0 - self.g0[0] * self.g0[0]; + let det = 1.0 - self[0] * self[0]; if det <= 0.0 { - return ppga3d::Line { - g0: simd::Simd32x3 { - f32x3: [self.g1[1], self.g1[2], self.g1[3]], - }, - g1: simd::Simd32x3 { - f32x3: [0.0, 0.0, 0.0], - }, - }; + return ppga3d::Line::from([self[5], self[6], self[7], 0.0, 0.0, 0.0]); } let a = 1.0 / det; - let b = self.g0[0].acos() * a.sqrt(); - let c = a * self.g1[0] * (1.0 - self.g0[0] * b); - let g0 = simd::Simd32x4::from(b) * self.g1 + simd::Simd32x4::from(c) * self.g0; - let g1 = simd::Simd32x4::from(b) * self.g0; - return ppga3d::Line { - g0: simd::Simd32x3 { - f32x3: [g0[1], g0[2], g0[3]], - }, - g1: simd::Simd32x3 { - f32x3: [g1[1], g1[2], g1[3]], - }, - }; + let b = self[0].acos() * a.sqrt(); + let c = a * self[4] * (1.0 - self[0] * b); + let g0 = simd::Simd32x4::from(b) * self.group1() + simd::Simd32x4::from(c) * self.group0(); + let g1 = simd::Simd32x4::from(b) * self.group0(); + return ppga3d::Line::from([g0[1], g0[2], g0[3], g1[1], g1[2], g1[3]]); } } @@ -260,7 +196,7 @@ impl Powf for ppga3d::Motor { type Output = Self; fn powf(self, exponent: f32) -> Self { - (ppga3d::Scalar { g0: exponent } * self.ln()).exp() + (ppga3d::Scalar::from([exponent]) * self.ln()).exp() } } diff --git a/src/simd.rs b/src/simd.rs index c8ee4ff..8be0bfe 100755 --- a/src/simd.rs +++ b/src/simd.rs @@ -1,5 +1,3 @@ -use std::ops::{Index, IndexMut}; - #[cfg(all(target_arch = "aarch64", target_feature = "neon"))] pub use std::arch::aarch64::*; #[cfg(all(target_arch = "arm", target_feature = "neon"))] @@ -136,7 +134,7 @@ macro_rules! swizzle { }; } -impl Index for Simd32x4 { +impl std::ops::Index for Simd32x4 { type Output = f32; fn index(&self, index: usize) -> &Self::Output { @@ -144,7 +142,7 @@ impl Index for Simd32x4 { } } -impl Index for Simd32x3 { +impl std::ops::Index for Simd32x3 { type Output = f32; fn index(&self, index: usize) -> &Self::Output { @@ -152,7 +150,7 @@ impl Index for Simd32x3 { } } -impl Index for Simd32x2 { +impl std::ops::Index for Simd32x2 { type Output = f32; fn index(&self, index: usize) -> &Self::Output { @@ -160,19 +158,19 @@ impl Index for Simd32x2 { } } -impl IndexMut for Simd32x4 { +impl std::ops::IndexMut for Simd32x4 { fn index_mut(&mut self, index: usize) -> &mut Self::Output { unsafe { &mut self.f32x4[index] } } } -impl IndexMut for Simd32x3 { +impl std::ops::IndexMut for Simd32x3 { fn index_mut(&mut self, index: usize) -> &mut Self::Output { unsafe { &mut self.f32x3[index] } } } -impl IndexMut for Simd32x2 { +impl std::ops::IndexMut for Simd32x2 { fn index_mut(&mut self, index: usize) -> &mut Self::Output { unsafe { &mut self.f32x2[index] } } @@ -241,11 +239,8 @@ impl std::convert::From for Simd32x2 { impl std::fmt::Debug for Simd32x4 { fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter - .debug_tuple("Vec4") - .field(&self[0]) - .field(&self[1]) - .field(&self[2]) - .field(&self[3]) + .debug_list() + .entries([self[0], self[1], self[2], self[3]].iter()) .finish() } } @@ -253,10 +248,8 @@ impl std::fmt::Debug for Simd32x4 { impl std::fmt::Debug for Simd32x3 { fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter - .debug_tuple("Vec3") - .field(&self[0]) - .field(&self[1]) - .field(&self[2]) + .debug_list() + .entries([self[0], self[1], self[2]].iter()) .finish() } } @@ -264,9 +257,8 @@ impl std::fmt::Debug for Simd32x3 { impl std::fmt::Debug for Simd32x2 { fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter - .debug_tuple("Vec2") - .field(&self[0]) - .field(&self[1]) + .debug_list() + .entries([self[0], self[1]].iter()) .finish() } } @@ -419,4 +411,4 @@ impl std::ops::Mul for Simd32x2 { ] }, ) } -} \ No newline at end of file +}