#![expect(
missing_docs,
reason = "TODO: https://github.com/linebender/fearless_simd/issues/40"
)]
use crate::{Level, Simd, SimdBase};
pub trait Select<T> {
fn select(self, if_true: T, if_false: T) -> T;
}
pub trait WithSimd {
type Output;
fn with_simd<S: Simd>(self, simd: S) -> Self::Output;
}
impl<R, F: FnOnce(Level) -> R> WithSimd for F {
type Output = R;
#[inline(always)]
fn with_simd<S: Simd>(self, simd: S) -> Self::Output {
self(simd.level())
}
}
pub trait Bytes: Sized {
type Bytes;
fn to_bytes(self) -> Self::Bytes;
fn from_bytes(value: Self::Bytes) -> Self;
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 {}
}
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 {
type Mask: SimdElement;
}
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 i64 {
type Mask = Self;
}
pub trait SimdCvtTruncate<T> {
fn truncate_from(x: T) -> Self;
fn truncate_from_precise(x: T) -> Self;
}
pub trait SimdCvtFloat<T> {
fn float_from(x: T) -> Self;
}
pub trait SimdCombine<S: Simd>: SimdBase<S> {
type Combined: SimdBase<S, Element = Self::Element, Block = Self::Block>;
fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined;
}
pub trait SimdSplit<S: Simd>: SimdBase<S> {
type Split: SimdBase<S, Element = Self::Element, Block = Self::Block>;
fn split(self) -> (Self::Split, Self::Split);
}