mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
rust-lang/portable-simd#262: also implement clamp for integer vectors
* add test from issue rust-lang/portable-simd#253
This commit is contained in:
parent
b6ee5293f4
commit
49043f4434
@ -67,36 +67,54 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_min_max_vector {
|
||||
macro_rules! impl_ord_methods_vector {
|
||||
{ $type:ty } => {
|
||||
impl<const LANES: usize> Simd<$type, LANES>
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
/// Returns the lane-wise minimum with other
|
||||
/// Returns the lane-wise minimum with `other`.
|
||||
#[must_use = "method returns a new vector and does not mutate the original value"]
|
||||
#[inline]
|
||||
pub fn min(self, other: Self) -> Self {
|
||||
self.lanes_gt(other).select(other, self)
|
||||
}
|
||||
|
||||
/// Returns the lane-wise maximum with other
|
||||
/// Returns the lane-wise maximum with `other`.
|
||||
#[must_use = "method returns a new vector and does not mutate the original value"]
|
||||
#[inline]
|
||||
pub fn max(self, other: Self) -> Self {
|
||||
self.lanes_lt(other).select(other, self)
|
||||
}
|
||||
|
||||
/// Restrict each lane to a certain interval.
|
||||
///
|
||||
/// For each lane, returns `max` if `self` is greater than `max`, and `min` if `self` is
|
||||
/// less than `min`. Otherwise returns `self`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `min > max` on any lane.
|
||||
#[must_use = "method returns a new vector and does not mutate the original value"]
|
||||
#[inline]
|
||||
pub fn clamp(self, min: Self, max: Self) -> Self {
|
||||
assert!(
|
||||
min.lanes_le(max).all(),
|
||||
"each lane in `min` must be less than or equal to the corresponding lane in `max`",
|
||||
);
|
||||
self.max(min).min(max)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_min_max_vector!(i8);
|
||||
impl_min_max_vector!(i16);
|
||||
impl_min_max_vector!(i32);
|
||||
impl_min_max_vector!(i64);
|
||||
impl_min_max_vector!(isize);
|
||||
impl_min_max_vector!(u8);
|
||||
impl_min_max_vector!(u16);
|
||||
impl_min_max_vector!(u32);
|
||||
impl_min_max_vector!(u64);
|
||||
impl_min_max_vector!(usize);
|
||||
impl_ord_methods_vector!(i8);
|
||||
impl_ord_methods_vector!(i16);
|
||||
impl_ord_methods_vector!(i32);
|
||||
impl_ord_methods_vector!(i64);
|
||||
impl_ord_methods_vector!(isize);
|
||||
impl_ord_methods_vector!(u8);
|
||||
impl_ord_methods_vector!(u16);
|
||||
impl_ord_methods_vector!(u32);
|
||||
impl_ord_methods_vector!(u64);
|
||||
impl_ord_methods_vector!(usize);
|
||||
|
@ -18,3 +18,15 @@ fn min_is_not_lexicographic() {
|
||||
let b = i16x2::from_array([12, -4]);
|
||||
assert_eq!(a.min(b), i16x2::from_array([10, -4]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clamp_is_not_lexicographic() {
|
||||
let a = i16x2::splat(10);
|
||||
let lo = i16x2::from_array([-12, -4]);
|
||||
let up = i16x2::from_array([-4, 12]);
|
||||
assert_eq!(a.clamp(lo, up), i16x2::from_array([-4, 10]));
|
||||
|
||||
let x = i16x2::from_array([1, 10]);
|
||||
let y = x.clamp(i16x2::splat(0), i16x2::splat(9));
|
||||
assert_eq!(y, i16x2::from_array([1, 9]));
|
||||
}
|
||||
|
@ -239,6 +239,18 @@ macro_rules! impl_signed_tests {
|
||||
let b = Vector::<LANES>::splat(0);
|
||||
assert_eq!(a.max(b), a);
|
||||
}
|
||||
|
||||
fn clamp<const LANES: usize>() {
|
||||
let min = Vector::<LANES>::splat(Scalar::MIN);
|
||||
let max = Vector::<LANES>::splat(Scalar::MAX);
|
||||
let zero = Vector::<LANES>::splat(0);
|
||||
let one = Vector::<LANES>::splat(1);
|
||||
let negone = Vector::<LANES>::splat(-1);
|
||||
assert_eq!(zero.clamp(min, max), zero);
|
||||
assert_eq!(zero.clamp(min, one), zero);
|
||||
assert_eq!(zero.clamp(one, max), one);
|
||||
assert_eq!(zero.clamp(min, negone), negone);
|
||||
}
|
||||
}
|
||||
|
||||
test_helpers::test_lanes_panic! {
|
||||
|
Loading…
Reference in New Issue
Block a user