Skip to content

Commit

Permalink
Update to use BorrowFrom
Browse files Browse the repository at this point in the history
  • Loading branch information
sfackler committed Nov 20, 2014
1 parent aa3e2d0 commit 2f3c605
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 207 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -31,6 +31,6 @@ static KEYWORDS: phf::Map<&'static str, Keyword> = phf_map! {
};

pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
KEYWORDS.find_equiv(keyword).map(|t| t.clone())
KEYWORDS.get(keyword).map(|t| t.clone())
}
```
71 changes: 25 additions & 46 deletions phf/src/map.rs
@@ -1,5 +1,6 @@
//! An immutable map constructed at compile time.
use core::prelude::*;
use core::borrow::BorrowFrom;
use core::iter;
use core::slice;
use core::fmt;
Expand Down Expand Up @@ -53,77 +54,55 @@ impl<K, V> fmt::Show for Map<K, V> where K: fmt::Show, V: fmt::Show {
}
}

impl<K, V> Index<K, V> for Map<K, V> where K: PhfHash+Eq {
fn index(&self, k: &K) -> &V {
impl<K, V, Sized? T> Index<T, V> for Map<K, V> where T: Eq + PhfHash + BorrowFrom<K> {
fn index(&self, k: &T) -> &V {
self.get(k).expect("invalid key")
}
}

impl<K, V> Map<K, V> where K: PhfHash+Eq {
/// Returns a reference to the value that `key` maps to.
pub fn get(&self, key: &K) -> Option<&V> {
self.get_entry_(key, |k| key == k).map(|e| &e.1)
impl<K, V> Map<K, V> {
/// Returns true if the `Map` is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}

/// Returns the number of entries in the `Map`.
pub fn len(&self) -> uint {
self.entries.len()
}

/// Determines if `key` is in the `Map`.
pub fn contains_key(&self, key: &K) -> bool {
pub fn contains_key<Sized? T>(&self, key: &T) -> bool where T: Eq + PhfHash + BorrowFrom<K> {
self.get(key).is_some()
}

/// Returns a reference to the value that `key` maps to.
pub fn get<Sized? T>(&self, key: &T) -> Option<&V> where T: Eq + PhfHash + BorrowFrom<K> {
self.get_entry(key).map(|e| e.1)
}

/// Returns a reference to the map's internal static instance of the given
/// key.
///
/// This can be useful for interning schemes.
pub fn get_key(&self, key: &K) -> Option<&K> {
self.get_entry_(key, |k| key == k).map(|e| &e.0)
pub fn get_key<Sized? T>(&self, key: &T) -> Option<&K> where T: Eq + PhfHash + BorrowFrom<K> {
self.get_entry(key).map(|e| e.0)
}
}

impl<K, V> Map<K, V> {
/// Returns true if the `Map` is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}

/// Returns the number of entries in the `Map`.
pub fn len(&self) -> uint {
self.entries.len()
}

fn get_entry_<Sized? T>(&self, key: &T, check: |&K| -> bool) -> Option<&(K, V)> where T: PhfHash {
/// Like `get`, but returns both the key and the value.
pub fn get_entry<Sized? T>(&self, key: &T) -> Option<(&K, &V)>
where T: Eq + PhfHash + BorrowFrom<K> {
let (g, f1, f2) = key.phf_hash(self.key);
let (d1, d2) = self.disps[(g % (self.disps.len() as u32)) as uint];
let entry = &self.entries[(shared::displace(f1, f2, d1, d2) % (self.entries.len() as u32))
as uint];
if check(&entry.0) {
Some(entry)
if BorrowFrom::borrow_from(&entry.0) == key {
Some((&entry.0, &entry.1))
} else {
None
}
}

/// Like `get`, but returns both the key and the value.
pub fn get_entry<Sized? T>(&self, key: &T) -> Option<(&K, &V)> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|e| (&e.0, &e.1))
}

/// Like `get`, but can operate on any type that is equivalent to a key.
pub fn get_equiv<Sized? T>(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|e| &e.1)
}

/// Like `get_key`, but can operate on any type that is equivalent to a
/// key.
pub fn get_key_equiv<Sized? T>(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|e| &e.0)
}

/// Like `get_kv`, but can operate on any type that is equivalent to a
/// key.
pub fn get_entry_equiv<Sized? T>(&self, key: &T) -> Option<(&K, &V)> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|e| (&e.0, &e.1))
}

/// Returns an iterator over the key/value pairs in the map.
///
/// Entries are retuned in an arbitrary but fixed order.
Expand Down
89 changes: 34 additions & 55 deletions phf/src/ordered_map.rs
@@ -1,8 +1,10 @@
//! An order-preserving immutable map constructed at compile time.
use core::prelude::*;
use core::borrow::BorrowFrom;
use core::fmt;
use core::slice;
use core::iter;

use PhfHash;
use shared;

Expand Down Expand Up @@ -58,91 +60,68 @@ impl<K, V> fmt::Show for OrderedMap<K, V> where K: fmt::Show, V: fmt::Show {
}
}

impl<K, V> Index<K, V> for OrderedMap<K, V> where K: PhfHash+Eq {
fn index(&self, k: &K) -> &V {
impl<K, V, Sized? T> Index<T, V> for OrderedMap<K, V> where T: Eq + PhfHash + BorrowFrom<K> {
fn index(&self, k: &T) -> &V {
self.get(k).expect("invalid key")
}
}

impl<K, V> OrderedMap<K, V> where K: PhfHash+Eq {
/// Returns a reference to the value that `key` maps to.
pub fn get(&self, key: &K) -> Option<&V> {
self.get_entry_(key, |k| key == k).map(|(_, e)| &e.1)
impl<K, V> OrderedMap<K, V> {
/// Returns the number of entries in the `Map`.
pub fn len(&self) -> uint {
self.entries.len()
}

/// Determines if `key` is in the `Map`.
pub fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
/// Returns true if the `Map` is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}

/// Returns a reference to the value that `key` maps to.
pub fn get<Sized? T>(&self, key: &T) -> Option<&V> where T: Eq + PhfHash + BorrowFrom<K> {
self.get_entry(key).map(|e| e.1)
}

/// Returns a reference to the map's internal static instance of the given
/// key.
///
/// This can be useful for interning schemes.
pub fn get_key(&self, key: &K) -> Option<&K> {
self.get_entry_(key, |k| k == key).map(|(_, e)| &e.0)
pub fn get_key<Sized? T>(&self, key: &T) -> Option<&K> where T: Eq + PhfHash + BorrowFrom<K> {
self.get_entry(key).map(|e| e.0)
}

/// Returns the index of the key within the list used to initialize
/// the ordered map.
pub fn get_index(&self, key: &K) -> Option<uint> {
self.get_entry_(key, |k| k == key).map(|(i, _)| i)
/// Determines if `key` is in the `Map`.
pub fn contains_key<Sized? T>(&self, key: &T) -> bool where T: Eq + PhfHash + BorrowFrom<K> {
self.get(key).is_some()
}
}

impl<K, V> OrderedMap<K, V> {
/// Returns true if the `Map` is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
/// Returns the index of the key within the list used to initialize
/// the ordered map.
pub fn get_index<Sized? T>(&self, key: &T) -> Option<uint>
where T: Eq + PhfHash + BorrowFrom<K> {
self.get_internal(key).map(|(i, _)| i)
}

/// Returns the number of entries in the `Map`.
pub fn len(&self) -> uint {
self.entries.len()
/// Like `get`, but returns both the key and the value.
pub fn get_entry<Sized? T>(&self, key: &T) -> Option<(&K, &V)>
where T: Eq + PhfHash + BorrowFrom<K> {
self.get_internal(key).map(|(_, e)| e)
}

fn get_entry_<Sized? T>(&self, key: &T, check: |&K| -> bool) -> Option<(uint, &(K, V))>
where T: PhfHash {
fn get_internal<Sized? T>(&self, key: &T) -> Option<(uint, (&K, &V))>
where T: Eq + PhfHash + BorrowFrom<K> {
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))
if BorrowFrom::borrow_from(&entry.0) == key {
Some((idx, (&entry.0, &entry.1)))
} else {
None
}
}

/// Like `get`, but returns both the key and the value.
pub fn get_entry<Sized? T>(&self, key: &T) -> Option<(&K, &V)> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|(_, e)| (&e.0, &e.1))
}

/// Like `get`, but can operate on any type that is equivalent to a key.
pub fn get_equiv<Sized? T>(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|(_, e)| &e.1)
}

/// Like `get_key`, but can operate on any type that is equivalent to a
/// key.
pub fn get_key_equiv<Sized? T>(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|(_, e)| &e.0)
}

/// Like `get_index`, but can operate on any type that is equivalent to a
/// key.
pub fn get_index_equiv<Sized? T>(&self, key: &T) -> Option<uint> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|(i, _)| i)
}

/// Like `get_kv`, but can operate on any type that is equivalent to a
/// key.
pub fn get_entry_equiv<Sized? T>(&self, key: &T) -> Option<(&K, &V)> where T: PhfHash+Equiv<K> {
self.get_entry_(key, |k| key.equiv(k)).map(|(_, e)| (&e.0, &e.1))
}

/// Returns an iterator over the key/value pairs in the map.
///
/// Entries are returned in the same order in which they were defined.
Expand Down
73 changes: 25 additions & 48 deletions phf/src/ordered_set.rs
@@ -1,5 +1,6 @@
//! An order-preserving immutable set constructed at compile time.
use core::prelude::*;
use core::borrow::BorrowFrom;
use core::fmt;
use ordered_map;
use {PhfHash, OrderedMap};
Expand Down Expand Up @@ -50,28 +51,46 @@ impl<T> fmt::Show for OrderedSet<T> where T: fmt::Show {
}
}

impl<T: PhfHash+Eq> OrderedSet<T> {
impl<T> OrderedSet<T> {
/// Returns the number of elements in the `OrderedSet`.
pub fn len(&self) -> uint {
self.map.len()
}

/// Returns true if the `OrderedSet` contains no elements.
pub fn is_empty(&self) -> bool {
self.len() == 0
}

/// Returns a reference to the set's internal static instance of the given
/// key.
///
/// This can be useful for interning schemes.
#[inline]
pub fn get_key(&self, key: &T) -> Option<&T> {
pub fn get_key<Sized? U>(&self, key: &U) -> Option<&T> where U: Eq + PhfHash + BorrowFrom<T> {
self.map.get_key(key)
}

/// Returns the index of the key within the list used to initialize
/// the ordered set.
pub fn get_index(&self, key: &T) -> Option<uint> {
pub fn get_index<Sized? U>(&self, key: &U) -> Option<uint>
where U: Eq + PhfHash + BorrowFrom<T> {
self.map.get_index(key)
}

/// Returns true if `value` is in the `Set`.
#[inline]
pub fn contains(&self, value: &T) -> bool {
pub fn contains<Sized? U>(&self, value: &U) -> bool where U: Eq + PhfHash + BorrowFrom<T> {
self.map.contains_key(value)
}

/// Returns an iterator over the values in the set.
///
/// Values are returned in the same order in which they were defined.
pub fn iter<'a>(&'a self) -> Entries<'a, T> {
Entries { iter: self.map.keys() }
}
}

impl<T> OrderedSet<T> where T: Eq + PhfHash {
/// Returns true if `other` shares no elements with `self`.
#[inline]
pub fn is_disjoint(&self, other: &OrderedSet<T>) -> bool {
Expand All @@ -91,48 +110,6 @@ impl<T: PhfHash+Eq> OrderedSet<T> {
}
}

impl<T> OrderedSet<T> {
/// Returns the number of elements in the `Set`.
#[inline]
pub fn len(&self) -> uint {
self.map.len()
}

/// Returns true if the `Set` contains no elements.
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}

/// Like `contains`, but can operate on any type that is equivalent to a
/// value
#[inline]
pub fn contains_equiv<Sized? U>(&self, key: &U) -> bool where U: PhfHash+Equiv<T> {
self.map.get_equiv(key).is_some()
}

/// Like `get_key`, but can operate on any type that is equivalent to a
/// value
#[inline]
pub fn get_key_equiv<Sized? U>(&self, key: &U) -> Option<&T> where U: PhfHash+Equiv<T> {
self.map.get_key_equiv(key)
}

/// Like `get_index`, but can operate on any type that is equivalent to a
/// key.
pub fn get_index_equiv<Sized? U>(&self, key: &U) -> Option<uint> where U: PhfHash+Equiv<T> {
self.map.get_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, ()>,
Expand Down

0 comments on commit 2f3c605

Please sign in to comment.