mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
auto merge of #15963 : nham/rust/moar_15294, r=alexcrichton
Implements PartialEq/Eq/Clone/Hash/FromIterator/Extendable for SmallIntMap and Clone/Show for TrieMap/TrieSet. cc #15294
This commit is contained in:
commit
d114ddac03
@ -24,6 +24,8 @@ use core::mem::replace;
|
||||
use {Collection, Mutable, Map, MutableMap, MutableSeq};
|
||||
use {vec, slice};
|
||||
use vec::Vec;
|
||||
use hash;
|
||||
use hash::Hash;
|
||||
|
||||
/// A map optimized for small integer keys.
|
||||
///
|
||||
@ -58,6 +60,7 @@ use vec::Vec;
|
||||
/// months.clear();
|
||||
/// assert!(months.is_empty());
|
||||
/// ```
|
||||
#[deriving(PartialEq, Eq)]
|
||||
pub struct SmallIntMap<T> {
|
||||
v: Vec<Option<T>>,
|
||||
}
|
||||
@ -151,6 +154,27 @@ impl<V> Default for SmallIntMap<V> {
|
||||
fn default() -> SmallIntMap<V> { SmallIntMap::new() }
|
||||
}
|
||||
|
||||
impl<V:Clone> Clone for SmallIntMap<V> {
|
||||
#[inline]
|
||||
fn clone(&self) -> SmallIntMap<V> {
|
||||
SmallIntMap { v: self.v.clone() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn clone_from(&mut self, source: &SmallIntMap<V>) {
|
||||
self.v.reserve(source.v.len());
|
||||
for (i, w) in self.v.mut_iter().enumerate() {
|
||||
*w = source.v[i].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <S: hash::Writer, T: Hash<S>> Hash<S> for SmallIntMap<T> {
|
||||
fn hash(&self, state: &mut S) {
|
||||
self.v.hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> SmallIntMap<V> {
|
||||
/// Create an empty SmallIntMap.
|
||||
///
|
||||
@ -362,6 +386,22 @@ impl<V: fmt::Show> fmt::Show for SmallIntMap<V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> FromIterator<(uint, V)> for SmallIntMap<V> {
|
||||
fn from_iter<Iter: Iterator<(uint, V)>>(iter: Iter) -> SmallIntMap<V> {
|
||||
let mut map = SmallIntMap::new();
|
||||
map.extend(iter);
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Extendable<(uint, V)> for SmallIntMap<V> {
|
||||
fn extend<Iter: Iterator<(uint, V)>>(&mut self, mut iter: Iter) {
|
||||
for (k, v) in iter {
|
||||
self.insert(k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! iterator {
|
||||
(impl $name:ident -> $elem:ty, $getter:ident) => {
|
||||
impl<'a, T> Iterator<$elem> for $name<'a, T> {
|
||||
@ -446,8 +486,10 @@ pub type Values<'a, T> =
|
||||
#[cfg(test)]
|
||||
mod test_map {
|
||||
use std::prelude::*;
|
||||
use vec::Vec;
|
||||
use hash;
|
||||
|
||||
use {Map, MutableMap, Mutable};
|
||||
use {Map, MutableMap, Mutable, MutableSeq};
|
||||
use super::SmallIntMap;
|
||||
|
||||
#[test]
|
||||
@ -698,6 +740,63 @@ mod test_map {
|
||||
assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
|
||||
assert_eq!(format!("{}", empty), "{}".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let mut a = SmallIntMap::new();
|
||||
|
||||
a.insert(1, 'x');
|
||||
a.insert(4, 'y');
|
||||
a.insert(6, 'z');
|
||||
|
||||
assert!(a.clone() == a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq() {
|
||||
let mut a = SmallIntMap::new();
|
||||
let mut b = SmallIntMap::new();
|
||||
|
||||
assert!(a == b);
|
||||
assert!(a.insert(0, 5i));
|
||||
assert!(a != b);
|
||||
assert!(b.insert(0, 4i));
|
||||
assert!(a != b);
|
||||
assert!(a.insert(5, 19));
|
||||
assert!(a != b);
|
||||
assert!(!b.insert(0, 5));
|
||||
assert!(a != b);
|
||||
assert!(b.insert(5, 19));
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
let mut x = SmallIntMap::new();
|
||||
let mut y = SmallIntMap::new();
|
||||
|
||||
assert!(hash::hash(&x) == hash::hash(&y));
|
||||
x.insert(1, 'a');
|
||||
x.insert(2, 'b');
|
||||
x.insert(3, 'c');
|
||||
|
||||
y.insert(3, 'c');
|
||||
y.insert(2, 'b');
|
||||
y.insert(1, 'a');
|
||||
|
||||
assert!(hash::hash(&x) == hash::hash(&y));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_iter() {
|
||||
let xs: Vec<(uint, char)> = vec![(1u, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
|
||||
|
||||
let map: SmallIntMap<char> = xs.iter().map(|&x| x).collect();
|
||||
|
||||
for &(k, v) in xs.iter() {
|
||||
assert_eq!(map.find(&k), Some(&v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -15,6 +15,8 @@ use core::prelude::*;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use core::default::Default;
|
||||
use core::fmt;
|
||||
use core::fmt::Show;
|
||||
use core::mem::zeroed;
|
||||
use core::mem;
|
||||
use core::uint;
|
||||
@ -31,6 +33,7 @@ static SIZE: uint = 1 << SHIFT;
|
||||
static MASK: uint = SIZE - 1;
|
||||
static NUM_CHUNKS: uint = uint::BITS / SHIFT;
|
||||
|
||||
#[deriving(Clone)]
|
||||
enum Child<T> {
|
||||
Internal(Box<TrieNode<T>>),
|
||||
External(uint, T),
|
||||
@ -75,6 +78,7 @@ enum Child<T> {
|
||||
/// map.clear();
|
||||
/// assert!(map.is_empty());
|
||||
/// ```
|
||||
#[deriving(Clone)]
|
||||
pub struct TrieMap<T> {
|
||||
root: TrieNode<T>,
|
||||
length: uint
|
||||
@ -89,6 +93,19 @@ impl<T: PartialEq> PartialEq for TrieMap<T> {
|
||||
|
||||
impl<T: Eq> Eq for TrieMap<T> {}
|
||||
|
||||
impl<T: Show> Show for TrieMap<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "{{"));
|
||||
|
||||
for (i, (k, v)) in self.iter().enumerate() {
|
||||
if i != 0 { try!(write!(f, ", ")); }
|
||||
try!(write!(f, "{}: {}", k, *v));
|
||||
}
|
||||
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Collection for TrieMap<T> {
|
||||
/// Return the number of elements in the map.
|
||||
#[inline]
|
||||
@ -500,11 +517,24 @@ impl<S: Writer, T: Hash<S>> Hash<S> for TrieMap<T> {
|
||||
/// set.clear();
|
||||
/// assert!(set.is_empty());
|
||||
/// ```
|
||||
#[deriving(Hash, PartialEq, Eq)]
|
||||
#[deriving(Clone, Hash, PartialEq, Eq)]
|
||||
pub struct TrieSet {
|
||||
map: TrieMap<()>
|
||||
}
|
||||
|
||||
impl Show for TrieSet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "{{"));
|
||||
|
||||
for (i, x) in self.iter().enumerate() {
|
||||
if i != 0 { try!(write!(f, ", ")); }
|
||||
try!(write!(f, "{}", x));
|
||||
}
|
||||
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Collection for TrieSet {
|
||||
/// Return the number of elements in the set.
|
||||
#[inline]
|
||||
@ -673,6 +703,19 @@ struct TrieNode<T> {
|
||||
children: [Child<T>, ..SIZE]
|
||||
}
|
||||
|
||||
impl<T:Clone> Clone for TrieNode<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> TrieNode<T> {
|
||||
let ch = &self.children;
|
||||
TrieNode {
|
||||
count: self.count,
|
||||
children: [ch[0].clone(), ch[1].clone(), ch[2].clone(), ch[3].clone(),
|
||||
ch[4].clone(), ch[5].clone(), ch[6].clone(), ch[7].clone(),
|
||||
ch[8].clone(), ch[9].clone(), ch[10].clone(), ch[11].clone(),
|
||||
ch[12].clone(), ch[13].clone(), ch[14].clone(), ch[15].clone()]}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TrieNode<T> {
|
||||
#[inline]
|
||||
fn new() -> TrieNode<T> {
|
||||
@ -1237,6 +1280,17 @@ mod test_map {
|
||||
assert!(m_upper.iter().all(|(_, &x)| x == 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let mut a = TrieMap::new();
|
||||
|
||||
a.insert(1, 'a');
|
||||
a.insert(2, 'b');
|
||||
a.insert(3, 'c');
|
||||
|
||||
assert!(a.clone() == a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq() {
|
||||
let mut a = TrieMap::new();
|
||||
@ -1271,6 +1325,20 @@ mod test_map {
|
||||
|
||||
assert!(hash::hash(&x) == hash::hash(&y));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let mut map = TrieMap::new();
|
||||
let empty: TrieMap<uint> = TrieMap::new();
|
||||
|
||||
map.insert(1, 'a');
|
||||
map.insert(2, 'b');
|
||||
|
||||
let map_str = format!("{}", map);
|
||||
|
||||
assert!(map_str == "{1: a, 2: b}".to_string());
|
||||
assert_eq!(format!("{}", empty), "{}".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -1420,4 +1488,29 @@ mod test_set {
|
||||
assert!(set.contains(x));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let mut set = TrieSet::new();
|
||||
let empty = TrieSet::new();
|
||||
|
||||
set.insert(1);
|
||||
set.insert(2);
|
||||
|
||||
let set_str = format!("{}", set);
|
||||
|
||||
assert!(set_str == "{1, 2}".to_string());
|
||||
assert_eq!(format!("{}", empty), "{}".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let mut a = TrieSet::new();
|
||||
|
||||
a.insert(1);
|
||||
a.insert(2);
|
||||
a.insert(3);
|
||||
|
||||
assert!(a.clone() == a);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user