about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/at_vec.rs20
-rw-r--r--src/libcore/core.rs2
-rw-r--r--src/libcore/int-template.rs4
-rw-r--r--src/libcore/iter-trait.rs38
-rw-r--r--src/libcore/iter-trait/dlist.rs2
-rw-r--r--src/libcore/iter-trait/dvec.rs6
-rw-r--r--src/libcore/iter-trait/option.rs2
-rw-r--r--src/libcore/iter.rs99
-rw-r--r--src/libcore/uint-template.rs4
-rw-r--r--src/libcore/vec.rs73
10 files changed, 138 insertions, 112 deletions
diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index 59ed352e1ee..7ae91aebed5 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<A>(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<A>(size: option<uint>,
+                           builder: fn(push: pure fn(+A))) -> @[A] {
+    build_sized(size.get_default(4), builder)
+}
+
 // Appending
 #[inline(always)]
 pure fn append<T: copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
diff --git a/src/libcore/core.rs b/src/libcore/core.rs
index 1fb831b46fa..2f7ae426517 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 9ebfec47c7c..cce13589bd5 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 5aeb958f5b2..80ec6ce6fee 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<A> IMPL_T<A>: iter::BaseIter<A> {
-    fn each(blk: fn(A) -> bool) { EACH(self, blk) }
-    fn size_hint() -> option<uint> { SIZE_HINT(self) }
+    pure fn each(blk: fn(A) -> bool) { EACH(self, blk) }
+    pure fn size_hint() -> option<uint> { SIZE_HINT(self) }
 }
 
 impl<A> IMPL_T<A>: iter::ExtendedIter<A> {
-    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 {
+    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<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) }
-    fn position(f: fn(A) -> bool) -> option<uint> {
+    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<uint> {
         iter::position(self, f)
     }
 }
 
 impl<A: copy> IMPL_T<A>: iter::CopyableIter<A> {
-    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<B>(op: fn(A) -> B) -> ~[B] { iter::map_to_vec(self, op) }
-    fn to_vec() -> ~[A] { iter::to_vec(self) }
+    pure fn map_to_vec<B>(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<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) }
-
-    fn find(p: fn(A) -> bool) -> option<A> {
-        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<A> { iter::find(self, p) }
 }
diff --git a/src/libcore/iter-trait/dlist.rs b/src/libcore/iter-trait/dlist.rs
index 91d6ffa765a..47ac9e7aa37 100644
--- a/src/libcore/iter-trait/dlist.rs
+++ b/src/libcore/iter-trait/dlist.rs
@@ -29,6 +29,6 @@ pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
     }
 }
 
-fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
+pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
     some(self.len())
 }
diff --git a/src/libcore/iter-trait/dvec.rs b/src/libcore/iter-trait/dvec.rs
index 5c02f8b5dea..045c52aa4fd 100644
--- a/src/libcore/iter-trait/dvec.rs
+++ b/src/libcore/iter-trait/dvec.rs
@@ -6,10 +6,10 @@ type IMPL_T<A> = dvec::DVec<A>;
  *
  * Attempts to access this dvec during iteration will fail.
  */
-fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
-    self.swap(|v| { vec::each(v, f); v })
+pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
+    unsafe { self.swap(|v| { vec::each(v, f); v }) }
 }
 
-fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
+pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
     some(self.len())
 }
diff --git a/src/libcore/iter-trait/option.rs b/src/libcore/iter-trait/option.rs
index 2bcb7bba56e..d0a502813db 100644
--- a/src/libcore/iter-trait/option.rs
+++ b/src/libcore/iter-trait/option.rs
@@ -7,7 +7,7 @@ pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
     }
 }
 
-fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
+pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> option<uint> {
     match self {
       none => some(0u),
       some(_) => some(1u)
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 06a1c6c9fba..b5b56756e11 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -1,35 +1,35 @@
 trait BaseIter<A> {
-    fn each(blk: fn(A) -> bool);
-    fn size_hint() -> option<uint>;
+    pure fn each(blk: fn(A) -> bool);
+    pure fn size_hint() -> option<uint>;
 }
 
 trait ExtendedIter<A> {
-    fn eachi(blk: fn(uint, A) -> bool);
-    fn all(blk: fn(A) -> bool) -> bool;
-    fn any(blk: fn(A) -> bool) -> bool;
-    fn foldl<B>(+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<uint>;
+    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<B>(+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<uint>;
 }
 
 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<A:copy> {
-    fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
-    fn map_to_vec<B>(op: fn(A) -> B) -> ~[B];
-    fn to_vec() -> ~[A];
-    fn min() -> A;
-    fn max() -> A;
-    fn find(p: fn(A) -> bool) -> option<A>;
+    pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
+    pure fn map_to_vec<B>(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<A>;
 }
 
-fn eachi<A,IA:BaseIter<A>>(self: IA, blk: fn(uint, A) -> bool) {
+pure fn eachi<A,IA:BaseIter<A>>(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<A,IA:BaseIter<A>>(self: IA, blk: fn(uint, A) -> bool) {
     }
 }
 
-fn all<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
+pure fn all<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
     for self.each |a| {
         if !blk(a) { return false; }
     }
     return true;
 }
 
-fn any<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
+pure fn any<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
     for self.each |a| {
         if blk(a) { return true; }
     }
     return false;
 }
 
-fn filter_to_vec<A:copy,IA:BaseIter<A>>(self: IA,
+pure fn filter_to_vec<A:copy,IA:BaseIter<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); }
+    do vec::build_sized_opt(self.size_hint()) |push| {
+        for self.each |a| {
+            if prd(a) { push(a); }
+        }
     }
-    return result;
 }
 
-fn map_to_vec<A:copy,B,IA:BaseIter<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));
+pure fn map_to_vec<A:copy,B,IA:BaseIter<A>>(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<A:copy,B:copy,IA:BaseIter<A>,IB:BaseIter<B>>(
+pure fn flat_map_to_vec<A:copy,B:copy,IA:BaseIter<A>,IB:BaseIter<B>>(
     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<A,B,IA:BaseIter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
+pure fn foldl<A,B,IA:BaseIter<A>>(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<A,B,IA:BaseIter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
     return b;
 }
 
-fn to_vec<A:copy,IA:BaseIter<A>>(self: IA) -> ~[A] {
+pure fn to_vec<A:copy,IA:BaseIter<A>>(self: IA) -> ~[A] {
     foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(r, ~[a]))
 }
 
-fn contains<A,IA:BaseIter<A>>(self: IA, x: A) -> bool {
+pure fn contains<A,IA:BaseIter<A>>(self: IA, x: A) -> bool {
     for self.each |a| {
         if a == x { return true; }
     }
     return false;
 }
 
-fn count<A,IA:BaseIter<A>>(self: IA, x: A) -> uint {
+pure fn count<A,IA:BaseIter<A>>(self: IA, x: A) -> uint {
     do foldl(self, 0u) |count, value| {
         if value == x {
             count + 1u
@@ -111,7 +110,7 @@ fn count<A,IA:BaseIter<A>>(self: IA, x: A) -> uint {
     }
 }
 
-fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
+pure fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
         -> option<uint> {
     let mut i = 0;
     for self.each |a| {
@@ -125,7 +124,7 @@ fn position<A,IA:BaseIter<A>>(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<A:copy,IA:BaseIter<A>>(self: IA) -> A {
+pure fn min<A:copy,IA:BaseIter<A>>(self: IA) -> A {
     match do foldl::<A,option<A>,IA>(self, none) |a, b| {
         match a {
           some(a_) if a_ < b => {
@@ -149,7 +148,7 @@ fn min<A:copy,IA:BaseIter<A>>(self: IA) -> A {
     }
 }
 
-fn max<A:copy,IA:BaseIter<A>>(self: IA) -> A {
+pure fn max<A:copy,IA:BaseIter<A>>(self: IA) -> A {
     match do foldl::<A,option<A>,IA>(self, none) |a, b| {
         match a {
           some(a_) if a_ > b => {
@@ -165,6 +164,14 @@ fn max<A:copy,IA:BaseIter<A>>(self: IA) -> A {
     }
 }
 
+pure fn find<A: copy,IA:BaseIter<A>>(self: IA,
+                                     p: fn(A) -> bool) -> option<A> {
+    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 8e2cdf65c4a..95e4edbba5c 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 daf36b21e6f..2c36e6bb5a0 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<A>(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<A>(size: option<uint>,
+                           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<T>(+v: ~[T]) -> ~[mut T] {
     unsafe { ::unsafe::transmute(v) }
@@ -1505,7 +1523,6 @@ impl<T> &[T]: ImmutableVector<T> {
 
 trait ImmutableCopyableVector<T> {
     pure fn filter(f: fn(T) -> bool) -> ~[T];
-    pure fn find(f: fn(T) -> bool) -> option<T>;
     pure fn rfind(f: fn(T) -> bool) -> option<T>;
 }
 
@@ -1521,15 +1538,6 @@ impl<T: copy> &[T]: ImmutableCopyableVector<T> {
     #[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<T> { find(self, f) }
-    /**
      * Search for the last element that matches a given predicate
      *
      * Apply function `f` to each element of `v` in reverse order. When
@@ -1756,44 +1764,41 @@ mod u8 {
 // required in the slice.
 
 impl<A> &[A]: iter::BaseIter<A> {
-    fn each(blk: fn(A) -> bool) { each(self, blk) }
-    fn size_hint() -> option<uint> { some(len(self)) }
+    pure fn each(blk: fn(A) -> bool) { each(self, blk) }
+    pure fn size_hint() -> option<uint> { some(len(self)) }
 }
 
 impl<A> &[A]: iter::ExtendedIter<A> {
-    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 {
+    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<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) }
-    fn position(f: fn(A) -> bool) -> option<uint> { iter::position(self, f) }
-}
-
-trait IterTraitExtensions<A> {
-    fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
-    fn map_to_vec<B>(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<uint> {
+        iter::position(self, f)
+    }
 }
 
-impl<A: copy> &[A]: IterTraitExtensions<A> {
-    fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
+impl<A: copy> &[A]: iter::CopyableIter<A> {
+    pure 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) }
+    pure fn map_to_vec<B>(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<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) }
+    pure fn min() -> A { iter::min(self) }
+    pure fn max() -> A { iter::max(self) }
+    pure fn find(p: fn(A) -> bool) -> option<A> { iter::find(self, p) }
 }
 // ___________________________________________________________________________