new, simpler approach to the iter library
This commit is contained in:
parent
5eca3c2210
commit
e348567f77
@ -42,6 +42,9 @@ export extfmt;
|
|||||||
export tuple;
|
export tuple;
|
||||||
export to_str;
|
export to_str;
|
||||||
|
|
||||||
|
// NDM seems to be necessary for resolve to work
|
||||||
|
export vec_iter, option_iter;
|
||||||
|
|
||||||
// FIXME: This creates some APIs that I do not want to commit to. It is
|
// FIXME: This creates some APIs that I do not want to commit to. It is
|
||||||
// currently exported for the uv code in std, but when that code moves into
|
// currently exported for the uv code in std, but when that code moves into
|
||||||
// core this should become unexported
|
// core this should become unexported
|
||||||
@ -144,16 +147,25 @@ mod f64;
|
|||||||
mod str;
|
mod str;
|
||||||
mod ptr;
|
mod ptr;
|
||||||
mod vec;
|
mod vec;
|
||||||
|
#[path="iter-trait"]
|
||||||
|
mod vec_iter {
|
||||||
|
#[path = "vec.rs"]
|
||||||
|
mod inst;
|
||||||
|
}
|
||||||
mod bool;
|
mod bool;
|
||||||
mod tuple;
|
mod tuple;
|
||||||
|
|
||||||
|
|
||||||
// Ubiquitous-utility-type modules
|
// Ubiquitous-utility-type modules
|
||||||
|
|
||||||
mod either;
|
mod either;
|
||||||
mod iter;
|
mod iter;
|
||||||
mod logging;
|
mod logging;
|
||||||
mod option;
|
mod option;
|
||||||
|
#[path="iter-trait"]
|
||||||
|
mod option_iter {
|
||||||
|
#[path = "option.rs"]
|
||||||
|
mod inst;
|
||||||
|
}
|
||||||
mod result;
|
mod result;
|
||||||
mod to_str;
|
mod to_str;
|
||||||
|
|
||||||
@ -195,5 +207,4 @@ mod cmath;
|
|||||||
// indent-tabs-mode: nil
|
// indent-tabs-mode: nil
|
||||||
// c-basic-offset: 4
|
// c-basic-offset: 4
|
||||||
// buffer-file-coding-system: utf-8-unix
|
// buffer-file-coding-system: utf-8-unix
|
||||||
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
||||||
// End:
|
// End:
|
||||||
|
@ -7,7 +7,9 @@ import option = option::option;
|
|||||||
import path = path::path;
|
import path = path::path;
|
||||||
import str::extensions;
|
import str::extensions;
|
||||||
import vec::extensions;
|
import vec::extensions;
|
||||||
|
import vec_iter::extensions;
|
||||||
import option::extensions;
|
import option::extensions;
|
||||||
|
import option_iter::extensions;
|
||||||
import ptr::extensions;
|
import ptr::extensions;
|
||||||
|
|
||||||
export path, option, some, none, unreachable;
|
export path, option, some, none, unreachable;
|
||||||
|
35
src/libcore/iter-trait.rs
Normal file
35
src/libcore/iter-trait.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// This makes use of a clever hack that brson came up with to
|
||||||
|
// workaround our lack of traits and lack of macros. See core.{rc,rs} for
|
||||||
|
// how this file is used.
|
||||||
|
|
||||||
|
import inst::{IMPL_T, EACH, SIZE_HINT};
|
||||||
|
export extensions;
|
||||||
|
|
||||||
|
impl extensions<A> of iter::base_iter<A> for IMPL_T<A> {
|
||||||
|
fn each(blk: fn(A) -> bool) { EACH(self, blk) }
|
||||||
|
fn size_hint() -> option<uint> { SIZE_HINT(self) }
|
||||||
|
fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
|
||||||
|
fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
|
||||||
|
fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
|
||||||
|
fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
|
||||||
|
iter::foldl(self, b0, blk)
|
||||||
|
}
|
||||||
|
fn contains(x: A) -> bool { iter::contains(self, x) }
|
||||||
|
fn count(x: A) -> uint { iter::count(self, x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl extensions<A:copy> for IMPL_T<A> {
|
||||||
|
fn filter_to_vec(pred: fn(A) -> bool) -> [A] {
|
||||||
|
iter::filter_to_vec(self, pred)
|
||||||
|
}
|
||||||
|
fn map_to_vec<B>(op: fn(A) -> B) -> [B] { iter::map_to_vec(self, op) }
|
||||||
|
fn to_vec() -> [A] { iter::to_vec(self) }
|
||||||
|
|
||||||
|
// FIXME--bug in resolve prevents this from working
|
||||||
|
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> [B] {
|
||||||
|
// iter::flat_map_to_vec(self, op)
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn min() -> A { iter::min(self) }
|
||||||
|
fn max() -> A { iter::max(self) }
|
||||||
|
}
|
15
src/libcore/iter-trait/option.rs
Normal file
15
src/libcore/iter-trait/option.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
type IMPL_T<A> = option<A>;
|
||||||
|
|
||||||
|
fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
|
||||||
|
alt self {
|
||||||
|
none { }
|
||||||
|
some(a) { f(a); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
|
||||||
|
alt self {
|
||||||
|
none { some(0u) }
|
||||||
|
some(_) { some(1u) }
|
||||||
|
}
|
||||||
|
}
|
9
src/libcore/iter-trait/vec.rs
Normal file
9
src/libcore/iter-trait/vec.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
type IMPL_T<A> = [const A];
|
||||||
|
|
||||||
|
fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
|
||||||
|
vec::each(self, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
|
||||||
|
some(vec::len(self))
|
||||||
|
}
|
@ -1,115 +1,81 @@
|
|||||||
iface iterable<A> {
|
iface base_iter<A> {
|
||||||
fn iter(blk: fn(A));
|
fn each(blk: fn(A) -> bool);
|
||||||
|
fn size_hint() -> option<uint>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> of iterable<A> for fn@(fn(A)) {
|
fn eachi<A,IA:base_iter<A>>(self: IA, blk: fn(uint, A) -> bool) {
|
||||||
fn iter(blk: fn(A)) {
|
|
||||||
self(blk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// accomodate the fact that int/uint are passed by value by default:
|
|
||||||
impl of iterable<int> for fn@(fn(int)) {
|
|
||||||
fn iter(blk: fn(&&int)) {
|
|
||||||
self {|i| blk(i)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl of iterable<uint> for fn@(fn(uint)) {
|
|
||||||
fn iter(blk: fn(&&uint)) {
|
|
||||||
self {|i| blk(i)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A> of iterable<A> for [A] {
|
|
||||||
fn iter(blk: fn(A)) {
|
|
||||||
vec::iter(self, blk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A> of iterable<A> for option<A> {
|
|
||||||
fn iter(blk: fn(A)) {
|
|
||||||
option::iter(self, blk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl of iterable<char> for str {
|
|
||||||
fn iter(blk: fn(&&char)) {
|
|
||||||
str::chars_iter(self) { |ch| blk(ch) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enumerate<A,IA:iterable<A>>(self: IA, blk: fn(uint, A)) {
|
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
self.iter {|a|
|
for self.each {|a|
|
||||||
blk(i, a);
|
if !blk(i, a) { break; }
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here: we have to use fn@ for predicates and map functions, because
|
fn all<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
|
||||||
// we will be binding them up into a closure. Disappointing. A true
|
for self.each {|a|
|
||||||
// region type system might be able to do better than this.
|
if !blk(a) { ret false; }
|
||||||
|
|
||||||
fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
|
|
||||||
self.iter {|a|
|
|
||||||
if prd(a) { blk(a) }
|
|
||||||
}
|
}
|
||||||
|
ret true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> option<B>,
|
fn any<A,IA:base_iter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
|
||||||
blk: fn(B)) {
|
for self.each {|a|
|
||||||
self.iter {|a|
|
if blk(a) { ret true; }
|
||||||
alt cnv(a) {
|
}
|
||||||
some(b) { blk(b) }
|
ret false;
|
||||||
none { }
|
}
|
||||||
|
|
||||||
|
fn filter_to_vec<A:copy,IA:base_iter<A>>(self: IA,
|
||||||
|
prd: fn(A) -> bool) -> [A] {
|
||||||
|
let mut result = [];
|
||||||
|
self.size_hint().iter {|hint| vec::reserve(result, hint); }
|
||||||
|
for self.each {|a|
|
||||||
|
if prd(a) { vec::push(result, a); }
|
||||||
|
}
|
||||||
|
ret result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_to_vec<A:copy,B,IA:base_iter<A>>(self: IA, op: fn(A) -> B) -> [B] {
|
||||||
|
let mut result = [];
|
||||||
|
self.size_hint().iter {|hint| vec::reserve(result, hint); }
|
||||||
|
for self.each {|a|
|
||||||
|
vec::push(result, op(a));
|
||||||
|
}
|
||||||
|
ret result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flat_map_to_vec<A:copy,B:copy,IA:base_iter<A>,IB:base_iter<B>>(
|
||||||
|
self: IA, op: fn(A) -> IB) -> [B] {
|
||||||
|
|
||||||
|
let mut result = [];
|
||||||
|
for self.each {|a|
|
||||||
|
for op(a).each {|b|
|
||||||
|
vec::push(result, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
|
fn foldl<A,B,IA:base_iter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
|
||||||
self.iter {|a|
|
|
||||||
let b = cnv(a);
|
|
||||||
blk(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
|
|
||||||
self: IA, cnv: fn@(A) -> IB, blk: fn(B)) {
|
|
||||||
self.iter {|a|
|
|
||||||
cnv(a).iter(blk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foldl<A,B,IA:iterable<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
|
|
||||||
let mut b <- b0;
|
let mut b <- b0;
|
||||||
self.iter {|a|
|
for self.each {|a|
|
||||||
b <- blk(b, a);
|
b = blk(b, a);
|
||||||
}
|
}
|
||||||
ret b;
|
ret b;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foldr<A:copy,B,IA:iterable<A>>(
|
fn to_vec<A:copy,IA:base_iter<A>>(self: IA) -> [A] {
|
||||||
self: IA, +b0: B, blk: fn(A, B) -> B) -> B {
|
|
||||||
|
|
||||||
let mut b <- b0;
|
|
||||||
reversed(self) {|a|
|
|
||||||
b <- blk(a, b);
|
|
||||||
}
|
|
||||||
ret b;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_vec<A:copy,IA:iterable<A>>(self: IA) -> [A] {
|
|
||||||
foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
|
foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This could be made more efficient with an riterable interface
|
fn contains<A,IA:base_iter<A>>(self: IA, x: A) -> bool {
|
||||||
// #2005
|
for self.each {|a|
|
||||||
fn reversed<A:copy,IA:iterable<A>>(self: IA, blk: fn(A)) {
|
if a == x { ret true; }
|
||||||
vec::riter(to_vec(self), blk)
|
}
|
||||||
|
ret false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count<A,IA:iterable<A>>(self: IA, x: A) -> uint {
|
fn count<A,IA:base_iter<A>>(self: IA, x: A) -> uint {
|
||||||
foldl(self, 0u) {|count, value|
|
foldl(self, 0u) {|count, value|
|
||||||
if value == x {
|
if value == x {
|
||||||
count + 1u
|
count + 1u
|
||||||
@ -127,7 +93,7 @@ fn repeat(times: uint, blk: fn()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min<A:copy,IA:iterable<A>>(self: IA) -> A {
|
fn min<A:copy,IA:base_iter<A>>(self: IA) -> A {
|
||||||
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
|
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
|
||||||
alt a {
|
alt a {
|
||||||
some(a_) if a_ < b {
|
some(a_) if a_ < b {
|
||||||
@ -143,7 +109,7 @@ fn min<A:copy,IA:iterable<A>>(self: IA) -> A {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max<A:copy,IA:iterable<A>>(self: IA) -> A {
|
fn max<A:copy,IA:base_iter<A>>(self: IA) -> A {
|
||||||
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
|
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
|
||||||
alt a {
|
alt a {
|
||||||
some(a_) if a_ > b {
|
some(a_) if a_ > b {
|
||||||
@ -159,6 +125,7 @@ fn max<A:copy,IA:iterable<A>>(self: IA) -> A {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn test_enumerate() {
|
fn test_enumerate() {
|
||||||
enumerate(["0", "1", "2"]) {|i,j|
|
enumerate(["0", "1", "2"]) {|i,j|
|
||||||
@ -296,4 +263,5 @@ fn test_foldr() {
|
|||||||
}
|
}
|
||||||
let sum = foldr([1, 2, 3, 4], 0, sub);
|
let sum = foldr([1, 2, 3, 4], 0, sub);
|
||||||
assert sum == -2;
|
assert sum == -2;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -101,23 +101,6 @@ impl extensions<T:copy> for option<T> {
|
|||||||
#[doc = "Performs an operation on the contained value or does nothing"]
|
#[doc = "Performs an operation on the contained value or does nothing"]
|
||||||
fn iter(f: fn(T)) { iter(self, f) }
|
fn iter(f: fn(T)) { iter(self, f) }
|
||||||
|
|
||||||
#[doc = "Converts `none` to a zero-element list and `some` to a \
|
|
||||||
one-element list."]
|
|
||||||
fn to_vec() -> [T] {
|
|
||||||
alt self {
|
|
||||||
some(t) { [t] }
|
|
||||||
none { [] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc = "Performs an operation on the contained value or does nothing"]
|
|
||||||
fn each(f: fn(T) -> bool) {
|
|
||||||
alt self {
|
|
||||||
none { /* ok */ }
|
|
||||||
some(e) { f(e); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc = "
|
#[doc = "
|
||||||
Gets the value out of an option
|
Gets the value out of an option
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ holds.
|
|||||||
Apply function `f` to each element of `v` and return a vector containing
|
Apply function `f` to each element of `v` and return a vector containing
|
||||||
only those elements for which `f` returned true.
|
only those elements for which `f` returned true.
|
||||||
"]
|
"]
|
||||||
fn filter<T: copy>(v: [T], f: fn(T) -> bool) -> [T] {
|
fn filter<T: copy>(v: [const T], f: fn(T) -> bool) -> [T] {
|
||||||
let mut result = [];
|
let mut result = [];
|
||||||
for each(v) {|elem|
|
for each(v) {|elem|
|
||||||
if f(elem) { result += [elem]; }
|
if f(elem) { result += [elem]; }
|
||||||
@ -970,23 +970,6 @@ fn unpack_slice<T,U>(s: [const T]/&, f: fn(*T, uint) -> U) -> U unsafe {
|
|||||||
|
|
||||||
#[doc = "Extension methods for vectors"]
|
#[doc = "Extension methods for vectors"]
|
||||||
impl extensions<T> for [const T] {
|
impl extensions<T> for [const T] {
|
||||||
#[doc = "
|
|
||||||
Return true if a vector contains an element with the given value
|
|
||||||
"]
|
|
||||||
#[inline]
|
|
||||||
fn contains(x: T) -> bool { contains(self, x) }
|
|
||||||
#[doc = "Returns the number of elements that are equal to a given value"]
|
|
||||||
#[inline]
|
|
||||||
fn count(x: T) -> uint { count(self, x) }
|
|
||||||
#[doc = "Iterates over a vector, with option to break"]
|
|
||||||
#[inline]
|
|
||||||
fn each<T>(f: fn(T) -> bool) { each(self, f) }
|
|
||||||
#[doc = "Iterates over a vector's elements and indices"]
|
|
||||||
#[inline]
|
|
||||||
fn eachi<T>(f: fn(uint, T) -> bool) { eachi(self, f) }
|
|
||||||
#[doc = "Reduce a vector from left to right"]
|
|
||||||
#[inline]
|
|
||||||
fn foldl<U: copy>(z: U, p: fn(U, T) -> U) -> U { foldl(z, self, p) }
|
|
||||||
#[doc = "Reduce a vector from right to left"]
|
#[doc = "Reduce a vector from right to left"]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn foldr<U: copy>(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) }
|
fn foldr<U: copy>(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) }
|
||||||
@ -1059,6 +1042,15 @@ impl extensions<T> for [const T] {
|
|||||||
|
|
||||||
#[doc = "Extension methods for vectors"]
|
#[doc = "Extension methods for vectors"]
|
||||||
impl extensions<T: copy> for [const T] {
|
impl extensions<T: copy> for [const T] {
|
||||||
|
#[doc = "
|
||||||
|
Construct a new vector from the elements of a vector for which some
|
||||||
|
predicate holds.
|
||||||
|
|
||||||
|
Apply function `f` to each element of `v` and return a vector containing
|
||||||
|
only those elements for which `f` returned true.
|
||||||
|
"]
|
||||||
|
#[inline]
|
||||||
|
fn filter(f: fn(T) -> bool) -> [T] { filter(self, f) }
|
||||||
#[doc = "
|
#[doc = "
|
||||||
Search for the first element that matches a given predicate
|
Search for the first element that matches a given predicate
|
||||||
|
|
||||||
@ -1099,19 +1091,16 @@ impl extensions<T: copy> for [const T] {
|
|||||||
#[doc = "Extension methods for vectors"]
|
#[doc = "Extension methods for vectors"]
|
||||||
impl extensions<T> for [T] {
|
impl extensions<T> for [T] {
|
||||||
#[doc = "
|
#[doc = "
|
||||||
Return true if a predicate matches all elements
|
Apply a function to each element of a vector and return the results
|
||||||
|
|
||||||
If the vector contains no elements then true is returned.
|
|
||||||
"]
|
"]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn all(f: fn(T) -> bool) -> bool { all(self, f) }
|
fn map<U>(f: fn(T) -> U) -> [U] { map(self, f) }
|
||||||
#[doc = "
|
#[doc = "
|
||||||
Return true if a predicate matches any elements
|
Apply a function to each element of a vector and return a concatenation
|
||||||
|
of each result vector
|
||||||
If the vector contains no elements then false is returned.
|
|
||||||
"]
|
"]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn any(f: fn(T) -> bool) -> bool { any(self, f) }
|
fn flat_map<U>(f: fn(T) -> [U]) -> [U] { flat_map(self, f) }
|
||||||
#[doc = "
|
#[doc = "
|
||||||
Apply a function to each element of a vector and return the results
|
Apply a function to each element of a vector and return the results
|
||||||
|
|
||||||
@ -1122,32 +1111,8 @@ impl extensions<T> for [T] {
|
|||||||
fn filter_map<U: copy>(f: fn(T) -> option<U>) -> [U] {
|
fn filter_map<U: copy>(f: fn(T) -> option<U>) -> [U] {
|
||||||
filter_map(self, f)
|
filter_map(self, f)
|
||||||
}
|
}
|
||||||
#[doc = "
|
|
||||||
Apply a function eo each element of a vector and return a concatenation
|
|
||||||
of each result vector
|
|
||||||
"]
|
|
||||||
#[inline]
|
|
||||||
fn flat_map<U>(f: fn(T) -> [U]) -> [U] { flat_map(self, f) }
|
|
||||||
#[doc = "
|
|
||||||
Apply a function to each element of a vector and return the results
|
|
||||||
"]
|
|
||||||
#[inline]
|
|
||||||
fn map<U>(f: fn(T) -> U) -> [U] { map(self, f) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = "Extension methods for vectors"]
|
|
||||||
impl extensions<T: copy> for [T] {
|
|
||||||
#[doc = "
|
|
||||||
Construct a new vector from the elements of a vector for which some
|
|
||||||
predicate holds.
|
|
||||||
|
|
||||||
Apply function `f` to each element of `v` and return a vector containing
|
|
||||||
only those elements for which `f` returned true.
|
|
||||||
"]
|
|
||||||
#[inline]
|
|
||||||
fn filter(f: fn(T) -> bool) -> [T] { filter(self, f) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc = "Unsafe operations"]
|
#[doc = "Unsafe operations"]
|
||||||
mod unsafe {
|
mod unsafe {
|
||||||
// FIXME: This should have crate visibility (#1893 blocks that)
|
// FIXME: This should have crate visibility (#1893 blocks that)
|
||||||
|
@ -7,14 +7,14 @@ fn start(+token: int) {
|
|||||||
import iter::*;
|
import iter::*;
|
||||||
|
|
||||||
let p = comm::port();
|
let p = comm::port();
|
||||||
let ch = iter::foldl(bind int::range(2, n_threads + 1, _),
|
let mut ch = comm::chan(p);
|
||||||
comm::chan(p)) { |ch, i|
|
int::range(2, n_threads + 1) { |i|
|
||||||
let id = n_threads + 2 - i;
|
let id = n_threads + 2 - i;
|
||||||
let to_child = task::spawn_listener::<int> {|p|
|
let to_child = task::spawn_listener::<int> {|p|
|
||||||
roundtrip(id, p, ch)
|
roundtrip(id, p, ch)
|
||||||
};
|
};
|
||||||
to_child
|
ch = to_child;
|
||||||
};
|
}
|
||||||
comm::send(ch, token);
|
comm::send(ch, token);
|
||||||
roundtrip(1, p, ch);
|
roundtrip(1, p, ch);
|
||||||
}
|
}
|
||||||
|
17
src/test/compile-fail/lub-in-args.rs
Normal file
17
src/test/compile-fail/lub-in-args.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
fn two_args<T>(x: T, y: T) { }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: [mut int] = [mut 3];
|
||||||
|
let y: [int] = [3];
|
||||||
|
let a: @mut int = @mut 3;
|
||||||
|
let b: @int = @3;
|
||||||
|
|
||||||
|
// NOTE:
|
||||||
|
//
|
||||||
|
// The fact that this test fails to compile reflects a known
|
||||||
|
// shortcoming of the current inference algorithm. These errors
|
||||||
|
// are *not* desirable.
|
||||||
|
|
||||||
|
two_args(x, y); //! ERROR (values differ in mutability)
|
||||||
|
two_args(a, b); //! ERROR (values differ in mutability)
|
||||||
|
}
|
@ -1,10 +1,40 @@
|
|||||||
import iter::*;
|
// This test had to do with an outdated version of the iterable iface.
|
||||||
|
// However, the condition it was testing seemed complex enough to
|
||||||
|
// warrant still having a test, so I inlined the old definitions.
|
||||||
|
|
||||||
|
iface iterable<A> {
|
||||||
|
fn iter(blk: fn(A));
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> of iterable<A> for fn@(fn(A)) {
|
||||||
|
fn iter(blk: fn(A)) { self(blk); }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl of iterable<uint> for fn@(fn(uint)) {
|
||||||
|
fn iter(blk: fn(&&uint)) { self { |i| blk(i) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
|
||||||
|
self.iter {|a|
|
||||||
|
if prd(a) { blk(a) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foldl<A,B,IA:iterable<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
|
||||||
|
let mut b <- b0;
|
||||||
|
self.iter { |a|
|
||||||
|
b <- blk(b, a);
|
||||||
|
}
|
||||||
|
ret b;
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let range = bind uint::range(0u, 1000u, _);
|
let range = bind uint::range(0u, 1000u, _);
|
||||||
let filt = bind iter::filter(range, {|&&n: uint|
|
let filt = bind filter(
|
||||||
n % 3u != 0u && n % 5u != 0u }, _);
|
range,
|
||||||
let sum = iter::foldl(filt, 0u) {|accum, &&n: uint| accum + n };
|
{|&&n: uint| n % 3u != 0u && n % 5u != 0u },
|
||||||
|
_);
|
||||||
|
let sum = foldl(filt, 0u) {|accum, &&n: uint| accum + n };
|
||||||
|
|
||||||
io::println(#fmt("%u", sum));
|
io::println(#fmt("%u", sum));
|
||||||
}
|
}
|
11
src/test/run-pass/iter-all.rs
Normal file
11
src/test/run-pass/iter-all.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fn is_even(&&x: uint) -> bool { (x % 2u) == 0u }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert ![1u, 2u].all(is_even);
|
||||||
|
assert [2u, 4u].all(is_even);
|
||||||
|
assert [].all(is_even);
|
||||||
|
|
||||||
|
assert !some(1u).all(is_even);
|
||||||
|
assert some(2u).all(is_even);
|
||||||
|
assert none.all(is_even);
|
||||||
|
}
|
11
src/test/run-pass/iter-any.rs
Normal file
11
src/test/run-pass/iter-any.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fn is_even(&&x: uint) -> bool { (x % 2u) == 0u }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert ![1u, 3u].any(is_even);
|
||||||
|
assert [1u, 2u].any(is_even);
|
||||||
|
assert ![].any(is_even);
|
||||||
|
|
||||||
|
assert !some(1u).any(is_even);
|
||||||
|
assert some(2u).any(is_even);
|
||||||
|
assert !none.any(is_even);
|
||||||
|
}
|
10
src/test/run-pass/iter-contains.rs
Normal file
10
src/test/run-pass/iter-contains.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fn main() {
|
||||||
|
assert [].contains(22u) == false;
|
||||||
|
assert [1u, 3u].contains(22u) == false;
|
||||||
|
assert [22u, 1u, 3u].contains(22u) == true;
|
||||||
|
assert [1u, 22u, 3u].contains(22u) == true;
|
||||||
|
assert [1u, 3u, 22u].contains(22u) == true;
|
||||||
|
assert none.contains(22u) == false;
|
||||||
|
assert some(1u).contains(22u) == false;
|
||||||
|
assert some(22u).contains(22u) == true;
|
||||||
|
}
|
9
src/test/run-pass/iter-count.rs
Normal file
9
src/test/run-pass/iter-count.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn main() {
|
||||||
|
assert [].count(22u) == 0u;
|
||||||
|
assert [1u, 3u].count(22u) == 0u;
|
||||||
|
assert [22u, 1u, 3u].count(22u) == 1u;
|
||||||
|
assert [22u, 1u, 22u].count(22u) == 2u;
|
||||||
|
assert none.count(22u) == 0u;
|
||||||
|
assert some(1u).count(22u) == 0u;
|
||||||
|
assert some(22u).count(22u) == 1u;
|
||||||
|
}
|
18
src/test/run-pass/iter-eachi.rs
Normal file
18
src/test/run-pass/iter-eachi.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
fn main() {
|
||||||
|
let mut c = 0u;
|
||||||
|
for [1u, 2u, 3u, 4u, 5u].eachi { |i, v|
|
||||||
|
assert (i + 1u) == v;
|
||||||
|
c += 1u;
|
||||||
|
}
|
||||||
|
assert c == 5u;
|
||||||
|
|
||||||
|
for none::<uint>.eachi { |i, v| fail; }
|
||||||
|
|
||||||
|
let mut c = 0u;
|
||||||
|
for some(1u).eachi { |i, v|
|
||||||
|
assert (i + 1u) == v;
|
||||||
|
c += 1u;
|
||||||
|
}
|
||||||
|
assert c == 1u;
|
||||||
|
|
||||||
|
}
|
9
src/test/run-pass/iter-filter-to-vec.rs
Normal file
9
src/test/run-pass/iter-filter-to-vec.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn is_even(&&x: uint) -> bool { (x % 2u) == 0u }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert [1u, 3u].filter_to_vec(is_even) == [];
|
||||||
|
assert [1u, 2u, 3u].filter_to_vec(is_even) == [2u];
|
||||||
|
assert none.filter_to_vec(is_even) == [];
|
||||||
|
assert some(1u).filter_to_vec(is_even) == [];
|
||||||
|
assert some(2u).filter_to_vec(is_even) == [2u];
|
||||||
|
}
|
21
src/test/run-pass/iter-flat-map-to-vec.rs
Normal file
21
src/test/run-pass/iter-flat-map-to-vec.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// xfail-test -- flat_map_to_vec currently disable
|
||||||
|
|
||||||
|
fn repeat(&&x: uint) -> [uint] { [x, x] }
|
||||||
|
|
||||||
|
fn incd_if_even(&&x: uint) -> option<uint> {
|
||||||
|
if (x % 2u) == 0u {some(x + 1u)} else {none}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert [1u, 3u].flat_map_to_vec(repeat) == [1u, 1u, 3u, 3u];
|
||||||
|
assert [].flat_map_to_vec(repeat) == [];
|
||||||
|
assert none.flat_map_to_vec(repeat) == [];
|
||||||
|
assert some(1u).flat_map_to_vec(repeat) == [1u, 1u];
|
||||||
|
assert some(2u).flat_map_to_vec(repeat) == [2u, 2u];
|
||||||
|
|
||||||
|
assert [1u, 2u, 5u].flat_map_to_vec(incd_if_even) == [3u];
|
||||||
|
assert [].flat_map_to_vec(incd_if_even) == [];
|
||||||
|
assert none.flat_map_to_vec(incd_if_even) == [];
|
||||||
|
assert some(1u).flat_map_to_vec(incd_if_even) == [];
|
||||||
|
assert some(2u).flat_map_to_vec(incd_if_even) == [3u];
|
||||||
|
}
|
9
src/test/run-pass/iter-foldl.rs
Normal file
9
src/test/run-pass/iter-foldl.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn add(&&x: float, &&y: uint) -> float { x + (y as float) }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert [1u, 3u].foldl(20f, add) == 24f;
|
||||||
|
assert [].foldl(20f, add) == 20f;
|
||||||
|
assert none.foldl(20f, add) == 20f;
|
||||||
|
assert some(1u).foldl(20f, add) == 21f;
|
||||||
|
assert some(2u).foldl(20f, add) == 22f;
|
||||||
|
}
|
9
src/test/run-pass/iter-map-to-vec.rs
Normal file
9
src/test/run-pass/iter-map-to-vec.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn inc(&&x: uint) -> uint { x + 1u }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert [1u, 3u].map_to_vec(inc) == [2u, 4u];
|
||||||
|
assert [1u, 2u, 3u].map_to_vec(inc) == [2u, 3u, 4u];
|
||||||
|
assert none.map_to_vec(inc) == [];
|
||||||
|
assert some(1u).map_to_vec(inc) == [2u];
|
||||||
|
assert some(2u).map_to_vec(inc) == [3u];
|
||||||
|
}
|
11
src/test/run-pass/iter-min-max.rs
Normal file
11
src/test/run-pass/iter-min-max.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fn is_even(&&x: uint) -> bool { (x % 2u) == 0u }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert [1u, 3u].min() == 1u;
|
||||||
|
assert [3u, 1u].min() == 1u;
|
||||||
|
assert some(1u).min() == 1u;
|
||||||
|
|
||||||
|
assert [1u, 3u].max() == 3u;
|
||||||
|
assert [3u, 1u].max() == 3u;
|
||||||
|
assert some(3u).max() == 3u;
|
||||||
|
}
|
7
src/test/run-pass/iter-to-vec.rs
Normal file
7
src/test/run-pass/iter-to-vec.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
assert [1u, 3u].to_vec() == [1u, 3u];
|
||||||
|
assert [].to_vec() == [];
|
||||||
|
assert none.to_vec() == [];
|
||||||
|
assert some(1u).to_vec() == [1u];
|
||||||
|
assert some(2u).to_vec() == [2u];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user