Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 49043f4

Browse files
authored
rust-lang/portable-simd#262: also implement clamp for integer vectors
* add test from issue rust-lang/portable-simd#253
1 parent b6ee529 commit 49043f4

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

crates/core_simd/src/comparisons.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,36 +67,54 @@ where
6767
}
6868
}
6969

70-
macro_rules! impl_min_max_vector {
70+
macro_rules! impl_ord_methods_vector {
7171
{ $type:ty } => {
7272
impl<const LANES: usize> Simd<$type, LANES>
7373
where
7474
LaneCount<LANES>: SupportedLaneCount,
7575
{
76-
/// Returns the lane-wise minimum with other
76+
/// Returns the lane-wise minimum with `other`.
7777
#[must_use = "method returns a new vector and does not mutate the original value"]
7878
#[inline]
7979
pub fn min(self, other: Self) -> Self {
8080
self.lanes_gt(other).select(other, self)
8181
}
8282

83-
/// Returns the lane-wise maximum with other
83+
/// Returns the lane-wise maximum with `other`.
8484
#[must_use = "method returns a new vector and does not mutate the original value"]
8585
#[inline]
8686
pub fn max(self, other: Self) -> Self {
8787
self.lanes_lt(other).select(other, self)
8888
}
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+
}
89107
}
90108
}
91109
}
92110

93-
impl_min_max_vector!(i8);
94-
impl_min_max_vector!(i16);
95-
impl_min_max_vector!(i32);
96-
impl_min_max_vector!(i64);
97-
impl_min_max_vector!(isize);
98-
impl_min_max_vector!(u8);
99-
impl_min_max_vector!(u16);
100-
impl_min_max_vector!(u32);
101-
impl_min_max_vector!(u64);
102-
impl_min_max_vector!(usize);
111+
impl_ord_methods_vector!(i8);
112+
impl_ord_methods_vector!(i16);
113+
impl_ord_methods_vector!(i32);
114+
impl_ord_methods_vector!(i64);
115+
impl_ord_methods_vector!(isize);
116+
impl_ord_methods_vector!(u8);
117+
impl_ord_methods_vector!(u16);
118+
impl_ord_methods_vector!(u32);
119+
impl_ord_methods_vector!(u64);
120+
impl_ord_methods_vector!(usize);

crates/core_simd/tests/i16_ops.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,15 @@ fn min_is_not_lexicographic() {
1818
let b = i16x2::from_array([12, -4]);
1919
assert_eq!(a.min(b), i16x2::from_array([10, -4]));
2020
}
21+
22+
#[test]
23+
fn clamp_is_not_lexicographic() {
24+
let a = i16x2::splat(10);
25+
let lo = i16x2::from_array([-12, -4]);
26+
let up = i16x2::from_array([-4, 12]);
27+
assert_eq!(a.clamp(lo, up), i16x2::from_array([-4, 10]));
28+
29+
let x = i16x2::from_array([1, 10]);
30+
let y = x.clamp(i16x2::splat(0), i16x2::splat(9));
31+
assert_eq!(y, i16x2::from_array([1, 9]));
32+
}

crates/core_simd/tests/ops_macros.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,18 @@ macro_rules! impl_signed_tests {
239239
let b = Vector::<LANES>::splat(0);
240240
assert_eq!(a.max(b), a);
241241
}
242+
243+
fn clamp<const LANES: usize>() {
244+
let min = Vector::<LANES>::splat(Scalar::MIN);
245+
let max = Vector::<LANES>::splat(Scalar::MAX);
246+
let zero = Vector::<LANES>::splat(0);
247+
let one = Vector::<LANES>::splat(1);
248+
let negone = Vector::<LANES>::splat(-1);
249+
assert_eq!(zero.clamp(min, max), zero);
250+
assert_eq!(zero.clamp(min, one), zero);
251+
assert_eq!(zero.clamp(one, max), one);
252+
assert_eq!(zero.clamp(min, negone), negone);
253+
}
242254
}
243255

244256
test_helpers::test_lanes_panic! {

0 commit comments

Comments
 (0)