From f6ce641e5676be8d70e961f020d79fc3d6dcfb74 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 9 Jul 2014 21:20:53 -0700 Subject: [PATCH] Parameterize the key type of PhfOrdered* --- phf/src/lib.rs | 172 +++++++++++++++++++++++++----------------------- phf/src/test.rs | 26 ++++---- 2 files changed, 102 insertions(+), 96 deletions(-) diff --git a/phf/src/lib.rs b/phf/src/lib.rs index ae1e8c54..9070f103 100644 --- a/phf/src/lib.rs +++ b/phf/src/lib.rs @@ -334,7 +334,7 @@ impl<'a, T> Iterator<&'a T> for PhfSetValues<'a, T> { /// /// use phf::PhfOrderedMap; /// -/// static MY_MAP: PhfOrderedMap = phf_ordered_map! { +/// static MY_MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map! { /// "hello" => 10, /// "world" => 11, /// }; @@ -347,7 +347,7 @@ impl<'a, T> Iterator<&'a T> for PhfSetValues<'a, T> { /// The fields of this struct are public so that they may be initialized by the /// `phf_ordered_map` macro. They are subject to change at any time and should /// never be accessed directly. -pub struct PhfOrderedMap { +pub struct PhfOrderedMap { #[doc(hidden)] pub k1: u64, #[doc(hidden)] @@ -357,14 +357,14 @@ pub struct PhfOrderedMap { #[doc(hidden)] pub idxs: &'static [uint], #[doc(hidden)] - pub entries: &'static [(&'static str, T)], + pub entries: &'static [(K, V)], } -impl fmt::Show for PhfOrderedMap { +impl fmt::Show for PhfOrderedMap { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "{{")); let mut first = true; - for (k, v) in self.entries() { + for &(ref k, ref v) in self.entries() { if !first { try!(write!(fmt, ", ")); } @@ -375,26 +375,29 @@ impl fmt::Show for PhfOrderedMap { } } -impl Collection for PhfOrderedMap { +impl Collection for PhfOrderedMap { fn len(&self) -> uint { self.entries.len() } } -impl<'a, T> Map<&'a str, T> for PhfOrderedMap { - fn find<'a>(&'a self, key: & &str) -> Option<&'a T> { - self.find_entry(key).map(|&(_, ref v)| v) +impl<'a, K: Hash+Eq, V> Map for PhfOrderedMap { + fn find<'a>(&'a self, key: &K) -> Option<&'a V> { + self.find_entry(key).map(|e| { + let &(_, ref v) = e; + v + }) } } -impl PhfOrderedMap { - fn find_entry(&self, key: & &str) -> Option<&'static (&'static str, T)> { +impl PhfOrderedMap { + fn find_entry<'a>(&'a self, key: &K) -> Option<&'a (K, V)> { let (g, f1, f2) = hash(key, self.k1, self.k2); let (d1, d2) = self.disps[g % self.disps.len()]; let idx = self.idxs[displace(f1, f2, d1, d2) % self.idxs.len()]; - let entry @ &(s, _) = &self.entries[idx]; + let entry @ &(ref s, _) = &self.entries[idx]; - if s == *key { + if s == key { Some(entry) } else { None @@ -405,40 +408,45 @@ impl PhfOrderedMap { /// key. /// /// This can be useful for interning schemes. - pub fn find_key(&self, key: & &str) -> Option<&'static str> { - self.find_entry(key).map(|&(s, _)| s) + pub fn find_key<'a>(&'a self, key: &K) -> Option<&'a K> { + self.find_entry(key).map(|e| { + let &(ref k, _) = e; + k + }) } +} +impl PhfOrderedMap { /// Returns an iterator over the key/value pairs in the map. /// /// Entries are retuned in the same order in which they were defined. - pub fn entries<'a>(&'a self) -> PhfOrderedMapEntries<'a, T> { + pub fn entries<'a>(&'a self) -> PhfOrderedMapEntries<'a, K, V> { PhfOrderedMapEntries { iter: self.entries.iter() } } /// Returns an iterator over the keys in the map. /// /// Keys are returned in the same order in which they were defined. - pub fn keys<'a>(&'a self) -> PhfOrderedMapKeys<'a, T> { + pub fn keys<'a>(&'a self) -> PhfOrderedMapKeys<'a, K, V> { PhfOrderedMapKeys { iter: self.entries() } } /// Returns an iterator over the values in the map. /// /// Values are returned in the same order in which they were defined. - pub fn values<'a>(&'a self) -> PhfOrderedMapValues<'a, T> { + pub fn values<'a>(&'a self) -> PhfOrderedMapValues<'a, K, V> { PhfOrderedMapValues { iter: self.entries() } } } /// An iterator over the entries in a `PhfOrderedMap`. -pub struct PhfOrderedMapEntries<'a, T> { - iter: slice::Items<'a, (&'static str, T)>, +pub struct PhfOrderedMapEntries<'a, K, V> { + iter: slice::Items<'a, (K, V)>, } -impl<'a, T> Iterator<(&'static str, &'a T)> for PhfOrderedMapEntries<'a, T> { - fn next(&mut self) -> Option<(&'static str, &'a T)> { - self.iter.next().map(|&(key, ref value)| (key, value)) +impl<'a, K, V> Iterator<&'a (K, V)> for PhfOrderedMapEntries<'a, K, V> { + fn next(&mut self) -> Option<&'a (K, V)> { + self.iter.next() } fn size_hint(&self) -> (uint, Option) { @@ -446,38 +454,34 @@ impl<'a, T> Iterator<(&'static str, &'a T)> for PhfOrderedMapEntries<'a, T> { } } -impl<'a, T> DoubleEndedIterator<(&'static str, &'a T)> - for PhfOrderedMapEntries<'a, T> { - fn next_back(&mut self) -> Option<(&'static str, &'a T)> { - self.iter.next_back().map(|&(key, ref value)| (key, value)) +impl<'a, K, V> DoubleEndedIterator<&'a (K, V)> + for PhfOrderedMapEntries<'a, K, V> { + fn next_back(&mut self) -> Option<&'a (K, V)> { + self.iter.next_back() } } -impl<'a, T> RandomAccessIterator<(&'static str, &'a T)> - for PhfOrderedMapEntries<'a, T> { +impl<'a, K, V> RandomAccessIterator<&'a (K, V)> + for PhfOrderedMapEntries<'a, K, V> { fn indexable(&self) -> uint { self.iter.indexable() } - fn idx(&mut self, index: uint) -> Option<(&'static str, &'a T)> { - // FIXME: mozilla/rust#13167 - self.iter.idx(index).map(|pair| { - let &(key, ref value) = pair; - (key, value) - }) + fn idx(&mut self, index: uint) -> Option<&'a (K, V)> { + self.iter.idx(index) } } -impl<'a, T> ExactSize<(&'static str, &'a T)> for PhfOrderedMapEntries<'a, T> {} +impl<'a, K, V> ExactSize<&'a (K, V)> for PhfOrderedMapEntries<'a, K, V> {} /// An iterator over the keys in a `PhfOrderedMap`. -pub struct PhfOrderedMapKeys<'a, T> { - iter: PhfOrderedMapEntries<'a, T>, +pub struct PhfOrderedMapKeys<'a, K, V> { + iter: PhfOrderedMapEntries<'a, K, V>, } -impl<'a, T> Iterator<&'static str> for PhfOrderedMapKeys<'a, T> { - fn next(&mut self) -> Option<&'static str> { - self.iter.next().map(|(key, _)| key) +impl<'a, K, V> Iterator<&'a K> for PhfOrderedMapKeys<'a, K, V> { + fn next(&mut self) -> Option<&'a K> { + self.iter.next().map(|&(ref key, _)| key) } fn size_hint(&self) -> (uint, Option) { @@ -485,32 +489,32 @@ impl<'a, T> Iterator<&'static str> for PhfOrderedMapKeys<'a, T> { } } -impl<'a, T> DoubleEndedIterator<&'static str> for PhfOrderedMapKeys<'a, T> { - fn next_back(&mut self) -> Option<&'static str> { - self.iter.next_back().map(|(key, _)| key) +impl<'a, K, V> DoubleEndedIterator<&'a K> for PhfOrderedMapKeys<'a, K, V> { + fn next_back(&mut self) -> Option<&'a K> { + self.iter.next_back().map(|&(ref key, _)| key) } } -impl<'a, T> RandomAccessIterator<&'static str> for PhfOrderedMapKeys<'a, T> { +impl<'a, K, V> RandomAccessIterator<&'a K> for PhfOrderedMapKeys<'a, K, V> { fn indexable(&self) -> uint { self.iter.indexable() } - fn idx(&mut self, index: uint) -> Option<&'static str> { - self.iter.idx(index).map(|(key, _)| key) + fn idx(&mut self, index: uint) -> Option<&'a K> { + self.iter.idx(index).map(|&(ref key, _)| key) } } -impl<'a, T> ExactSize<&'static str> for PhfOrderedMapKeys<'a, T> {} +impl<'a, K, V> ExactSize<&'a K> for PhfOrderedMapKeys<'a, K, V> {} /// An iterator over the values in a `PhfOrderedMap`. -pub struct PhfOrderedMapValues<'a, T> { - iter: PhfOrderedMapEntries<'a, T>, +pub struct PhfOrderedMapValues<'a, K, V> { + iter: PhfOrderedMapEntries<'a, K, V>, } -impl<'a, T> Iterator<&'a T> for PhfOrderedMapValues<'a, T> { - fn next(&mut self) -> Option<&'a T> { - self.iter.next().map(|(_, value)| value) +impl<'a, K, V> Iterator<&'a V> for PhfOrderedMapValues<'a, K, V> { + fn next(&mut self) -> Option<&'a V> { + self.iter.next().map(|&(_, ref value)| value) } fn size_hint(&self) -> (uint, Option) { @@ -518,23 +522,23 @@ impl<'a, T> Iterator<&'a T> for PhfOrderedMapValues<'a, T> { } } -impl<'a, T> DoubleEndedIterator<&'a T> for PhfOrderedMapValues<'a, T> { - fn next_back(&mut self) -> Option<&'a T> { - self.iter.next_back().map(|(_, value)| value) +impl<'a, K, V> DoubleEndedIterator<&'a V> for PhfOrderedMapValues<'a, K, V> { + fn next_back(&mut self) -> Option<&'a V> { + self.iter.next_back().map(|&(_, ref value)| value) } } -impl<'a, T> RandomAccessIterator<&'a T> for PhfOrderedMapValues<'a, T> { +impl<'a, K, V> RandomAccessIterator<&'a V> for PhfOrderedMapValues<'a, K, V> { fn indexable(&self) -> uint { self.iter.indexable() } - fn idx(&mut self, index: uint) -> Option<&'a T> { - self.iter.idx(index).map(|(_, value)| value) + fn idx(&mut self, index: uint) -> Option<&'a V> { + self.iter.idx(index).map(|&(_, ref value)| value) } } -impl<'a, T> ExactSize<&'a T> for PhfOrderedMapValues<'a, T> {} +impl<'a, K, V> ExactSize<&'a V> for PhfOrderedMapValues<'a, K, V> {} /// An order-preserving immutable set constructed at compile time. /// @@ -551,7 +555,7 @@ impl<'a, T> ExactSize<&'a T> for PhfOrderedMapValues<'a, T> {} /// /// use phf::PhfOrderedSet; /// -/// static MY_SET: PhfOrderedSet = phf_ordered_set! { +/// static MY_SET: PhfOrderedSet<&'static str> = phf_ordered_set! { /// "hello", /// "world", /// }; @@ -564,12 +568,12 @@ impl<'a, T> ExactSize<&'a T> for PhfOrderedMapValues<'a, T> {} /// The fields of this struct are public so that they may be initialized by the /// `phf_ordered_set` macro. They are subject to change at any time and should /// never be accessed directly. -pub struct PhfOrderedSet { +pub struct PhfOrderedSet { #[doc(hidden)] - pub map: PhfOrderedMap<()>, + pub map: PhfOrderedMap, } -impl fmt::Show for PhfOrderedSet { +impl fmt::Show for PhfOrderedSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "{{")); let mut first = true; @@ -584,57 +588,59 @@ impl fmt::Show for PhfOrderedSet { } } -impl Collection for PhfOrderedSet { +impl Collection for PhfOrderedSet { #[inline] fn len(&self) -> uint { self.map.len() } } -impl<'a> Set<&'a str> for PhfOrderedSet { +impl Set for PhfOrderedSet { #[inline] - fn contains(&self, value: & &'a str) -> bool { + fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } #[inline] - fn is_disjoint(&self, other: &PhfOrderedSet) -> bool { - !self.iter().any(|value| other.contains(&value)) + fn is_disjoint(&self, other: &PhfOrderedSet) -> bool { + !self.iter().any(|value| other.contains(value)) } #[inline] - fn is_subset(&self, other: &PhfOrderedSet) -> bool { - self.iter().all(|value| other.contains(&value)) + fn is_subset(&self, other: &PhfOrderedSet) -> bool { + self.iter().all(|value| other.contains(value)) } } -impl PhfOrderedSet { +impl PhfOrderedSet { /// Returns a reference to the set's internal static instance of the given /// key. /// /// This can be useful for interning schemes. #[inline] - pub fn find_key(&self, key: & &str) -> Option<&'static str> { + pub fn find_key<'a>(&'a self, key: &T) -> Option<&'a T> { self.map.find_key(key) } +} +impl PhfOrderedSet { /// Returns an iterator over the values in the set. /// /// Values are returned in the same order in which they were defined. #[inline] - pub fn iter<'a>(&'a self) -> PhfOrderedSetValues<'a> { + pub fn iter<'a>(&'a self) -> PhfOrderedSetValues<'a, T> { PhfOrderedSetValues { iter: self.map.keys() } } } /// An iterator over the values in a `PhfOrderedSet`. -pub struct PhfOrderedSetValues<'a> { - iter: PhfOrderedMapKeys<'a, ()>, +pub struct PhfOrderedSetValues<'a, T> { + iter: PhfOrderedMapKeys<'a, T, ()>, } -impl<'a> Iterator<&'static str> for PhfOrderedSetValues<'a> { +impl<'a, T> Iterator<&'a T> for PhfOrderedSetValues<'a, T> { #[inline] - fn next(&mut self) -> Option<&'static str> { + fn next(&mut self) -> Option<&'a T> { self.iter.next() } @@ -644,23 +650,23 @@ impl<'a> Iterator<&'static str> for PhfOrderedSetValues<'a> { } } -impl<'a> DoubleEndedIterator<&'static str> for PhfOrderedSetValues<'a> { +impl<'a, T> DoubleEndedIterator<&'a T> for PhfOrderedSetValues<'a, T> { #[inline] - fn next_back(&mut self) -> Option<&'static str> { + fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() } } -impl<'a> RandomAccessIterator<&'static str> for PhfOrderedSetValues<'a> { +impl<'a, T> RandomAccessIterator<&'a T> for PhfOrderedSetValues<'a, T> { #[inline] fn indexable(&self) -> uint { self.iter.indexable() } #[inline] - fn idx(&mut self, index: uint) -> Option<&'static str> { + fn idx(&mut self, index: uint) -> Option<&'a T> { self.iter.idx(index) } } -impl<'a> ExactSize<&'static str> for PhfOrderedSetValues<'a> {} +impl<'a, T> ExactSize<&'a T> for PhfOrderedSetValues<'a, T> {} diff --git a/phf/src/test.rs b/phf/src/test.rs index 2a948eed..ef7ee04d 100644 --- a/phf/src/test.rs +++ b/phf/src/test.rs @@ -159,18 +159,18 @@ mod ordered_map { use phf::PhfOrderedMap; #[allow(dead_code)] - static TRAILING_COMMA: PhfOrderedMap = phf_ordered_map!( + static TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, ); #[allow(dead_code)] - static NO_TRAILING_COMMA: PhfOrderedMap = phf_ordered_map!( + static NO_TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10 ); #[test] fn test_two() { - static map: PhfOrderedMap = phf_ordered_map!( + static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, ); @@ -182,29 +182,29 @@ mod ordered_map { #[test] fn test_entries() { - static MAP: PhfOrderedMap = phf_ordered_map!( + static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, "baz" => 12, ); - let vec = MAP.entries().map(|(k, &v)| (k, v)).collect::>(); + let vec = MAP.entries().map(|&(k, v)| (k, v)).collect::>(); assert_eq!(vec, vec!(("foo", 10i), ("bar", 11), ("baz", 12))); } #[test] fn test_keys() { - static MAP: PhfOrderedMap = phf_ordered_map!( + static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, "baz" => 12, ); - let vec = MAP.keys().collect::>(); + let vec = MAP.keys().map(|&e| e).collect::>(); assert_eq!(vec, vec!("foo", "bar", "baz")); } #[test] fn test_values() { - static MAP: PhfOrderedMap = phf_ordered_map!( + static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, "baz" => 12, @@ -218,18 +218,18 @@ mod ordered_set { use phf::PhfOrderedSet; #[allow(dead_code)] - static TRAILING_COMMA: PhfOrderedSet = phf_ordered_set! { + static TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! { "foo", }; #[allow(dead_code)] - static NO_TRAILING_COMMA: PhfOrderedSet = phf_ordered_set! { + static NO_TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! { "foo" }; #[test] fn test_two() { - static SET: PhfOrderedSet = phf_ordered_set! { + static SET: PhfOrderedSet<&'static str> = phf_ordered_set! { "hello", "there", "world", @@ -243,12 +243,12 @@ mod ordered_set { #[test] fn test_iter() { - static SET: PhfOrderedSet = phf_ordered_set! { + static SET: PhfOrderedSet<&'static str> = phf_ordered_set! { "hello", "there", "world", }; - let vec = SET.iter().collect::>(); + let vec = SET.iter().map(|&e| e).collect::>(); assert_eq!(vec, vec!("hello", "there", "world")); } }