about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-07-27 06:16:14 +0000
committerbors <bors@rust-lang.org>2014-07-27 06:16:14 +0000
commitd114ddac030d6ed63b3076ccc0e7db081c0a9409 (patch)
tree07123ded4a678b1be386d2756f4456f5122be60a /src
parent2de3fad72c7e845e0ba8c29d68003b163161576d (diff)
parentfadbc0b88bb39ac42aa4874e4a90df53a778ef59 (diff)
downloadrust-d114ddac030d6ed63b3076ccc0e7db081c0a9409.tar.gz
rust-d114ddac030d6ed63b3076ccc0e7db081c0a9409.zip
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 
Diffstat (limited to 'src')
-rw-r--r--src/libcollections/smallintmap.rs101
-rw-r--r--src/libcollections/trie.rs95
2 files changed, 194 insertions, 2 deletions
diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs
index 7266790ba4f..a60f80b9aef 100644
--- a/src/libcollections/smallintmap.rs
+++ b/src/libcollections/smallintmap.rs
@@ -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)]
diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs
index 14ab122f0a4..1ac05fbd562 100644
--- a/src/libcollections/trie.rs
+++ b/src/libcollections/trie.rs
@@ -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> {
@@ -1238,6 +1281,17 @@ mod test_map {
     }
 
     #[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();
         let mut b = 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);
+    }
 }