rill_core/math/vector/
macros.rs1use crate::math::vector::scalar::ScalarVector4;
29use crate::math::vector::traits::Vector;
30
31#[macro_export]
33macro_rules! vec_map {
34 ($input:expr, $output:expr, |$x:ident| $($body:tt)*) => {{
35 use $crate::math::vector::traits::Vector;
36 use $crate::math::vector::scalar::ScalarVector4;
37 const N: usize = 4;
38 let input: &[_] = $input;
39 let output: &mut [_] = $output;
40 assert_eq!(input.len(), output.len(), "input and output slices must have equal length");
41
42 if input.is_empty() {
43 return;
44 }
45
46 let closure = |$x: ScalarVector4<_>| -> ScalarVector4<_> { $($body)* };
47
48 let chunks = input.len() / N;
49 let remainder = input.len() % N;
50
51 #[allow(clippy::needless_range_loop)]
52 for i in 0..chunks {
53 let start = i * N;
54 let x = <ScalarVector4<_>>::load(&input[start..start + N]);
55 let y = closure(x);
56 y.store(&mut output[start..start + N]);
57 }
58
59 if remainder > 0 {
60 let start = chunks * N;
61 let mut temp_input = [Default::default(); 4];
62 #[allow(clippy::needless_range_loop)]
63 for i in 0..remainder {
64 temp_input[i] = input[start + i];
65 }
66 let x = <ScalarVector4<_>>::load(&temp_input[0..4]);
67 let y = closure(x);
68 #[allow(clippy::needless_range_loop)]
69 for i in 0..remainder {
70 output[start + i] = y.extract(i);
71 }
72 }
73 }};
74}
75
76#[macro_export]
81macro_rules! vec_expr {
82 ($val:expr) => {
83 $val
84 };
85}
86
87#[macro_export]
91macro_rules! vec_eval {
92 ($($t:tt)*) => {
93 $($t)*
94 };
95}
96
97pub use crate::vec_eval;
98pub use crate::vec_expr;
99pub use crate::vec_map;
100
101#[cfg(test)]
106mod tests {
107 use super::*;
108 use crate::math::vector::scalar::ScalarVector4;
109
110 #[test]
111 fn test_vec_map_f32() {
112 let input = [1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
113 let mut output = [0.0f32; 8];
114
115 vec_map!(&input, &mut output, |x| x * 2.0 + 1.0);
117
118 assert_eq!(output[0], 3.0); assert_eq!(output[1], 5.0); assert_eq!(output[2], 7.0);
121 assert_eq!(output[3], 9.0);
122 assert_eq!(output[4], 11.0);
123 assert_eq!(output[5], 13.0);
124 assert_eq!(output[6], 15.0);
125 assert_eq!(output[7], 17.0);
126 }
127
128 #[test]
129 fn test_vec_map_f64() {
130 let input = [1.0f64, 2.0, 3.0, 4.0];
131 let mut output = [0.0f64; 4];
132
133 vec_map!(&input, &mut output, |x| x * 3.0 - 1.0);
134
135 assert_eq!(output[0], 2.0); assert_eq!(output[1], 5.0); assert_eq!(output[2], 8.0);
138 assert_eq!(output[3], 11.0);
139 }
140
141 #[test]
142 fn test_vec_map_empty() {
143 let input: [f32; 0] = [];
144 let mut output: [f32; 0] = [];
145 vec_map!(&input, &mut output, |x| x * 2.0); }
147
148 #[test]
149 fn test_vec_map_remainder() {
150 let input = [1.0f32, 2.0, 3.0]; let mut output = [0.0f32; 3];
152
153 vec_map!(&input, &mut output, |x| x + 10.0);
154
155 assert_eq!(output[0], 11.0);
156 assert_eq!(output[1], 12.0);
157 assert_eq!(output[2], 13.0);
158 }
159
160 #[test]
161 fn test_vec_expr_stub() {
162 let vec = ScalarVector4::splat(5.0);
163 let result = vec_expr!(vec);
164 assert_eq!(result, vec);
165 }
166
167 #[test]
168 fn test_vec_eval_stub() {
169 let a = ScalarVector4::splat(2.0);
170 let b = ScalarVector4::splat(3.0);
171 let result = vec_eval!(a + b);
172 assert_eq!(result, ScalarVector4::splat(5.0));
173 }
174}