diff --git a/src/lib.rs b/src/lib.rs index 6641a3a..1bc9e7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -376,17 +376,56 @@ pub fn clamp(input: T, min: T, max: T) -> T { } } +/// A value bounded by a minimum value +/// +/// If input is less than min then this returns min. +/// Otherwise this returns input. +/// `clamp_min(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::min(std::f32::NAN, 1.0)`. +#[inline] +pub fn clamp_min(input: T, min: T) -> T { + if input < min { + min + } else { + input + } +} + +/// A value bounded by a maximum value +/// +/// If input is greater than max then this returns max. +/// Otherwise this returns input. +/// `clamp_max(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::max(std::f32::NAN, 1.0)`. +#[inline] +pub fn clamp_max(input: T, max: T) -> T { + if input > max { + max + } else { + input + } +} + #[test] fn clamp_test() { // Int test assert_eq!(1, clamp(1, -1, 2)); assert_eq!(-1, clamp(-2, -1, 2)); assert_eq!(2, clamp(3, -1, 2)); + assert_eq!(1, clamp_min(1, -1)); + assert_eq!(-1, clamp_min(-2, -1)); + assert_eq!(-1, clamp_max(1, -1)); + assert_eq!(-2, clamp_max(-2, -1)); // Float test assert_eq!(1.0, clamp(1.0, -1.0, 2.0)); assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0)); assert_eq!(2.0, clamp(3.0, -1.0, 2.0)); + assert_eq!(1.0, clamp_min(1.0, -1.0)); + assert_eq!(-1.0, clamp_min(-2.0, -1.0)); + assert_eq!(-1.0, clamp_max(1.0, -1.0)); + assert_eq!(-2.0, clamp_max(-2.0, -1.0)); + assert!(clamp(::core::f32::NAN, -1.0, 1.0).is_nan()); + assert!(clamp_min(::core::f32::NAN, 1.0).is_nan()); + assert!(clamp_max(::core::f32::NAN, 1.0).is_nan()); } #[test]