core_simd/simd/cmp/
eq.rs

1use crate::simd::{
2    Mask, Simd, SimdElement,
3    ptr::{SimdConstPtr, SimdMutPtr},
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        {
25            type Mask = Mask<<$number as SimdElement>::Mask, N>;
26
27            #[inline]
28            fn simd_eq(self, other: Self) -> Self::Mask {
29                // Safety: `self` is a vector, and the result of the comparison
30                // is always a valid mask.
31                unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_eq(self, other)) }
32            }
33
34            #[inline]
35            fn simd_ne(self, other: Self) -> Self::Mask {
36                // Safety: `self` is a vector, and the result of the comparison
37                // is always a valid mask.
38                unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ne(self, other)) }
39            }
40        }
41        )*
42    }
43}
44
45impl_number! { f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize }
46
47macro_rules! impl_mask {
48    { $($integer:ty),* } => {
49        $(
50        impl<const N: usize> SimdPartialEq for Mask<$integer, N>
51        {
52            type Mask = Self;
53
54            #[inline]
55            fn simd_eq(self, other: Self) -> Self::Mask {
56                // Safety: `self` is a vector, and the result of the comparison
57                // is always a valid mask.
58                unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_eq(self.to_simd(), other.to_simd())) }
59            }
60
61            #[inline]
62            fn simd_ne(self, other: Self) -> Self::Mask {
63                // Safety: `self` is a vector, and the result of the comparison
64                // is always a valid mask.
65                unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ne(self.to_simd(), other.to_simd())) }
66            }
67        }
68        )*
69    }
70}
71
72impl_mask! { i8, i16, i32, i64, isize }
73
74impl<T, const N: usize> SimdPartialEq for Simd<*const T, N> {
75    type Mask = Mask<isize, N>;
76
77    #[inline]
78    fn simd_eq(self, other: Self) -> Self::Mask {
79        self.addr().simd_eq(other.addr())
80    }
81
82    #[inline]
83    fn simd_ne(self, other: Self) -> Self::Mask {
84        self.addr().simd_ne(other.addr())
85    }
86}
87
88impl<T, const N: usize> SimdPartialEq for Simd<*mut T, N> {
89    type Mask = Mask<isize, N>;
90
91    #[inline]
92    fn simd_eq(self, other: Self) -> Self::Mask {
93        self.addr().simd_eq(other.addr())
94    }
95
96    #[inline]
97    fn simd_ne(self, other: Self) -> Self::Mask {
98        self.addr().simd_ne(other.addr())
99    }
100}