Skip to content

Commit 0cb1ac0

Browse files
committed
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
2 parents 1c35ab3 + bbe03da commit 0cb1ac0

File tree

4 files changed

+189
-15
lines changed

4 files changed

+189
-15
lines changed

src/libextra/priority_queue.rs

+27
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use std::unstable::intrinsics::{move_val_init, init};
1717
use std::util::{replace, swap};
1818
use std::vec;
19+
use std::iterator::FromIterator;
1920

2021
/// A priority queue implemented with a binary heap
2122
pub struct PriorityQueue<T> {
@@ -191,6 +192,21 @@ impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> {
191192
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
192193
}
193194

195+
impl<T: Ord, Iter: Iterator<T>> FromIterator<T, Iter> for PriorityQueue<T> {
196+
pub fn from_iterator(iter: &mut Iter) -> PriorityQueue<T> {
197+
let (lower, _) = iter.size_hint();
198+
199+
let mut q = PriorityQueue::new();
200+
q.reserve_at_least(lower);
201+
202+
for iter.advance |elem| {
203+
q.push(elem);
204+
}
205+
206+
q
207+
}
208+
}
209+
194210
#[cfg(test)]
195211
mod tests {
196212
use sort::merge_sort;
@@ -341,4 +357,15 @@ mod tests {
341357
#[should_fail]
342358
#[ignore(cfg(windows))]
343359
fn test_empty_replace() { let mut heap = PriorityQueue::new(); heap.replace(5); }
360+
361+
#[test]
362+
fn test_from_iter() {
363+
let xs = ~[9u, 8, 7, 6, 5, 4, 3, 2, 1];
364+
365+
let mut q: PriorityQueue<uint> = xs.rev_iter().transform(|&x| x).collect();
366+
367+
for xs.iter().advance |&x| {
368+
assert_eq!(q.pop(), x);
369+
}
370+
}
344371
}

src/libextra/treemap.rs

+47
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use std::num;
1717
use std::util::{swap, replace};
18+
use std::iterator::FromIterator;
1819

1920
// This is implemented as an AA tree, which is a simplified variation of
2021
// a red-black tree where red (horizontal) nodes can only be added
@@ -699,6 +700,30 @@ fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
699700
};
700701
}
701702

703+
impl<K: TotalOrd, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for TreeMap<K, V> {
704+
pub fn from_iterator(iter: &mut T) -> TreeMap<K, V> {
705+
let mut map = TreeMap::new();
706+
707+
for iter.advance |(k, v)| {
708+
map.insert(k, v);
709+
}
710+
711+
map
712+
}
713+
}
714+
715+
impl<T: TotalOrd, Iter: Iterator<T>> FromIterator<T, Iter> for TreeSet<T> {
716+
pub fn from_iterator(iter: &mut Iter) -> TreeSet<T> {
717+
let mut set = TreeSet::new();
718+
719+
for iter.advance |elem| {
720+
set.insert(elem);
721+
}
722+
723+
set
724+
}
725+
}
726+
702727
#[cfg(test)]
703728
mod test_treemap {
704729

@@ -1017,6 +1042,17 @@ mod test_treemap {
10171042
i += 1;
10181043
}
10191044
}
1045+
1046+
#[test]
1047+
fn test_from_iter() {
1048+
let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1049+
1050+
let map: TreeMap<int, int> = xs.iter().transform(|&x| x).collect();
1051+
1052+
for xs.iter().advance |&(k, v)| {
1053+
assert_eq!(map.find(&k), Some(&v));
1054+
}
1055+
}
10201056
}
10211057

10221058
#[cfg(test)]
@@ -1244,4 +1280,15 @@ mod test_set {
12441280
assert_eq!(m.pop(&1), Some(2));
12451281
assert_eq!(m.pop(&1), None);
12461282
}
1283+
1284+
#[test]
1285+
fn test_from_iter() {
1286+
let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9];
1287+
1288+
let set: TreeSet<int> = xs.iter().transform(|&x| x).collect();
1289+
1290+
for xs.iter().advance |x: &int| {
1291+
assert!(set.contains(x));
1292+
}
1293+
}
12471294
}

src/libstd/hashmap.rs

+49-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
1919
use cmp::{Eq, Equiv};
2020
use hash::Hash;
21-
use iterator::{Iterator, IteratorUtil};
21+
use iterator::{Iterator, IteratorUtil, FromIterator};
2222
use num;
2323
use option::{None, Option, Some};
2424
use rand::RngUtil;
@@ -612,6 +612,18 @@ impl<'self, K> Iterator<&'self K> for HashSetIterator<'self, K> {
612612
}
613613
}
614614

615+
impl<K: Eq + Hash, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for HashMap<K, V> {
616+
pub fn from_iterator(iter: &mut T) -> HashMap<K, V> {
617+
let (lower, _) = iter.size_hint();
618+
let mut map = HashMap::with_capacity(lower);
619+
620+
for iter.advance |(k, v)| {
621+
map.insert(k, v);
622+
}
623+
624+
map
625+
}
626+
}
615627

616628
/// An implementation of a hash set using the underlying representation of a
617629
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
@@ -727,6 +739,20 @@ impl<T:Hash + Eq> HashSet<T> {
727739
}
728740
}
729741

742+
impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
743+
pub fn from_iterator(iter: &mut T) -> HashSet<K> {
744+
let (lower, _) = iter.size_hint();
745+
let mut set = HashSet::with_capacity(lower);
746+
747+
for iter.advance |k| {
748+
set.insert(k);
749+
}
750+
751+
set
752+
}
753+
}
754+
755+
730756
#[cfg(test)]
731757
mod test_map {
732758
use container::{Container, Map, Set};
@@ -939,6 +965,17 @@ mod test_map {
939965

940966
assert_eq!(m.find_equiv(&("qux")), None);
941967
}
968+
969+
#[test]
970+
fn test_from_iter() {
971+
let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
972+
973+
let map: HashMap<int, int> = xs.iter().transform(|&x| x).collect();
974+
975+
for xs.iter().advance |&(k, v)| {
976+
assert_eq!(map.find(&k), Some(&v));
977+
}
978+
}
942979
}
943980

944981
#[cfg(test)]
@@ -1120,4 +1157,15 @@ mod test_set {
11201157
}
11211158
assert_eq!(i, expected.len());
11221159
}
1160+
1161+
#[test]
1162+
fn test_from_iter() {
1163+
let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9];
1164+
1165+
let set: HashSet<int> = xs.iter().transform(|&x| x).collect();
1166+
1167+
for xs.iter().advance |x: &int| {
1168+
assert!(set.contains(x));
1169+
}
1170+
}
11231171
}

src/libstd/trie.rs

+66-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! An ordered map and set for integer keys implemented as a radix trie
1212
1313
use prelude::*;
14-
use iterator::IteratorUtil;
14+
use iterator::{IteratorUtil, FromIterator};
1515
use uint;
1616
use util::{swap, replace};
1717

@@ -173,6 +173,18 @@ impl<T> TrieMap<T> {
173173
}
174174
}
175175

176+
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
177+
pub fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
178+
let mut map = TrieMap::new();
179+
180+
for iter.advance |(k, v)| {
181+
map.insert(k, v);
182+
}
183+
184+
map
185+
}
186+
}
187+
176188
#[allow(missing_doc)]
177189
pub struct TrieSet {
178190
priv map: TrieMap<()>
@@ -232,6 +244,18 @@ impl TrieSet {
232244
}
233245
}
234246

247+
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
248+
pub fn from_iterator(iter: &mut Iter) -> TrieSet {
249+
let mut set = TrieSet::new();
250+
251+
for iter.advance |elem| {
252+
set.insert(elem);
253+
}
254+
255+
set
256+
}
257+
}
258+
235259
struct TrieNode<T> {
236260
count: uint,
237261
children: [Child<T>, ..SIZE]
@@ -384,7 +408,7 @@ pub fn check_integrity<T>(trie: &TrieNode<T>) {
384408
}
385409

386410
#[cfg(test)]
387-
mod tests {
411+
mod test_map {
388412
use super::*;
389413
use core::option::{Some, None};
390414
use uint;
@@ -512,6 +536,39 @@ mod tests {
512536
}
513537
}
514538

539+
#[test]
540+
fn test_swap() {
541+
let mut m = TrieMap::new();
542+
assert_eq!(m.swap(1, 2), None);
543+
assert_eq!(m.swap(1, 3), Some(2));
544+
assert_eq!(m.swap(1, 4), Some(3));
545+
}
546+
547+
#[test]
548+
fn test_pop() {
549+
let mut m = TrieMap::new();
550+
m.insert(1, 2);
551+
assert_eq!(m.pop(&1), Some(2));
552+
assert_eq!(m.pop(&1), None);
553+
}
554+
555+
#[test]
556+
fn test_from_iter() {
557+
let xs = ~[(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
558+
559+
let map: TrieMap<int> = xs.iter().transform(|&x| x).collect();
560+
561+
for xs.iter().advance |&(k, v)| {
562+
assert_eq!(map.find(&k), Some(&v));
563+
}
564+
}
565+
}
566+
567+
#[cfg(test)]
568+
mod test_set {
569+
use super::*;
570+
use uint;
571+
515572
#[test]
516573
fn test_sane_chunk() {
517574
let x = 1;
@@ -535,18 +592,13 @@ mod tests {
535592
}
536593

537594
#[test]
538-
fn test_swap() {
539-
let mut m = TrieMap::new();
540-
assert_eq!(m.swap(1, 2), None);
541-
assert_eq!(m.swap(1, 3), Some(2));
542-
assert_eq!(m.swap(1, 4), Some(3));
543-
}
595+
fn test_from_iter() {
596+
let xs = ~[9u, 8, 7, 6, 5, 4, 3, 2, 1];
544597

545-
#[test]
546-
fn test_pop() {
547-
let mut m = TrieMap::new();
548-
m.insert(1, 2);
549-
assert_eq!(m.pop(&1), Some(2));
550-
assert_eq!(m.pop(&1), None);
598+
let set: TrieSet = xs.iter().transform(|&x| x).collect();
599+
600+
for xs.iter().advance |x| {
601+
assert!(set.contains(x));
602+
}
551603
}
552604
}

0 commit comments

Comments
 (0)