From 61eea759b53785fd8233a565de0765ce66fb824d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 24 Jul 2014 22:28:08 -0700 Subject: [PATCH] Add more _equiv methods This should be enough to do everything you'd be able to do before Closes #8 --- phf/src/lib.rs | 90 ++++++++++++++++++++++++++++++++++++++----------- phf/src/test.rs | 26 ++++++++++++++ 2 files changed, 97 insertions(+), 19 deletions(-) diff --git a/phf/src/lib.rs b/phf/src/lib.rs index 486fae9f..2352c91b 100644 --- a/phf/src/lib.rs +++ b/phf/src/lib.rs @@ -90,6 +90,19 @@ impl Index for PhfMap { } impl PhfMap { + /// Returns a reference to the map's internal static instance of the given + /// key. + /// + /// This can be useful for interning schemes. + pub fn find_key(&self, key: &K) -> Option<&K> { + self.get_entry(key, |k| key == k).map(|e| { + let &(ref k, _) = e; + k + }) + } +} + +impl PhfMap { fn get_entry(&self, key: &T, check: |&K| -> bool) -> Option<&(K, V)> { let (g, f1, f2) = shared::hash(key, self.k1, self.k2); @@ -103,17 +116,6 @@ impl PhfMap { } } - /// Returns a reference to the map's internal static instance of the given - /// key. - /// - /// This can be useful for interning schemes. - pub fn find_key(&self, key: &K) -> Option<&K> { - self.get_entry(key, |k| key == k).map(|e| { - let &(ref k, _) = e; - k - }) - } - /// Like `find`, but can operate on any type that is equivalent to a key. pub fn find_equiv>(&self, key: &T) -> Option<&V> { self.get_entry(key, |k| key.equiv(k)).map(|e| { @@ -304,6 +306,22 @@ impl PhfSet { } } +impl PhfSet { + /// Like `contains`, but can operate on any type that is equivalent to a + /// value + #[inline] + pub fn contains_equiv>(&self, key: &U) -> bool { + self.map.find_equiv(key).is_some() + } + + /// Like `find_key`, but can operate on any type that is equivalent to a + /// value + #[inline] + pub fn find_key_equiv>(&self, key: &U) -> Option<&T> { + self.map.find_key_equiv(key) + } +} + impl PhfSet { /// Returns an iterator over the values in the set. /// @@ -401,7 +419,7 @@ impl Collection for PhfOrderedMap { impl Map for PhfOrderedMap { fn find(&self, key: &K) -> Option<&V> { - self.find_entry(key).map(|e| { + self.find_entry(key, |k| k == key).map(|e| { let &(_, ref v) = e; v }) @@ -415,25 +433,45 @@ impl Index for PhfOrderedMap { } impl PhfOrderedMap { - fn find_entry(&self, key: &K) -> Option<&(K, V)> { + /// Returns a reference to the map's internal static instance of the given + /// key. + /// + /// This can be useful for interning schemes. + pub fn find_key(&self, key: &K) -> Option<&K> { + self.find_entry(key, |k| k == key).map(|e| { + let &(ref k, _) = e; + k + }) + } +} + +impl PhfOrderedMap { + fn find_entry(&self, key: &T, check: |&K| -> bool) + -> Option<&(K, V)> { let (g, f1, f2) = shared::hash(key, self.k1, self.k2); let (d1, d2) = self.disps[g % self.disps.len()]; let idx = self.idxs[shared::displace(f1, f2, d1, d2) % self.idxs.len()]; let entry @ &(ref s, _) = &self.entries[idx]; - if s == key { + if check(s) { Some(entry) } else { None } } - /// Returns a reference to the map's internal static instance of the given + /// Like `find`, but can operate on any type that is equivalent to a key. + pub fn find_equiv>(&self, key: &T) -> Option<&V> { + self.find_entry(key, |k| key.equiv(k)).map(|e| { + let &(_, ref v) = e; + v + }) + } + + /// Like `find_key`, but can operate on any type that is equivalent to a /// key. - /// - /// This can be useful for interning schemes. - pub fn find_key(&self, key: &K) -> Option<&K> { - self.find_entry(key).map(|e| { + pub fn find_key_equiv>(&self, key: &T) -> Option<&K> { + self.find_entry(key, |k| key.equiv(k)).map(|e| { let &(ref k, _) = e; k }) @@ -648,6 +686,20 @@ impl PhfOrderedSet { } impl PhfOrderedSet { + /// Like `contains`, but can operate on any type that is equivalent to a + /// value + #[inline] + pub fn contains_equiv>(&self, key: &U) -> bool { + self.map.find_equiv(key).is_some() + } + + /// Like `find_key`, but can operate on any type that is equivalent to a + /// value + #[inline] + pub fn find_key_equiv>(&self, key: &U) -> Option<&T> { + self.map.find_key_equiv(key) + } + /// Returns an iterator over the values in the set. /// /// Values are returned in the same order in which they were defined. diff --git a/phf/src/test.rs b/phf/src/test.rs index 2587e31f..edfa789f 100644 --- a/phf/src/test.rs +++ b/phf/src/test.rs @@ -241,6 +241,15 @@ mod set { assert!(set.contains(&"world")); assert_eq!(2, set.len()); } + + #[test] + fn test_non_static_str_contains() { + static SET: PhfSet<&'static str> = phf_set! { + "hello", + "world", + }; + assert!(SET.contains_equiv(&"hello".to_string().as_slice())); + } } mod ordered_map { @@ -317,6 +326,14 @@ mod ordered_map { ); map["b"]; } + + #[test] + fn test_non_static_str_key() { + static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + "a" => 0, + ); + assert_eq!(Some(&0), map.find_equiv(&"a".to_string().as_slice())); + } } mod ordered_set { @@ -356,4 +373,13 @@ mod ordered_set { let vec = SET.iter().map(|&e| e).collect::>(); assert_eq!(vec, vec!("hello", "there", "world")); } + + #[test] + fn test_non_static_str_contains() { + static SET: PhfOrderedSet<&'static str> = phf_ordered_set! { + "hello", + "world", + }; + assert!(SET.contains_equiv(&"hello".to_string().as_slice())); + } }