Skip to content

Commit 3fe05a9

Browse files
committed
Move most iter functionality to extra, fixes #7343
1 parent 0fc99f1 commit 3fe05a9

File tree

6 files changed

+345
-326
lines changed

6 files changed

+345
-326
lines changed

src/libextra/iter.rs

+328
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/*! Composable internal iterators
12+
13+
Internal iterators are functions implementing the protocol used by the `for` loop.
14+
15+
An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
16+
breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
17+
tied to specific traits. For example:
18+
19+
~~~ {.rust}
20+
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
21+
~~~
22+
23+
An external iterator object implementing the interface in the `iterator` module can be used as an
24+
internal iterator by calling the `advance` method. For example:
25+
26+
~~~ {.rust}
27+
let xs = [0u, 1, 2, 3, 4, 5];
28+
let ys = [30, 40, 50, 60];
29+
let mut it = xs.iter().chain(ys.iter());
30+
for it.advance |&x: &uint| {
31+
println(x.to_str());
32+
}
33+
~~~
34+
35+
Internal iterators provide a subset of the functionality of an external iterator. It's not possible
36+
to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
37+
much easier to implement.
38+
39+
*/
40+
41+
use std::vec;
42+
use std::cmp::Ord;
43+
use std::option::{Option, Some, None};
44+
use std::num::{One, Zero};
45+
use std::ops::{Add, Mul};
46+
47+
#[allow(missing_doc)]
48+
pub trait FromIter<T> {
49+
/// Build a container with elements from an internal iterator.
50+
///
51+
/// # Example:
52+
///
53+
/// ~~~ {.rust}
54+
/// let xs = ~[1, 2, 3];
55+
/// let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) };
56+
/// assert_eq!(xs, ys);
57+
/// ~~~
58+
pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self;
59+
}
60+
61+
/**
62+
* Return true if `predicate` is true for any values yielded by an internal iterator.
63+
*
64+
* Example:
65+
*
66+
* ~~~ {.rust}
67+
* let xs = ~[1u, 2, 3, 4, 5];
68+
* assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
69+
* assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
70+
* ~~~
71+
*/
72+
#[inline]
73+
pub fn any<T>(predicate: &fn(T) -> bool,
74+
iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
75+
for iter |x| {
76+
if predicate(x) {
77+
return true;
78+
}
79+
}
80+
return false;
81+
}
82+
83+
/**
84+
* Return true if `predicate` is true for all values yielded by an internal iterator.
85+
*
86+
* # Example:
87+
*
88+
* ~~~ {.rust}
89+
* assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
90+
* assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
91+
* ~~~
92+
*/
93+
#[inline]
94+
pub fn all<T>(predicate: &fn(T) -> bool,
95+
iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
96+
// If we ever break, iter will return false, so this will only return true
97+
// if predicate returns true for everything.
98+
iter(|x| predicate(x))
99+
}
100+
101+
/**
102+
* Return the first element where `predicate` returns `true`. Return `None` if no element is found.
103+
*
104+
* # Example:
105+
*
106+
* ~~~ {.rust}
107+
* let xs = ~[1u, 2, 3, 4, 5, 6];
108+
* assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4);
109+
* ~~~
110+
*/
111+
#[inline]
112+
pub fn find<T>(predicate: &fn(&T) -> bool,
113+
iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
114+
for iter |x| {
115+
if predicate(&x) {
116+
return Some(x);
117+
}
118+
}
119+
None
120+
}
121+
122+
/**
123+
* Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
124+
*
125+
* # Example:
126+
*
127+
* ~~~ {.rust}
128+
* let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
129+
* assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
130+
* ~~~
131+
*/
132+
#[inline]
133+
pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
134+
let mut result = None;
135+
for iter |x| {
136+
match result {
137+
Some(ref mut y) => {
138+
if x > *y {
139+
*y = x;
140+
}
141+
}
142+
None => result = Some(x)
143+
}
144+
}
145+
result
146+
}
147+
148+
/**
149+
* Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
150+
*
151+
* # Example:
152+
*
153+
* ~~~ {.rust}
154+
* let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
155+
* assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5);
156+
* ~~~
157+
*/
158+
#[inline]
159+
pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
160+
let mut result = None;
161+
for iter |x| {
162+
match result {
163+
Some(ref mut y) => {
164+
if x < *y {
165+
*y = x;
166+
}
167+
}
168+
None => result = Some(x)
169+
}
170+
}
171+
result
172+
}
173+
174+
/**
175+
* Reduce an iterator to an accumulated value.
176+
*
177+
* # Example:
178+
*
179+
* ~~~ {.rust}
180+
* assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
181+
* ~~~
182+
*/
183+
#[inline]
184+
pub fn fold<T, U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T {
185+
let mut result = start;
186+
for iter |x| {
187+
f(&mut result, x);
188+
}
189+
result
190+
}
191+
192+
/**
193+
* Reduce an iterator to an accumulated value.
194+
*
195+
* `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
196+
* forces the iterator to yield borrowed pointers.
197+
*
198+
* # Example:
199+
*
200+
* ~~~ {.rust}
201+
* fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
202+
* fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
203+
* }
204+
* ~~~
205+
*/
206+
#[inline]
207+
pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T {
208+
let mut result = start;
209+
for iter |x| {
210+
f(&mut result, x);
211+
}
212+
result
213+
}
214+
215+
/**
216+
* Return the sum of the items yielding by an iterator.
217+
*
218+
* # Example:
219+
*
220+
* ~~~ {.rust}
221+
* let xs: ~[int] = ~[1, 2, 3, 4];
222+
* assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);
223+
* ~~~
224+
*/
225+
#[inline]
226+
pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
227+
fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
228+
}
229+
230+
/**
231+
* Return the product of the items yielded by an iterator.
232+
*
233+
* # Example:
234+
*
235+
* ~~~ {.rust}
236+
* let xs: ~[int] = ~[1, 2, 3, 4];
237+
* assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
238+
* ~~~
239+
*/
240+
#[inline]
241+
pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
242+
fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
243+
}
244+
245+
impl<T> FromIter<T> for ~[T]{
246+
#[inline]
247+
pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
248+
let mut v = ~[];
249+
for iter |x| { v.push(x) }
250+
v
251+
}
252+
}
253+
254+
#[cfg(test)]
255+
mod tests {
256+
use super::*;
257+
use prelude::*;
258+
259+
use int;
260+
use uint;
261+
262+
#[test]
263+
fn test_from_iter() {
264+
let xs = ~[1, 2, 3];
265+
let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) };
266+
assert_eq!(xs, ys);
267+
}
268+
269+
#[test]
270+
fn test_any() {
271+
let xs = ~[1u, 2, 3, 4, 5];
272+
assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
273+
assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
274+
}
275+
276+
#[test]
277+
fn test_all() {
278+
assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f)));
279+
assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f)));
280+
}
281+
282+
#[test]
283+
fn test_find() {
284+
let xs = ~[1u, 2, 3, 4, 5, 6];
285+
assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4);
286+
}
287+
288+
#[test]
289+
fn test_max() {
290+
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
291+
assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
292+
}
293+
294+
#[test]
295+
fn test_min() {
296+
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
297+
assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5);
298+
}
299+
300+
#[test]
301+
fn test_fold() {
302+
assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
303+
}
304+
305+
#[test]
306+
fn test_sum() {
307+
let xs: ~[int] = ~[1, 2, 3, 4];
308+
assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);
309+
}
310+
311+
#[test]
312+
fn test_empty_sum() {
313+
let xs: ~[int] = ~[];
314+
assert_eq!(do sum |f| { xs.iter().advance(f) }, 0);
315+
}
316+
317+
#[test]
318+
fn test_product() {
319+
let xs: ~[int] = ~[1, 2, 3, 4];
320+
assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
321+
}
322+
323+
#[test]
324+
fn test_empty_product() {
325+
let xs: ~[int] = ~[];
326+
assert_eq!(do product |f| { xs.iter().advance(f) }, 1);
327+
}
328+
}

src/librustc/middle/ty.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use util::enum_set::{EnumSet, CLike};
2929
use std::cast;
3030
use std::cmp;
3131
use std::hashmap::{HashMap, HashSet};
32-
use std::iter;
3332
use std::ops;
3433
use std::ptr::to_unsafe_ptr;
3534
use std::to_bytes;
@@ -1752,7 +1751,7 @@ pub struct TypeContents {
17521751

17531752
impl TypeContents {
17541753
pub fn meets_bounds(&self, cx: ctxt, bbs: BuiltinBounds) -> bool {
1755-
iter::all(|bb| self.meets_bound(cx, bb), |f| bbs.each(f))
1754+
bbs.iter().all(|bb| self.meets_bound(cx, bb))
17561755
}
17571756

17581757
pub fn meets_bound(&self, cx: ctxt, bb: BuiltinBound) -> bool {

src/librustc/util/enum_set.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ impl<E:CLike> Iterator<E> for EnumSetIterator<E> {
135135
mod test {
136136

137137
use std::cast;
138-
use std::iter;
139138

140139
use util::enum_set::*;
141140

@@ -237,7 +236,7 @@ mod test {
237236
}
238237

239238
///////////////////////////////////////////////////////////////////////////
240-
// iterator
239+
// iter / each
241240

242241
#[test]
243242
fn test_iterator() {
@@ -263,15 +262,6 @@ mod test {
263262
assert_eq!(~[A,B,C], elems)
264263
}
265264

266-
fn collect(e: EnumSet<Foo>) -> ~[Foo] {
267-
let mut elems = ~[];
268-
e.each(|elem| {
269-
elems.push(elem);
270-
true
271-
});
272-
elems
273-
}
274-
275265
#[test]
276266
fn test_each() {
277267
let mut e1: EnumSet<Foo> = EnumSet::empty();
@@ -291,6 +281,15 @@ mod test {
291281
assert_eq!(~[A,B,C], collect(e1))
292282
}
293283

284+
fn collect(e: EnumSet<Foo>) -> ~[Foo] {
285+
let mut elems = ~[];
286+
e.each(|elem| {
287+
elems.push(elem);
288+
true
289+
});
290+
elems
291+
}
292+
294293
///////////////////////////////////////////////////////////////////////////
295294
// operators
296295

0 commit comments

Comments
 (0)