rill_core/math/vector/
macros.rs1use crate::math::vector::scalar::ScalarVector4;
29use crate::math::vector::traits::Vector;
30
31#[macro_export]
32macro_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 for i in 0..chunks {
52 let start = i * N;
53 let x = <ScalarVector4<_>>::load(&input[start..start + N]);
54 let y = closure(x);
55 y.store(&mut output[start..start + N]);
56 }
57
58 if remainder > 0 {
59 let start = chunks * N;
60 let mut temp_input = [Default::default(); 4];
61 for i in 0..remainder {
62 temp_input[i] = input[start + i];
63 }
64 let x = <ScalarVector4<_>>::load(&temp_input[0..4]);
65 let y = closure(x);
66 for i in 0..remainder {
67 output[start + i] = y.extract(i);
68 }
69 }
70 }};
71}
72
73#[macro_export]
78macro_rules! vec_expr {
79 ($val:expr) => {
80 $val
81 };
82}
83
84#[macro_export]
88macro_rules! vec_eval {
89 ($($t:tt)*) => {
90 $($t)*
91 };
92}
93
94pub use crate::vec_eval;
95pub use crate::vec_expr;
96pub use crate::vec_map;
97
98#[cfg(test)]
103mod tests {
104 use super::*;
105 use crate::math::vector::scalar::ScalarVector4;
106
107 #[test]
108 fn test_vec_map_f32() {
109 let input = [1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
110 let mut output = [0.0f32; 8];
111
112 vec_map!(&input, &mut output, |x| x * 2.0 + 1.0);
114
115 assert_eq!(output[0], 3.0); assert_eq!(output[1], 5.0); assert_eq!(output[2], 7.0);
118 assert_eq!(output[3], 9.0);
119 assert_eq!(output[4], 11.0);
120 assert_eq!(output[5], 13.0);
121 assert_eq!(output[6], 15.0);
122 assert_eq!(output[7], 17.0);
123 }
124
125 #[test]
126 fn test_vec_map_f64() {
127 let input = [1.0f64, 2.0, 3.0, 4.0];
128 let mut output = [0.0f64; 4];
129
130 vec_map!(&input, &mut output, |x| x * 3.0 - 1.0);
131
132 assert_eq!(output[0], 2.0); assert_eq!(output[1], 5.0); assert_eq!(output[2], 8.0);
135 assert_eq!(output[3], 11.0);
136 }
137
138 #[test]
139 fn test_vec_map_empty() {
140 let input: [f32; 0] = [];
141 let mut output: [f32; 0] = [];
142 vec_map!(&input, &mut output, |x| x * 2.0); }
144
145 #[test]
146 fn test_vec_map_remainder() {
147 let input = [1.0f32, 2.0, 3.0]; let mut output = [0.0f32; 3];
149
150 vec_map!(&input, &mut output, |x| x + 10.0);
151
152 assert_eq!(output[0], 11.0);
153 assert_eq!(output[1], 12.0);
154 assert_eq!(output[2], 13.0);
155 }
156
157 #[test]
158 fn test_vec_expr_stub() {
159 let vec = ScalarVector4::splat(5.0);
160 let result = vec_expr!(vec);
161 assert_eq!(result, vec);
162 }
163
164 #[test]
165 fn test_vec_eval_stub() {
166 let a = ScalarVector4::splat(2.0);
167 let b = ScalarVector4::splat(3.0);
168 let result = vec_eval!(a + b);
169 assert_eq!(result, ScalarVector4::splat(5.0));
170 }
171}