about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-08 10:25:15 -0700
committerbors <bors@rust-lang.org>2013-06-08 10:25:15 -0700
commitb8fa9d3be10e952fbcaf14f3098aebf13dedd7ec (patch)
treef99d1c8374844ccf7a3368110d3e33c0e51f18bb /src/libstd
parente2ec8e71cec0373616953f8188cf7c4953269af0 (diff)
parent98ba91f81bea38d8fc8bd5bc0cb44ac3e173a53c (diff)
downloadrust-b8fa9d3be10e952fbcaf14f3098aebf13dedd7ec.tar.gz
rust-b8fa9d3be10e952fbcaf14f3098aebf13dedd7ec.zip
auto merge of #7015 : huonw/rust/each-fn-kill, r=thestinger
Continuation of #6995/#6999.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs2
-rw-r--r--src/libstd/iter.rs1
-rw-r--r--src/libstd/iterator.rs21
-rw-r--r--src/libstd/ptr.rs2
-rw-r--r--src/libstd/rand.rs3
-rw-r--r--src/libstd/repr.rs3
-rw-r--r--src/libstd/str.rs438
-rw-r--r--src/libstd/str/ascii.rs6
-rw-r--r--src/libstd/sys.rs1
-rw-r--r--src/libstd/trie.rs1
-rw-r--r--src/libstd/unstable/lang.rs3
-rw-r--r--src/libstd/vec.rs523
12 files changed, 255 insertions, 749 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 23f901c23ed..a118e445fe2 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -286,8 +286,6 @@ pub mod raw {
 #[cfg(test)]
 mod test {
     use super::*;
-    use prelude::*;
-
     use uint;
 
     #[test]
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index 8a0ec3ade4d..4886588bb94 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -42,7 +42,6 @@ much easier to implement.
 
 use cmp::Ord;
 use option::{Option, Some, None};
-use vec::OwnedVector;
 use num::{One, Zero};
 use ops::{Add, Mul};
 
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index 4ed82f63b39..8803844fdd0 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -18,7 +18,6 @@ implementing the `Iterator` trait.
 */
 
 use cmp;
-use iter;
 use iter::{FromIter, Times};
 use num::{Zero, One};
 use option::{Option, Some, None};
@@ -326,7 +325,7 @@ pub trait IteratorUtil<A> {
     /// assert!(a.iter().all(|&x| *x > 0));
     /// assert!(!a.iter().all(|&x| *x > 2));
     /// ~~~
-    fn all(&mut self, f: &fn(&A) -> bool) -> bool;
+    fn all(&mut self, f: &fn(A) -> bool) -> bool;
 
     /// Tests whether any element of an iterator satisfies the specified
     /// predicate.
@@ -341,7 +340,7 @@ pub trait IteratorUtil<A> {
     /// assert!(it.any(|&x| *x == 3));
     /// assert!(!it.any(|&x| *x == 3));
     /// ~~~
-    fn any(&mut self, f: &fn(&A) -> bool) -> bool;
+    fn any(&mut self, f: &fn(A) -> bool) -> bool;
 }
 
 /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
@@ -462,14 +461,14 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
     fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) }
 
     #[inline(always)]
-    fn all(&mut self, f: &fn(&A) -> bool) -> bool {
-        for self.advance |x| { if !f(&x) { return false; } }
+    fn all(&mut self, f: &fn(A) -> bool) -> bool {
+        for self.advance |x| { if !f(x) { return false; } }
         return true;
     }
 
     #[inline(always)]
-    fn any(&mut self, f: &fn(&A) -> bool) -> bool {
-        for self.advance |x| { if f(&x) { return true; } }
+    fn any(&mut self, f: &fn(A) -> bool) -> bool {
+        for self.advance |x| { if f(x) { return true; } }
         return false;
     }
 }
@@ -1080,18 +1079,18 @@ mod tests {
     #[test]
     fn test_all() {
         let v = ~&[1, 2, 3, 4, 5];
-        assert!(v.iter().all(|&x| *x < 10));
+        assert!(v.iter().all(|&x| x < 10));
         assert!(!v.iter().all(|&x| x.is_even()));
-        assert!(!v.iter().all(|&x| *x > 100));
+        assert!(!v.iter().all(|&x| x > 100));
         assert!(v.slice(0, 0).iter().all(|_| fail!()));
     }
 
     #[test]
     fn test_any() {
         let v = ~&[1, 2, 3, 4, 5];
-        assert!(v.iter().any(|&x| *x < 10));
+        assert!(v.iter().any(|&x| x < 10));
         assert!(v.iter().any(|&x| x.is_even()));
-        assert!(!v.iter().any(|&x| *x > 100));
+        assert!(!v.iter().any(|&x| x > 100));
         assert!(!v.slice(0, 0).iter().any(|_| fail!()));
     }
 }
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index c8e2f58d801..e2cbf716dd1 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -11,8 +11,6 @@
 //! Unsafe pointer utility functions
 
 use cast;
-#[cfg(stage0)] use libc;
-#[cfg(stage0)] use libc::{c_void, size_t};
 use option::{Option, Some, None};
 use sys;
 use unstable::intrinsics;
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index b763c1c2d76..7946f7e4f13 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -43,6 +43,7 @@ fn main () {
 use cast;
 use cmp;
 use int;
+use iterator::IteratorUtil;
 use local_data;
 use prelude::*;
 use str;
@@ -479,7 +480,7 @@ impl<R: Rng> RngUtil for R {
     fn gen_char_from(&mut self, chars: &str) -> char {
         assert!(!chars.is_empty());
         let mut cs = ~[];
-        for str::each_char(chars) |c| { cs.push(c) }
+        for chars.iter().advance |c| { cs.push(c) }
         self.choose(cs)
     }
 
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index 14bec48782f..46f69d020d1 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -22,6 +22,7 @@ use intrinsic;
 use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
 use intrinsic::Opaque;
 use io::{Writer, WriterUtil};
+use iterator::IteratorUtil;
 use libc::c_void;
 use managed;
 use ptr;
@@ -209,7 +210,7 @@ impl ReprVisitor {
 
     pub fn write_escaped_slice(&self, slice: &str) {
         self.writer.write_char('"');
-        for slice.each_char |ch| {
+        for slice.iter().advance |ch| {
             self.writer.write_escaped_char(ch);
         }
         self.writer.write_char('"');
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 359c64c5f28..f9d11164995 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -25,7 +25,7 @@ use clone::Clone;
 use cmp::{TotalOrd, Ordering, Less, Equal, Greater};
 use container::Container;
 use iter::Times;
-use iterator::Iterator;
+use iterator::{Iterator, IteratorUtil};
 use libc;
 use option::{None, Option, Some};
 use old_iter::{BaseIter, EqIter};
@@ -35,7 +35,7 @@ use str;
 use to_str::ToStr;
 use uint;
 use vec;
-use vec::{OwnedVector, OwnedCopyableVector};
+use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector};
 
 #[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq};
 
@@ -608,11 +608,7 @@ pub fn byte_slice_no_callback<'a>(s: &'a str) -> &'a [u8] {
 
 /// Convert a string to a unique vector of characters
 pub fn to_chars(s: &str) -> ~[char] {
-    let mut buf = ~[];
-    for each_char(s) |c| {
-        buf.push(c);
-    }
-    buf
+    s.iter().collect()
 }
 
 /**
@@ -856,12 +852,12 @@ pub fn levdistance(s: &str, t: &str) -> uint {
 
     let mut dcol = vec::from_fn(tlen + 1, |x| x);
 
-    for s.each_chari |i, sc| {
+    for s.iter().enumerate().advance |(i, sc)| {
 
         let mut current = i;
         dcol[0] = current + 1;
 
-        for t.each_chari |j, tc| {
+        for t.iter().enumerate().advance |(j, tc)| {
 
             let next = dcol[j + 1];
 
@@ -943,7 +939,7 @@ pub fn each_split_within<'a>(ss: &'a str,
     let mut cont = true;
     let slice: &fn() = || { cont = it(slice(ss, slice_start, last_end)) };
 
-    let machine: &fn(uint, char) -> bool = |i, c| {
+    let machine: &fn((uint, char)) -> bool = |(i, c)| {
         let whitespace = if char::is_whitespace(c)       { Ws }       else { Cr };
         let limit      = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim };
 
@@ -968,12 +964,12 @@ pub fn each_split_within<'a>(ss: &'a str,
         cont
     };
 
-    str::each_chari(ss, machine);
+    ss.iter().enumerate().advance(machine);
 
     // Let the automaton 'run out' by supplying trailing whitespace
     let mut fake_i = ss.len();
     while cont && match state { B | C => true, A => false } {
-        machine(fake_i, ' ');
+        machine((fake_i, ' '));
         fake_i += 1;
     }
     return cont;
@@ -1247,97 +1243,12 @@ pub fn any(ss: &str, pred: &fn(char) -> bool) -> bool {
 pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str {
     let mut result = ~"";
     reserve(&mut result, len(ss));
-    for ss.each_char |cc| {
+    for ss.iter().advance |cc| {
         str::push_char(&mut result, ff(cc));
     }
     result
 }
 
-/// Iterate over the bytes in a string
-#[inline(always)]
-pub fn each(s: &str, it: &fn(u8) -> bool) -> bool {
-    eachi(s, |_i, b| it(b))
-}
-
-/// Iterate over the bytes in a string, with indices
-#[inline(always)]
-pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) -> bool {
-    let mut pos = 0;
-    let len = s.len();
-
-    while pos < len {
-        if !it(pos, s[pos]) { return false; }
-        pos += 1;
-    }
-    return true;
-}
-
-/// Iterate over the bytes in a string in reverse
-#[inline(always)]
-pub fn each_reverse(s: &str, it: &fn(u8) -> bool) -> bool {
-    eachi_reverse(s, |_i, b| it(b) )
-}
-
-/// Iterate over the bytes in a string in reverse, with indices
-#[inline(always)]
-pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) -> bool {
-    let mut pos = s.len();
-    while pos > 0 {
-        pos -= 1;
-        if !it(pos, s[pos]) { return false; }
-    }
-    return true;
-}
-
-/// Iterate over each char of a string, without allocating
-#[inline(always)]
-pub fn each_char(s: &str, it: &fn(char) -> bool) -> bool {
-    let mut i = 0;
-    let len = len(s);
-    while i < len {
-        let CharRange {ch, next} = char_range_at(s, i);
-        if !it(ch) { return false; }
-        i = next;
-    }
-    return true;
-}
-
-/// Iterates over the chars in a string, with indices
-#[inline(always)]
-pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) -> bool {
-    let mut pos = 0;
-    let mut ch_pos = 0u;
-    let len = s.len();
-    while pos < len {
-        let CharRange {ch, next} = char_range_at(s, pos);
-        pos = next;
-        if !it(ch_pos, ch) { return false; }
-        ch_pos += 1u;
-    }
-    return true;
-}
-
-/// Iterates over the chars in a string in reverse
-#[inline(always)]
-pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) -> bool {
-    each_chari_reverse(s, |_, c| it(c))
-}
-
-/// Iterates over the chars in a string in reverse, with indices
-#[inline(always)]
-pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) -> bool {
-    let mut pos = s.len();
-    let mut ch_pos = s.char_len();
-    while pos > 0 {
-        let CharRange {ch, next} = char_range_at_reverse(s, pos);
-        pos = next;
-        ch_pos -= 1;
-
-        if !it(ch_pos, ch) { return false; }
-    }
-    return true;
-}
-
 /*
 Section: Searching
 */
@@ -1657,7 +1568,7 @@ pub fn rfind_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) -> O
 // Utility used by various searching functions
 fn match_at<'a,'b>(haystack: &'a str, needle: &'b str, at: uint) -> bool {
     let mut i = at;
-    for each(needle) |c| { if haystack[i] != c { return false; } i += 1u; }
+    for needle.bytes_iter().advance |c| { if haystack[i] != c { return false; } i += 1u; }
     return true;
 }
 
@@ -1880,7 +1791,7 @@ pub fn is_utf16(v: &[u16]) -> bool {
 /// Converts to a vector of `u16` encoded as UTF-16
 pub fn to_utf16(s: &str) -> ~[u16] {
     let mut u = ~[];
-    for s.each_char |ch| {
+    for s.iter().advance |ch| {
         // Arithmetic with u32 literals is easier on the eyes than chars.
         let mut ch = ch as u32;
 
@@ -2396,7 +2307,7 @@ pub fn capacity(s: &const ~str) -> uint {
 pub fn escape_default(s: &str) -> ~str {
     let mut out: ~str = ~"";
     reserve_at_least(&mut out, str::len(s));
-    for s.each_char |c| {
+    for s.iter().advance |c| {
         push_str(&mut out, char::escape_default(c));
     }
     out
@@ -2406,7 +2317,7 @@ pub fn escape_default(s: &str) -> ~str {
 pub fn escape_unicode(s: &str) -> ~str {
     let mut out: ~str = ~"";
     reserve_at_least(&mut out, str::len(s));
-    for s.each_char |c| {
+    for s.iter().advance |c| {
         push_str(&mut out, char::escape_unicode(c));
     }
     out
@@ -2608,15 +2519,10 @@ pub trait StrSlice<'self> {
     fn any(&self, it: &fn(char) -> bool) -> bool;
     fn contains<'a>(&self, needle: &'a str) -> bool;
     fn contains_char(&self, needle: char) -> bool;
-    fn char_iter(&self) -> StrCharIterator<'self>;
-    fn each(&self, it: &fn(u8) -> bool) -> bool;
-    fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool;
-    fn each_reverse(&self, it: &fn(u8) -> bool) -> bool;
-    fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool;
-    fn each_char(&self, it: &fn(char) -> bool) -> bool;
-    fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool;
-    fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool;
-    fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool;
+    fn iter(&self) -> StrCharIterator<'self>;
+    fn rev_iter(&self) -> StrCharRevIterator<'self>;
+    fn bytes_iter(&self) -> StrBytesIterator<'self>;
+    fn bytes_rev_iter(&self) -> StrBytesRevIterator<'self>;
     fn ends_with(&self, needle: &str) -> bool;
     fn is_empty(&self) -> bool;
     fn is_whitespace(&self) -> bool;
@@ -2670,46 +2576,28 @@ impl<'self> StrSlice<'self> for &'self str {
     }
 
     #[inline]
-    fn char_iter(&self) -> StrCharIterator<'self> {
+    fn iter(&self) -> StrCharIterator<'self> {
         StrCharIterator {
             index: 0,
             string: *self
         }
     }
-
-    /// Iterate over the bytes in a string
-    #[inline]
-    fn each(&self, it: &fn(u8) -> bool) -> bool { each(*self, it) }
-    /// Iterate over the bytes in a string, with indices
-    #[inline]
-    fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool { eachi(*self, it) }
-    /// Iterate over the bytes in a string
-    #[inline]
-    fn each_reverse(&self, it: &fn(u8) -> bool) -> bool { each_reverse(*self, it) }
-    /// Iterate over the bytes in a string, with indices
-    #[inline]
-    fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool {
-        eachi_reverse(*self, it)
-    }
-    /// Iterate over the chars in a string
-    #[inline]
-    fn each_char(&self, it: &fn(char) -> bool) -> bool { each_char(*self, it) }
-    /// Iterate over the chars in a string, with indices
     #[inline]
-    fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool {
-        each_chari(*self, it)
+    fn rev_iter(&self) -> StrCharRevIterator<'self> {
+        StrCharRevIterator {
+            index: self.len(),
+            string: *self
+        }
     }
-    /// Iterate over the chars in a string in reverse
-    #[inline]
-    fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool {
-        each_char_reverse(*self, it)
+
+    fn bytes_iter(&self) -> StrBytesIterator<'self> {
+        StrBytesIterator { it: as_bytes_slice(*self).iter() }
     }
-    /// Iterate over the chars in a string in reverse, with indices from the
-    /// end
-    #[inline]
-    fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool {
-        each_chari_reverse(*self, it)
+    fn bytes_rev_iter(&self) -> StrBytesRevIterator<'self> {
+        StrBytesRevIterator { it: as_bytes_slice(*self).rev_iter() }
     }
+
+
     /// Returns true if one string ends with another
     #[inline]
     fn ends_with(&self, needle: &str) -> bool {
@@ -2880,9 +2768,55 @@ impl<'self> Iterator<char> for StrCharIterator<'self> {
         }
     }
 }
+/// External iterator for a string's characters in reverse order. Use
+/// with the `std::iterator` module.
+pub struct StrCharRevIterator<'self> {
+    priv index: uint,
+    priv string: &'self str,
+}
+
+impl<'self> Iterator<char> for StrCharRevIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<char> {
+        if self.index > 0 {
+            let CharRange {ch, next} = char_range_at_reverse(self.string, self.index);
+            self.index = next;
+            Some(ch)
+        } else {
+            None
+        }
+    }
+}
+
+/// External iterator for a string's bytes. Use with the `std::iterator`
+/// module.
+pub struct StrBytesIterator<'self> {
+    priv it: vec::VecIterator<'self, u8>
+}
+
+impl<'self> Iterator<u8> for StrBytesIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<u8> {
+        self.it.next().map_consume(|&x| x)
+    }
+}
+
+/// External iterator for a string's bytes in reverse order. Use with
+/// the `std::iterator` module.
+pub struct StrBytesRevIterator<'self> {
+    priv it: vec::VecRevIterator<'self, u8>
+}
+
+impl<'self> Iterator<u8> for StrBytesRevIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<u8> {
+        self.it.next().map_consume(|&x| x)
+    }
+}
 
 #[cfg(test)]
 mod tests {
+    use iterator::IteratorUtil;
     use container::Container;
     use char;
     use option::Some;
@@ -2977,7 +2911,7 @@ mod tests {
             let mut v = ~[];
             for each_split_char(s, c) |s| { v.push(s.to_owned()) }
             debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         t("abc.hello.there", '.', [~"abc", ~"hello", ~"there"]);
         t(".hello.there", '.', [~"", ~"hello", ~"there"]);
@@ -2995,7 +2929,7 @@ mod tests {
             let mut v = ~[];
             for each_split_char(s, c) |s| { v.push(s.to_owned()) }
             debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         let data = "ประเทศไทย中华Việt Nam";
         t(data, 'V', [~"ประเทศไทย中华", ~"iệt Nam"]);
@@ -3010,7 +2944,7 @@ mod tests {
             for each_splitn_char(s, c, n) |s| { v.push(s.to_owned()) }
             debug!("split_byte to: %?", v);
             debug!("comparing vs. %?", u);
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         t("abc.hello.there", '.', 0u, [~"abc.hello.there"]);
         t("abc.hello.there", '.', 1u, [~"abc", ~"hello.there"]);
@@ -3037,7 +2971,7 @@ mod tests {
             for each_splitn_char(s, c, n) |s| { v.push(s.to_owned()) }
             debug!("split_byte to: %?", v);
             debug!("comparing vs. %?", u);
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
 
         t("ประเทศไทย中华Việt Nam", '华', 1u, [~"ประเทศไทย中", ~"Việt Nam"]);
@@ -3055,7 +2989,7 @@ mod tests {
             for each_splitn_char(s, c, n) |s| { v.push(s.to_owned()) }
             debug!("split_byte to: %?", v);
             debug!("comparing vs. %?", u);
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         let data = "ประเทศไทย中华Việt Nam";
         t(data, 'V', 1u, [~"ประเทศไทย中华", ~"iệt Nam"]);
@@ -3069,7 +3003,7 @@ mod tests {
             let mut v = ~[];
             for each_split_char_no_trailing(s, c) |s| { v.push(s.to_owned()) }
             debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         t("abc.hello.there", '.', [~"abc", ~"hello", ~"there"]);
         t(".hello.there", '.', [~"", ~"hello", ~"there"]);
@@ -3088,7 +3022,7 @@ mod tests {
             let mut v = ~[];
             for each_split_char_no_trailing(s, c) |s| { v.push(s.to_owned()) }
             debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         let data = "ประเทศไทย中华Việt Nam";
         t(data, 'V', [~"ประเทศไทย中华", ~"iệt Nam"]);
@@ -3100,7 +3034,7 @@ mod tests {
         fn t<'a>(s: &str, sep: &'a str, u: &[~str]) {
             let mut v = ~[];
             for each_split_str(s, sep) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         t("--1233345--", "12345", [~"--1233345--"]);
         t("abc::hello::there", "::", [~"abc", ~"hello", ~"there"]);
@@ -3124,7 +3058,7 @@ mod tests {
         fn t(s: &str, sepf: &fn(char) -> bool, u: &[~str]) {
             let mut v = ~[];
             for each_split(s, sepf) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
 
         t("ประเทศไทย中华Việt Nam", |cc| cc == '华', [~"ประเทศไทย中", ~"Việt Nam"]);
@@ -3140,7 +3074,7 @@ mod tests {
         fn t(s: &str, sepf: &fn(char) -> bool, u: &[~str]) {
             let mut v = ~[];
             for each_split_no_trailing(s, sepf) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
 
         t("ประเทศไทย中华Việt Nam", |cc| cc == '华', [~"ประเทศไทย中", ~"Việt Nam"]);
@@ -3159,7 +3093,7 @@ mod tests {
         fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) {
             let mut v = ~[];
             for f(s) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
 
         t(lf, each_line, [~"", ~"Mary had a little lamb", ~"Little lamb"]);
@@ -3179,7 +3113,7 @@ mod tests {
         fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) {
             let mut v = ~[];
             for f(s) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         let data = "\nMary had a little lamb\nLittle lamb\n";
 
@@ -3193,7 +3127,7 @@ mod tests {
         fn t(s: &str, i: uint, u: &[~str]) {
             let mut v = ~[];
             for each_split_within(s, i) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         t("", 0, []);
         t("", 15, []);
@@ -3964,155 +3898,13 @@ mod tests {
         let s = ~"ศไทย中华Việt Nam";
         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
         let mut pos = s.len();
-        for v.each_reverse |ch| {
+        for v.rev_iter().advance |ch| {
             assert!(s.char_at_reverse(pos) == *ch);
             pos -= from_char(*ch).len();
         }
     }
 
     #[test]
-    fn test_each() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = 0;
-
-        for s.each |b| {
-            assert_eq!(b, v[pos]);
-            pos += 1;
-        }
-    }
-
-    #[test]
-    fn test_each_empty() {
-        for "".each |b| {
-            assert_eq!(b, 0u8);
-        }
-    }
-
-    #[test]
-    fn test_eachi() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = 0;
-
-        for s.eachi |i, b| {
-            assert_eq!(pos, i);
-            assert_eq!(b, v[pos]);
-            pos += 1;
-        }
-    }
-
-    #[test]
-    fn test_eachi_empty() {
-        for "".eachi |i, b| {
-            assert_eq!(i, 0);
-            assert_eq!(b, 0);
-        }
-    }
-
-    #[test]
-    fn test_each_reverse() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = v.len();
-
-        for s.each_reverse |b| {
-            pos -= 1;
-            assert_eq!(b, v[pos]);
-        }
-    }
-
-    #[test]
-    fn test_each_empty_reverse() {
-        for "".each_reverse |b| {
-            assert_eq!(b, 0u8);
-        }
-    }
-
-    #[test]
-    fn test_eachi_reverse() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = v.len();
-
-        for s.eachi_reverse |i, b| {
-            pos -= 1;
-            assert_eq!(pos, i);
-            assert_eq!(b, v[pos]);
-        }
-    }
-
-    #[test]
-    fn test_eachi_reverse_empty() {
-        for "".eachi_reverse |i, b| {
-            assert_eq!(i, 0);
-            assert_eq!(b, 0);
-        }
-    }
-
-    #[test]
-    fn test_each_char() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = 0;
-        for s.each_char |ch| {
-            assert_eq!(ch, v[pos]);
-            pos += 1;
-        }
-    }
-
-    #[test]
-    fn test_each_chari() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = 0;
-        for s.each_chari |i, ch| {
-            assert_eq!(pos, i);
-            assert_eq!(ch, v[pos]);
-            pos += 1;
-        }
-    }
-
-    #[test]
-    fn test_each_char_reverse() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = v.len();
-        for s.each_char_reverse |ch| {
-            pos -= 1;
-            assert_eq!(ch, v[pos]);
-        }
-    }
-
-    #[test]
-    fn test_each_chari_reverse() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = v.len();
-        for s.each_chari_reverse |i, ch| {
-            pos -= 1;
-            assert_eq!(pos, i);
-            assert_eq!(ch, v[pos]);
-        }
-    }
-
-    #[test]
     fn test_escape_unicode() {
         assert_eq!(escape_unicode("abc"), ~"\\x61\\x62\\x63");
         assert_eq!(escape_unicode("a c"), ~"\\x61\\x20\\x63");
@@ -4167,7 +3959,23 @@ mod tests {
         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
 
         let mut pos = 0;
-        let mut it = s.char_iter();
+        let mut it = s.iter();
+
+        for it.advance |c| {
+            assert_eq!(c, v[pos]);
+            pos += 1;
+        }
+        assert_eq!(pos, v.len());
+    }
+
+    #[test]
+    fn test_rev_iterator() {
+        use iterator::*;
+        let s = ~"ศไทย中华Việt Nam";
+        let v = ~['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+        let mut pos = 0;
+        let mut it = s.rev_iter();
 
         for it.advance |c| {
             assert_eq!(c, v[pos]);
@@ -4175,4 +3983,36 @@ mod tests {
         }
         assert_eq!(pos, v.len());
     }
+
+    #[test]
+    fn test_bytes_iterator() {
+        let s = ~"ศไทย中华Việt Nam";
+        let v = [
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109
+        ];
+        let mut pos = 0;
+
+        for s.bytes_iter().advance |b| {
+            assert_eq!(b, v[pos]);
+            pos += 1;
+        }
+    }
+
+    #[test]
+    fn test_bytes_rev_iterator() {
+        let s = ~"ศไทย中华Việt Nam";
+        let v = [
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109
+        ];
+        let mut pos = v.len();
+
+        for s.bytes_rev_iter().advance |b| {
+            pos -= 1;
+            assert_eq!(b, v[pos]);
+        }
+    }
 }
diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs
index 3b31d70f7a1..e288d605714 100644
--- a/src/libstd/str/ascii.rs
+++ b/src/libstd/str/ascii.rs
@@ -15,6 +15,7 @@ use str;
 use str::StrSlice;
 use cast;
 use old_iter::BaseIter;
+use iterator::IteratorUtil;
 use vec::{CopyableVector, ImmutableVector, OwnedVector};
 
 /// Datatype to hold one ascii character. It is 8 bit long.
@@ -101,10 +102,7 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self str {
 
     #[inline(always)]
     fn is_ascii(&self) -> bool {
-        for self.each |b| {
-            if !b.is_ascii() { return false; }
-        }
-        true
+        self.bytes_iter().all(|b| b.is_ascii())
     }
 }
 
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs
index 583923bc2e3..87e13e494aa 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -14,7 +14,6 @@
 
 use option::{Some, None};
 use cast;
-use cmp::{Eq, Ord};
 use gc;
 use io;
 use libc;
diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs
index 7899edbfcb9..4bd3946f885 100644
--- a/src/libstd/trie.rs
+++ b/src/libstd/trie.rs
@@ -14,7 +14,6 @@ use prelude::*;
 use iterator::IteratorUtil;
 use uint;
 use util::{swap, replace};
-use vec;
 
 // FIXME: #5244: need to manually update the TrieNode constructor
 static SHIFT: uint = 4;
diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs
index 350b18d4541..cd3e0cf303e 100644
--- a/src/libstd/unstable/lang.rs
+++ b/src/libstd/unstable/lang.rs
@@ -10,6 +10,7 @@
 
 //! Runtime calls emitted by the compiler.
 
+use iterator::IteratorUtil;
 use uint;
 use cast::transmute;
 use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO};
@@ -133,7 +134,7 @@ unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
         Some(borrow_list) => { // recording borrows
             let mut msg = ~"borrowed";
             let mut sep = " at ";
-            for borrow_list.each_reverse |entry| {
+            for borrow_list.rev_iter().advance |entry| {
                 if entry.box == box {
                     str::push_str(&mut msg, sep);
                     let filename = str::raw::from_c_str(entry.file);
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index d8424f4a29e..6137b589bdb 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -1066,138 +1066,12 @@ impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] {
     }
 }
 
-/**
- * Reduces a vector from left to right.
- *
- * # Arguments
- * * `z` - initial accumulator value
- * * `v` - vector to iterate over
- * * `p` - a closure to operate on vector elements
- *
- * # Examples
- *
- * Sum all values in the vector [1, 2, 3]:
- *
- * ~~~ {.rust}
- * vec::foldl(0, [1, 2, 3], |a, b| a + *b);
- * ~~~
- *
- */
-pub fn foldl<'a, T, U>(z: T, v: &'a [U], p: &fn(t: T, u: &'a U) -> T) -> T {
-    let mut accum = z;
-    let mut i = 0;
-    let l = v.len();
-    while i < l {
-        // Use a while loop so that liveness analysis can handle moving
-        // the accumulator.
-        accum = p(accum, &v[i]);
-        i += 1;
-    }
-    accum
-}
-
-/**
- * Reduces a vector from right to left. Note that the argument order is
- * reversed compared to `foldl` to reflect the order they are provided to
- * the closure.
- *
- * # Arguments
- * * `v` - vector to iterate over
- * * `z` - initial accumulator value
- * * `p` - a closure to do operate on vector elements
- *
- * # Examples
- *
- * Sum all values in the vector [1, 2, 3]:
- *
- * ~~~ {.rust}
- * vec::foldr([1, 2, 3], 0, |a, b| a + *b);
- * ~~~
- *
- */
-pub fn foldr<'a, T, U>(v: &'a [T], mut z: U, p: &fn(t: &'a T, u: U) -> U) -> U {
-    let mut i = v.len();
-    while i > 0 {
-        i -= 1;
-        z = p(&v[i], z);
-    }
-    return z;
-}
-
-/**
- * Return true if a predicate matches any elements
- *
- * If the vector contains no elements then false is returned.
- */
-pub fn any<T>(v: &[T], f: &fn(t: &T) -> bool) -> bool {
-    for each(v) |elem| { if f(elem) { return true; } }
-    false
-}
-
-/**
- * Return true if a predicate matches any elements in both vectors.
- *
- * If the vectors contains no elements then false is returned.
- */
-pub fn any2<T, U>(v0: &[T], v1: &[U],
-                   f: &fn(a: &T, b: &U) -> bool) -> bool {
-    let v0_len = len(v0);
-    let v1_len = len(v1);
-    let mut i = 0u;
-    while i < v0_len && i < v1_len {
-        if f(&v0[i], &v1[i]) { return true; };
-        i += 1u;
-    }
-    false
-}
-
-/**
- * Return true if a predicate matches all elements
- *
- * If the vector contains no elements then true is returned.
- */
-pub fn all<T>(v: &[T], f: &fn(t: &T) -> bool) -> bool {
-    for each(v) |elem| { if !f(elem) { return false; } }
-    true
-}
-
-/**
- * Return true if a predicate matches all elements
- *
- * If the vector contains no elements then true is returned.
- */
-pub fn alli<T>(v: &[T], f: &fn(uint, t: &T) -> bool) -> bool {
-    for eachi(v) |i, elem| { if !f(i, elem) { return false; } }
-    true
-}
-
-/**
- * Return true if a predicate matches all elements in both vectors.
- *
- * If the vectors are not the same size then false is returned.
- */
-pub fn all2<T, U>(v0: &[T], v1: &[U],
-                   f: &fn(t: &T, u: &U) -> bool) -> bool {
-    let v0_len = len(v0);
-    if v0_len != len(v1) { return false; }
-    let mut i = 0u;
-    while i < v0_len { if !f(&v0[i], &v1[i]) { return false; }; i += 1u; }
-    true
-}
-
 /// Return true if a vector contains an element with the given value
 pub fn contains<T:Eq>(v: &[T], x: &T) -> bool {
     for each(v) |elt| { if *x == *elt { return true; } }
     false
 }
 
-/// Returns the number of elements that are equal to a given value
-pub fn count<T:Eq>(v: &[T], x: &T) -> uint {
-    let mut cnt = 0u;
-    for each(v) |elt| { if *x == *elt { cnt += 1u; } }
-    cnt
-}
-
 /**
  * Search for the first element that matches a given predicate
  *
@@ -1599,34 +1473,6 @@ pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool {
 }
 
 /**
- * Iterates over a vector's elements in reverse
- *
- * Return true to continue, false to break.
- */
-#[inline(always)]
-pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) -> bool {
-    eachi_reverse(v, |_i, v| blk(v))
-}
-
-/**
- * Iterates over a vector's elements and indices in reverse
- *
- * Return true to continue, false to break.
- */
-#[inline(always)]
-pub fn eachi_reverse<'r,T>(v: &'r [T],
-                            blk: &fn(i: uint, v: &'r T) -> bool) -> bool {
-    let mut i = v.len();
-    while i > 0 {
-        i -= 1;
-        if !blk(i, &v[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-/**
  * Iterate over all permutations of vector `v`.
  *
  * Permutations are produced in lexicographic order with respect to the order
@@ -1964,6 +1810,7 @@ impl<'self,T:Copy> CopyableVector<T> for &'self [T] {
 pub trait ImmutableVector<'self, T> {
     fn slice(&self, start: uint, end: uint) -> &'self [T];
     fn iter(self) -> VecIterator<'self, T>;
+    fn rev_iter(self) -> VecRevIterator<'self, T>;
     fn head(&self) -> &'self T;
     fn head_opt(&self) -> Option<&'self T>;
     fn tail(&self) -> &'self [T];
@@ -1974,13 +1821,9 @@ pub trait ImmutableVector<'self, T> {
     fn last_opt(&self) -> Option<&'self T>;
     fn position(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
     fn rposition(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
-    fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool;
-    fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool;
-    fn foldr<'a, U>(&'a self, z: U, p: &fn(t: &'a T, u: U) -> U) -> U;
     fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U];
     fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U];
     fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U];
-    fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool;
     fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U];
     fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U];
     unsafe fn unsafe_ref(&self, index: uint) -> *T;
@@ -2002,6 +1845,15 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
                         lifetime: cast::transmute(p)}
         }
     }
+    #[inline]
+    fn rev_iter(self) -> VecRevIterator<'self, T> {
+        unsafe {
+            let p = vec::raw::to_ptr(self);
+            VecRevIterator{ptr: p.offset(self.len() - 1),
+                           end: p.offset(-1),
+                           lifetime: cast::transmute(p)}
+        }
+    }
 
     /// Returns the first element of a vector, failing if the vector is empty.
     #[inline]
@@ -2059,24 +1911,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
         rposition(*self, f)
     }
 
-    /// Iterates over a vector's elements in reverse.
-    #[inline]
-    fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool {
-        each_reverse(*self, blk)
-    }
-
-    /// Iterates over a vector's elements and indices in reverse.
-    #[inline]
-    fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool {
-        eachi_reverse(*self, blk)
-    }
-
-    /// Reduce a vector from right to left
-    #[inline]
-    fn foldr<'a, U>(&'a self, z: U, p: &fn(t: &'a T, u: U) -> U) -> U {
-        foldr(*self, z, p)
-    }
-
     /// Apply a function to each element of a vector and return the results
     #[inline]
     fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) }
@@ -2101,14 +1935,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     }
 
     /**
-     * Returns true if the function returns true for all elements.
-     *
-     *     If the vector is empty, true is returned.
-     */
-    fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool {
-        alli(*self, f)
-    }
-    /**
      * Apply a function to each element of a vector and return a concatenation
      * of each result vector
      */
@@ -2350,7 +2176,8 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
 #[allow(missing_doc)]
 pub trait MutableVector<'self, T> {
     fn mut_slice(self, start: uint, end: uint) -> &'self mut [T];
-    fn mut_iter(self) -> MutVecIterator<'self, T>;
+    fn mut_iter(self) -> VecMutIterator<'self, T>;
+    fn mut_rev_iter(self) -> VecMutRevIterator<'self, T>;
 
     unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T;
     unsafe fn unsafe_set(&self, index: uint, val: T);
@@ -2363,14 +2190,23 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
     }
 
     #[inline]
-    fn mut_iter(self) -> MutVecIterator<'self, T> {
+    fn mut_iter(self) -> VecMutIterator<'self, T> {
         unsafe {
             let p = vec::raw::to_mut_ptr(self);
-            MutVecIterator{ptr: p, end: p.offset(self.len()),
+            VecMutIterator{ptr: p, end: p.offset(self.len()),
                            lifetime: cast::transmute(p)}
         }
     }
 
+    fn mut_rev_iter(self) -> VecMutRevIterator<'self, T> {
+        unsafe {
+            let p = vec::raw::to_mut_ptr(self);
+            VecMutRevIterator{ptr: p.offset(self.len() - 1),
+                              end: p.offset(-1),
+                              lifetime: cast::transmute(p)}
+        }
+    }
+
     #[inline(always)]
     unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T {
         let pair_ptr: &(*mut T, uint) = transmute(self);
@@ -2872,52 +2708,69 @@ impl<A:Clone> Clone for ~[A] {
     }
 }
 
-/// An external iterator for vectors (use with the std::iterator module)
+macro_rules! iterator {
+    /* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
+    (struct $name:ident -> $ptr:ty, $elem:ty) => {
+        pub struct $name<'self, T> {
+            priv ptr: $ptr,
+            priv end: $ptr,
+            priv lifetime: $elem // FIXME: #5922
+        }
+    };*/
+    (impl $name:ident -> $elem:ty, $step:expr) => {
+        // could be implemented with &[T] with .slice(), but this avoids bounds checks
+        impl<'self, T> Iterator<$elem> for $name<'self, T> {
+            #[inline]
+            fn next(&mut self) -> Option<$elem> {
+                unsafe {
+                    if self.ptr == self.end {
+                        None
+                    } else {
+                        let old = self.ptr;
+                        self.ptr = self.ptr.offset($step);
+                        Some(cast::transmute(old))
+                    }
+                }
+            }
+        }
+    }
+}
+
+//iterator!{struct VecIterator -> *T, &'self T}
+/// An iterator for iterating over a vector
 pub struct VecIterator<'self, T> {
     priv ptr: *T,
     priv end: *T,
     priv lifetime: &'self T // FIXME: #5922
 }
+iterator!{impl VecIterator -> &'self T, 1}
 
-// could be implemented with &[T] with .slice(), but this avoids bounds checks
-impl<'self, T> Iterator<&'self T> for VecIterator<'self, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'self T> {
-        unsafe {
-            if self.ptr == self.end {
-                None
-            } else {
-                let old = self.ptr;
-                self.ptr = self.ptr.offset(1);
-                Some(cast::transmute(old))
-            }
-        }
-    }
+//iterator!{struct VecRevIterator -> *T, &'self T}
+/// An iterator for iterating over a vector in reverse
+pub struct VecRevIterator<'self, T> {
+    priv ptr: *T,
+    priv end: *T,
+    priv lifetime: &'self T // FIXME: #5922
 }
+iterator!{impl VecRevIterator -> &'self T, -1}
 
-/// An external iterator for vectors with the possibility of mutating
-/// elements. (use with the std::iterator module)
-pub struct MutVecIterator<'self, T> {
+//iterator!{struct VecMutIterator -> *mut T, &'self mut T}
+/// An iterator for mutating the elements of a vector
+pub struct VecMutIterator<'self, T> {
     priv ptr: *mut T,
     priv end: *mut T,
     priv lifetime: &'self mut T // FIXME: #5922
 }
+iterator!{impl VecMutIterator -> &'self mut T, 1}
 
-// could be implemented with &[T] with .slice(), but this avoids bounds checks
-impl<'self, T> Iterator<&'self mut T> for MutVecIterator<'self, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'self mut T> {
-        unsafe {
-            if self.ptr == self.end {
-                None
-            } else {
-                let old = self.ptr;
-                self.ptr = self.ptr.offset(1);
-                Some(cast::transmute(old))
-            }
-        }
-    }
+//iterator!{struct VecMutRevIterator -> *mut T, &'self mut T}
+/// An iterator for mutating the elements of a vector in reverse
+pub struct VecMutRevIterator<'self, T> {
+    priv ptr: *mut T,
+    priv end: *mut T,
+    priv lifetime: &'self mut T // FIXME: #5922
 }
+iterator!{impl VecMutRevIterator -> &'self mut T, -1}
 
 impl<T> FromIter<T> for ~[T]{
     #[inline(always)]
@@ -3468,39 +3321,6 @@ mod tests {
     }
 
     #[test]
-    fn test_foldl() {
-        // Test on-stack fold.
-        let mut v = ~[1u, 2u, 3u];
-        let mut sum = foldl(0u, v, add);
-        assert_eq!(sum, 6u);
-
-        // Test on-heap fold.
-        v = ~[1u, 2u, 3u, 4u, 5u];
-        sum = foldl(0u, v, add);
-        assert_eq!(sum, 15u);
-    }
-
-    #[test]
-    fn test_foldl2() {
-        fn sub(a: int, b: &int) -> int {
-            a - *b
-        }
-        let v = ~[1, 2, 3, 4];
-        let sum = foldl(0, v, sub);
-        assert_eq!(sum, -10);
-    }
-
-    #[test]
-    fn test_foldr() {
-        fn sub(a: &int, b: int) -> int {
-            *a - b
-        }
-        let v = ~[1, 2, 3, 4];
-        let sum = foldr(v, 0, sub);
-        assert_eq!(sum, -2);
-    }
-
-    #[test]
     fn test_each_empty() {
         for each::<int>([]) |_v| {
             fail!(); // should never be executed
@@ -3528,51 +3348,14 @@ mod tests {
     }
 
     #[test]
-    fn test_each_reverse_empty() {
-        let v: ~[int] = ~[];
-        for v.each_reverse |_v| {
-            fail!(); // should never execute
-        }
-    }
-
-    #[test]
-    fn test_each_reverse_nonempty() {
-        let mut i = 0;
-        for each_reverse([1, 2, 3]) |v| {
-            if i == 0 { assert!(*v == 3); }
-            i += *v
-        }
-        assert_eq!(i, 6);
-    }
-
-    #[test]
-    fn test_eachi_reverse() {
-        let mut i = 0;
-        for eachi_reverse([0, 1, 2]) |j, v| {
-            if i == 0 { assert!(*v == 2); }
-            assert_eq!(j, *v as uint);
-            i += *v;
-        }
-        assert_eq!(i, 3);
-    }
-
-    #[test]
-    fn test_eachi_reverse_empty() {
-        let v: ~[int] = ~[];
-        for v.eachi_reverse |_i, _v| {
-            fail!(); // should never execute
-        }
-    }
-
-    #[test]
     fn test_each_ret_len0() {
-        let mut a0 : [int, .. 0] = [];
+        let a0 : [int, .. 0] = [];
         assert_eq!(each(a0, |_p| fail!()), true);
     }
 
     #[test]
     fn test_each_ret_len1() {
-        let mut a1 = [17];
+        let a1 = [17];
         assert_eq!(each(a1, |_p| true), true);
         assert_eq!(each(a1, |_p| false), false);
     }
@@ -3601,33 +3384,6 @@ mod tests {
     }
 
     #[test]
-    fn test_any_and_all() {
-        assert!(any([1u, 2u, 3u], is_three));
-        assert!(!any([0u, 1u, 2u], is_three));
-        assert!(any([1u, 2u, 3u, 4u, 5u], is_three));
-        assert!(!any([1u, 2u, 4u, 5u, 6u], is_three));
-
-        assert!(all([3u, 3u, 3u], is_three));
-        assert!(!all([3u, 3u, 2u], is_three));
-        assert!(all([3u, 3u, 3u, 3u, 3u], is_three));
-        assert!(!all([3u, 3u, 0u, 1u, 2u], is_three));
-    }
-
-    #[test]
-    fn test_any2_and_all2() {
-
-        assert!(any2([2u, 4u, 6u], [2u, 4u, 6u], is_equal));
-        assert!(any2([1u, 2u, 3u], [4u, 5u, 3u], is_equal));
-        assert!(!any2([1u, 2u, 3u], [4u, 5u, 6u], is_equal));
-        assert!(any2([2u, 4u, 6u], [2u, 4u], is_equal));
-
-        assert!(all2([2u, 4u, 6u], [2u, 4u, 6u], is_equal));
-        assert!(!all2([1u, 2u, 3u], [4u, 5u, 3u], is_equal));
-        assert!(!all2([1u, 2u, 3u], [4u, 5u, 6u], is_equal));
-        assert!(!all2([2u, 4u, 6u], [2u, 4u], is_equal));
-    }
-
-    #[test]
     fn test_zip_unzip() {
         let v1 = ~[1, 2, 3];
         let v2 = ~[4, 5, 6];
@@ -4375,113 +4131,6 @@ mod tests {
     #[ignore(windows)]
     #[should_fail]
     #[allow(non_implicitly_copyable_typarams)]
-    fn test_foldl_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do foldl((~0, @0), v) |_a, _b| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            (~0, @0)
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_foldr_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do foldr(v, (~0, @0)) |_a, _b| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            (~0, @0)
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_any_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do any(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_any2_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do any(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_all_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do all(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_alli_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do alli(v) |_i, _elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_all2_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do all2(v, v) |_elt1, _elt2| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
     fn test_find_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
         let mut i = 0;
@@ -4643,6 +4292,30 @@ mod tests {
     }
 
     #[test]
+    fn test_rev_iterator() {
+        use iterator::*;
+
+        let xs = [1, 2, 5, 10, 11];
+        let ys = [11, 10, 5, 2, 1];
+        let mut i = 0;
+        for xs.rev_iter().advance |&x| {
+            assert_eq!(x, ys[i]);
+            i += 1;
+        }
+        assert_eq!(i, 5);
+    }
+
+    #[test]
+    fn test_mut_rev_iterator() {
+        use iterator::*;
+        let mut xs = [1u, 2, 3, 4, 5];
+        for xs.mut_rev_iter().enumerate().advance |(i,x)| {
+            *x += i;
+        }
+        assert_eq!(xs, [5, 5, 5, 5, 5])
+    }
+
+    #[test]
     fn test_reverse_part() {
         let mut values = [1,2,3,4,5];
         reverse_part(values,1,4);