use std::ops::{Deref, DerefMut, Index, IndexMut};
use crate::traits::Simd;
use super::{
conversion::{simd_container_flat_slice, simd_container_flat_slice_mut},
packed::PackedMxN,
};
#[derive(Clone, Debug)]
pub struct VecSimd<T>
where
T: Simd + Default + Clone,
{
pub(crate) simd_rows: PackedMxN<T>,
}
impl<T> VecSimd<T>
where
T: Simd + Default + Clone,
{
#[inline]
pub fn with(t: T::Element, size: usize) -> Self {
Self {
simd_rows: PackedMxN::with(T::splat(t), 1, size),
}
}
#[inline]
#[must_use]
pub fn flat(&self) -> &[T::Element] {
simd_container_flat_slice(&self.simd_rows.data[..], self.simd_rows.row_length)
}
#[inline]
pub fn flat_mut(&mut self) -> &mut [T::Element] {
simd_container_flat_slice_mut(&mut self.simd_rows.data[..], self.simd_rows.row_length)
}
}
impl<T> Index<usize> for VecSimd<T>
where
T: Simd + Default + Clone,
{
type Output = T;
#[inline]
fn index(&self, index: usize) -> &Self::Output {
&self.simd_rows.data[index]
}
}
impl<T> IndexMut<usize> for VecSimd<T>
where
T: Simd + Default + Clone,
{
#[inline]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.simd_rows.data[index]
}
}
impl<T> Deref for VecSimd<T>
where
T: Simd + Default + Clone,
{
type Target = [T];
fn deref(&self) -> &[T] {
&self.simd_rows.data[..]
}
}
impl<T> DerefMut for VecSimd<T>
where
T: Simd + Default + Clone,
{
fn deref_mut(&mut self) -> &mut [T] {
&mut self.simd_rows.data[..]
}
}
#[cfg(test)]
mod test {
use super::VecSimd;
use crate::arch::f32x4;
#[test]
fn allocation_size() {
let v_1 = VecSimd::<f32x4>::with(0.0f32, 4);
let v_2 = VecSimd::<f32x4>::with(0.0f32, 5);
assert_eq!(v_1.simd_rows.data.len(), 1);
assert_eq!(v_2.simd_rows.data.len(), 2);
}
#[test]
fn flat() {
let mut v = VecSimd::<f32x4>::with(10.0f32, 16);
let r_m = v.flat_mut();
assert_eq!(r_m.len(), 16);
for x in r_m {
*x = 1.0
}
let mut sum = 0.0;
let r = v.flat();
assert_eq!(r.len(), 16);
for x in r {
sum += x;
}
assert!((sum - 16.0).abs() <= std::f32::EPSILON);
}
#[test]
fn deref() {
let v = VecSimd::<f32x4>::with(0.0f32, 16);
assert_eq!(&v[0], &v[0]);
}
}