pub use std::collections::hash_set::{Drain, IntoIter, Iter};
use crate::AllocError;
use crate::FxBuildHasher;
use std::borrow::Borrow;
use std::collections::HashSet as StdHashSet;
use std::fmt;
use std::hash::{BuildHasher, Hash};
#[repr(transparent)]
pub struct HashSet<T, S = FxBuildHasher>(StdHashSet<T, S>);
impl<T> HashSet<T, FxBuildHasher> {
#[must_use]
#[inline]
pub fn new() -> HashSet<T, FxBuildHasher> {
HashSet::default()
}
}
impl<T, S> HashSet<T, S> {
#[inline]
pub fn from_std(hash_set: StdHashSet<T, S>) -> Self {
HashSet(hash_set)
}
#[inline]
pub fn into_std(self) -> StdHashSet<T, S> {
self.0
}
#[inline]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
self.0.iter()
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn drain(&mut self) -> Drain<'_, T> {
self.0.drain()
}
#[inline]
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&T) -> bool,
{
self.0.retain(f)
}
#[inline]
pub fn clear(&mut self) {
self.0.clear()
}
#[inline]
pub fn with_hasher(hasher: S) -> HashSet<T, S> {
HashSet(StdHashSet::with_hasher(hasher))
}
#[inline]
pub fn hasher(&self) -> &S {
self.0.hasher()
}
}
impl<T, S> HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
#[inline]
pub fn try_with_capacity(capacity: usize) -> Result<HashSet<T, S>, AllocError>
where
S: Default,
{
let mut set = StdHashSet::with_hasher(Default::default());
set.try_reserve(capacity)?;
Ok(HashSet(set))
}
#[inline]
pub fn try_with_capacity_and_hasher(capacity: usize, hasher: S) -> Result<HashSet<T, S>, AllocError> {
let mut set = StdHashSet::with_hasher(hasher);
set.try_reserve(capacity)?;
Ok(HashSet(set))
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), AllocError> {
self.0.try_reserve(additional)?;
Ok(())
}
#[inline]
pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
where
T: Borrow<Q>,
Q: Hash + Eq,
{
self.0.contains(value)
}
#[inline]
pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
where
T: Borrow<Q>,
Q: Hash + Eq,
{
self.0.get(value)
}
#[inline]
pub fn try_insert(&mut self, value: T) -> Result<bool, AllocError> {
self.0.try_reserve(1)?;
Ok(self.0.insert(value))
}
#[inline]
pub fn replace(&mut self, value: T) -> Result<Option<T>, AllocError> {
self.0.try_reserve(1)?;
Ok(self.0.replace(value))
}
#[inline]
pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
where
T: Borrow<Q>,
Q: Hash + Eq,
{
self.0.remove(value)
}
#[inline]
pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
where
T: Borrow<Q>,
Q: Hash + Eq,
{
self.0.take(value)
}
}
impl<T, S> PartialEq for HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
#[inline]
fn eq(&self, other: &HashSet<T, S>) -> bool {
self.0.eq(&other.0)
}
}
impl<T, S> Eq for HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
}
impl<T, S> fmt::Debug for HashSet<T, S>
where
T: fmt::Debug,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl<T, S> Default for HashSet<T, S>
where
S: Default,
{
#[inline]
fn default() -> HashSet<T, S> {
HashSet::with_hasher(Default::default())
}
}
impl<'a, T, S> IntoIterator for &'a HashSet<T, S> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<T, S> IntoIterator for HashSet<T, S> {
type Item = T;
type IntoIter = IntoIter<T>;
#[inline]
fn into_iter(self) -> IntoIter<T> {
self.0.into_iter()
}
}
#[cfg(feature = "serde")]
mod serde {
use crate::HashSet;
use serde::de::{SeqAccess, Visitor};
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use std::hash::{BuildHasher, Hash};
use std::marker::PhantomData;
impl<T, H> Serialize for HashSet<T, H>
where
T: Eq + Hash + Serialize,
H: BuildHasher,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_seq(self)
}
}
impl<'de, T, H> Deserialize<'de> for HashSet<T, H>
where
T: Eq + Hash + Deserialize<'de>,
H: BuildHasher + Default + Deserialize<'de>,
{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct SeqVisitor<T, H> {
_marker: PhantomData<HashSet<T, H>>,
}
impl<'de, T, H> Visitor<'de> for SeqVisitor<T, H>
where
T: Eq + Hash + Deserialize<'de>,
H: BuildHasher + Default + Deserialize<'de>,
{
type Value = HashSet<T, H>;
#[inline]
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let cap = seq.size_hint().unwrap_or(8).min(4096);
let mut values =
HashSet::try_with_capacity_and_hasher(cap, H::default()).map_err(A::Error::custom)?;
while let Some(value) = seq.next_element()? {
values.try_insert(value).map_err(A::Error::custom)?;
}
Ok(values)
}
}
let visitor = SeqVisitor { _marker: PhantomData };
deserializer.deserialize_seq(visitor)
}
}
}