From f17bae1c34380b0566207df8e54807f3773109ce Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 1 Nov 2014 14:17:26 -0700 Subject: [PATCH] Switch over PhfOrderedMap to new naming scheme --- phf/src/lib.rs | 249 +--------------------------------------- phf/src/ordered_map.rs | 250 +++++++++++++++++++++++++++++++++++++++++ phf/tests/test.rs | 22 ++-- phf_mac/src/util.rs | 2 +- 4 files changed, 266 insertions(+), 257 deletions(-) create mode 100644 phf/src/ordered_map.rs diff --git a/phf/src/lib.rs b/phf/src/lib.rs index 23026880..303cb8d8 100644 --- a/phf/src/lib.rs +++ b/phf/src/lib.rs @@ -12,8 +12,6 @@ extern crate core; extern crate collections; use core::fmt; -use core::iter; -use core::slice; use core::prelude::*; use collections::Map as MapTrait; use collections::Set as SetTrait; @@ -21,257 +19,18 @@ use collections::Set as SetTrait; pub use shared::PhfHash; pub use map::Map; pub use set::Set; +pub use ordered_map::OrderedMap; #[path="../../shared/mod.rs"] mod shared; pub mod map; pub mod set; +pub mod ordered_map; mod std { pub use core::fmt; } -/// An order-preserving immutable map constructed at compile time. -/// -/// Unlike a `PhfMap`, iteration order is guaranteed to match the definition -/// order. -/// -/// `PhfOrderedMap`s may be created with the `phf_ordered_map` macro: -/// -/// ```rust -/// # #![feature(phase)] -/// extern crate phf; -/// #[phase(plugin)] -/// extern crate phf_mac; -/// -/// use phf::PhfOrderedMap; -/// -/// static MY_MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map! { -/// "hello" => 10, -/// "world" => 11, -/// }; -/// -/// # fn main() {} -/// ``` -/// -/// # Note -/// -/// 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 { - #[doc(hidden)] - pub key: u64, - #[doc(hidden)] - pub disps: &'static [(u32, u32)], - #[doc(hidden)] - pub idxs: &'static [uint], - #[doc(hidden)] - pub entries: &'static [(K, V)], -} - -impl fmt::Show for PhfOrderedMap where K: fmt::Show, V: fmt::Show { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "{{")); - let mut first = true; - for &(ref k, ref v) in self.entries() { - if !first { - try!(write!(fmt, ", ")); - } - try!(write!(fmt, "{}: {}", k, v)) - first = false; - } - write!(fmt, "}}") - } -} - -impl Collection for PhfOrderedMap { - fn len(&self) -> uint { - self.entries.len() - } -} - -impl MapTrait for PhfOrderedMap where K: PhfHash+Eq { - fn find(&self, key: &K) -> Option<&V> { - self.find_entry(key, |k| k == key).map(|(_, e)| &e.1) - } -} - -impl Index for PhfOrderedMap where K: PhfHash+Eq { - fn index(&self, k: &K) -> &V { - self.find(k).expect("invalid key") - } -} - -impl PhfOrderedMap where K: PhfHash+Eq { - /// 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)| &e.0) - } - - /// Returns the index of the key within the list used to initialize - /// the ordered map. - pub fn find_index(&self, key: &K) -> Option { - self.find_entry(key, |k| k == key).map(|(i, _)| i) - } -} - -impl PhfOrderedMap { - fn find_entry(&self, key: &T, check: |&K| -> bool) -> Option<(uint, &(K, V))> - where T: PhfHash { - let (g, f1, f2) = key.phf_hash(self.key); - let (d1, d2) = self.disps[(g % (self.disps.len() as u32)) as uint]; - let idx = self.idxs[(shared::displace(f1, f2, d1, d2) % (self.idxs.len() as u32)) as uint]; - let entry = &self.entries[idx]; - - if check(&entry.0) { - Some((idx, entry)) - } else { - None - } - } - - /// Like `find`, but can operate on any type that is equivalent to a key. - pub fn find_equiv(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv { - self.find_entry(key, |k| key.equiv(k)).map(|(_, e)| &e.1) - } - - /// Like `find_key`, but can operate on any type that is equivalent to a - /// key. - pub fn find_key_equiv(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv { - self.find_entry(key, |k| key.equiv(k)).map(|(_, e)| &e.0) - } - - /// Like `find_index`, but can operate on any type that is equivalent to a - /// key. - pub fn find_index_equiv(&self, key: &T) -> Option where T: PhfHash+Equiv { - self.find_entry(key, |k| key.equiv(k)).map(|(i, _)| i) - } - - /// Returns an iterator over the key/value pairs in the map. - /// - /// Entries are returned in the same order in which they were defined. - 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, K, V> { - PhfOrderedMapKeys { iter: self.entries().map(|e| &e.0) } - } - - /// 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, K, V> { - PhfOrderedMapValues { iter: self.entries().map(|e| &e.1) } - } -} - -/// An iterator over the entries in a `PhfOrderedMap`. -pub struct PhfOrderedMapEntries<'a, K:'a, V:'a> { - iter: slice::Items<'a, (K, V)>, -} - -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) { - self.iter.size_hint() - } -} - -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, 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<&'a (K, V)> { - self.iter.idx(index) - } -} - -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, K:'a, V:'a> { - iter: iter::Map<'a, &'a (K, V), &'a K, PhfOrderedMapEntries<'a, K, V>>, -} - -impl<'a, K, V> Iterator<&'a K> for PhfOrderedMapKeys<'a, K, V> { - fn next(&mut self) -> Option<&'a K> { - self.iter.next() - } - - fn size_hint(&self) -> (uint, Option) { - self.iter.size_hint() - } -} - -impl<'a, K, V> DoubleEndedIterator<&'a K> for PhfOrderedMapKeys<'a, K, V> { - fn next_back(&mut self) -> Option<&'a K> { - self.iter.next_back() - } -} - -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<&'a K> { - self.iter.idx(index) - } -} - -impl<'a, K, V> ExactSize<&'a K> for PhfOrderedMapKeys<'a, K, V> {} - -/// An iterator over the values in a `PhfOrderedMap`. -pub struct PhfOrderedMapValues<'a, K:'a, V:'a> { - iter: iter::Map<'a, &'a (K, V), &'a V, PhfOrderedMapEntries<'a, K, V>>, -} - -impl<'a, K, V> Iterator<&'a V> for PhfOrderedMapValues<'a, K, V> { - fn next(&mut self) -> Option<&'a V> { - self.iter.next() - } - - fn size_hint(&self) -> (uint, Option) { - self.iter.size_hint() - } -} - -impl<'a, K, V> DoubleEndedIterator<&'a V> for PhfOrderedMapValues<'a, K, V> { - fn next_back(&mut self) -> Option<&'a V> { - self.iter.next_back() - } -} - -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 V> { - self.iter.idx(index) - } -} - -impl<'a, K, V> ExactSize<&'a V> for PhfOrderedMapValues<'a, K, V> {} - /// An order-preserving immutable set constructed at compile time. /// /// Unlike a `PhfSet`, iteration order is guaranteed to match the definition @@ -302,7 +61,7 @@ impl<'a, K, V> ExactSize<&'a V> for PhfOrderedMapValues<'a, K, V> {} /// never be accessed directly. pub struct PhfOrderedSet { #[doc(hidden)] - pub map: PhfOrderedMap, + pub map: OrderedMap, } impl fmt::Show for PhfOrderedSet where T: fmt::Show { @@ -393,7 +152,7 @@ impl PhfOrderedSet { /// An iterator over the values in a `PhfOrderedSet`. pub struct PhfOrderedSetValues<'a, T:'a> { - iter: PhfOrderedMapKeys<'a, T, ()>, + iter: ordered_map::Keys<'a, T, ()>, } impl<'a, T> Iterator<&'a T> for PhfOrderedSetValues<'a, T> { diff --git a/phf/src/ordered_map.rs b/phf/src/ordered_map.rs new file mode 100644 index 00000000..0548cef9 --- /dev/null +++ b/phf/src/ordered_map.rs @@ -0,0 +1,250 @@ +//! An order-preserving immutable map constructed at compile time. +use core::prelude::*; +use core::fmt; +use core::slice; +use core::iter; +use PhfHash; +use shared; +use collections::Map as MapTrait; + +/// An order-preserving immutable map constructed at compile time. +/// +/// Unlike a `PhfMap`, iteration order is guaranteed to match the definition +/// order. +/// +/// `OrderedMap`s may be created with the `phf_ordered_map` macro: +/// +/// ```rust +/// # #![feature(phase)] +/// extern crate phf; +/// #[phase(plugin)] +/// extern crate phf_mac; +/// +/// use phf::OrderedMap; +/// +/// static MY_MAP: OrderedMap<&'static str, int> = phf_ordered_map! { +/// "hello" => 10, +/// "world" => 11, +/// }; +/// +/// # fn main() {} +/// ``` +/// +/// # Note +/// +/// 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 OrderedMap { + #[doc(hidden)] + pub key: u64, + #[doc(hidden)] + pub disps: &'static [(u32, u32)], + #[doc(hidden)] + pub idxs: &'static [uint], + #[doc(hidden)] + pub entries: &'static [(K, V)], +} + +impl fmt::Show for OrderedMap where K: fmt::Show, V: fmt::Show { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + try!(write!(fmt, "{{")); + let mut first = true; + for &(ref k, ref v) in self.entries() { + if !first { + try!(write!(fmt, ", ")); + } + try!(write!(fmt, "{}: {}", k, v)) + first = false; + } + write!(fmt, "}}") + } +} + +impl Collection for OrderedMap { + fn len(&self) -> uint { + self.entries.len() + } +} + +impl MapTrait for OrderedMap where K: PhfHash+Eq { + fn find(&self, key: &K) -> Option<&V> { + self.find_entry(key, |k| k == key).map(|(_, e)| &e.1) + } +} + +impl Index for OrderedMap where K: PhfHash+Eq { + fn index(&self, k: &K) -> &V { + self.find(k).expect("invalid key") + } +} + +impl OrderedMap where K: PhfHash+Eq { + /// 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)| &e.0) + } + + /// Returns the index of the key within the list used to initialize + /// the ordered map. + pub fn find_index(&self, key: &K) -> Option { + self.find_entry(key, |k| k == key).map(|(i, _)| i) + } +} + +impl OrderedMap { + fn find_entry(&self, key: &T, check: |&K| -> bool) -> Option<(uint, &(K, V))> + where T: PhfHash { + let (g, f1, f2) = key.phf_hash(self.key); + let (d1, d2) = self.disps[(g % (self.disps.len() as u32)) as uint]; + let idx = self.idxs[(shared::displace(f1, f2, d1, d2) % (self.idxs.len() as u32)) as uint]; + let entry = &self.entries[idx]; + + if check(&entry.0) { + Some((idx, entry)) + } else { + None + } + } + + /// Like `find`, but can operate on any type that is equivalent to a key. + pub fn find_equiv(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv { + self.find_entry(key, |k| key.equiv(k)).map(|(_, e)| &e.1) + } + + /// Like `find_key`, but can operate on any type that is equivalent to a + /// key. + pub fn find_key_equiv(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv { + self.find_entry(key, |k| key.equiv(k)).map(|(_, e)| &e.0) + } + + /// Like `find_index`, but can operate on any type that is equivalent to a + /// key. + pub fn find_index_equiv(&self, key: &T) -> Option where T: PhfHash+Equiv { + self.find_entry(key, |k| key.equiv(k)).map(|(i, _)| i) + } + + /// Returns an iterator over the key/value pairs in the map. + /// + /// Entries are returned in the same order in which they were defined. + pub fn entries<'a>(&'a self) -> Entries<'a, K, V> { + Entries { 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) -> Keys<'a, K, V> { + Keys { iter: self.entries().map(|e| &e.0) } + } + + /// 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) -> Values<'a, K, V> { + Values { iter: self.entries().map(|e| &e.1) } + } +} + +/// An iterator over the entries in a `OrderedMap`. +pub struct Entries<'a, K:'a, V:'a> { + iter: slice::Items<'a, (K, V)>, +} + +impl<'a, K, V> Iterator<&'a (K, V)> for Entries<'a, K, V> { + fn next(&mut self) -> Option<&'a (K, V)> { + self.iter.next() + } + + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator<&'a (K, V)> for Entries<'a, K, V> { + fn next_back(&mut self) -> Option<&'a (K, V)> { + self.iter.next_back() + } +} + +impl<'a, K, V> RandomAccessIterator<&'a (K, V)> for Entries<'a, K, V> { + fn indexable(&self) -> uint { + self.iter.indexable() + } + + fn idx(&mut self, index: uint) -> Option<&'a (K, V)> { + self.iter.idx(index) + } +} + +impl<'a, K, V> ExactSize<&'a (K, V)> for Entries<'a, K, V> {} + +/// An iterator over the keys in a `OrderedMap`. +pub struct Keys<'a, K:'a, V:'a> { + iter: iter::Map<'a, &'a (K, V), &'a K, Entries<'a, K, V>>, +} + +impl<'a, K, V> Iterator<&'a K> for Keys<'a, K, V> { + fn next(&mut self) -> Option<&'a K> { + self.iter.next() + } + + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator<&'a K> for Keys<'a, K, V> { + fn next_back(&mut self) -> Option<&'a K> { + self.iter.next_back() + } +} + +impl<'a, K, V> RandomAccessIterator<&'a K> for Keys<'a, K, V> { + fn indexable(&self) -> uint { + self.iter.indexable() + } + + fn idx(&mut self, index: uint) -> Option<&'a K> { + self.iter.idx(index) + } +} + +impl<'a, K, V> ExactSize<&'a K> for Keys<'a, K, V> {} + +/// An iterator over the values in a `OrderedMap`. +pub struct Values<'a, K:'a, V:'a> { + iter: iter::Map<'a, &'a (K, V), &'a V, Entries<'a, K, V>>, +} + +impl<'a, K, V> Iterator<&'a V> for Values<'a, K, V> { + fn next(&mut self) -> Option<&'a V> { + self.iter.next() + } + + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator<&'a V> for Values<'a, K, V> { + fn next_back(&mut self) -> Option<&'a V> { + self.iter.next_back() + } +} + +impl<'a, K, V> RandomAccessIterator<&'a V> for Values<'a, K, V> { + fn indexable(&self) -> uint { + self.iter.indexable() + } + + fn idx(&mut self, index: uint) -> Option<&'a V> { + self.iter.idx(index) + } +} + +impl<'a, K, V> ExactSize<&'a V> for Values<'a, K, V> {} + diff --git a/phf/tests/test.rs b/phf/tests/test.rs index 85ae2ede..6997dd43 100644 --- a/phf/tests/test.rs +++ b/phf/tests/test.rs @@ -253,21 +253,21 @@ mod set { } mod ordered_map { - use phf::PhfOrderedMap; + use phf; #[allow(dead_code)] - static TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static TRAILING_COMMA: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, ); #[allow(dead_code)] - static NO_TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static NO_TRAILING_COMMA: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10 ); #[test] fn test_two() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, ); @@ -279,7 +279,7 @@ mod ordered_map { #[test] fn test_find_index() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 5, "bar" => 5, "baz" => 5, @@ -296,7 +296,7 @@ mod ordered_map { #[test] fn test_entries() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, "baz" => 12, @@ -307,7 +307,7 @@ mod ordered_map { #[test] fn test_keys() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, "baz" => 12, @@ -318,7 +318,7 @@ mod ordered_map { #[test] fn test_values() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "foo" => 10, "bar" => 11, "baz" => 12, @@ -329,7 +329,7 @@ mod ordered_map { #[test] fn test_index_ok() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "a" => 0, ); assert_eq!(0, MAP["a"]); @@ -338,7 +338,7 @@ mod ordered_map { #[test] #[should_fail] fn test_index_fail() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "a" => 0, ); MAP["b"]; @@ -346,7 +346,7 @@ mod ordered_map { #[test] fn test_non_static_str_key() { - static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( + static MAP: phf::OrderedMap<&'static str, int> = phf_ordered_map!( "a" => 0, ); assert_eq!(Some(&0), MAP.find_equiv("a".to_string()[])); diff --git a/phf_mac/src/util.rs b/phf_mac/src/util.rs index 945159aa..83b73339 100644 --- a/phf_mac/src/util.rs +++ b/phf_mac/src/util.rs @@ -239,7 +239,7 @@ pub fn create_ordered_map(cx: &mut ExtCtxt, sp: Span, entries: Vec, state let entries = cx.expr_vec(sp, entries); let key = state.key; - MacExpr::new(quote_expr!(cx, ::phf::PhfOrderedMap { + MacExpr::new(quote_expr!(cx, ::phf::OrderedMap { key: $key, disps: &$disps, idxs: &$idxs,