1use std::ops::{Deref, DerefMut, Index, IndexMut};
2
3use crate::traits::Simd;
4
5use super::{
6 conversion::{simd_container_flat_slice, simd_container_flat_slice_mut},
7 packed::PackedMxN,
8};
9
10#[derive(Clone, Debug)]
29pub struct VecSimd<T>
30where
31 T: Simd + Default + Clone,
32{
33 pub(crate) simd_rows: PackedMxN<T>,
34}
35
36impl<T> VecSimd<T>
37where
38 T: Simd + Default + Clone,
39{
40 #[inline]
42 pub fn with(t: T::Element, size: usize) -> Self {
43 Self {
44 simd_rows: PackedMxN::with(T::splat(t), 1, size),
45 }
46 }
47
48 #[inline]
50 #[must_use]
51 pub fn flat(&self) -> &[T::Element] {
52 simd_container_flat_slice(&self.simd_rows.data[..], self.simd_rows.row_length)
53 }
54
55 #[inline]
57 pub fn flat_mut(&mut self) -> &mut [T::Element] {
58 simd_container_flat_slice_mut(&mut self.simd_rows.data[..], self.simd_rows.row_length)
59 }
60}
61
62impl<T> Index<usize> for VecSimd<T>
63where
64 T: Simd + Default + Clone,
65{
66 type Output = T;
67
68 #[inline]
69 fn index(&self, index: usize) -> &Self::Output {
70 &self.simd_rows.data[index]
71 }
72}
73
74impl<T> IndexMut<usize> for VecSimd<T>
75where
76 T: Simd + Default + Clone,
77{
78 #[inline]
79 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
80 &mut self.simd_rows.data[index]
81 }
82}
83
84impl<T> Deref for VecSimd<T>
85where
86 T: Simd + Default + Clone,
87{
88 type Target = [T];
89
90 fn deref(&self) -> &[T] {
91 &self.simd_rows.data[..]
92 }
93}
94
95impl<T> DerefMut for VecSimd<T>
96where
97 T: Simd + Default + Clone,
98{
99 fn deref_mut(&mut self) -> &mut [T] {
100 &mut self.simd_rows.data[..]
101 }
102}
103
104#[cfg(test)]
105mod test {
106 use super::VecSimd;
107 use crate::arch::f32x4;
108
109 #[test]
110 fn allocation_size() {
111 let v_1 = VecSimd::<f32x4>::with(0.0f32, 4);
112 let v_2 = VecSimd::<f32x4>::with(0.0f32, 5);
113
114 assert_eq!(v_1.simd_rows.data.len(), 1);
115 assert_eq!(v_2.simd_rows.data.len(), 2);
116 }
117
118 #[test]
119 fn flat() {
120 let mut v = VecSimd::<f32x4>::with(10.0f32, 16);
121 let r_m = v.flat_mut();
122
123 assert_eq!(r_m.len(), 16);
124
125 for x in r_m {
126 *x = 1.0
127 }
128
129 let mut sum = 0.0;
130 let r = v.flat();
131
132 assert_eq!(r.len(), 16);
133
134 for x in r {
135 sum += x;
136 }
137
138 assert!((sum - 16.0).abs() <= std::f32::EPSILON);
139 }
140
141 #[test]
142 fn deref() {
143 let v = VecSimd::<f32x4>::with(0.0f32, 16);
144 assert_eq!(&v[0], &v[0]);
145 }
146}