]> git.proxmox.com Git - rustc.git/blame - library/portable-simd/crates/core_simd/src/comparisons.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / library / portable-simd / crates / core_simd / src / comparisons.rs
CommitLineData
3c0e092e
XL
1use crate::simd::intrinsics;
2use crate::simd::{LaneCount, Mask, Simd, SimdElement, SupportedLaneCount};
3
4impl<T, const LANES: usize> Simd<T, LANES>
5where
6 T: SimdElement + PartialEq,
7 LaneCount<LANES>: SupportedLaneCount,
8{
9 /// Test if each lane is equal to the corresponding lane in `other`.
10 #[inline]
a2a8927a 11 #[must_use = "method returns a new mask and does not mutate the original value"]
3c0e092e 12 pub fn lanes_eq(self, other: Self) -> Mask<T::Mask, LANES> {
5e7ed085
FG
13 // Safety: `self` is a vector, and the result of the comparison
14 // is always a valid mask.
3c0e092e
XL
15 unsafe { Mask::from_int_unchecked(intrinsics::simd_eq(self, other)) }
16 }
17
18 /// Test if each lane is not equal to the corresponding lane in `other`.
19 #[inline]
a2a8927a 20 #[must_use = "method returns a new mask and does not mutate the original value"]
3c0e092e 21 pub fn lanes_ne(self, other: Self) -> Mask<T::Mask, LANES> {
5e7ed085
FG
22 // Safety: `self` is a vector, and the result of the comparison
23 // is always a valid mask.
3c0e092e
XL
24 unsafe { Mask::from_int_unchecked(intrinsics::simd_ne(self, other)) }
25 }
26}
27
28impl<T, const LANES: usize> Simd<T, LANES>
29where
30 T: SimdElement + PartialOrd,
31 LaneCount<LANES>: SupportedLaneCount,
32{
33 /// Test if each lane is less than the corresponding lane in `other`.
34 #[inline]
a2a8927a 35 #[must_use = "method returns a new mask and does not mutate the original value"]
3c0e092e 36 pub fn lanes_lt(self, other: Self) -> Mask<T::Mask, LANES> {
5e7ed085
FG
37 // Safety: `self` is a vector, and the result of the comparison
38 // is always a valid mask.
3c0e092e
XL
39 unsafe { Mask::from_int_unchecked(intrinsics::simd_lt(self, other)) }
40 }
41
42 /// Test if each lane is greater than the corresponding lane in `other`.
43 #[inline]
a2a8927a 44 #[must_use = "method returns a new mask and does not mutate the original value"]
3c0e092e 45 pub fn lanes_gt(self, other: Self) -> Mask<T::Mask, LANES> {
5e7ed085
FG
46 // Safety: `self` is a vector, and the result of the comparison
47 // is always a valid mask.
3c0e092e
XL
48 unsafe { Mask::from_int_unchecked(intrinsics::simd_gt(self, other)) }
49 }
50
51 /// Test if each lane is less than or equal to the corresponding lane in `other`.
52 #[inline]
a2a8927a 53 #[must_use = "method returns a new mask and does not mutate the original value"]
3c0e092e 54 pub fn lanes_le(self, other: Self) -> Mask<T::Mask, LANES> {
5e7ed085
FG
55 // Safety: `self` is a vector, and the result of the comparison
56 // is always a valid mask.
3c0e092e
XL
57 unsafe { Mask::from_int_unchecked(intrinsics::simd_le(self, other)) }
58 }
59
60 /// Test if each lane is greater than or equal to the corresponding lane in `other`.
61 #[inline]
a2a8927a 62 #[must_use = "method returns a new mask and does not mutate the original value"]
3c0e092e 63 pub fn lanes_ge(self, other: Self) -> Mask<T::Mask, LANES> {
5e7ed085
FG
64 // Safety: `self` is a vector, and the result of the comparison
65 // is always a valid mask.
3c0e092e
XL
66 unsafe { Mask::from_int_unchecked(intrinsics::simd_ge(self, other)) }
67 }
68}
5e7ed085
FG
69
70macro_rules! impl_ord_methods_vector {
71 { $type:ty } => {
72 impl<const LANES: usize> Simd<$type, LANES>
73 where
74 LaneCount<LANES>: SupportedLaneCount,
75 {
76 /// Returns the lane-wise minimum with `other`.
77 #[must_use = "method returns a new vector and does not mutate the original value"]
78 #[inline]
79 pub fn min(self, other: Self) -> Self {
80 self.lanes_gt(other).select(other, self)
81 }
82
83 /// Returns the lane-wise maximum with `other`.
84 #[must_use = "method returns a new vector and does not mutate the original value"]
85 #[inline]
86 pub fn max(self, other: Self) -> Self {
87 self.lanes_lt(other).select(other, self)
88 }
89
90 /// Restrict each lane to a certain interval.
91 ///
92 /// For each lane, returns `max` if `self` is greater than `max`, and `min` if `self` is
93 /// less than `min`. Otherwise returns `self`.
94 ///
95 /// # Panics
96 ///
97 /// Panics if `min > max` on any lane.
98 #[must_use = "method returns a new vector and does not mutate the original value"]
99 #[inline]
100 pub fn clamp(self, min: Self, max: Self) -> Self {
101 assert!(
102 min.lanes_le(max).all(),
103 "each lane in `min` must be less than or equal to the corresponding lane in `max`",
104 );
105 self.max(min).min(max)
106 }
107 }
108 }
109}
110
111impl_ord_methods_vector!(i8);
112impl_ord_methods_vector!(i16);
113impl_ord_methods_vector!(i32);
114impl_ord_methods_vector!(i64);
115impl_ord_methods_vector!(isize);
116impl_ord_methods_vector!(u8);
117impl_ord_methods_vector!(u16);
118impl_ord_methods_vector!(u32);
119impl_ord_methods_vector!(u64);
120impl_ord_methods_vector!(usize);