use core::{
marker::Sized,
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub},
};
pub trait Bool:
Copy
+ BitAnd<Self, Output = Self>
+ BitOr<Self, Output = Self>
+ BitXor<Self, Output = Self>
+ Not<Output = Self>
{
const FALSE: Self;
const TRUE: Self;
fn bitmask(self) -> u64;
fn all(self) -> bool;
fn any(self) -> bool;
fn none(self) -> bool;
}
pub trait Num: Sized + Clone {
type Element;
type Bool: Bool;
fn lanes() -> usize;
fn splat(val: Self::Element) -> Self;
fn extract(&self, i: usize) -> Self::Element;
unsafe fn extract_unchecked(&self, i: usize) -> Self::Element;
fn replace(&mut self, i: usize, val: Self::Element);
unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element);
fn select(self, cond: Self::Bool, other: Self) -> Self;
#[inline]
fn map_lanes(self, f: impl Fn(Self::Element) -> Self::Element) -> Self {
let mut result = self.clone();
for i in 0..Self::lanes() {
unsafe { result.replace_unchecked(i, f(self.extract_unchecked(i))) }
}
result
}
#[inline]
fn zip_map_lanes(
self,
b: Self,
f: impl Fn(Self::Element, Self::Element) -> Self::Element,
) -> Self {
let mut result = self.clone();
for i in 0..Self::lanes() {
unsafe {
let a = self.extract_unchecked(i);
let b = b.extract_unchecked(i);
result.replace_unchecked(i, f(a, b))
}
}
result
}
}
pub trait PartialOrdEx: Num {
fn gt(self, other: Self) -> Self::Bool;
fn lt(self, other: Self) -> Self::Bool;
fn ge(self, other: Self) -> Self::Bool;
fn le(self, other: Self) -> Self::Bool;
fn eq(self, other: Self) -> Self::Bool;
fn ne(self, other: Self) -> Self::Bool;
fn max(self, other: Self) -> Self;
fn min(self, other: Self) -> Self;
fn clamp(self, min: Self, max: Self) -> Self;
}
pub trait Signed: Sized + Num + core::ops::Neg<Output = Self> {
fn absf(self) -> Self;
fn signumf(self) -> Self;
}
pub trait Float: Num + Copy + core::ops::Neg<Output = Self> {
fn asinf(self) -> Self;
fn acosf(self) -> Self;
fn atanf(self) -> Self;
fn atan2f(self, x: Self) -> Self;
fn ceilf(self) -> Self;
fn copysignf(self, sign: Self) -> Self;
fn expf(self) -> Self;
fn floorf(self) -> Self;
fn is_finite(self) -> Self::Bool;
fn is_nan(self) -> Self::Bool;
fn mul_addf(self, b: Self, c: Self) -> Self;
fn powif(self, n: i32) -> Self;
fn powff(self, n: Self) -> Self;
fn recip(self) -> Self;
fn roundf(self) -> Self;
fn sqrtf(self) -> Self;
fn sinf(self) -> Self;
fn cosf(self) -> Self;
fn sin_cosf(self) -> (Self, Self);
fn tanf(self) -> Self;
fn minf(self, other: Self) -> Self;
fn maxf(self, other: Self) -> Self;
}
pub trait NumConstEx: Sized {
const ZERO: Self;
const ONE: Self;
const TWO: Self;
}
pub trait FloatConstEx: Sized {
const NEG_ONE: Self;
const TWO: Self;
const HALF: Self;
}
pub trait NanConstEx: Sized {
const NAN: Self;
}
pub trait NumEx:
Num
+ NumConstEx
+ Copy
+ Clone
+ PartialEq
+ PartialOrdEx
+ Add<Output = Self>
+ Div<Output = Self>
+ Mul<Output = Self>
+ Sub<Output = Self>
+ Rem<Output = Self>
+ Add<Self::Element, Output = Self>
+ Div<Self::Element, Output = Self>
+ Mul<Self::Element, Output = Self>
+ Sub<Self::Element, Output = Self>
+ Rem<Self::Element, Output = Self>
{
}
pub trait SignedEx: Signed + NumEx {}
pub trait IntegerShiftOps<Rhs>: Sized + Shl<Rhs, Output = Self> + Shr<Rhs, Output = Self> {}
pub trait IntegerBitOps:
Sized + Not<Output = Self> + BitAnd<Output = Self> + BitOr<Output = Self> + BitXor<Output = Self>
{
}