mod table2;
mod table4;
pub(crate) use entry::{entry2, entry3, entry4, Entry};
pub(crate) use table2::Table2;
pub(crate) use table4::Table4;
#[cfg(feature = "nightly-simd")]
pub(crate) use table4::{Index4, Index4x4};
macro_rules! const_assert {
($($tt:tt)*) => {
const _: () = assert!($($tt)*);
};
}
const_assert!(i32::BITS <= usize::BITS, "We cast i32 to usize for indexing.");
#[cfg(feature = "nightly-simd")]
mod entry {
use core::simd::{f32x2, f32x4, Simd};
const_assert!(
core::mem::size_of::<f32x2>() == 8 && core::mem::align_of::<f32x2>() <= 8,
"We assume this for the lookup code. Please let me know if this assertion ever fails."
);
const_assert!(
core::mem::size_of::<f32x4>() == 16 && core::mem::align_of::<f32x4>() <= 16,
"We assume this for the lookup code. Please let me know if this assertion ever fails."
);
#[repr(transparent)]
pub(crate) struct Entry<const N: usize>(pub Simd<f32, N>);
impl<const N: usize> Entry<N> {
pub(crate) fn as_array(&self) -> &[f32; N] {
self.0.as_array()
}
}
pub(crate) const fn entry2(x: f32, y: f32) -> Entry<2> {
Entry(f32x2::from_array([x, y]))
}
pub(crate) const fn entry3(x: f32, y: f32, z: f32) -> Entry<4> {
Entry(f32x4::from_array([x, y, z, 0.0]))
}
pub(crate) const fn entry4(x: f32, y: f32, z: f32, w: f32) -> Entry<4> {
Entry(f32x4::from_array([x, y, z, w]))
}
}
#[cfg(not(feature = "nightly-simd"))]
mod entry {
#[repr(transparent)]
pub(crate) struct Entry<const N: usize>([f32; N]);
impl<const N: usize> Entry<N> {
pub(crate) fn as_array(&self) -> &[f32; N] {
&self.0
}
}
pub(crate) const fn entry2(x: f32, y: f32) -> Entry<2> {
Entry([x, y])
}
pub(crate) const fn entry3(x: f32, y: f32, z: f32) -> Entry<4> {
Entry([x, y, z, 0.0])
}
pub(crate) const fn entry4(x: f32, y: f32, z: f32, w: f32) -> Entry<4> {
Entry([x, y, z, w])
}
}