pub mod width;
use crate::arch::Token;
use crate::scalar::Scalar;
use core::ops::{
Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign,
};
pub trait Native<Token> {
type Width: width::Width;
}
pub type NativeWidth<Scalar, Token> = <Scalar as Native<Token>>::Width;
pub type NativeVector<Scalar, Token> = VectorOf<Scalar, NativeWidth<Scalar, Token>, Token>;
pub type VectorOf<Scalar, Width, Token> = <Scalar as self::Scalar<Token, Width>>::Vector;
pub unsafe trait Vector: Copy {
type Scalar: Copy;
type Token: Token;
type Width: width::Width;
type Underlying: Copy;
#[inline]
fn width() -> usize {
<Self::Width as width::Width>::VALUE
}
#[inline]
fn to_token(self) -> Self::Token {
unsafe { Self::Token::new_unchecked() }
}
#[inline]
fn as_slice(&self) -> &[Self::Scalar] {
unsafe { core::slice::from_raw_parts(self as *const _ as *const _, Self::width()) }
}
#[inline]
fn as_slice_mut(&mut self) -> &mut [Self::Scalar] {
unsafe { core::slice::from_raw_parts_mut(self as *mut _ as *mut _, Self::width()) }
}
#[inline]
fn to_underlying(self) -> Self::Underlying {
assert_eq!(
(
core::mem::size_of::<Self::Underlying>(),
core::mem::align_of::<Self::Underlying>(),
),
(core::mem::align_of::<Self>(), core::mem::size_of::<Self>(),)
);
unsafe { core::mem::transmute_copy(&self) }
}
#[inline]
fn from_underlying(
#[allow(unused_variables)] token: Self::Token,
underlying: Self::Underlying,
) -> Self {
assert_eq!(
(
core::mem::size_of::<Self::Underlying>(),
core::mem::align_of::<Self::Underlying>(),
),
(core::mem::align_of::<Self>(), core::mem::size_of::<Self>(),)
);
unsafe { core::mem::transmute_copy(&underlying) }
}
#[inline]
unsafe fn read_ptr(
#[allow(unused_variables)] token: Self::Token,
from: *const Self::Scalar,
) -> Self {
(from as *const Self).read_unaligned()
}
#[inline]
unsafe fn read_aligned_ptr(
#[allow(unused_variables)] token: Self::Token,
from: *const Self::Scalar,
) -> Self {
(from as *const Self).read()
}
#[inline]
unsafe fn read_unchecked(token: Self::Token, from: &[Self::Scalar]) -> Self {
Self::read_ptr(token, from.as_ptr())
}
#[inline]
fn read(token: Self::Token, from: &[Self::Scalar]) -> Self {
assert!(
from.len() >= Self::width(),
"source not larget enough to load vector"
);
unsafe { Self::read_unchecked(token, from) }
}
#[inline]
unsafe fn write_ptr(self, to: *mut Self::Scalar) {
(to as *mut Self).write_unaligned(self);
}
#[inline]
unsafe fn write_aligned_ptr(self, to: *mut Self::Scalar) {
(to as *mut Self).write(self);
}
#[inline]
unsafe fn write_unchecked(self, to: &mut [Self::Scalar]) {
self.write_ptr(to.as_mut_ptr());
}
#[inline]
fn write(self, to: &mut [Self::Scalar]) {
assert!(
to.len() >= Self::width(),
"destination not large enough to store vector"
);
unsafe { self.write_unchecked(to) };
}
fn zeroed(token: Self::Token) -> Self;
fn splat(token: Self::Token, from: Self::Scalar) -> Self;
}
pub trait Ops:
Vector
+ AsRef<[<Self as Vector>::Scalar]>
+ AsMut<[<Self as Vector>::Scalar]>
+ Deref<Target = [<Self as Vector>::Scalar]>
+ DerefMut
+ Add<Self, Output = Self>
+ Add<<Self as Vector>::Scalar, Output = Self>
+ AddAssign<Self>
+ AddAssign<<Self as Vector>::Scalar>
+ Sub<Self, Output = Self>
+ Sub<<Self as Vector>::Scalar, Output = Self>
+ SubAssign<Self>
+ SubAssign<<Self as Vector>::Scalar>
+ Mul<Self, Output = Self>
+ Mul<<Self as Vector>::Scalar, Output = Self>
+ MulAssign<Self>
+ MulAssign<<Self as Vector>::Scalar>
+ Div<Self, Output = Self>
+ Div<<Self as Vector>::Scalar, Output = Self>
+ DivAssign<Self>
+ DivAssign<<Self as Vector>::Scalar>
{
}
impl<V> Ops for V where
V: Vector
+ AsRef<[<V as Vector>::Scalar]>
+ AsMut<[<V as Vector>::Scalar]>
+ Deref<Target = [<V as Vector>::Scalar]>
+ DerefMut
+ Add<V, Output = V>
+ Add<<V as Vector>::Scalar, Output = V>
+ AddAssign<V>
+ AddAssign<<V as Vector>::Scalar>
+ Sub<V, Output = V>
+ Sub<<V as Vector>::Scalar, Output = V>
+ SubAssign<V>
+ SubAssign<<V as Vector>::Scalar>
+ Mul<V, Output = V>
+ Mul<<V as Vector>::Scalar, Output = V>
+ MulAssign<V>
+ MulAssign<<V as Vector>::Scalar>
+ Div<V, Output = V>
+ Div<<V as Vector>::Scalar, Output = V>
+ DivAssign<V>
+ DivAssign<<V as Vector>::Scalar>
{
}
pub trait Signed: Ops + Neg<Output = Self> {}
impl<V> Signed for V where V: Ops + Neg<Output = V> {}
pub trait Complex: Signed {
type RealScalar: Copy;
fn conj(self) -> Self;
fn mul_i(self) -> Self;
fn mul_neg_i(self) -> Self;
}