1
Fork 0

std: Implement Extendable for hashmap, str and trie

This commit is contained in:
blake2-ppc 2013-07-30 02:17:17 +02:00
parent f8ae526f70
commit 5307d3674e
3 changed files with 67 additions and 30 deletions

View file

@ -19,7 +19,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
use clone::Clone; use clone::Clone;
use cmp::{Eq, Equiv}; use cmp::{Eq, Equiv};
use hash::Hash; use hash::Hash;
use iterator::{Iterator, IteratorUtil, FromIterator, Chain}; use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain};
use num; use num;
use option::{None, Option, Some}; use option::{None, Option, Some};
use rand::RngUtil; use rand::RngUtil;
@ -618,18 +618,22 @@ impl<K> Iterator<K> for HashSetConsumeIterator<K> {
} }
impl<K: Eq + Hash, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for HashMap<K, V> { 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> { fn from_iterator(iter: &mut T) -> HashMap<K, V> {
let (lower, _) = iter.size_hint(); let (lower, _) = iter.size_hint();
let mut map = HashMap::with_capacity(lower); let mut map = HashMap::with_capacity(lower);
map.extend(iter);
for iter.advance |(k, v)| {
map.insert(k, v);
}
map map
} }
} }
impl<K: Eq + Hash, V, T: Iterator<(K, V)>> Extendable<(K, V), T> for HashMap<K, V> {
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 /// An implementation of a hash set using the underlying representation of a
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet` /// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
/// requires that the elements implement the `Eq` and `Hash` traits. /// requires that the elements implement the `Eq` and `Hash` traits.
@ -771,18 +775,22 @@ impl<T:Hash + Eq> HashSet<T> {
} }
impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> { impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
pub fn from_iterator(iter: &mut T) -> HashSet<K> { fn from_iterator(iter: &mut T) -> HashSet<K> {
let (lower, _) = iter.size_hint(); let (lower, _) = iter.size_hint();
let mut set = HashSet::with_capacity(lower); let mut set = HashSet::with_capacity(lower);
set.extend(iter);
for iter.advance |k| {
set.insert(k);
}
set set
} }
} }
impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
fn extend(&mut self, iter: &mut T) {
for iter.advance |k| {
self.insert(k);
}
}
}
// FIXME #7814: use std::iterator::FilterIterator // FIXME #7814: use std::iterator::FilterIterator
/// Building block for Set operation iterators /// Building block for Set operation iterators
pub struct EnvFilterIterator<A, Env, I> { pub struct EnvFilterIterator<A, Env, I> {

View file

@ -23,7 +23,8 @@ use char::Char;
use clone::Clone; use clone::Clone;
use container::{Container, Mutable}; use container::{Container, Mutable};
use iter::Times; 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 libc;
use num::Zero; use num::Zero;
use option::{None, Option, Some}; use option::{None, Option, Some};
@ -2323,13 +2324,23 @@ impl<T: Iterator<char>> FromIterator<char, T> for ~str {
fn from_iterator(iterator: &mut T) -> ~str { fn from_iterator(iterator: &mut T) -> ~str {
let (lower, _) = iterator.size_hint(); let (lower, _) = iterator.size_hint();
let mut buf = with_capacity(lower); let mut buf = with_capacity(lower);
for iterator.advance |ch| { buf.extend(iterator);
buf.push_char(ch)
}
buf buf
} }
} }
impl<T: Iterator<char>> Extendable<char, T> 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 // This works because every lifetime is a sub-lifetime of 'static
impl<'self> Zero for &'self str { impl<'self> Zero for &'self str {
fn zero() -> &'self str { "" } fn zero() -> &'self str { "" }
@ -2503,6 +2514,16 @@ mod tests {
assert_eq!(data, s.as_slice()); 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] #[test]
fn test_clear() { fn test_clear() {
let mut empty = ~""; let mut empty = ~"";

View file

@ -11,7 +11,7 @@
//! An ordered map and set for integer keys implemented as a radix trie //! An ordered map and set for integer keys implemented as a radix trie
use prelude::*; use prelude::*;
use iterator::{IteratorUtil, FromIterator}; use iterator::{IteratorUtil, FromIterator, Extendable};
use uint; use uint;
use util::{swap, replace}; use util::{swap, replace};
@ -155,17 +155,21 @@ impl<T> TrieMap<T> {
} }
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> { impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
pub fn from_iterator(iter: &mut Iter) -> TrieMap<T> { fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
let mut map = TrieMap::new(); let mut map = TrieMap::new();
map.extend(iter);
for iter.advance |(k, v)| {
map.insert(k, v);
}
map map
} }
} }
impl<T, Iter: Iterator<(uint, T)>> Extendable<(uint, T), Iter> for TrieMap<T> {
fn extend(&mut self, iter: &mut Iter) {
for iter.advance |(k, v)| {
self.insert(k, v);
}
}
}
#[allow(missing_doc)] #[allow(missing_doc)]
pub struct TrieSet { pub struct TrieSet {
priv map: TrieMap<()> priv map: TrieMap<()>
@ -222,17 +226,21 @@ impl TrieSet {
} }
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet { impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
pub fn from_iterator(iter: &mut Iter) -> TrieSet { fn from_iterator(iter: &mut Iter) -> TrieSet {
let mut set = TrieSet::new(); let mut set = TrieSet::new();
set.extend(iter);
for iter.advance |elem| {
set.insert(elem);
}
set set
} }
} }
impl<Iter: Iterator<uint>> Extendable<uint, Iter> for TrieSet {
fn extend(&mut self, iter: &mut Iter) {
for iter.advance |elem| {
self.insert(elem);
}
}
}
struct TrieNode<T> { struct TrieNode<T> {
count: uint, count: uint,
children: [Child<T>, ..SIZE] children: [Child<T>, ..SIZE]