diff --git a/src/libcore/char.rs b/src/libcore/char.rs index ef2bd91e97313..7868b463807f6 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -10,6 +10,7 @@ //! Utilities for manipulating the char type +#[cfg(notest)] use cmp::Ord; use option::{None, Option, Some}; use str; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7476531ef944c..8fc2db6d6f19a 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -41,6 +41,9 @@ much easier to implement. */ +use cmp::Ord; +use option::{Option, Some, None}; + pub trait Times { fn times(&self, it: &fn() -> bool); } @@ -104,6 +107,78 @@ pub fn all(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { true } +/** + * Return the first element where `predicate` returns `true`. Return `None` if no element is found. + * + * # Example: + * + * ~~~~ + * let xs = ~[1u, 2, 3, 4, 5, 6]; + * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4); + * ~~~~ + */ +#[inline(always)] +pub fn find(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> Option { + for iter |x| { + if predicate(&x) { + return Some(x); + } + } + None +} + +/** + * Return the largest item yielded by an iterator. Return `None` if the iterator is empty. + * + * # Example: + * + * ~~~~ + * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + * assert_eq!(max(|f| xs.each(f)).unwrap(), &15); + * ~~~~ + */ +#[inline] +pub fn max(iter: &fn(f: &fn(T) -> bool)) -> Option { + let mut result = None; + for iter |x| { + match result { + Some(ref mut y) => { + if x > *y { + *y = x; + } + } + None => result = Some(x) + } + } + result +} + +/** + * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty. + * + * # Example: + * + * ~~~~ + * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5); + * ~~~~ + */ +#[inline] +pub fn min(iter: &fn(f: &fn(T) -> bool)) -> Option { + let mut result = None; + for iter |x| { + match result { + Some(ref mut y) => { + if x < *y { + *y = x; + } + } + None => result = Some(x) + } + } + result +} + #[cfg(test)] mod tests { use super::*; @@ -128,4 +203,22 @@ mod tests { assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f))); assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f))); } + + #[test] + fn test_find() { + let xs = ~[1u, 2, 3, 4, 5, 6]; + assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4); + } + + #[test] + fn test_max() { + let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + assert_eq!(max(|f| xs.each(f)).unwrap(), &15); + } + + #[test] + fn test_min() { + let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; + assert_eq!(min(|f| xs.each(f)).unwrap(), &-5); + } }