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 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<K> Iterator<K> for HashSetConsumeIterator<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> {
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.extend(iter);
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
/// 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<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> {
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.extend(iter);
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
/// Building block for Set operation iterators
pub struct EnvFilterIterator<A, Env, I> {

View file

@ -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<T: Iterator<char>> FromIterator<char, T> 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<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
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 = ~"";

View file

@ -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<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> {
fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
let mut map = TrieMap::new();
for iter.advance |(k, v)| {
map.insert(k, v);
}
map.extend(iter);
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)]
pub struct TrieSet {
priv map: TrieMap<()>
@ -222,17 +226,21 @@ impl 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();
for iter.advance |elem| {
set.insert(elem);
}
set.extend(iter);
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> {
count: uint,
children: [Child<T>, ..SIZE]