#![expect(
missing_docs,
reason = "TODO: https://github.com/linebender/fearless_simd/issues/40"
)]
use crate::{Simd, SimdBase, seal::Seal};
use core::fmt::{Binary, Debug, Display, LowerExp, UpperExp};
use core::iter::{Product, Sum};
use core::ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
};
use core::str::FromStr;
pub trait Select<T: Seal>: Seal {
fn select(self, if_true: T, if_false: T) -> T;
}
pub trait Bytes: Sized + Seal {
type Bytes: Bytes<Bytes = Self::Bytes>;
fn to_bytes(self) -> Self::Bytes;
fn from_bytes(value: Self::Bytes) -> Self;
#[doc(alias = "reinterpret")]
#[doc(alias = "transmute")]
#[inline(always)]
fn bitcast<U: Bytes<Bytes = Self::Bytes>>(self) -> U {
U::from_bytes(self.to_bytes())
}
}
pub(crate) mod seal {
#[expect(
unnameable_types,
reason = "This is a sealed trait, so being unnameable is the entire point"
)]
pub trait Seal {}
}
impl Seal for f32 {}
impl Seal for f64 {}
impl Seal for u8 {}
impl Seal for i8 {}
impl Seal for u16 {}
impl Seal for i16 {}
impl Seal for u32 {}
impl Seal for i32 {}
impl Seal for u64 {}
impl Seal for i64 {}
pub trait SimdFrom<T, S: Simd> {
fn simd_from(simd: S, value: T) -> Self;
}
pub trait SimdInto<T, S> {
fn simd_into(self, simd: S) -> T;
}
impl<F, T: SimdFrom<F, S>, S: Simd> SimdInto<T, S> for F {
fn simd_into(self, simd: S) -> T {
SimdFrom::simd_from(simd, self)
}
}
impl<T, S: Simd> SimdFrom<T, S> for T {
fn simd_from(_simd: S, value: T) -> Self {
value
}
}
pub trait SimdElement:
Copy
+ Clone
+ Seal
+ Default
+ Debug
+ Display
+ FromStr
+ LowerExp
+ UpperExp
+ PartialOrd
+ PartialEq
+ From<bool>
+ Add<Self, Output = Self>
+ AddAssign<Self>
+ Sub<Self, Output = Self>
+ SubAssign<Self>
+ Mul<Self, Output = Self>
+ MulAssign<Self>
+ Div<Self, Output = Self>
+ DivAssign<Self>
+ Rem<Self, Output = Self>
+ RemAssign<Self>
+ Sum<Self>
+ Product<Self>
+ for<'a> Add<&'a Self, Output = Self>
+ for<'a> AddAssign<&'a Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ for<'a> SubAssign<&'a Self>
+ for<'a> Mul<&'a Self, Output = Self>
+ for<'a> MulAssign<&'a Self>
+ for<'a> Div<&'a Self, Output = Self>
+ for<'a> DivAssign<&'a Self>
+ for<'a> Rem<&'a Self, Output = Self>
+ for<'a> RemAssign<&'a Self>
+ for<'a> Sum<&'a Self>
+ for<'a> Product<&'a Self>
{
type Mask: SimdElement<Mask = Self::Mask>;
const BITS: usize = size_of::<Self>() * u8::BITS as usize;
}
impl SimdElement for f32 {
type Mask = i32;
}
impl SimdElement for f64 {
type Mask = i64;
}
impl SimdElement for u8 {
type Mask = i8;
}
impl SimdElement for i8 {
type Mask = Self;
}
impl SimdElement for u16 {
type Mask = i16;
}
impl SimdElement for i16 {
type Mask = Self;
}
impl SimdElement for u32 {
type Mask = i32;
}
impl SimdElement for i32 {
type Mask = Self;
}
impl SimdElement for u64 {
type Mask = i64;
}
impl SimdElement for i64 {
type Mask = Self;
}
pub trait SimdIntElement:
SimdElement
+ Eq
+ Ord
+ Binary
+ Not<Output = Self>
+ Shl<usize, Output = Self>
+ ShlAssign<usize>
+ Shr<usize, Output = Self>
+ ShrAssign<usize>
+ BitAnd<Self, Output = Self>
+ BitAndAssign<Self>
+ BitOr<Self, Output = Self>
+ BitOrAssign<Self>
+ BitXor<Self, Output = Self>
+ BitXorAssign<Self>
+ for<'a> Shl<&'a usize, Output = Self>
+ for<'a> ShlAssign<&'a usize>
+ for<'a> Shr<&'a usize, Output = Self>
+ for<'a> ShrAssign<&'a usize>
+ for<'a> BitAnd<&'a Self, Output = Self>
+ for<'a> BitAndAssign<&'a Self>
+ for<'a> BitOr<&'a Self, Output = Self>
+ for<'a> BitOrAssign<&'a Self>
+ for<'a> BitXor<&'a Self, Output = Self>
+ for<'a> BitXorAssign<&'a Self>
{
}
impl SimdIntElement for u8 {}
impl SimdIntElement for u16 {}
impl SimdIntElement for u32 {}
impl SimdIntElement for u64 {}
impl SimdIntElement for i8 {}
impl SimdIntElement for i16 {}
impl SimdIntElement for i32 {}
impl SimdIntElement for i64 {}
pub trait SimdFloatElement: SimdElement + Neg<Output = Self> + From<i8> + From<u8> {}
impl SimdFloatElement for f32 {}
impl SimdFloatElement for f64 {}
pub trait SimdCvtTruncate<T: Seal>: Seal {
fn truncate_from(x: T) -> Self;
fn truncate_from_precise(x: T) -> Self;
}
pub trait SimdCvtFloat<T: Seal>: Seal {
fn float_from(x: T) -> Self;
}
pub trait SimdInterleaved<S: Simd>: SimdBase<S> {
fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4];
fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]);
}
pub trait SimdCombine<S: Simd>: SimdBase<S> + Seal {
type Combined: SimdBase<S, Element = Self::Element, Block = Self::Block>
+ SimdSplit<S, Split = Self>;
fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined;
}
pub trait SimdSplit<S: Simd>: SimdBase<S> + Seal {
type Split: SimdBase<S, Element = Self::Element, Block = Self::Block>
+ SimdCombine<S, Combined = Self>;
fn split(self) -> (Self::Split, Self::Split);
}
pub trait SimdWiden<S: Simd>: SimdBase<S> + Seal {
type Widened: SimdNarrow<S, Narrowed = Self>;
fn widen(self) -> (Self::Widened, Self::Widened);
}
pub trait SimdNarrow<S: Simd>: SimdBase<S> + Seal {
type Narrowed: SimdWiden<S, Widened = Self>;
fn narrow(self, high: Self) -> Self::Narrowed;
fn saturating_narrow(self, high: Self) -> Self::Narrowed;
fn relaxed_narrow(self, high: Self) -> Self::Narrowed;
}