From 4ff7ef434ff5805dc8636fa0bb821feeb0705d22 Mon Sep 17 00:00:00 2001 From: =Mark Sinclair Date: Sun, 14 Jul 2013 11:26:03 -0400 Subject: [PATCH 1/3] Implemented FromIterator for std::hashmap --- src/libstd/hashmap.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 6c93cd0dc86..d62a445882e 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -18,7 +18,7 @@ use container::{Container, Mutable, Map, Set}; 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; @@ -610,6 +610,18 @@ impl<'self, K> Iterator<&'self K> for HashSetIterator<'self, K> { } } +impl> FromIterator<(K, V), T> for HashMap { + pub fn from_iterator(iter: &mut T) -> HashMap { + 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` @@ -935,6 +947,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 = xs.iter().transform(|&x| x).collect(); + + for xs.iter().advance |&(k, v)| { + assert_eq!(map.find(&k), Some(&v)); + } + } } #[cfg(test)] From bb6615d43a872d8cd3e2e33be5ff9efebf9cc02e Mon Sep 17 00:00:00 2001 From: =Mark Sinclair Date: Sun, 14 Jul 2013 12:20:48 -0400 Subject: [PATCH 2/3] Implemented FromIterator for TrieMap and TrieSet --- src/libstd/hashmap.rs | 25 ++++++++++++++ src/libstd/trie.rs | 80 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 91 insertions(+), 14 deletions(-) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index d62a445882e..c219886cd03 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -735,6 +735,20 @@ impl HashSet { } } +impl> FromIterator for HashSet { + pub fn from_iterator(iter: &mut T) -> HashSet { + 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}; @@ -1139,4 +1153,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 = 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 8ce02d59ab1..fd2cfa08b30 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}; @@ -171,6 +171,18 @@ impl TrieMap { } } +impl> FromIterator<(uint, T), Iter> for TrieMap { + pub fn from_iterator(iter: &mut Iter) -> TrieMap { + let mut map = TrieMap::new(); + + for iter.advance |(k, v)| { + map.insert(k, v); + } + + map + } +} + #[allow(missing_doc)] pub struct TrieSet { priv map: TrieMap<()> @@ -230,6 +242,18 @@ impl TrieSet { } } +impl> FromIterator 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 { count: uint, children: [Child, ..SIZE] @@ -382,7 +406,7 @@ pub fn check_integrity(trie: &TrieNode) { } #[cfg(test)] -mod tests { +mod test_map { use super::*; use core::option::{Some, None}; use uint; @@ -510,6 +534,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 = 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; @@ -533,18 +590,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]; + + let set: TrieSet = xs.iter().transform(|&x| x).collect(); - #[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); + for xs.iter().advance |x| { + assert!(set.contains(x)); + } } } From bbe03da9c6bad23d8e09077461c1616872e1aca0 Mon Sep 17 00:00:00 2001 From: =Mark Sinclair Date: Sun, 14 Jul 2013 13:18:50 -0400 Subject: [PATCH 3/3] Stripped trailing spaces; Implemented FromIterator for TreeMap and PriorityQueue --- src/libextra/priority_queue.rs | 27 +++++++++++++++++++ src/libextra/treemap.rs | 47 ++++++++++++++++++++++++++++++++++ src/libstd/hashmap.rs | 8 +++--- src/libstd/trie.rs | 4 +-- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 1f7ba9f6530..58bf4ba9247 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -16,6 +16,7 @@ use std::unstable::intrinsics::{move_val_init, init}; use std::util::{replace, swap}; use std::vec; +use std::iterator::FromIterator; /// A priority queue implemented with a binary heap pub struct PriorityQueue { @@ -191,6 +192,21 @@ impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> { fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } +impl> FromIterator for PriorityQueue { + pub fn from_iterator(iter: &mut Iter) -> PriorityQueue { + let (lower, _) = iter.size_hint(); + + let mut q = PriorityQueue::new(); + q.reserve_at_least(lower); + + for iter.advance |elem| { + q.push(elem); + } + + q + } +} + #[cfg(test)] mod tests { use sort::merge_sort; @@ -341,4 +357,15 @@ mod tests { #[should_fail] #[ignore(cfg(windows))] fn test_empty_replace() { let mut heap = PriorityQueue::new(); heap.replace(5); } + + #[test] + fn test_from_iter() { + let xs = ~[9u, 8, 7, 6, 5, 4, 3, 2, 1]; + + let mut q: PriorityQueue = xs.rev_iter().transform(|&x| x).collect(); + + for xs.iter().advance |&x| { + assert_eq!(q.pop(), x); + } + } } diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 8fac055d26f..d3d7dbfe402 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -15,6 +15,7 @@ use std::num; use std::util::{swap, replace}; +use std::iterator::FromIterator; // This is implemented as an AA tree, which is a simplified variation of // a red-black tree where red (horizontal) nodes can only be added @@ -695,6 +696,30 @@ fn remove(node: &mut Option<~TreeNode>, }; } +impl> FromIterator<(K, V), T> for TreeMap { + pub fn from_iterator(iter: &mut T) -> TreeMap { + let mut map = TreeMap::new(); + + for iter.advance |(k, v)| { + map.insert(k, v); + } + + map + } +} + +impl> FromIterator for TreeSet { + pub fn from_iterator(iter: &mut Iter) -> TreeSet { + let mut set = TreeSet::new(); + + for iter.advance |elem| { + set.insert(elem); + } + + set + } +} + #[cfg(test)] mod test_treemap { @@ -1013,6 +1038,17 @@ mod test_treemap { i += 1; } } + + #[test] + fn test_from_iter() { + let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: TreeMap = xs.iter().transform(|&x| x).collect(); + + for xs.iter().advance |&(k, v)| { + assert_eq!(map.find(&k), Some(&v)); + } + } } #[cfg(test)] @@ -1240,4 +1276,15 @@ mod test_set { assert_eq!(m.pop(&1), Some(2)); assert_eq!(m.pop(&1), None); } + + #[test] + fn test_from_iter() { + let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9]; + + let set: TreeSet = xs.iter().transform(|&x| x).collect(); + + for xs.iter().advance |x: &int| { + assert!(set.contains(x)); + } + } } diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index c219886cd03..44161127c14 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -621,7 +621,7 @@ impl> FromIterator<(K, V), T> for HashMap> FromIterator for HashSet { set } } - + #[cfg(test)] mod test_map { @@ -965,7 +965,7 @@ mod test_map { #[test] fn test_from_iter() { let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - + let map: HashMap = xs.iter().transform(|&x| x).collect(); for xs.iter().advance |&(k, v)| { @@ -1157,7 +1157,7 @@ mod test_set { #[test] fn test_from_iter() { let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9]; - + let set: HashSet = xs.iter().transform(|&x| x).collect(); for xs.iter().advance |x: &int| { diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index fd2cfa08b30..ffacfe12ca2 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -553,7 +553,7 @@ mod test_map { #[test] fn test_from_iter() { let xs = ~[(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - + let map: TrieMap = xs.iter().transform(|&x| x).collect(); for xs.iter().advance |&(k, v)| { @@ -592,7 +592,7 @@ mod test_set { #[test] fn test_from_iter() { let xs = ~[9u, 8, 7, 6, 5, 4, 3, 2, 1]; - + let set: TrieSet = xs.iter().transform(|&x| x).collect(); for xs.iter().advance |x| {