Browse Source

Merge #135

135: Debug-panic in clamp_min/max if min/max is NAN r=cuviper a=jturner314

This also improves the docs for `clamp`, `clamp_min`, and `clamp_max`.

Closes #134.

Co-authored-by: Jim Turner <[email protected]>
bors[bot] 5 years ago
parent
commit
d394467906
1 changed files with 43 additions and 0 deletions
  1. 43 0
      src/lib.rs

+ 43 - 0
src/lib.rs

@@ -364,6 +364,8 @@ float_trait_impl!(Num for f32 f64);
 ///  If input is less than min then this returns min.
 ///  If input is greater than max then this returns max.
 ///  Otherwise this returns input.
+///
+/// **Panics** in debug mode if `!(min <= max)`.
 #[inline]
 pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
     debug_assert!(min <= max, "min must be less than or equal to max");
@@ -381,8 +383,11 @@ pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
 ///  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)`.
+///
+/// **Panics** in debug mode if `!(min == min)`. (This occurs if `min` is `NAN`.)
 #[inline]
 pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
+    debug_assert!(min == min, "min must not be NAN");
     if input < min {
         min
     } else {
@@ -395,8 +400,11 @@ pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
 ///  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)`.
+///
+/// **Panics** in debug mode if `!(max == max)`. (This occurs if `max` is `NAN`.)
 #[inline]
 pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T {
+    debug_assert!(max == max, "max must not be NAN");
     if input > max {
         max
     } else {
@@ -428,6 +436,41 @@ fn clamp_test() {
     assert!(clamp_max(::core::f32::NAN, 1.0).is_nan());
 }
 
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_nan_min() {
+    clamp(0., ::core::f32::NAN, 1.);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_nan_max() {
+    clamp(0., -1., ::core::f32::NAN);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_nan_min_max() {
+    clamp(0., ::core::f32::NAN, ::core::f32::NAN);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_min_nan_min() {
+    clamp_min(0., ::core::f32::NAN);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_max_nan_max() {
+    clamp_max(0., ::core::f32::NAN);
+}
+
 #[test]
 fn from_str_radix_unwrap() {
     // The Result error must impl Debug to allow unwrap()