generic_simd/arch/
generic.rs

1//! Generic vector types for any platform.
2
3use crate::{
4    arch::Token,
5    scalar::Scalar,
6    shim::{Shim2, Shim4, Shim8},
7    vector::{width, Native, Vector},
8};
9
10#[cfg(feature = "complex")]
11use num_complex::Complex;
12
13/// Generic instruction set token.
14#[derive(Copy, Clone, Debug)]
15pub struct Generic;
16
17unsafe impl Token for Generic {
18    #[inline]
19    fn new() -> Option<Self> {
20        Some(Self)
21    }
22
23    #[inline]
24    unsafe fn new_unchecked() -> Self {
25        Self
26    }
27}
28
29/// A generic vector of one `f32`.
30#[derive(Clone, Copy, Debug)]
31#[repr(transparent)]
32#[allow(non_camel_case_types)]
33pub struct f32x1(f32);
34
35/// A generic vector of one `f64`.
36#[derive(Clone, Copy, Debug)]
37#[repr(transparent)]
38#[allow(non_camel_case_types)]
39pub struct f64x1(f64);
40
41/// A generic vector of one `Complex<f32>`.
42///
43/// Requires feature `"complex"`.
44#[cfg(feature = "complex")]
45#[derive(Clone, Copy, Debug)]
46#[repr(transparent)]
47#[allow(non_camel_case_types)]
48pub struct cf32x1(Complex<f32>);
49
50/// A generic vector of one `Complex<f64>`.
51///
52/// Requires feature `"complex"`.
53#[cfg(feature = "complex")]
54#[derive(Clone, Copy, Debug)]
55#[repr(transparent)]
56#[allow(non_camel_case_types)]
57pub struct cf64x1(Complex<f64>);
58
59macro_rules! implement {
60    {
61        $vector:ty, $scalar:ty
62    } => {
63        impl Scalar<Generic, width::W1> for $scalar {
64            type Vector = $vector;
65        }
66
67        impl Scalar<Generic, width::W2> for $scalar {
68            type Vector = Shim2<$vector, $scalar>;
69        }
70
71        impl Scalar<Generic, width::W4> for $scalar {
72            type Vector = Shim4<$vector, $scalar>;
73        }
74
75        impl Scalar<Generic, width::W8> for $scalar {
76            type Vector = Shim8<$vector, $scalar>;
77        }
78
79        impl Native<Generic> for $scalar {
80            type Width = width::W1;
81        }
82    }
83}
84
85implement! { f32x1, f32 }
86implement! { f64x1, f64 }
87
88#[cfg(feature = "complex")]
89implement! { cf32x1, Complex<f32> }
90#[cfg(feature = "complex")]
91implement! { cf64x1, Complex<f64> }
92
93macro_rules! implement {
94    {
95        $vector:ty, $scalar:ty
96    } => {
97        arithmetic_ops! {
98            feature: Generic::new_unchecked(),
99            for $vector:
100                add -> (),
101                sub -> (),
102                mul -> (),
103                div -> ()
104        }
105
106        impl core::ops::Neg for $vector {
107            type Output = Self;
108
109            #[inline]
110            fn neg(self) -> Self {
111                Self(-self.0)
112            }
113        }
114
115        as_slice! { $vector }
116
117        unsafe impl Vector for $vector {
118            type Scalar = $scalar;
119
120            type Token = Generic;
121
122            type Width = crate::vector::width::W1;
123
124            type Underlying = $scalar;
125
126            #[inline]
127            fn zeroed(_: Self::Token) -> Self {
128                Self(<$scalar>::default())
129            }
130
131            #[inline]
132            fn splat(_: Self::Token, from: Self::Scalar) -> Self {
133                Self(from)
134            }
135        }
136    }
137}
138
139implement! { f32x1, f32 }
140implement! { f64x1, f64 }
141
142#[cfg(feature = "complex")]
143implement! { cf32x1, Complex<f32> }
144#[cfg(feature = "complex")]
145implement! { cf64x1, Complex<f64> }
146
147#[cfg(feature = "complex")]
148macro_rules! implement_complex {
149    {
150        $vector:ty, $real:ty
151    } => {
152        impl crate::vector::Complex for $vector {
153            type RealScalar = $real;
154
155            #[inline]
156            fn conj(self) -> Self {
157                Self(Complex::new(self.0.re, -self.0.im))
158            }
159
160            #[inline]
161            fn mul_i(self) -> Self {
162                Self(Complex::new(-self.0.im, self.0.re))
163            }
164
165            #[inline]
166            fn mul_neg_i(self) -> Self {
167                Self(Complex::new(self.0.im, -self.0.re))
168            }
169        }
170    }
171}
172
173#[cfg(feature = "complex")]
174implement_complex! { cf32x1, f32 }
175#[cfg(feature = "complex")]
176implement_complex! { cf64x1, f64 }