remove extra::iter

This module provided adaptors for the old internal iterator protocol,
but they proved to be quite unreadable and are not generic enough to
handle borrowed pointers well.

Since Rust no longer defines an internal iteration protocol, I don't
think there's going to be any reuse via these adaptors.
This commit is contained in:
Daniel Micay 2013-08-05 23:43:06 -04:00
parent 40d11a5461
commit 8f9bbc476d
13 changed files with 17 additions and 348 deletions

View File

@ -544,7 +544,7 @@ an intermediate generation has already exited:
~~~
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# fn wait_for_a_while() { do 1000.times { task::yield() } }
# fn wait_for_a_while() { for _ in range(0, 1000u) { task::yield() } }
# do task::try::<int> {
do task::spawn_supervised {
do task::spawn_supervised {
@ -563,7 +563,7 @@ other at all, using `task::spawn_unlinked` for _isolated failure_.
~~~
# use std::task;
# fn random() -> uint { 100 }
# fn sleep_for(i: uint) { do i.times { task::yield() } }
# fn sleep_for(i: uint) { for _ in range(0, i) { task::yield() } }
# do task::try::<()> {
let (time1, time2) = (random(), random());
do task::spawn_unlinked {

View File

@ -1894,7 +1894,7 @@ struct TimeBomb {
impl Drop for TimeBomb {
fn drop(&self) {
do self.explosivity.times {
for _ in range(0, self.explosivity) {
println("blam!");
}
}

View File

@ -1,331 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*! Composable internal iterators
Internal iterators are functions implementing the protocol used by the `for` loop.
An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
tied to specific traits. For example:
~~~ {.rust}
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
~~~
An external iterator object implementing the interface in the `iterator` module can be used as an
internal iterator by calling the `advance` method. For example:
~~~ {.rust}
let xs = [0u, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut it = xs.iter().chain(ys.iter());
for &x: &uint in it {
println(x.to_str());
}
~~~
Internal iterators provide a subset of the functionality of an external iterator. It's not possible
to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
much easier to implement.
*/
use std::vec;
use std::cmp::Ord;
use std::option::{Option, Some, None};
use std::num::{One, Zero};
use std::ops::{Add, Mul};
#[allow(missing_doc)]
pub trait FromIter<T> {
/// 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.iter().advance(|x| f(*x)) };
/// assert_eq!(xs, ys);
/// ~~~
pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self;
}
/**
* Return true if `predicate` is true for any values yielded by an internal iterator.
*
* Example:
*
* ~~~ {.rust}
* let xs = ~[1u, 2, 3, 4, 5];
* assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
* assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
* ~~~
*/
#[inline]
pub fn any<T>(predicate: &fn(T) -> bool,
iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
do iter |x| {
predicate(x)
}
}
/**
* Return true if `predicate` is true for all values yielded by an internal iterator.
*
* # Example:
*
* ~~~ {.rust}
* assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
* assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
* ~~~
*/
#[inline]
pub fn all<T>(predicate: &fn(T) -> bool,
iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
// If we ever break, iter will return false, so this will only return true
// if predicate returns true for everything.
iter(|x| predicate(x))
}
/**
* Return the first element where `predicate` returns `true`. Return `None` if no element is found.
*
* # Example:
*
* ~~~ {.rust}
* let xs = ~[1u, 2, 3, 4, 5, 6];
* assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4);
* ~~~
*/
#[inline]
pub fn find<T>(predicate: &fn(&T) -> bool,
iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
let mut ret = None;
do iter |x| {
if predicate(&x) {
ret = Some(x);
false
} else { true }
};
ret
}
/**
* Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
*
* # Example:
*
* ~~~ {.rust}
* let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
* assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
* ~~~
*/
#[inline]
pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
let mut result = None;
do iter |x| {
match result {
Some(ref mut y) => {
if x > *y {
*y = x;
}
}
None => result = Some(x)
}
true
};
result
}
/**
* Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
*
* # Example:
*
* ~~~ {.rust}
* let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
* assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5);
* ~~~
*/
#[inline]
pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
let mut result = None;
do iter |x| {
match result {
Some(ref mut y) => {
if x < *y {
*y = x;
}
}
None => result = Some(x)
}
true
};
result
}
/**
* Reduce an iterator to an accumulated value.
*
* # Example:
*
* ~~~ {.rust}
* assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
* ~~~
*/
#[inline]
pub fn fold<T, U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T {
let mut result = start;
do iter |x| {
f(&mut result, x);
true
};
result
}
/**
* Reduce an iterator to an accumulated value.
*
* `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
* forces the iterator to yield borrowed pointers.
*
* # Example:
*
* ~~~ {.rust}
* fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
* fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
* }
* ~~~
*/
#[inline]
pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T {
let mut result = start;
do iter |x| {
f(&mut result, x);
true
};
result
}
/**
* Return the sum of the items yielding by an iterator.
*
* # Example:
*
* ~~~ {.rust}
* let xs: ~[int] = ~[1, 2, 3, 4];
* assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);
* ~~~
*/
#[inline]
pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
}
/**
* Return the product of the items yielded by an iterator.
*
* # Example:
*
* ~~~ {.rust}
* let xs: ~[int] = ~[1, 2, 3, 4];
* assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
* ~~~
*/
#[inline]
pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
}
impl<T> FromIter<T> for ~[T]{
#[inline]
pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
let mut v = ~[];
do iter |x| { v.push(x); true };
v
}
}
#[cfg(test)]
mod tests {
use super::*;
use prelude::*;
use int;
use uint;
#[test]
fn test_from_iter() {
let xs = ~[1, 2, 3];
let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) };
assert_eq!(xs, ys);
}
#[test]
fn test_any() {
let xs = ~[1u, 2, 3, 4, 5];
assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
}
#[test]
fn test_all() {
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.iter().advance(f)).unwrap(), 4);
}
#[test]
fn test_max() {
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
}
#[test]
fn test_min() {
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5);
}
#[test]
fn test_fold() {
assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
}
#[test]
fn test_sum() {
let xs: ~[int] = ~[1, 2, 3, 4];
assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);
}
#[test]
fn test_empty_sum() {
let xs: ~[int] = ~[];
assert_eq!(do sum |f| { xs.iter().advance(f) }, 0);
}
#[test]
fn test_product() {
let xs: ~[int] = ~[1, 2, 3, 4];
assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
}
#[test]
fn test_empty_product() {
let xs: ~[int] = ~[];
assert_eq!(do product |f| { xs.iter().advance(f) }, 1);
}
}

View File

@ -637,7 +637,7 @@ mod test {
let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc);
write_markdown(doc, writer_factory);
// We expect two pages to have been written
do 2.times {
for _ in range(0, 2u) {
po.recv();
}
}
@ -649,7 +649,7 @@ mod test {
~"#[link(name = \"core\")]; mod a { }");
let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc);
write_markdown(doc, writer_factory);
do 2.times {
for _ in range(0, 2u) {
let (page, markdown) = po.recv();
match page {
doc::CratePage(_) => {

View File

@ -59,7 +59,7 @@ impl Results {
{
let mut set = f();
do timed(&mut self.random_ints) {
do num_keys.times {
for _ in range(0, num_keys) {
set.insert((rng.next() as uint) % rand_cap);
}
}
@ -103,7 +103,7 @@ impl Results {
{
let mut set = f();
do timed(&mut self.random_strings) {
do num_keys.times {
for _ in range(0, num_keys) {
let s = uint::to_str(rng.next() as uint);
set.insert(s);
}

View File

@ -105,7 +105,7 @@ fn main() {
let symbols = [" ", "", "", "", "", ""];
let mut pixels = [0f32, ..256*256];
let n2d = ~Noise2DContext::new();
do 100.times {
for _ in range(0, 100u) {
for y in range(0, 256) {
for x in range(0, 256) {
let v = n2d.get(

View File

@ -169,7 +169,7 @@ fn rendezvous(nn: uint, set: ~[color]) {
let mut creatures_met = 0;
// set up meetings...
do nn.times {
for _ in range(0, nn) {
let fst_creature: CreatureInfo = from_creatures.recv();
let snd_creature: CreatureInfo = from_creatures.recv();

View File

@ -164,7 +164,7 @@ impl RandomFasta {
let chars_left = n % LINE_LEN;
let mut buf = [0, ..LINE_LEN + 1];
do lines.times {
for _ in range(0, lines) {
for i in range(0u, LINE_LEN) {
buf[i] = self.nextc();
}

View File

@ -54,7 +54,7 @@ impl Code {
fn unpack(&self, frame: i32) -> ~str {
let mut key = **self;
let mut result = ~[];
do (frame as uint).times {
for _ in range(0, frame) {
result.push(unpack_symbol((key as u8) & 3));
key >>= 2;
}
@ -251,7 +251,7 @@ fn generate_frequencies(frequencies: &mut Table,
let mut code = Code(0);
// Pull first frame.
do (frame as uint).times {
for _ in range(0, frame) {
code = code.push_char(input[0]);
input = next_char(input);
}

View File

@ -79,7 +79,7 @@ struct Planet {
fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: i32) {
let mut d = [ 0.0, ..3 ];
do (steps as uint).times {
for _ in range(0, steps) {
for i in range(0u, N_BODIES) {
for j in range(i + 1, N_BODIES) {
d[0] = bodies[i].x[0] - bodies[j].x[0];

View File

@ -56,7 +56,7 @@ fn main() {
let mut u = vec::from_elem(n, 1f64);
let mut v = u.clone();
let mut tmp = u.clone();
do 8.times {
for _ in range(0, 8u) {
mult_AtAv(u, v, tmp);
mult_AtAv(v, u, tmp);
}

View File

@ -32,7 +32,7 @@ fn main() {
}
fn run(repeat: int, depth: int) {
do (repeat as uint).times {
for _ in range(0, repeat) {
info!("starting %.4f", precise_time_s());
do task::try {
recurse_or_fail(depth, None)

View File

@ -32,7 +32,7 @@ fn grandchild_group(num_tasks: uint) {
let (po, ch) = stream();
let ch = SharedChan::new(ch);
do num_tasks.times {
for _ in range(0, num_tasks) {
let ch = ch.clone();
do task::spawn { // linked
ch.send(());
@ -41,7 +41,7 @@ fn grandchild_group(num_tasks: uint) {
}
}
error!("Grandchild group getting started");
do num_tasks.times {
for _ in range(0, num_tasks) {
// Make sure all above children are fully spawned; i.e., enlisted in
// their ancestor groups.
po.recv();