about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-08-12 18:39:39 +0200
committerblake2-ppc <blake2-ppc>2013-08-15 02:52:55 +0200
commita5f9494199c0990002b52c29fed998c5753f4a0b (patch)
tree3803bb54a0d4172b751e9402ae02a38fb4a8ff1a /src
parente7b572952c76fd6b05c947aa3193e10410773078 (diff)
downloadrust-a5f9494199c0990002b52c29fed998c5753f4a0b.tar.gz
rust-a5f9494199c0990002b52c29fed998c5753f4a0b.zip
std: Change either::{lefts, rights} to return an iterator
Diffstat (limited to 'src')
-rw-r--r--src/libstd/either.rs53
-rw-r--r--src/libsyntax/parse/parser.rs6
2 files changed, 31 insertions, 28 deletions
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index 132ebc72960..7150430893b 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -16,7 +16,7 @@ use option::{Some, None};
 use clone::Clone;
 use container::Container;
 use cmp::Eq;
-use iterator::Iterator;
+use iterator::{Iterator, FilterMap};
 use result::Result;
 use result;
 use str::StrSlice;
@@ -116,32 +116,35 @@ impl<L, R> Either<L, R> {
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Extracts from a vector of either all the left values
-pub fn lefts<L: Clone, R>(eithers: &[Either<L, R>]) -> ~[L] {
-    do vec::build_sized(eithers.len()) |push| {
-        for elt in eithers.iter() {
-            match *elt {
-                Left(ref l) => { push((*l).clone()); }
-                _ => { /* fallthrough */ }
-            }
+/// An iterator yielding the `Left` values of its source
+pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
+
+/// An iterator yielding the `Right` values of its source
+pub type Rights<L, R, Iter> = FilterMap<'static, Either<L, R>, R, Iter>;
+
+/// Extracts all the left values
+pub fn lefts<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
+    -> Lefts<L, R, Iter> {
+    do eithers.filter_map |elt| {
+        match elt {
+            Left(x) => Some(x),
+            _ => None,
         }
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Extracts from a vector of either all the right values
-pub fn rights<L, R: Clone>(eithers: &[Either<L, R>]) -> ~[R] {
-    do vec::build_sized(eithers.len()) |push| {
-        for elt in eithers.iter() {
-            match *elt {
-                Right(ref r) => { push((*r).clone()); }
-                _ => { /* fallthrough */ }
-            }
+/// Extracts all the right values
+pub fn rights<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
+    -> Rights<L, R, Iter> {
+    do eithers.filter_map |elt| {
+        match elt {
+            Right(x) => Some(x),
+            _ => None,
         }
     }
 }
 
+
 // FIXME: #8228 Replaceable by an external iterator?
 /// Extracts from a vector of either all the left values and right values
 ///
@@ -182,42 +185,42 @@ mod tests {
     #[test]
     fn test_lefts() {
         let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result, ~[10, 12, 14]);
     }
 
     #[test]
     fn test_lefts_none() {
         let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_lefts_empty() {
         let input: ~[Either<int, int>] = ~[];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_rights() {
         let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result, ~[11, 13]);
     }
 
     #[test]
     fn test_rights_none() {
         let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_rights_empty() {
         let input: ~[Either<int, int>] = ~[];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b38de31c56a..a2664dcf890 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3445,7 +3445,7 @@ impl Parser {
                 |p| p.parse_arg()
             );
 
-        let inputs = either::lefts(args_or_capture_items);
+        let inputs = either::lefts(args_or_capture_items.move_iter()).collect();
 
         let (ret_style, ret_ty) = self.parse_ret_ty();
         ast::fn_decl {
@@ -3608,7 +3608,7 @@ impl Parser {
 
         let hi = self.span.hi;
 
-        let inputs = either::lefts(args_or_capture_items);
+        let inputs = either::lefts(args_or_capture_items.move_iter()).collect();
         let (ret_style, ret_ty) = self.parse_ret_ty();
 
         let fn_decl = ast::fn_decl {
@@ -3641,7 +3641,7 @@ impl Parser {
         };
 
         ast::fn_decl {
-            inputs: either::lefts(inputs_captures),
+            inputs: either::lefts(inputs_captures.move_iter()).collect(),
             output: output,
             cf: return_val,
         }