fearless_simd/
traits.rs

1// Copyright 2025 the Fearless_SIMD Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4#![expect(
5    missing_docs,
6    reason = "TODO: https://github.com/linebender/fearless_simd/issues/40"
7)]
8use crate::{Level, Simd};
9
10pub trait Select<T> {
11    fn select(self, if_true: T, if_false: T) -> T;
12}
13
14// Same as pulp
15pub trait WithSimd {
16    type Output;
17
18    fn with_simd<S: Simd>(self, simd: S) -> Self::Output;
19}
20
21impl<R, F: FnOnce(Level) -> R> WithSimd for F {
22    type Output = R;
23
24    #[inline(always)]
25    fn with_simd<S: Simd>(self, simd: S) -> Self::Output {
26        self(simd.level())
27    }
28}
29
30pub trait Bytes: Sized {
31    type Bytes;
32
33    fn to_bytes(self) -> Self::Bytes;
34
35    fn from_bytes(value: Self::Bytes) -> Self;
36
37    fn bitcast<U: Bytes<Bytes = Self::Bytes>>(self) -> U {
38        U::from_bytes(self.to_bytes())
39    }
40}
41
42pub(crate) mod seal {
43    #[expect(unnameable_types, reason = "TODO")]
44    pub trait Seal {}
45}
46
47/// Value conversion, adding a SIMD blessing.
48///
49/// Analogous to [`From`], but takes a SIMD token, which is used to bless
50/// the new value. Most such conversions are safe transmutes, but this
51/// trait also supports splats, and implementations can use the SIMD token
52/// to use an efficient splat intrinsic.
53///
54/// The [`SimdInto`] trait is also provided for convenience.
55pub trait SimdFrom<T, S: Simd> {
56    fn simd_from(value: T, simd: S) -> Self;
57}
58
59/// Value conversion, adding a SIMD blessing.
60///
61/// This trait is syntactic sugar for [`SimdFrom`] and exists only to allow
62/// `impl SimdInto` syntax in signatures, which would otherwise require
63/// cumbersome `where` clauses in terms of `SimdFrom`.
64///
65/// Avoid implementing this trait directly, prefer implementing [`SimdFrom`].
66pub trait SimdInto<T, S> {
67    fn simd_into(self, simd: S) -> T;
68}
69
70impl<F, T: SimdFrom<F, S>, S: Simd> SimdInto<T, S> for F {
71    fn simd_into(self, simd: S) -> T {
72        SimdFrom::simd_from(self, simd)
73    }
74}
75
76impl<T, S: Simd> SimdFrom<T, S> for T {
77    fn simd_from(value: T, _simd: S) -> Self {
78        value
79    }
80}
81
82pub trait SimdElement {
83    type Mask: SimdElement;
84}
85
86impl SimdElement for f32 {
87    type Mask = i32;
88}
89
90impl SimdElement for f64 {
91    type Mask = i64;
92}
93
94impl SimdElement for u8 {
95    type Mask = i8;
96}
97
98impl SimdElement for i8 {
99    type Mask = i8;
100}
101
102impl SimdElement for u16 {
103    type Mask = i16;
104}
105
106impl SimdElement for i16 {
107    type Mask = i16;
108}
109
110impl SimdElement for u32 {
111    type Mask = i32;
112}
113
114impl SimdElement for i32 {
115    type Mask = i32;
116}
117
118impl SimdElement for i64 {
119    type Mask = i64;
120}
121
122/// Construction of integer vectors from floats by truncation
123pub trait SimdCvtTruncate<T> {
124    fn truncate_from(x: T) -> Self;
125}
126
127/// Construction of floating point vectors from integers
128pub trait SimdCvtFloat<T> {
129    fn float_from(x: T) -> Self;
130}