-
Notifications
You must be signed in to change notification settings - Fork 34
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,76 @@ | ||
use std::hash::{BuildHasher, Hash, Hasher, RandomState}; | ||
|
||
use hashbrown::hash_table::Entry; | ||
use hashbrown::HashTable; | ||
|
||
use crate::{PartialEqVariadic, VariadicExt}; | ||
|
||
pub struct VariadicHashSet<T, S = RandomState> { | ||
Check warning on line 8 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 8 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 13 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 13 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 32 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 32 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 39 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 39 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 55 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 55 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 59 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 59 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 64 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 64 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 70 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
Check failure on line 70 in variadics/src/hash_set.rs GitHub Actions / Docs (rustdoc)
|
||
Self { | ||
table: HashTable::with_capacity(capacity), | ||
hasher, | ||
} | ||
} | ||
} |