diff --git a/src/system.rs b/src/system.rs index d73ff3c1..b3fc10ff 100644 --- a/src/system.rs +++ b/src/system.rs @@ -754,6 +754,21 @@ macro_rules! system { value: self.value.min(other.value), } } + + /// f{32,64}: Restrict a value to a certain interval unless it is NaN. + /// Ord: Restrict a value to a certain interval. + #[must_use = "method returns a new number and does not mutate the original value"] + #[inline(always)] + pub fn clamp(self, min: Self, max: Self) -> Self + where + V: $crate::num::Float, + { + Quantity { + dimension: $crate::lib::marker::PhantomData, + units: $crate::lib::marker::PhantomData, + value: self.value.clamp(min.value, max.value), + } + } } // Explicitly definte floating point methods for float and complex storage types. @@ -1083,6 +1098,15 @@ macro_rules! system { value: self.value.min(other.value), } } + + #[inline(always)] + fn clamp(self, min: Self, max: Self) -> Self { + Quantity { + dimension: $crate::lib::marker::PhantomData, + units: $crate::lib::marker::PhantomData, + value: self.value.clamp(min.value, max.value), + } + } } autoconvert! { diff --git a/src/tests/system.rs b/src/tests/system.rs index 99e48491..f5c99d99 100644 --- a/src/tests/system.rs +++ b/src/tests/system.rs @@ -371,6 +371,13 @@ mod float { Test::eq(&Length::new::(l.min(*r)), &Length::new::(*l).min(Length::new::(*r))) } + + #[allow(trivial_casts)] + fn clamp(x: A, min: A, max: A) -> bool { + Test::eq( + &Length::new::(x.clamp(*min, *max)), + &Length::new::(*x).clamp(Length::new::(*min), Length::new::(*max))) + } } } } @@ -571,6 +578,16 @@ mod fixed { &Ord::min(Length::new::((*l).clone()), Length::new::((*r).clone()))) } + + #[allow(trivial_casts)] + fn clamp(x: A, min: A, max: A) -> bool { + Test::eq(&Length::new::((*x).clone().clamp((*min).clone(), (*max).clone())), + &Ord::clamp( + Length::new::((*x).clone()), + Length::new::((*min).clone()), + Length::new::((*max).clone()), + )) + } } } }