use crate::{
arch::Token,
scalar::Scalar,
shim::{Shim2, Shim4, Shim8},
vector::{width, Native, Vector},
};
#[cfg(feature = "complex")]
use num_complex::Complex;
#[derive(Copy, Clone, Debug)]
pub struct Generic;
unsafe impl Token for Generic {
#[inline]
fn new() -> Option<Self> {
Some(Self)
}
#[inline]
unsafe fn new_unchecked() -> Self {
Self
}
}
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
#[allow(non_camel_case_types)]
pub struct f32x1(f32);
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
#[allow(non_camel_case_types)]
pub struct f64x1(f64);
#[cfg(feature = "complex")]
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
#[allow(non_camel_case_types)]
pub struct cf32x1(Complex<f32>);
#[cfg(feature = "complex")]
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
#[allow(non_camel_case_types)]
pub struct cf64x1(Complex<f64>);
macro_rules! implement {
{
$vector:ty, $scalar:ty
} => {
impl Scalar<Generic, width::W1> for $scalar {
type Vector = $vector;
}
impl Scalar<Generic, width::W2> for $scalar {
type Vector = Shim2<$vector, $scalar>;
}
impl Scalar<Generic, width::W4> for $scalar {
type Vector = Shim4<$vector, $scalar>;
}
impl Scalar<Generic, width::W8> for $scalar {
type Vector = Shim8<$vector, $scalar>;
}
impl Native<Generic> for $scalar {
type Width = width::W1;
}
}
}
implement! { f32x1, f32 }
implement! { f64x1, f64 }
#[cfg(feature = "complex")]
implement! { cf32x1, Complex<f32> }
#[cfg(feature = "complex")]
implement! { cf64x1, Complex<f64> }
macro_rules! implement {
{
$vector:ty, $scalar:ty
} => {
arithmetic_ops! {
feature: Generic::new_unchecked(),
for $vector:
add -> (),
sub -> (),
mul -> (),
div -> ()
}
impl core::ops::Neg for $vector {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self(-self.0)
}
}
as_slice! { $vector }
unsafe impl Vector for $vector {
type Scalar = $scalar;
type Token = Generic;
type Width = crate::vector::width::W1;
type Underlying = $scalar;
#[inline]
fn zeroed(_: Self::Token) -> Self {
Self(<$scalar>::default())
}
#[inline]
fn splat(_: Self::Token, from: Self::Scalar) -> Self {
Self(from)
}
}
}
}
implement! { f32x1, f32 }
implement! { f64x1, f64 }
#[cfg(feature = "complex")]
implement! { cf32x1, Complex<f32> }
#[cfg(feature = "complex")]
implement! { cf64x1, Complex<f64> }
#[cfg(feature = "complex")]
macro_rules! implement_complex {
{
$vector:ty, $real:ty
} => {
impl crate::vector::Complex for $vector {
type RealScalar = $real;
#[inline]
fn conj(self) -> Self {
Self(Complex::new(self.0.re, -self.0.im))
}
#[inline]
fn mul_i(self) -> Self {
Self(Complex::new(-self.0.im, self.0.re))
}
#[inline]
fn mul_neg_i(self) -> Self {
Self(Complex::new(self.0.im, -self.0.re))
}
}
}
}
#[cfg(feature = "complex")]
implement_complex! { cf32x1, f32 }
#[cfg(feature = "complex")]
implement_complex! { cf64x1, f64 }