From 5307d3674e2df2baef0e37125a98227590fc43d2 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Tue, 30 Jul 2013 02:17:17 +0200 Subject: [PATCH] std: Implement Extendable for hashmap, str and trie --- src/libstd/hashmap.rs | 34 +++++++++++++++++++++------------- src/libstd/str.rs | 29 +++++++++++++++++++++++++---- src/libstd/trie.rs | 34 +++++++++++++++++++++------------- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index a9a11b611d6..e43293f3212 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -19,7 +19,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; use clone::Clone; use cmp::{Eq, Equiv}; use hash::Hash; -use iterator::{Iterator, IteratorUtil, FromIterator, Chain}; +use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain}; use num; use option::{None, Option, Some}; use rand::RngUtil; @@ -618,18 +618,22 @@ impl Iterator for HashSetConsumeIterator { } impl> FromIterator<(K, V), T> for HashMap { - pub fn from_iterator(iter: &mut T) -> HashMap { + 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.extend(iter); map } } +impl> Extendable<(K, V), T> for HashMap { + fn extend(&mut self, iter: &mut T) { + for iter.advance |(k, v)| { + self.insert(k, v); + } + } +} + /// An implementation of a hash set using the underlying representation of a /// HashMap where the value is (). As with the `HashMap` type, a `HashSet` /// requires that the elements implement the `Eq` and `Hash` traits. @@ -771,18 +775,22 @@ impl HashSet { } impl> FromIterator for HashSet { - pub fn from_iterator(iter: &mut T) -> HashSet { + 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.extend(iter); set } } +impl> Extendable for HashSet { + fn extend(&mut self, iter: &mut T) { + for iter.advance |k| { + self.insert(k); + } + } +} + // FIXME #7814: use std::iterator::FilterIterator /// Building block for Set operation iterators pub struct EnvFilterIterator { diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 2aa5f586dd8..fff859321fb 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -23,7 +23,8 @@ use char::Char; use clone::Clone; use container::{Container, Mutable}; use iter::Times; -use iterator::{Iterator, FromIterator, IteratorUtil, Filter, AdditiveIterator, Map}; +use iterator::{Iterator, FromIterator, Extendable, IteratorUtil}; +use iterator::{Filter, AdditiveIterator, Map}; use libc; use num::Zero; use option::{None, Option, Some}; @@ -2323,13 +2324,23 @@ impl> FromIterator for ~str { fn from_iterator(iterator: &mut T) -> ~str { let (lower, _) = iterator.size_hint(); let mut buf = with_capacity(lower); - for iterator.advance |ch| { - buf.push_char(ch) - } + buf.extend(iterator); buf } } +impl> Extendable for ~str { + #[inline] + fn extend(&mut self, iterator: &mut T) { + let (lower, _) = iterator.size_hint(); + let reserve = lower + self.len(); + self.reserve_at_least(reserve); + for iterator.advance |ch| { + self.push_char(ch) + } + } +} + // This works because every lifetime is a sub-lifetime of 'static impl<'self> Zero for &'self str { fn zero() -> &'self str { "" } @@ -2503,6 +2514,16 @@ mod tests { assert_eq!(data, s.as_slice()); } + #[test] + fn test_extend() { + let data = ~"ประเทศไทย中"; + let mut cpy = data.clone(); + let other = "abc"; + let mut it = other.iter(); + cpy.extend(&mut it); + assert_eq!(cpy, data + other); + } + #[test] fn test_clear() { let mut empty = ~""; diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 4665f361340..6a0554a8c8d 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, FromIterator}; +use iterator::{IteratorUtil, FromIterator, Extendable}; use uint; use util::{swap, replace}; @@ -155,17 +155,21 @@ impl TrieMap { } impl> FromIterator<(uint, T), Iter> for TrieMap { - pub fn from_iterator(iter: &mut Iter) -> TrieMap { + fn from_iterator(iter: &mut Iter) -> TrieMap { let mut map = TrieMap::new(); - - for iter.advance |(k, v)| { - map.insert(k, v); - } - + map.extend(iter); map } } +impl> Extendable<(uint, T), Iter> for TrieMap { + fn extend(&mut self, iter: &mut Iter) { + for iter.advance |(k, v)| { + self.insert(k, v); + } + } +} + #[allow(missing_doc)] pub struct TrieSet { priv map: TrieMap<()> @@ -222,17 +226,21 @@ impl TrieSet { } impl> FromIterator for TrieSet { - pub fn from_iterator(iter: &mut Iter) -> TrieSet { + fn from_iterator(iter: &mut Iter) -> TrieSet { let mut set = TrieSet::new(); - - for iter.advance |elem| { - set.insert(elem); - } - + set.extend(iter); set } } +impl> Extendable for TrieSet { + fn extend(&mut self, iter: &mut Iter) { + for iter.advance |elem| { + self.insert(elem); + } + } +} + struct TrieNode { count: uint, children: [Child, ..SIZE]