diff --git a/phf/src/lib.rs b/phf/src/lib.rs index 303cb8d8..fb18adc2 100644 --- a/phf/src/lib.rs +++ b/phf/src/lib.rs @@ -11,179 +11,20 @@ extern crate core; extern crate collections; -use core::fmt; -use core::prelude::*; -use collections::Map as MapTrait; -use collections::Set as SetTrait; - pub use shared::PhfHash; pub use map::Map; pub use set::Set; pub use ordered_map::OrderedMap; +pub use ordered_set::OrderedSet; #[path="../../shared/mod.rs"] mod shared; pub mod map; pub mod set; pub mod ordered_map; +pub mod ordered_set; mod std { pub use core::fmt; } -/// An order-preserving immutable set constructed at compile time. -/// -/// Unlike a `PhfSet`, iteration order is guaranteed to match the definition -/// order. -/// -/// `PhfOrderedSet`s may be created with the `phf_ordered_set` macro: -/// -/// ```rust -/// # #![feature(phase)] -/// extern crate phf; -/// #[phase(plugin)] -/// extern crate phf_mac; -/// -/// use phf::PhfOrderedSet; -/// -/// static MY_SET: PhfOrderedSet<&'static str> = phf_ordered_set! { -/// "hello", -/// "world", -/// }; -/// -/// # fn main() {} -/// ``` -/// -/// # Note -/// -/// 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 { - #[doc(hidden)] - pub map: OrderedMap, -} - -impl fmt::Show for PhfOrderedSet where T: fmt::Show { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "{{")); - let mut first = true; - for entry in self.iter() { - if !first { - try!(write!(fmt, ", ")); - } - try!(write!(fmt, "{}", entry)); - first = false; - } - write!(fmt, "}}") - } -} - -impl Collection for PhfOrderedSet { - #[inline] - fn len(&self) -> uint { - self.map.len() - } -} - -impl SetTrait for PhfOrderedSet where T: PhfHash+Eq { - #[inline] - 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)) - } - - #[inline] - fn is_subset(&self, other: &PhfOrderedSet) -> bool { - self.iter().all(|value| other.contains(value)) - } -} - -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: &T) -> Option<&T> { - self.map.find_key(key) - } - - /// Returns the index of the key within the list used to initialize - /// the ordered set. - pub fn find_index(&self, key: &T) -> Option { - self.map.find_index(key) - } -} - -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 where U: PhfHash+Equiv { - 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> where U: PhfHash+Equiv { - self.map.find_key_equiv(key) - } - - /// Like `find_index`, but can operate on any type that is equivalent to a - /// key. - pub fn find_index_equiv(&self, key: &U) -> Option where U: PhfHash+Equiv { - self.map.find_index_equiv(key) - } - - /// 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, T> { - PhfOrderedSetValues { iter: self.map.keys() } - } -} - -/// An iterator over the values in a `PhfOrderedSet`. -pub struct PhfOrderedSetValues<'a, T:'a> { - iter: ordered_map::Keys<'a, T, ()>, -} - -impl<'a, T> Iterator<&'a T> for PhfOrderedSetValues<'a, T> { - #[inline] - fn next(&mut self) -> Option<&'a T> { - self.iter.next() - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - self.iter.size_hint() - } -} - -impl<'a, T> DoubleEndedIterator<&'a T> for PhfOrderedSetValues<'a, T> { - #[inline] - fn next_back(&mut self) -> Option<&'a T> { - self.iter.next_back() - } -} - -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<&'a T> { - self.iter.idx(index) - } -} - -impl<'a, T> ExactSize<&'a T> for PhfOrderedSetValues<'a, T> {} diff --git a/phf/src/ordered_set.rs b/phf/src/ordered_set.rs new file mode 100644 index 00000000..1f51e6a2 --- /dev/null +++ b/phf/src/ordered_set.rs @@ -0,0 +1,165 @@ +//! An order-preserving immutable set constructed at compile time. +use core::prelude::*; +use core::fmt; +use ordered_map; +use {PhfHash, OrderedMap}; +use collections::Map as MapTrait; +use collections::Set as SetTrait; + +/// An order-preserving immutable set constructed at compile time. +/// +/// Unlike a `PhfSet`, iteration order is guaranteed to match the definition +/// order. +/// +/// `OrderedSet`s may be created with the `phf_ordered_set` macro: +/// +/// ```rust +/// # #![feature(phase)] +/// extern crate phf; +/// #[phase(plugin)] +/// extern crate phf_mac; +/// +/// use phf::OrderedSet; +/// +/// static MY_SET: OrderedSet<&'static str> = phf_ordered_set! { +/// "hello", +/// "world", +/// }; +/// +/// # fn main() {} +/// ``` +/// +/// # Note +/// +/// 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 OrderedSet { + #[doc(hidden)] + pub map: OrderedMap, +} + +impl fmt::Show for OrderedSet where T: fmt::Show { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + try!(write!(fmt, "{{")); + let mut first = true; + for entry in self.iter() { + if !first { + try!(write!(fmt, ", ")); + } + try!(write!(fmt, "{}", entry)); + first = false; + } + write!(fmt, "}}") + } +} + +impl Collection for OrderedSet { + #[inline] + fn len(&self) -> uint { + self.map.len() + } +} + +impl SetTrait for OrderedSet where T: PhfHash+Eq { + #[inline] + fn contains(&self, value: &T) -> bool { + self.map.contains_key(value) + } + + #[inline] + fn is_disjoint(&self, other: &OrderedSet) -> bool { + !self.iter().any(|value| other.contains(value)) + } + + #[inline] + fn is_subset(&self, other: &OrderedSet) -> bool { + self.iter().all(|value| other.contains(value)) + } +} + +impl OrderedSet { + /// 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: &T) -> Option<&T> { + self.map.find_key(key) + } + + /// Returns the index of the key within the list used to initialize + /// the ordered set. + pub fn find_index(&self, key: &T) -> Option { + self.map.find_index(key) + } +} + +impl OrderedSet { + /// Like `contains`, but can operate on any type that is equivalent to a + /// value + #[inline] + pub fn contains_equiv(&self, key: &U) -> bool where U: PhfHash+Equiv { + 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> where U: PhfHash+Equiv { + self.map.find_key_equiv(key) + } + + /// Like `find_index`, but can operate on any type that is equivalent to a + /// key. + pub fn find_index_equiv(&self, key: &U) -> Option where U: PhfHash+Equiv { + self.map.find_index_equiv(key) + } + + /// 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) -> Entries<'a, T> { + Entries { iter: self.map.keys() } + } +} + +/// An iterator over the values in a `OrderedSet`. +pub struct Entries<'a, T:'a> { + iter: ordered_map::Keys<'a, T, ()>, +} + +impl<'a, T> Iterator<&'a T> for Entries<'a, T> { + #[inline] + fn next(&mut self) -> Option<&'a T> { + self.iter.next() + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } +} + +impl<'a, T> DoubleEndedIterator<&'a T> for Entries<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a T> { + self.iter.next_back() + } +} + +impl<'a, T> RandomAccessIterator<&'a T> for Entries<'a, T> { + #[inline] + fn indexable(&self) -> uint { + self.iter.indexable() + } + + #[inline] + fn idx(&mut self, index: uint) -> Option<&'a T> { + self.iter.idx(index) + } +} + +impl<'a, T> ExactSize<&'a T> for Entries<'a, T> {} + diff --git a/phf/tests/test.rs b/phf/tests/test.rs index 6997dd43..9e7561b7 100644 --- a/phf/tests/test.rs +++ b/phf/tests/test.rs @@ -354,21 +354,21 @@ mod ordered_map { } mod ordered_set { - use phf::PhfOrderedSet; + use phf; #[allow(dead_code)] - static TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! { + static TRAILING_COMMA: phf::OrderedSet<&'static str> = phf_ordered_set! { "foo", }; #[allow(dead_code)] - static NO_TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! { + static NO_TRAILING_COMMA: phf::OrderedSet<&'static str> = phf_ordered_set! { "foo" }; #[test] fn test_two() { - static SET: PhfOrderedSet<&'static str> = phf_ordered_set! { + static SET: phf::OrderedSet<&'static str> = phf_ordered_set! { "hello", "there", "world", @@ -382,7 +382,7 @@ mod ordered_set { #[test] fn test_find_index() { - static SET: PhfOrderedSet<&'static str> = phf_ordered_set! { + static SET: phf::OrderedSet<&'static str> = phf_ordered_set! { "foo", "bar", "baz", @@ -399,7 +399,7 @@ mod ordered_set { #[test] fn test_iter() { - static SET: PhfOrderedSet<&'static str> = phf_ordered_set! { + static SET: phf::OrderedSet<&'static str> = phf_ordered_set! { "hello", "there", "world", @@ -410,7 +410,7 @@ mod ordered_set { #[test] fn test_non_static_str_contains() { - static SET: PhfOrderedSet<&'static str> = phf_ordered_set! { + static SET: phf::OrderedSet<&'static str> = phf_ordered_set! { "hello", "world", }; diff --git a/phf_mac/src/util.rs b/phf_mac/src/util.rs index 83b73339..bad58e8d 100644 --- a/phf_mac/src/util.rs +++ b/phf_mac/src/util.rs @@ -250,5 +250,5 @@ pub fn create_ordered_map(cx: &mut ExtCtxt, sp: Span, entries: Vec, state pub fn create_ordered_set(cx: &mut ExtCtxt, sp: Span, entries: Vec, state: HashState) -> Box { let map = create_ordered_map(cx, sp, entries, state).make_expr().unwrap(); - MacExpr::new(quote_expr!(cx, ::phf::PhfOrderedSet { map: $map })) + MacExpr::new(quote_expr!(cx, ::phf::OrderedSet { map: $map })) }