2 use std::hash::BuildHasher;
4 use std::collections::HashMap;
5 use std::collections::hash_map::RawEntryMut;
6 use std::borrow::Borrow;
8 pub trait HashInterner<K: Eq + Hash> {
9 fn intern_ref<Q: ?Sized, F: FnOnce() -> K>(&mut self, value: &Q, make: F) -> K
13 fn intern<Q, F: FnOnce(Q) -> K>(&mut self, value: Q, make: F) -> K
18 impl<K: Eq + Hash + Copy, S: BuildHasher> HashInterner<K> for HashMap<K, (), S> {
20 fn intern_ref<Q: ?Sized, F: FnOnce() -> K>(&mut self, value: &Q, make: F) -> K
24 let mut hasher = self.hasher().build_hasher();
25 value.hash(&mut hasher);
26 let hash = hasher.finish();
27 let entry = self.raw_entry_mut().from_key_hashed_nocheck(hash, value);
30 RawEntryMut::Occupied(e) => *e.key(),
31 RawEntryMut::Vacant(e) => {
33 e.insert_hashed_nocheck(hash, v, ());
40 fn intern<Q, F: FnOnce(Q) -> K>(&mut self, value: Q, make: F) -> K
44 let mut hasher = self.hasher().build_hasher();
45 value.hash(&mut hasher);
46 let hash = hasher.finish();
47 let entry = self.raw_entry_mut().from_key_hashed_nocheck(hash, &value);
50 RawEntryMut::Occupied(e) => *e.key(),
51 RawEntryMut::Vacant(e) => {
53 e.insert_hashed_nocheck(hash, v, ());