1use crate::simd::{
2 ptr::{SimdConstPtr, SimdMutPtr},
3 LaneCount, Mask, Simd, SimdElement, SupportedLaneCount,
4};
5
6/// Parallel `PartialEq`.
7pub trait SimdPartialEq {
8 /// The mask type returned by each comparison.
9 type Mask;
10
11 /// Test if each element is equal to the corresponding element in `other`.
12 #[must_use = "method returns a new mask and does not mutate the original value"]
13 fn simd_eq(self, other: Self) -> Self::Mask;
14
15 /// Test if each element is equal to the corresponding element in `other`.
16 #[must_use = "method returns a new mask and does not mutate the original value"]
17 fn simd_ne(self, other: Self) -> Self::Mask;
18}
19
20macro_rules! impl_number {
21 { $($number:ty),* } => {
22 $(
23 impl<const N: usize> SimdPartialEq for Simd<$number, N>
24 where
25 LaneCount<N>: SupportedLaneCount,
26 {
27 type Mask = Mask<<$number as SimdElement>::Mask, N>;
28
29 #[inline]
30 fn simd_eq(self, other: Self) -> Self::Mask {
31 // Safety: `self` is a vector, and the result of the comparison
32 // is always a valid mask.
33 unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_eq(self, other)) }
34 }
35
36 #[inline]
37 fn simd_ne(self, other: Self) -> Self::Mask {
38 // Safety: `self` is a vector, and the result of the comparison
39 // is always a valid mask.
40 unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_ne(self, other)) }
41 }
42 }
43 )*
44 }
45}
46
47impl_number! { f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize }
48
49macro_rules! impl_mask {
50 { $($integer:ty),* } => {
51 $(
52 impl<const N: usize> SimdPartialEq for Mask<$integer, N>
53 where
54 LaneCount<N>: SupportedLaneCount,
55 {
56 type Mask = Self;
57
58 #[inline]
59 fn simd_eq(self, other: Self) -> Self::Mask {
60 // Safety: `self` is a vector, and the result of the comparison
61 // is always a valid mask.
62 unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_eq(self.to_int(), other.to_int())) }
63 }
64
65 #[inline]
66 fn simd_ne(self, other: Self) -> Self::Mask {
67 // Safety: `self` is a vector, and the result of the comparison
68 // is always a valid mask.
69 unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_ne(self.to_int(), other.to_int())) }
70 }
71 }
72 )*
73 }
74}
75
76impl_mask! { i8, i16, i32, i64, isize }
77
78impl<T, const N: usize> SimdPartialEq for Simd<*const T, N>
79where
80 LaneCount<N>: SupportedLaneCount,
81{
82 type Mask = Mask<isize, N>;
83
84 #[inline]
85 fn simd_eq(self, other: Self) -> Self::Mask {
86 self.addr().simd_eq(other.addr())
87 }
88
89 #[inline]
90 fn simd_ne(self, other: Self) -> Self::Mask {
91 self.addr().simd_ne(other.addr())
92 }
93}
94
95impl<T, const N: usize> SimdPartialEq for Simd<*mut T, N>
96where
97 LaneCount<N>: SupportedLaneCount,
98{
99 type Mask = Mask<isize, N>;
100
101 #[inline]
102 fn simd_eq(self, other: Self) -> Self::Mask {
103 self.addr().simd_eq(other.addr())
104 }
105
106 #[inline]
107 fn simd_ne(self, other: Self) -> Self::Mask {
108 self.addr().simd_ne(other.addr())
109 }
110}
111