about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-14 12:01:22 -0700
committerbors <bors@rust-lang.org>2013-07-14 12:01:22 -0700
commit0cb1ac0f9f7bf98ea8ab5ccbd6ef319decc41a72 (patch)
tree273268a2048fe1c4c1e41750f8fac87d1d7810f1 /src/libstd
parent1c35ab322ff2f26962a3550fffc2fa4154224b64 (diff)
parentbbe03da9c6bad23d8e09077461c1616872e1aca0 (diff)
downloadrust-0cb1ac0f9f7bf98ea8ab5ccbd6ef319decc41a72.tar.gz
rust-0cb1ac0f9f7bf98ea8ab5ccbd6ef319decc41a72.zip
auto merge of #7788 : MarkJr94/rust/from_iter, r=cmr
Added Iterators for HashMap/Set, TreeMap/Set, TrieMap/Set, and PriorityQueue as per Issue #7626 
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/hashmap.rs50
-rw-r--r--src/libstd/trie.rs80
2 files changed, 115 insertions, 15 deletions
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index e95c63e8912..0e31e47d56b 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -18,7 +18,7 @@
 use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
 use cmp::{Eq, Equiv};
 use hash::Hash;
-use iterator::{Iterator, IteratorUtil};
+use iterator::{Iterator, IteratorUtil, FromIterator};
 use num;
 use option::{None, Option, Some};
 use rand::RngUtil;
@@ -612,6 +612,18 @@ impl<'self, K> Iterator<&'self K> for HashSetIterator<'self, K> {
     }
 }
 
+impl<K: Eq + Hash, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for HashMap<K, V> {
+    pub fn from_iterator(iter: &mut T) -> HashMap<K, V> {
+        let (lower, _) = iter.size_hint();
+        let mut map = HashMap::with_capacity(lower);
+
+        for iter.advance |(k, v)| {
+            map.insert(k, v);
+        }
+
+        map
+    }
+}
 
 /// An implementation of a hash set using the underlying representation of a
 /// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
@@ -727,6 +739,20 @@ impl<T:Hash + Eq> HashSet<T> {
     }
 }
 
+impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
+    pub fn from_iterator(iter: &mut T) -> HashSet<K> {
+        let (lower, _) = iter.size_hint();
+        let mut set = HashSet::with_capacity(lower);
+
+        for iter.advance |k| {
+            set.insert(k);
+        }
+
+        set
+    }
+}
+
+
 #[cfg(test)]
 mod test_map {
     use container::{Container, Map, Set};
@@ -939,6 +965,17 @@ mod test_map {
 
         assert_eq!(m.find_equiv(&("qux")), None);
     }
+
+    #[test]
+    fn test_from_iter() {
+        let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let map: HashMap<int, int> = xs.iter().transform(|&x| x).collect();
+
+        for xs.iter().advance |&(k, v)| {
+            assert_eq!(map.find(&k), Some(&v));
+        }
+    }
 }
 
 #[cfg(test)]
@@ -1120,4 +1157,15 @@ mod test_set {
         }
         assert_eq!(i, expected.len());
     }
+
+    #[test]
+    fn test_from_iter() {
+        let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+        let set: HashSet<int> = xs.iter().transform(|&x| x).collect();
+
+        for xs.iter().advance |x: &int| {
+            assert!(set.contains(x));
+        }
+    }
 }
diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs
index c4bfda7e2be..3882ab0de63 100644
--- a/src/libstd/trie.rs
+++ b/src/libstd/trie.rs
@@ -11,7 +11,7 @@
 //! An ordered map and set for integer keys implemented as a radix trie
 
 use prelude::*;
-use iterator::IteratorUtil;
+use iterator::{IteratorUtil, FromIterator};
 use uint;
 use util::{swap, replace};
 
@@ -173,6 +173,18 @@ impl<T> TrieMap<T> {
     }
 }
 
+impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
+    pub fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
+        let mut map = TrieMap::new();
+
+        for iter.advance |(k, v)| {
+            map.insert(k, v);
+        }
+
+        map
+    }
+}
+
 #[allow(missing_doc)]
 pub struct TrieSet {
     priv map: TrieMap<()>
@@ -232,6 +244,18 @@ impl TrieSet {
     }
 }
 
+impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
+    pub fn from_iterator(iter: &mut Iter) -> TrieSet {
+        let mut set = TrieSet::new();
+
+        for iter.advance |elem| {
+            set.insert(elem);
+        }
+
+        set
+    }
+}
+
 struct TrieNode<T> {
     count: uint,
     children: [Child<T>, ..SIZE]
@@ -384,7 +408,7 @@ pub fn check_integrity<T>(trie: &TrieNode<T>) {
 }
 
 #[cfg(test)]
-mod tests {
+mod test_map {
     use super::*;
     use core::option::{Some, None};
     use uint;
@@ -513,6 +537,39 @@ mod tests {
     }
 
     #[test]
+    fn test_swap() {
+        let mut m = TrieMap::new();
+        assert_eq!(m.swap(1, 2), None);
+        assert_eq!(m.swap(1, 3), Some(2));
+        assert_eq!(m.swap(1, 4), Some(3));
+    }
+
+    #[test]
+    fn test_pop() {
+        let mut m = TrieMap::new();
+        m.insert(1, 2);
+        assert_eq!(m.pop(&1), Some(2));
+        assert_eq!(m.pop(&1), None);
+    }
+
+    #[test]
+    fn test_from_iter() {
+        let xs = ~[(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let map: TrieMap<int> = xs.iter().transform(|&x| x).collect();
+
+        for xs.iter().advance |&(k, v)| {
+            assert_eq!(map.find(&k), Some(&v));
+        }
+    }
+}
+
+#[cfg(test)]
+mod test_set {
+    use super::*;
+    use uint;
+
+    #[test]
     fn test_sane_chunk() {
         let x = 1;
         let y = 1 << (uint::bits - 1);
@@ -535,18 +592,13 @@ mod tests {
     }
 
     #[test]
-    fn test_swap() {
-        let mut m = TrieMap::new();
-        assert_eq!(m.swap(1, 2), None);
-        assert_eq!(m.swap(1, 3), Some(2));
-        assert_eq!(m.swap(1, 4), Some(3));
-    }
+    fn test_from_iter() {
+        let xs = ~[9u, 8, 7, 6, 5, 4, 3, 2, 1];
 
-    #[test]
-    fn test_pop() {
-        let mut m = TrieMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.pop(&1), Some(2));
-        assert_eq!(m.pop(&1), None);
+        let set: TrieSet = xs.iter().transform(|&x| x).collect();
+
+        for xs.iter().advance |x| {
+            assert!(set.contains(x));
+        }
     }
 }