diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index 59ed352e1ee5a..7ae91aebed59b 100644
--- a/src/libcore/at_vec.rs
+++ b/src/libcore/at_vec.rs
@@ -4,7 +4,7 @@ import ptr::addr_of;
export init_op;
export capacity;
-export build_sized, build;
+export build_sized, build, build_sized_opt;
export map;
export from_fn, from_elem;
export unsafe;
@@ -78,6 +78,24 @@ pure fn build(builder: fn(push: pure fn(+A))) -> @[A] {
build_sized(4, builder)
}
+/**
+ * Builds a vector by calling a provided function with an argument
+ * function that pushes an element to the back of a vector.
+ * This version takes an initial size for the vector.
+ *
+ * # Arguments
+ *
+ * * size - An option, maybe containing initial size of the vector to reserve
+ * * builder - A function that will construct the vector. It recieves
+ * as an argument a function that will push an element
+ * onto the vector being constructed.
+ */
+#[inline(always)]
+pure fn build_sized_opt(size: option,
+ builder: fn(push: pure fn(+A))) -> @[A] {
+ build_sized(size.get_default(4), builder)
+}
+
// Appending
#[inline(always)]
pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] {
diff --git a/src/libcore/core.rs b/src/libcore/core.rs
index 1fb831b46fa70..2f7ae426517a5 100644
--- a/src/libcore/core.rs
+++ b/src/libcore/core.rs
@@ -8,7 +8,7 @@ import Path = path::Path;
import tuple::{TupleOps, ExtendedTupleOps};
import str::{StrSlice, UniqueStr};
import vec::{ConstVector, CopyableVector, ImmutableVector};
-import vec::{ImmutableCopyableVector, IterTraitExtensions};
+import vec::{ImmutableCopyableVector};
import iter::{BaseIter, ExtendedIter, CopyableIter, Times, TimesIx};
import num::Num;
import ptr::Ptr;
diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs
index 9ebfec47c7c81..cce13589bd5a7 100644
--- a/src/libcore/int-template.rs
+++ b/src/libcore/int-template.rs
@@ -95,7 +95,7 @@ impl T: iter::Times {
will execute the given function exactly x times. If we assume that \
`x` is an int, this is functionally equivalent to \
`for int::range(0, x) |_i| { /* anything */ }`."]
- fn times(it: fn() -> bool) {
+ pure fn times(it: fn() -> bool) {
if self < 0 {
fail fmt!{"The .times method expects a nonnegative number, \
but found %?", self};
@@ -111,7 +111,7 @@ impl T: iter::Times {
impl T: iter::TimesIx {
#[inline(always)]
/// Like `times`, but provides an index
- fn timesi(it: fn(uint) -> bool) {
+ pure fn timesi(it: fn(uint) -> bool) {
let slf = self as uint;
if slf < 0u {
fail fmt!{"The .timesi method expects a nonnegative number, \
diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs
index 5aeb958f5b22b..80ec6ce6feefd 100644
--- a/src/libcore/iter-trait.rs
+++ b/src/libcore/iter-trait.rs
@@ -6,43 +6,39 @@ import inst::{IMPL_T, EACH, SIZE_HINT};
export extensions;
impl IMPL_T: iter::BaseIter {
- fn each(blk: fn(A) -> bool) { EACH(self, blk) }
- fn size_hint() -> option { SIZE_HINT(self) }
+ pure fn each(blk: fn(A) -> bool) { EACH(self, blk) }
+ pure fn size_hint() -> option { SIZE_HINT(self) }
}
impl IMPL_T: iter::ExtendedIter {
- 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(+b0: B, blk: fn(B, A) -> B) -> B {
+ pure fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
+ pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
+ pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
+ pure fn foldl(+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) }
- fn position(f: fn(A) -> bool) -> option {
+ pure fn contains(x: A) -> bool { iter::contains(self, x) }
+ pure fn count(x: A) -> uint { iter::count(self, x) }
+ pure fn position(f: fn(A) -> bool) -> option {
iter::position(self, f)
}
}
impl IMPL_T: iter::CopyableIter {
- fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
+ pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
iter::filter_to_vec(self, pred)
}
- fn map_to_vec(op: fn(A) -> B) -> ~[B] { iter::map_to_vec(self, op) }
- fn to_vec() -> ~[A] { iter::to_vec(self) }
+ pure fn map_to_vec(op: fn(A) -> B) -> ~[B] {
+ iter::map_to_vec(self, op)
+ }
+ pure fn to_vec() -> ~[A] { iter::to_vec(self) }
// FIXME--bug in resolve prevents this from working (#2611)
// fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] {
// iter::flat_map_to_vec(self, op)
// }
- fn min() -> A { iter::min(self) }
- fn max() -> A { iter::max(self) }
-
- fn find(p: fn(A) -> bool) -> option {
- for self.each |i| {
- if p(i) { return some(i) }
- }
- return none;
- }
+ pure fn min() -> A { iter::min(self) }
+ pure fn max() -> A { iter::max(self) }
+ pure fn find(p: fn(A) -> bool) -> option { iter::find(self, p) }
}
diff --git a/src/libcore/iter-trait/dlist.rs b/src/libcore/iter-trait/dlist.rs
index 91d6ffa765aa0..47ac9e7aa374a 100644
--- a/src/libcore/iter-trait/dlist.rs
+++ b/src/libcore/iter-trait/dlist.rs
@@ -29,6 +29,6 @@ pure fn EACH(self: IMPL_T, f: fn(A) -> bool) {
}
}
-fn SIZE_HINT(self: IMPL_T) -> option {
+pure fn SIZE_HINT(self: IMPL_T) -> option {
some(self.len())
}
diff --git a/src/libcore/iter-trait/dvec.rs b/src/libcore/iter-trait/dvec.rs
index 5c02f8b5deab3..045c52aa4fd4b 100644
--- a/src/libcore/iter-trait/dvec.rs
+++ b/src/libcore/iter-trait/dvec.rs
@@ -6,10 +6,10 @@ type IMPL_T = dvec::DVec;
*
* Attempts to access this dvec during iteration will fail.
*/
-fn EACH(self: IMPL_T, f: fn(A) -> bool) {
- self.swap(|v| { vec::each(v, f); v })
+pure fn EACH(self: IMPL_T, f: fn(A) -> bool) {
+ unsafe { self.swap(|v| { vec::each(v, f); v }) }
}
-fn SIZE_HINT(self: IMPL_T) -> option {
+pure fn SIZE_HINT(self: IMPL_T) -> option {
some(self.len())
}
diff --git a/src/libcore/iter-trait/option.rs b/src/libcore/iter-trait/option.rs
index 2bcb7bba56ef9..d0a502813db51 100644
--- a/src/libcore/iter-trait/option.rs
+++ b/src/libcore/iter-trait/option.rs
@@ -7,7 +7,7 @@ pure fn EACH(self: IMPL_T, f: fn(A) -> bool) {
}
}
-fn SIZE_HINT(self: IMPL_T) -> option {
+pure fn SIZE_HINT(self: IMPL_T) -> option {
match self {
none => some(0u),
some(_) => some(1u)
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 06a1c6c9fba83..b5b56756e11e9 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -1,35 +1,35 @@
trait BaseIter {
- fn each(blk: fn(A) -> bool);
- fn size_hint() -> option;
+ pure fn each(blk: fn(A) -> bool);
+ pure fn size_hint() -> option;
}
trait ExtendedIter {
- fn eachi(blk: fn(uint, A) -> bool);
- fn all(blk: fn(A) -> bool) -> bool;
- fn any(blk: fn(A) -> bool) -> bool;
- fn foldl(+b0: B, blk: fn(B, A) -> B) -> B;
- fn contains(x: A) -> bool;
- fn count(x: A) -> uint;
- fn position(f: fn(A) -> bool) -> option;
+ pure fn eachi(blk: fn(uint, A) -> bool);
+ pure fn all(blk: fn(A) -> bool) -> bool;
+ pure fn any(blk: fn(A) -> bool) -> bool;
+ pure fn foldl(+b0: B, blk: fn(B, A) -> B) -> B;
+ pure fn contains(x: A) -> bool;
+ pure fn count(x: A) -> uint;
+ pure fn position(f: fn(A) -> bool) -> option;
}
trait Times {
- fn times(it: fn() -> bool);
+ pure fn times(it: fn() -> bool);
}
trait TimesIx{
- fn timesi(it: fn(uint) -> bool);
+ pure fn timesi(it: fn(uint) -> bool);
}
trait CopyableIter {
- fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
- fn map_to_vec(op: fn(A) -> B) -> ~[B];
- fn to_vec() -> ~[A];
- fn min() -> A;
- fn max() -> A;
- fn find(p: fn(A) -> bool) -> option;
+ pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
+ pure fn map_to_vec(op: fn(A) -> B) -> ~[B];
+ pure fn to_vec() -> ~[A];
+ pure fn min() -> A;
+ pure fn max() -> A;
+ pure fn find(p: fn(A) -> bool) -> option;
}
-fn eachi>(self: IA, blk: fn(uint, A) -> bool) {
+pure fn eachi>(self: IA, blk: fn(uint, A) -> bool) {
let mut i = 0u;
for self.each |a| {
if !blk(i, a) { break; }
@@ -37,52 +37,51 @@ fn eachi>(self: IA, blk: fn(uint, A) -> bool) {
}
}
-fn all>(self: IA, blk: fn(A) -> bool) -> bool {
+pure fn all>(self: IA, blk: fn(A) -> bool) -> bool {
for self.each |a| {
if !blk(a) { return false; }
}
return true;
}
-fn any>(self: IA, blk: fn(A) -> bool) -> bool {
+pure fn any>(self: IA, blk: fn(A) -> bool) -> bool {
for self.each |a| {
if blk(a) { return true; }
}
return false;
}
-fn filter_to_vec>(self: IA,
+pure fn filter_to_vec>(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); }
+ do vec::build_sized_opt(self.size_hint()) |push| {
+ for self.each |a| {
+ if prd(a) { push(a); }
+ }
}
- return result;
}
-fn map_to_vec>(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));
+pure fn map_to_vec>(self: IA, op: fn(A) -> B)
+ -> ~[B] {
+ do vec::build_sized_opt(self.size_hint()) |push| {
+ for self.each |a| {
+ push(op(a));
+ }
}
- return result;
}
-fn flat_map_to_vec,IB:BaseIter>(
+pure fn flat_map_to_vec,IB:BaseIter>(
self: IA, op: fn(A) -> IB) -> ~[B] {
- let mut result = ~[];
- for self.each |a| {
- for op(a).each |b| {
- vec::push(result, b);
+ do vec::build |push| {
+ for self.each |a| {
+ for op(a).each |b| {
+ push(b);
+ }
}
}
- return result;
}
-fn foldl>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
+pure fn foldl>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
let mut b <- b0;
for self.each |a| {
b = blk(b, a);
@@ -90,18 +89,18 @@ fn foldl>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
return b;
}
-fn to_vec>(self: IA) -> ~[A] {
+pure fn to_vec>(self: IA) -> ~[A] {
foldl::(self, ~[], |r, a| vec::append(r, ~[a]))
}
-fn contains>(self: IA, x: A) -> bool {
+pure fn contains>(self: IA, x: A) -> bool {
for self.each |a| {
if a == x { return true; }
}
return false;
}
-fn count>(self: IA, x: A) -> uint {
+pure fn count>(self: IA, x: A) -> uint {
do foldl(self, 0u) |count, value| {
if value == x {
count + 1u
@@ -111,7 +110,7 @@ fn count>(self: IA, x: A) -> uint {
}
}
-fn position>(self: IA, f: fn(A) -> bool)
+pure fn position>(self: IA, f: fn(A) -> bool)
-> option {
let mut i = 0;
for self.each |a| {
@@ -125,7 +124,7 @@ fn position>(self: IA, f: fn(A) -> bool)
// iter interface, such as would provide "reach" in addition to "each". as is,
// it would have to be implemented with foldr, which is too inefficient.
-fn repeat(times: uint, blk: fn() -> bool) {
+pure fn repeat(times: uint, blk: fn() -> bool) {
let mut i = 0u;
while i < times {
if !blk() { break }
@@ -133,7 +132,7 @@ fn repeat(times: uint, blk: fn() -> bool) {
}
}
-fn min>(self: IA) -> A {
+pure fn min>(self: IA) -> A {
match do foldl::,IA>(self, none) |a, b| {
match a {
some(a_) if a_ < b => {
@@ -149,7 +148,7 @@ fn min>(self: IA) -> A {
}
}
-fn max>(self: IA) -> A {
+pure fn max>(self: IA) -> A {
match do foldl::,IA>(self, none) |a, b| {
match a {
some(a_) if a_ > b => {
@@ -165,6 +164,14 @@ fn max>(self: IA) -> A {
}
}
+pure fn find>(self: IA,
+ p: fn(A) -> bool) -> option {
+ for self.each |i| {
+ if p(i) { return some(i) }
+ }
+ return none;
+}
+
/*
#[test]
fn test_enumerate() {
diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs
index 8e2cdf65c4a2d..95e4edbba5ce4 100644
--- a/src/libcore/uint-template.rs
+++ b/src/libcore/uint-template.rs
@@ -87,7 +87,7 @@ impl T: iter::Times {
will execute the given function exactly x times. If we assume that \
`x` is an int, this is functionally equivalent to \
`for int::range(0, x) |_i| { /* anything */ }`."]
- fn times(it: fn() -> bool) {
+ pure fn times(it: fn() -> bool) {
let mut i = self;
while i > 0 {
if !it() { break }
@@ -99,7 +99,7 @@ impl T: iter::Times {
impl T: iter::TimesIx {
#[inline(always)]
/// Like `times`, but with an index, `eachi`-style.
- fn timesi(it: fn(uint) -> bool) {
+ pure fn timesi(it: fn(uint) -> bool) {
let slf = self as uint;
let mut i = 0u;
while i < slf {
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index daf36b21e6f53..2c36e6bb5a053 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -18,7 +18,7 @@ export len;
export from_fn;
export from_elem;
export from_slice;
-export build, build_sized;
+export build, build_sized, build_sized_opt;
export to_mut;
export from_mut;
export head;
@@ -259,6 +259,24 @@ pure fn build(builder: fn(push: pure fn(+A))) -> ~[A] {
build_sized(4, builder)
}
+/**
+ * Builds a vector by calling a provided function with an argument
+ * function that pushes an element to the back of a vector.
+ * This version takes an initial size for the vector.
+ *
+ * # Arguments
+ *
+ * * size - An option, maybe containing initial size of the vector to reserve
+ * * builder - A function that will construct the vector. It recieves
+ * as an argument a function that will push an element
+ * onto the vector being constructed.
+ */
+#[inline(always)]
+pure fn build_sized_opt(size: option,
+ builder: fn(push: pure fn(+A))) -> ~[A] {
+ build_sized(size.get_default(4), builder)
+}
+
/// Produces a mut vector from an immutable vector.
pure fn to_mut(+v: ~[T]) -> ~[mut T] {
unsafe { ::unsafe::transmute(v) }
@@ -1505,7 +1523,6 @@ impl &[T]: ImmutableVector {
trait ImmutableCopyableVector {
pure fn filter(f: fn(T) -> bool) -> ~[T];
- pure fn find(f: fn(T) -> bool) -> option;
pure fn rfind(f: fn(T) -> bool) -> option;
}
@@ -1520,15 +1537,6 @@ impl &[T]: ImmutableCopyableVector {
*/
#[inline]
pure fn filter(f: fn(T) -> bool) -> ~[T] { filter(self, f) }
- /**
- * Search for the first element that matches a given predicate
- *
- * Apply function `f` to each element of `v`, starting from the first.
- * When function `f` returns true then an option containing the element
- * is returned. If `f` matches no elements then none is returned.
- */
- #[inline]
- pure fn find(f: fn(T) -> bool) -> option { find(self, f) }
/**
* Search for the last element that matches a given predicate
*
@@ -1756,44 +1764,41 @@ mod u8 {
// required in the slice.
impl &[A]: iter::BaseIter {
- fn each(blk: fn(A) -> bool) { each(self, blk) }
- fn size_hint() -> option { some(len(self)) }
+ pure fn each(blk: fn(A) -> bool) { each(self, blk) }
+ pure fn size_hint() -> option { some(len(self)) }
}
impl &[A]: iter::ExtendedIter {
- 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(+b0: B, blk: fn(B, A) -> B) -> B {
+ pure fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
+ pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
+ pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
+ pure fn foldl(+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) }
- fn position(f: fn(A) -> bool) -> option { iter::position(self, f) }
-}
-
-trait IterTraitExtensions {
- fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
- fn map_to_vec(op: fn(A) -> B) -> ~[B];
- fn to_vec() -> ~[A];
- fn min() -> A;
- fn max() -> A;
+ pure fn contains(x: A) -> bool { iter::contains(self, x) }
+ pure fn count(x: A) -> uint { iter::count(self, x) }
+ pure fn position(f: fn(A) -> bool) -> option {
+ iter::position(self, f)
+ }
}
-impl &[A]: IterTraitExtensions {
- fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
+impl &[A]: iter::CopyableIter {
+ pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
iter::filter_to_vec(self, pred)
}
- fn map_to_vec(op: fn(A) -> B) -> ~[B] { iter::map_to_vec(self, op) }
- fn to_vec() -> ~[A] { iter::to_vec(self) }
+ pure fn map_to_vec(op: fn(A) -> B) -> ~[B] {
+ iter::map_to_vec(self, op)
+ }
+ pure fn to_vec() -> ~[A] { iter::to_vec(self) }
// FIXME--bug in resolve prevents this from working (#2611)
// fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] {
// iter::flat_map_to_vec(self, op)
// }
- fn min() -> A { iter::min(self) }
- fn max() -> A { iter::max(self) }
+ pure fn min() -> A { iter::min(self) }
+ pure fn max() -> A { iter::max(self) }
+ pure fn find(p: fn(A) -> bool) -> option { iter::find(self, p) }
}
// ___________________________________________________________________________