use std::borrow::Borrow;
use std::fmt;
use kevy_hash::KevyHash;
use crate::iter::Iter;
use crate::map::KevyMap;
#[derive(Clone)]
pub struct KevySet<K>(KevyMap<K, ()>);
impl<K> KevySet<K> {
pub fn new() -> Self {
Self(KevyMap::new())
}
pub fn with_capacity(cap_hint: usize) -> Self {
Self(KevyMap::with_capacity(cap_hint))
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn clear(&mut self) {
self.0.clear();
}
pub fn iter(&self) -> SetIter<'_, K> {
SetIter(self.0.iter())
}
pub fn as_map(&self) -> &KevyMap<K, ()> {
&self.0
}
}
impl<K: KevyHash + Eq> KevySet<K> {
pub fn insert(&mut self, key: K) -> bool {
self.0.insert(key, ()).is_none()
}
}
impl<K> KevySet<K> {
pub fn contains<Q>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
Q: KevyHash + Eq + ?Sized,
{
self.0.contains_key(key)
}
pub fn remove<Q>(&mut self, key: &Q) -> bool
where
K: Borrow<Q>,
Q: KevyHash + Eq + ?Sized,
{
self.0.remove(key).is_some()
}
}
impl<K> Default for KevySet<K> {
fn default() -> Self {
Self::new()
}
}
impl<K: fmt::Debug> fmt::Debug for KevySet<K> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
pub struct SetIter<'a, K>(Iter<'a, K, ()>);
impl<'a, K> Iterator for SetIter<'a, K> {
type Item = &'a K;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(k, _)| k)
}
}
impl<'a, K> IntoIterator for &'a KevySet<K> {
type Item = &'a K;
type IntoIter = SetIter<'a, K>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<K: KevyHash + Eq> FromIterator<K> for KevySet<K> {
fn from_iter<I: IntoIterator<Item = K>>(iter: I) -> Self {
let iter = iter.into_iter();
let mut s = match iter.size_hint() {
(lo, Some(hi)) if hi <= lo.saturating_mul(2) => Self::with_capacity(hi),
(lo, _) => Self::with_capacity(lo),
};
for k in iter {
s.insert(k);
}
s
}
}
impl<K: KevyHash + Eq> Extend<K> for KevySet<K> {
fn extend<I: IntoIterator<Item = K>>(&mut self, iter: I) {
for k in iter {
self.insert(k);
}
}
}