-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ workspace = true | |
|
||
[dependencies] | ||
sealed = "0.5.0" | ||
hashbrown = "0.14.0" | ||
|
||
[dev-dependencies] | ||
trybuild = "1.0" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
use std::hash::{BuildHasher, Hash, Hasher, RandomState}; | ||
|
||
use hashbrown::hash_table::{Entry, HashTable}; | ||
|
||
use crate::{PartialEqVariadic, VariadicExt}; | ||
|
||
pub struct VariadicHashSet<T, S = RandomState> { | ||
Check warning on line 7 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 7 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
table: HashTable<T>, | ||
hasher: S, | ||
} | ||
impl<T> VariadicHashSet<T> { | ||
pub fn new() -> Self { | ||
Check warning on line 12 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 12 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
Self { | ||
table: HashTable::new(), | ||
hasher: RandomState::default(), | ||
} | ||
} | ||
} | ||
impl<T, S> VariadicHashSet<T, S> | ||
where | ||
T: VariadicExt + PartialEqVariadic, | ||
for<'a> T::AsRefVar<'a>: Hash, | ||
S: BuildHasher, | ||
{ | ||
fn get_hash(hasher: &S, ref_var: T::AsRefVar<'_>) -> u64 { | ||
let mut hasher = hasher.build_hasher(); | ||
ref_var.hash(&mut hasher); | ||
hasher.finish() | ||
} | ||
|
||
pub fn get<'a>(&'a self, ref_var: T::AsRefVar<'_>) -> Option<&'a T> { | ||
Check warning on line 31 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 31 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
let hash = Self::get_hash(&self.hasher, ref_var); | ||
self.table.find(hash, |item| { | ||
<T as PartialEqVariadic>::eq_ref(ref_var, item.as_ref_var()) | ||
}) | ||
} | ||
|
||
pub fn insert(&mut self, element: T) -> bool { | ||
Check warning on line 38 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 38 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
let hash = Self::get_hash(&self.hasher, element.as_ref_var()); | ||
let entry = self.table.entry( | ||
hash, | ||
|item| <T as PartialEqVariadic>::eq(&element, &item), | ||
|item| Self::get_hash(&self.hasher, item.as_ref_var()), | ||
); | ||
match entry { | ||
Entry::Occupied(_occupied_entry) => false, | ||
Entry::Vacant(vacant_entry) => { | ||
vacant_entry.insert(element); | ||
true | ||
} | ||
} | ||
} | ||
|
||
pub fn len(&self) -> usize { | ||
Check warning on line 54 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 54 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
self.table.len() | ||
} | ||
|
||
pub fn iter<'a>(&'a self) -> impl Iterator<Item = T::AsRefVar<'a>> { | ||
Check warning on line 58 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 58 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
self.table.iter().map(|item| item.as_ref_var()) | ||
} | ||
} | ||
impl<T, S> VariadicHashSet<T, S> { | ||
pub fn with_hasher(hasher: S) -> Self { | ||
Check warning on line 63 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 63 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
Self { | ||
table: HashTable::new(), | ||
hasher, | ||
} | ||
} | ||
pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self { | ||
Check warning on line 69 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 69 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
Self { | ||
table: HashTable::with_capacity(capacity), | ||
hasher, | ||
} | ||
} | ||
} |