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