core/portable-simd/crates/core_simd/src/simd/cmp/
eq.rs

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 not 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}