From af2086a2f1914f5e4db8534b6c0784b612f3a33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Mon, 3 Jun 2013 23:26:53 +0200 Subject: [PATCH 1/4] Added iter::FromIter --- src/libstd/iter.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index e5d79d79fcef3..fde27a6fc09d6 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -51,6 +51,29 @@ pub trait Times { fn times(&self, it: &fn() -> bool) -> bool; } +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; +} + +// NOTE: This should be in vec but can't because of coherence +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 + } +} + /** * Transform an internal iterator into an owned vector. * @@ -64,9 +87,7 @@ pub trait Times { */ #[inline(always)] pub fn to_vec(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { - let mut v = ~[]; - for iter |x| { v.push(x) } - v + FromIter::from_iter(iter) } /** @@ -268,6 +289,13 @@ mod tests { assert_eq!(xs, ys); } + #[test] + fn test_from_iter() { + let xs: ~[int] = ~[1, 2, 3]; + let ys: ~[int] = do FromIter::from_iter |f| { xs.each(|x| f(*x)) }; + assert_eq!(xs, ys); + } + #[test] fn test_any() { let xs = ~[1u, 2, 3, 4, 5]; From 857d433b9a300989f373f34771218895ec59715a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Mon, 3 Jun 2013 23:48:52 +0200 Subject: [PATCH 2/4] Added IteratorUtil::collect --- src/libstd/iterator.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 780a5a827d10c..14f161380aadf 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -19,6 +19,7 @@ implementing the `Iterator` trait. use cmp; use iter; +use iter::FromIter; use num::{Zero, One}; use prelude::*; @@ -255,6 +256,20 @@ pub trait IteratorUtil { /// ~~~ fn to_vec(&mut self) -> ~[A]; + /// Loops through the entire iterator, collecting all of the elements into + /// a container implementing `FromIter`. + /// + /// # Example + /// + /// ~~~ {.rust} + /// use std::iterator::*; + /// + /// let a = [1, 2, 3, 4, 5]; + /// let b: ~[int] = a.iter().transform(|&x| x).collect(); + /// assert!(a == b); + /// ~~~ + fn collect>(&mut self) -> B; + /// Loops through `n` iterations, returning the `n`th element of the /// iterator. /// @@ -419,6 +434,11 @@ impl> IteratorUtil for T { iter::to_vec::(|f| self.advance(f)) } + #[inline(always)] + fn collect>(&mut self) -> B { + FromIter::from_iter::(|f| self.advance(f)) + } + /// Return the `n`th item yielded by an iterator. #[inline(always)] fn nth(&mut self, mut n: uint) -> Option { @@ -1062,6 +1082,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]; From 070015468d014f93da2a366f7f5e37c0678f6c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Tue, 4 Jun 2013 10:06:24 +0200 Subject: [PATCH 3/4] Removed IteratorUtil::to_vec and iter::to_vec --- src/libstd/iter.rs | 44 +++++++++++------------------------------- src/libstd/iterator.rs | 19 ------------------ 2 files changed, 11 insertions(+), 52 deletions(-) diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index fde27a6fc09d6..9a50b8a67416d 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -51,16 +51,17 @@ pub trait Times { fn times(&self, it: &fn() -> bool) -> bool; } +#[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); - // ~~~ + /// 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; } @@ -74,22 +75,6 @@ impl FromIter for ~[T]{ } } -/** - * 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] { - FromIter::from_iter(iter) -} - /** * Return true if `predicate` is true for any values yielded by an internal iterator. * @@ -282,16 +267,9 @@ mod tests { use int; use uint; - #[test] - fn test_to_vec() { - let xs = ~[1, 2, 3]; - let ys = do to_vec |f| { xs.each(|x| f(*x)) }; - assert_eq!(xs, ys); - } - #[test] fn test_from_iter() { - let xs: ~[int] = ~[1, 2, 3]; + let xs: = ~[1, 2, 3]; 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 14f161380aadf..2a3bbc3322d2b 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -242,20 +242,6 @@ 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. - /// - /// # Example - /// - /// ~~~ {.rust} - /// use std::iterator::*; - /// - /// let a = [1, 2, 3, 4, 5]; - /// let b = a.iter().transform(|&x| x).to_vec(); - /// assert!(a == b); - /// ~~~ - fn to_vec(&mut self) -> ~[A]; - /// Loops through the entire iterator, collecting all of the elements into /// a container implementing `FromIter`. /// @@ -429,11 +415,6 @@ impl> IteratorUtil for T { } } - #[inline(always)] - fn to_vec(&mut self) -> ~[A] { - iter::to_vec::(|f| self.advance(f)) - } - #[inline(always)] fn collect>(&mut self) -> B { FromIter::from_iter::(|f| self.advance(f)) From cac489115458af3eed301d8d4f9c6c7d6779b058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Thu, 6 Jun 2013 22:34:50 +0200 Subject: [PATCH 4/4] Fixups --- src/librustc/util/enum_set.rs | 16 ++++++++-------- src/libstd/iter.rs | 12 +----------- src/libstd/iterator.rs | 15 +++++++++------ src/libstd/prelude.rs | 5 +++-- src/libstd/vec.rs | 10 ++++++++++ 5 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index 85fceabf0ac8f..3528f20cfb3cf 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 9a50b8a67416d..8a0ec3ade4d4e 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -65,16 +65,6 @@ pub trait FromIter { pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self; } -// NOTE: This should be in vec but can't because of coherence -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 - } -} - /** * Return true if `predicate` is true for any values yielded by an internal iterator. * @@ -269,7 +259,7 @@ mod tests { #[test] fn test_from_iter() { - let xs: = ~[1, 2, 3]; + let xs = ~[1, 2, 3]; 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 2a3bbc3322d2b..7f723e44c2b05 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -19,9 +19,12 @@ implementing the `Iterator` trait. use cmp; use iter; -use iter::FromIter; +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 @@ -871,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]); } @@ -904,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] @@ -1065,7 +1068,7 @@ mod tests { #[test] fn test_collect() { - let a = [1, 2, 3, 4, 5]; + let a = ~[1, 2, 3, 4, 5]; let b: ~[int] = a.iter().transform(|&x| x).collect(); assert_eq!(a, b); } diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index ab8a699a50299..bb10cec30edf7 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 80905bdaeab7e..8340b956b658f 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};