use super::utils::UnsafeWrapper;
use std::borrow::Borrow;
use std::collections::{HashSet, hash_set};
use std::fmt;
use std::hash::Hash;
pub struct Set<T>(UnsafeWrapper<HashSet<T>>);
impl<T: Eq + Hash> Set<T> {
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Self(UnsafeWrapper::new(HashSet::with_capacity(capacity)))
}
pub fn contains<Q>(&self, value: &Q) -> bool
where
T: Borrow<Q>,
Q: ?Sized + Hash + Eq,
{
unsafe { self.0.with(|inner| inner.contains(value)) }
}
pub fn insert(&self, value: T) -> bool {
unsafe { self.0.with(|inner| inner.insert(value)) }
}
pub fn remove<Q>(&self, value: &Q) -> bool
where
T: Borrow<Q>,
Q: ?Sized + Hash + Eq,
{
unsafe { self.0.with(|inner| inner.remove(value)) }
}
pub fn clear(&self) {
unsafe { self.0.with(|inner| inner.clear()) }
}
pub fn len(&self) -> usize {
unsafe { self.0.with(|inner| inner.len()) }
}
pub fn capacity(&self) -> usize {
unsafe { self.0.with(|inner| inner.capacity()) }
}
pub fn is_empty(&self) -> bool {
unsafe { self.0.with(|inner| inner.is_empty()) }
}
pub fn into_inner(self) -> HashSet<T> {
self.0.into_inner()
}
}
impl<T> From<HashSet<T>> for Set<T> {
fn from(hash_set: HashSet<T>) -> Self {
Self(UnsafeWrapper::new(hash_set))
}
}
impl<T: fmt::Debug> fmt::Debug for Set<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe { self.0.with(|inner| inner.fmt(f)) }
}
}
impl<T> Default for Set<T> {
fn default() -> Self {
Self(UnsafeWrapper::new(HashSet::default()))
}
}
impl<T: Clone> Clone for Set<T> {
fn clone(&self) -> Self {
unsafe { self.0.with(|inner| Self(UnsafeWrapper::new(inner.clone()))) }
}
}
impl<T> IntoIterator for Set<T> {
type Item = T;
type IntoIter = hash_set::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_inner().into_iter()
}
}
#[cfg(test)]
mod tests {
use super::*;
use static_assertions::{assert_impl_all, assert_not_impl_any};
use std::{rc::Rc, sync::Arc};
#[test]
fn test_set_is_send_but_not_sync() {
assert_impl_all!(Set<usize>: std::marker::Send);
assert_not_impl_any!(Set<Rc<usize>>: std::marker::Send);
assert_not_impl_any!(Set<Arc<usize>>: Sync);
assert_not_impl_any!(Arc<Set<usize>>: std::marker::Send, Sync);
}
}