diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index b90c6daf9eb..a567eaa57d5 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -39,7 +39,7 @@ #![stable] -use option::{Option, Some}; +use option::{Option, Some, None}; /// Trait for values that can be compared for equality and inequality. /// @@ -268,6 +268,32 @@ pub fn max(v1: T, v2: T) -> T { if v1 > v2 { v1 } else { v2 } } +/// Compare and return the minimum of two values if there is one. +/// +/// Returns the first argument if the comparison determines them to be equal. +#[inline] +#[experimental] +pub fn partial_min(v1: T, v2: T) -> Option { + match v1.partial_cmp(&v2) { + Some(Less) | Some(Equal) => Some(v1), + Some(Greater) => Some(v2), + None => None + } +} + +/// Compare and return the maximum of two values if there is one. +/// +/// Returns the first argument if the comparison determines them to be equal. +#[inline] +#[experimental] +pub fn partial_max(v1: T, v2: T) -> Option { + match v1.partial_cmp(&v2) { + Some(Less) => Some(v2), + Some(Equal) | Some(Greater) => Some(v1), + None => None + } +} + // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types mod impls { use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering, diff --git a/src/libcoretest/cmp.rs b/src/libcoretest/cmp.rs index a25d205e225..4ac3f7e9310 100644 --- a/src/libcoretest/cmp.rs +++ b/src/libcoretest/cmp.rs @@ -9,6 +9,7 @@ // except according to those terms. use core::cmp::lexical_ordering; +use core::cmp::{ partial_min, partial_max }; #[test] fn test_int_totalord() { @@ -56,6 +57,72 @@ fn test_lexical_ordering() { } } +#[test] +fn test_partial_min() { + use core::f64::NAN; + let data_integer = [ + // a, b, result + (0i, 0i, Some(0i)), + (1i, 0i, Some(0i)), + (0i, 1i, Some(0i)), + (-1i, 0i, Some(-1i)), + (0i, -1i, Some(-1i)) + ]; + + let data_float = [ + // a, b, result + (0.0f64, 0.0f64, Some(0.0f64)), + (1.0f64, 0.0f64, Some(0.0f64)), + (0.0f64, 1.0f64, Some(0.0f64)), + (-1.0f64, 0.0f64, Some(-1.0f64)), + (0.0f64, -1.0f64, Some(-1.0f64)), + (NAN, NAN, None), + (NAN, 1.0f64, None), + (1.0f64, NAN, None) + ]; + + for &(a, b, result) in data_integer.iter() { + assert!(partial_min(a, b) == result); + } + + for &(a, b, result) in data_float.iter() { + assert!(partial_min(a, b) == result); + } +} + +#[test] +fn test_partial_max() { + use core::f64::NAN; + let data_integer = [ + // a, b, result + (0i, 0i, Some(0i)), + (1i, 0i, Some(1i)), + (0i, 1i, Some(1i)), + (-1i, 0i, Some(0i)), + (0i, -1i, Some(0i)) + ]; + + let data_float = [ + // a, b, result + (0.0f64, 0.0f64, Some(0.0f64)), + (1.0f64, 0.0f64, Some(1.0f64)), + (0.0f64, 1.0f64, Some(1.0f64)), + (-1.0f64, 0.0f64, Some(0.0f64)), + (0.0f64, -1.0f64, Some(0.0f64)), + (NAN, NAN, None), + (NAN, 1.0f64, None), + (1.0f64, NAN, None) + ]; + + for &(a, b, result) in data_integer.iter() { + assert!(partial_max(a, b) == result); + } + + for &(a, b, result) in data_float.iter() { + assert!(partial_max(a, b) == result); + } +} + #[test] fn test_user_defined_eq() { // Our type.