about summary refs log tree commit diff
path: root/src/libcore/vec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore/vec.rs')
-rw-r--r--src/libcore/vec.rs104
1 files changed, 84 insertions, 20 deletions
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 7846d3d0302..9ad5d9f32da 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -10,8 +10,6 @@
 
 //! Vectors
 
-#[forbid(deprecated_mode)];
-#[forbid(deprecated_pattern)];
 #[warn(non_camel_case_types)];
 
 use container::{Container, Mutable};
@@ -841,14 +839,37 @@ pub pure fn map2<T: Copy, U: Copy, V>(v0: &[T], v1: &[U],
     u
 }
 
-/**
- * Apply a function to each element of a vector and return the results
- *
- * If function `f` returns `none` then that element is excluded from
- * the resulting vector.
- */
-pub pure fn filter_map<T, U: Copy>(v: &[T], f: fn(t: &T) -> Option<U>)
-    -> ~[U] {
+pub fn filter_map<T, U>(
+    v: ~[T],
+    f: fn(t: T) -> Option<U>) -> ~[U]
+{
+    /*!
+     *
+     * Apply a function to each element of a vector and return the results.
+     * Consumes the input vector.  If function `f` returns `None` then that
+     * element is excluded from the resulting vector.
+     */
+
+    let mut result = ~[];
+    do consume(v) |_, elem| {
+        match f(elem) {
+            None => {}
+            Some(result_elem) => { result.push(result_elem); }
+        }
+    }
+    result
+}
+
+pub pure fn filter_mapped<T, U: Copy>(
+    v: &[T],
+    f: fn(t: &T) -> Option<U>) -> ~[U]
+{
+    /*!
+     *
+     * Like `filter_map()`, but operates on a borrowed slice
+     * and does not consume the input.
+     */
+
     let mut result = ~[];
     for each(v) |elem| {
         match f(elem) {
@@ -1695,7 +1716,7 @@ pub trait ImmutableVector<T> {
     fn map_r<U>(&self, f: fn(x: &T) -> U) -> ~[U];
     pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool;
     pure fn flat_map<U>(&self, f: fn(t: &T) -> ~[U]) -> ~[U];
-    pure fn filter_map<U: Copy>(&self, f: fn(t: &T) -> Option<U>) -> ~[U];
+    pure fn filter_mapped<U: Copy>(&self, f: fn(t: &T) -> Option<U>) -> ~[U];
 }
 
 /// Extension methods for vectors
@@ -1758,8 +1779,8 @@ impl<T> &[T]: ImmutableVector<T> {
      * the resulting vector.
      */
     #[inline]
-    pure fn filter_map<U: Copy>(&self, f: fn(t: &T) -> Option<U>) -> ~[U] {
-        filter_map(*self, f)
+    pure fn filter_mapped<U: Copy>(&self, f: fn(t: &T) -> Option<U>) -> ~[U] {
+        filter_mapped(*self, f)
     }
 }
 
@@ -2439,10 +2460,14 @@ mod tests {
 
     pure fn is_equal(x: &uint, y:&uint) -> bool { return *x == *y; }
 
-    fn square_if_odd(n: &uint) -> Option<uint> {
+    fn square_if_odd_r(n: &uint) -> Option<uint> {
         return if *n % 2u == 1u { Some(*n * *n) } else { None };
     }
 
+    fn square_if_odd_v(n: uint) -> Option<uint> {
+        return if n % 2u == 1u { Some(n * n) } else { None };
+    }
+
     fn add(x: uint, y: &uint) -> uint { return x + *y; }
 
     #[test]
@@ -2775,17 +2800,17 @@ mod tests {
     }
 
     #[test]
-    fn test_filter_map() {
+    fn test_filter_mapped() {
         // Test on-stack filter-map.
         let mut v = ~[1u, 2u, 3u];
-        let mut w = filter_map(v, square_if_odd);
+        let mut w = filter_mapped(v, square_if_odd_r);
         assert (len(w) == 2u);
         assert (w[0] == 1u);
         assert (w[1] == 9u);
 
         // Test on-heap filter-map.
         v = ~[1u, 2u, 3u, 4u, 5u];
-        w = filter_map(v, square_if_odd);
+        w = filter_mapped(v, square_if_odd_r);
         assert (len(w) == 3u);
         assert (w[0] == 1u);
         assert (w[1] == 9u);
@@ -2804,7 +2829,46 @@ mod tests {
         let all_odd2: ~[int] = ~[];
         let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3];
         let mix_dest: ~[int] = ~[1, 3, 0, 0];
-        assert (filter_map(all_even, halve) == map(all_even, halve_for_sure));
+        assert (filter_mapped(all_even, halve) ==
+                map(all_even, halve_for_sure));
+        assert (filter_mapped(all_odd1, halve) == ~[]);
+        assert (filter_mapped(all_odd2, halve) == ~[]);
+        assert (filter_mapped(mix, halve) == mix_dest);
+    }
+
+    #[test]
+    fn test_filter_map() {
+        // Test on-stack filter-map.
+        let mut v = ~[1u, 2u, 3u];
+        let mut w = filter_map(v, square_if_odd_v);
+        assert (len(w) == 2u);
+        assert (w[0] == 1u);
+        assert (w[1] == 9u);
+
+        // Test on-heap filter-map.
+        v = ~[1u, 2u, 3u, 4u, 5u];
+        w = filter_map(v, square_if_odd_v);
+        assert (len(w) == 3u);
+        assert (w[0] == 1u);
+        assert (w[1] == 9u);
+        assert (w[2] == 25u);
+
+        fn halve(i: int) -> Option<int> {
+            if i % 2 == 0 {
+                return option::Some::<int>(i / 2);
+            } else {
+                return option::None::<int>;
+            }
+        }
+        fn halve_for_sure(i: &int) -> int { return *i / 2; }
+        let all_even: ~[int] = ~[0, 2, 8, 6];
+        let all_even0: ~[int] = copy all_even;
+        let all_odd1: ~[int] = ~[1, 7, 3];
+        let all_odd2: ~[int] = ~[];
+        let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3];
+        let mix_dest: ~[int] = ~[1, 3, 0, 0];
+        assert (filter_map(all_even, halve) ==
+                map(all_even0, halve_for_sure));
         assert (filter_map(all_odd1, halve) == ~[]);
         assert (filter_map(all_odd2, halve) == ~[]);
         assert (filter_map(mix, halve) == mix_dest);
@@ -3664,10 +3728,10 @@ mod tests {
     #[ignore(windows)]
     #[should_fail]
     #[allow(non_implicitly_copyable_typarams)]
-    fn test_filter_map_fail() {
+    fn test_filter_mapped_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
         let mut i = 0;
-        do filter_map(v) |_elt| {
+        do filter_mapped(v) |_elt| {
             if i == 2 {
                 die!()
             }