diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index 85fceabf0ac..3528f20cfb3 100644 --- a/src/librustc/util/enum_set.rs +++ b/src/librustc/util/enum_set.rs @@ -207,19 +207,19 @@ mod test { fn test_each() { let mut e1: EnumSet = EnumSet::empty(); - assert_eq!(~[], iter::to_vec(|f| e1.each(f))) + assert_eq!(~[], iter::FromIter::from_iter::(|f| e1.each(f))) e1.add(A); - assert_eq!(~[A], iter::to_vec(|f| e1.each(f))) + assert_eq!(~[A], iter::FromIter::from_iter::(|f| e1.each(f))) e1.add(C); - assert_eq!(~[A,C], iter::to_vec(|f| e1.each(f))) + assert_eq!(~[A,C], iter::FromIter::from_iter::(|f| e1.each(f))) e1.add(C); - assert_eq!(~[A,C], iter::to_vec(|f| e1.each(f))) + assert_eq!(~[A,C], iter::FromIter::from_iter::(|f| e1.each(f))) e1.add(B); - assert_eq!(~[A,B,C], iter::to_vec(|f| e1.each(f))) + assert_eq!(~[A,B,C], iter::FromIter::from_iter::(|f| e1.each(f))) } /////////////////////////////////////////////////////////////////////////// @@ -236,12 +236,12 @@ mod test { e2.add(C); let e_union = e1 | e2; - assert_eq!(~[A,B,C], iter::to_vec(|f| e_union.each(f))) + assert_eq!(~[A,B,C], iter::FromIter::from_iter::(|f| e_union.each(f))) let e_intersection = e1 & e2; - assert_eq!(~[C], iter::to_vec(|f| e_intersection.each(f))) + assert_eq!(~[C], iter::FromIter::from_iter::(|f| e_intersection.each(f))) let e_subtract = e1 - e2; - assert_eq!(~[A], iter::to_vec(|f| e_subtract.each(f))) + assert_eq!(~[A], iter::FromIter::from_iter::(|f| e_subtract.each(f))) } } diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index e5d79d79fce..8a0ec3ade4d 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -51,22 +51,18 @@ pub trait Times { fn times(&self, it: &fn() -> bool) -> bool; } -/** - * Transform an internal iterator into an owned vector. - * - * # Example: - * - * ~~~ {.rust} - * let xs = ~[1, 2, 3]; - * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) }; - * assert_eq!(xs, ys); - * ~~~ - */ -#[inline(always)] -pub fn to_vec(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { - let mut v = ~[]; - for iter |x| { v.push(x) } - v +#[allow(missing_doc)] +pub trait FromIter { + /// Build a container with elements from an internal iterator. + /// + /// # Example: + /// + /// ~~~ {.rust} + /// let xs = ~[1, 2, 3]; + /// let ys: ~[int] = do FromIter::from_iter |f| { xs.each(|x| f(*x)) }; + /// assert_eq!(xs, ys); + /// ~~~ + pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self; } /** @@ -262,9 +258,9 @@ mod tests { use uint; #[test] - fn test_to_vec() { + fn test_from_iter() { let xs = ~[1, 2, 3]; - let ys = do to_vec |f| { xs.each(|x| f(*x)) }; + let ys: ~[int] = do FromIter::from_iter |f| { xs.each(|x| f(*x)) }; assert_eq!(xs, ys); } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 780a5a827d1..7f723e44c2b 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -19,8 +19,12 @@ implementing the `Iterator` trait. use cmp; use iter; +use iter::{FromIter, Times}; use num::{Zero, One}; -use prelude::*; +use option::{Option, Some, None}; +use ops::{Add, Mul}; +use cmp::Ord; +use clone::Clone; /// An interface for dealing with "external iterators". These types of iterators /// can be resumed at any time as all state is stored internally as opposed to @@ -241,8 +245,8 @@ pub trait IteratorUtil { /// ~~~ fn advance(&mut self, f: &fn(A) -> bool) -> bool; - /// Loops through the entire iterator, accumulating all of the elements into - /// a vector. + /// Loops through the entire iterator, collecting all of the elements into + /// a container implementing `FromIter`. /// /// # Example /// @@ -250,10 +254,10 @@ pub trait IteratorUtil { /// use std::iterator::*; /// /// let a = [1, 2, 3, 4, 5]; - /// let b = a.iter().transform(|&x| x).to_vec(); + /// let b: ~[int] = a.iter().transform(|&x| x).collect(); /// assert!(a == b); /// ~~~ - fn to_vec(&mut self) -> ~[A]; + fn collect>(&mut self) -> B; /// Loops through `n` iterations, returning the `n`th element of the /// iterator. @@ -415,8 +419,8 @@ impl> IteratorUtil for T { } #[inline(always)] - fn to_vec(&mut self) -> ~[A] { - iter::to_vec::(|f| self.advance(f)) + fn collect>(&mut self) -> B { + FromIter::from_iter::(|f| self.advance(f)) } /// Return the `n`th item yielded by an iterator. @@ -870,9 +874,9 @@ mod tests { use uint; #[test] - fn test_counter_to_vec() { + fn test_counter_from_iter() { let mut it = Counter::new(0, 5).take(10); - let xs = iter::to_vec(|f| it.advance(f)); + let xs: ~[int] = iter::FromIter::from_iter::(|f| it.advance(f)); assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); } @@ -903,7 +907,7 @@ mod tests { fn test_filter_map() { let mut it = Counter::new(0u, 1u).take(10) .filter_map(|x: uint| if x.is_even() { Some(x*x) } else { None }); - assert_eq!(it.to_vec(), ~[0*0, 2*2, 4*4, 6*6, 8*8]); + assert_eq!(it.collect::<~[uint]>(), ~[0*0, 2*2, 4*4, 6*6, 8*8]); } #[test] @@ -1062,6 +1066,13 @@ mod tests { assert_eq!(v.slice(0, 0).iter().transform(|&x| x).min(), None); } + #[test] + fn test_collect() { + let a = ~[1, 2, 3, 4, 5]; + let b: ~[int] = a.iter().transform(|&x| x).collect(); + assert_eq!(a, b); + } + #[test] fn test_all() { let v = ~&[1, 2, 3, 4, 5]; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index ab8a699a502..bb10cec30ed 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -14,7 +14,7 @@ Many programming languages have a 'prelude': a particular subset of the libraries that come with the language. Every program imports the prelude by default. -For example, it would be annoying to add `use io::println;` to every single +For example, it would be annoying to add `use std::io::println;` to every single program, and the vast majority of Rust programs will wish to print to standard output. Therefore, it makes sense to import it into every program. @@ -49,7 +49,8 @@ pub use hash::Hash; pub use old_iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter}; pub use old_iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter}; pub use old_iter::{ExtendedMutableIter}; -pub use iter::Times; +pub use iter::{Times, FromIter}; +// FIXME: #5898 pub use iterator::{Iterator, IteratorUtil}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic}; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 80905bdaeab..8340b956b65 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -20,6 +20,7 @@ use clone::Clone; use old_iter::BaseIter; use old_iter; use iterator::Iterator; +use iter::FromIter; use kinds::Copy; use libc; use old_iter::CopyableIter; @@ -2996,6 +2997,15 @@ impl<'self, T> Iterator<&'self mut T> for MutVecIterator<'self, T> { } } +impl FromIter for ~[T]{ + #[inline(always)] + pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { + let mut v = ~[]; + for iter |x| { v.push(x) } + v + } +} + #[cfg(test)] mod tests { use option::{None, Option, Some};