use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
pub mod intersection;
pub mod storage;
pub use self::intersection::Intersection;
pub use self::storage::SetStorage;
use crate::raw::RawStorage;
use crate::Key;
pub type Iter<'a, T> = <<T as Key>::SetStorage as SetStorage<T>>::Iter<'a>;
pub type IntoIter<T> = <<T as Key>::SetStorage as SetStorage<T>>::IntoIter;
#[repr(transparent)]
pub struct Set<T>
where
T: Key,
{
storage: T::SetStorage,
}
impl<T> Set<T>
where
T: Key,
{
#[inline]
#[must_use]
pub fn new() -> Set<T> {
Set {
storage: T::SetStorage::empty(),
}
}
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
self.storage.iter()
}
#[inline]
pub fn contains(&self, value: T) -> bool {
self.storage.contains(value)
}
#[inline]
pub fn insert(&mut self, value: T) -> bool {
self.storage.insert(value)
}
#[inline]
pub fn remove(&mut self, value: T) -> bool {
self.storage.remove(value)
}
#[inline]
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(T) -> bool,
{
self.storage.retain(f);
}
#[inline]
pub fn clear(&mut self) {
self.storage.clear();
}
#[inline]
pub fn is_empty(&self) -> bool {
self.storage.is_empty()
}
#[inline]
pub fn len(&self) -> usize {
self.storage.len()
}
#[inline]
pub fn intersection<'a>(&'a self, other: &'a Set<T>) -> Intersection<'a, T> {
if self.len() <= other.len() {
Intersection {
iter: self.iter(),
other,
}
} else {
Intersection {
iter: other.iter(),
other: self,
}
}
}
}
impl<T> Set<T>
where
T: Key,
T::SetStorage: RawStorage,
{
#[inline]
pub fn as_raw(&self) -> <T::SetStorage as RawStorage>::Value {
self.storage.as_raw()
}
#[inline]
pub fn from_raw(raw: <T::SetStorage as RawStorage>::Value) -> Self {
Self {
storage: <T::SetStorage as RawStorage>::from_raw(raw),
}
}
}
impl<T> Clone for Set<T>
where
T: Key,
T::SetStorage: Clone,
{
#[inline]
fn clone(&self) -> Set<T> {
Set {
storage: self.storage.clone(),
}
}
}
impl<T> Copy for Set<T>
where
T: Key,
T::SetStorage: Copy,
{
}
impl<T> Default for Set<T>
where
T: Key,
{
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<T> fmt::Debug for Set<T>
where
T: Key + fmt::Debug,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T> PartialEq for Set<T>
where
T: Key,
T::SetStorage: PartialEq,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.storage == other.storage
}
}
impl<T> Eq for Set<T>
where
T: Key,
T::SetStorage: Eq,
{
}
impl<T> Hash for Set<T>
where
T: Key,
T::SetStorage: Hash,
{
#[inline]
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
self.storage.hash(state);
}
}
impl<T> PartialOrd for Set<T>
where
T: Key,
T::SetStorage: PartialOrd,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.storage.partial_cmp(&other.storage)
}
#[inline]
fn lt(&self, other: &Self) -> bool {
self.storage.lt(&other.storage)
}
#[inline]
fn le(&self, other: &Self) -> bool {
self.storage.le(&other.storage)
}
#[inline]
fn gt(&self, other: &Self) -> bool {
self.storage.gt(&other.storage)
}
#[inline]
fn ge(&self, other: &Self) -> bool {
self.storage.ge(&other.storage)
}
}
impl<T> Ord for Set<T>
where
T: Key,
T::SetStorage: Ord,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.storage.cmp(&other.storage)
}
#[inline]
fn max(self, other: Self) -> Self {
Self {
storage: self.storage.max(other.storage),
}
}
#[inline]
fn min(self, other: Self) -> Self {
Self {
storage: self.storage.min(other.storage),
}
}
#[inline]
fn clamp(self, min: Self, max: Self) -> Self {
Self {
storage: self.storage.clamp(min.storage, max.storage),
}
}
}
impl<'a, T> IntoIterator for &'a Set<T>
where
T: Key,
{
type Item = T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T> IntoIterator for Set<T>
where
T: Key,
{
type Item = T;
type IntoIter = IntoIter<T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.storage.into_iter()
}
}
impl<T> FromIterator<T> for Set<T>
where
T: Key,
{
#[inline]
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
let mut set = Self::new();
for value in iter {
set.insert(value);
}
set
}
}
#[cfg(feature = "serde")]
impl<T> serde::Serialize for Set<T>
where
T: Key + serde::Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeSeq as _;
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for v in self {
seq.serialize_element(&v)?;
}
seq.end()
}
}
#[cfg(feature = "serde")]
impl<'de, T> serde::de::Deserialize<'de> for Set<T>
where
T: Key + serde::de::Deserialize<'de>,
{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct SeqVisitor<T>(core::marker::PhantomData<T>);
impl<'de, T> serde::de::Visitor<'de> for SeqVisitor<T>
where
T: Key + serde::de::Deserialize<'de>,
{
type Value = Set<T>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence")
}
#[inline]
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: serde::de::SeqAccess<'de>,
{
let mut set = Set::new();
while let Some(elem) = visitor.next_element()? {
set.insert(elem);
}
Ok(set)
}
}
deserializer.deserialize_seq(SeqVisitor(core::marker::PhantomData))
}
}
#[cfg(feature = "musli02")]
impl<M, T> musli_core02::Encode<M> for Set<T>
where
T: Key + musli_core02::Encode<M>,
{
type Encode = Self;
#[inline]
fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
where
E: musli_core02::Encoder<Mode = M>,
{
use musli_core02::en::SequenceEncoder as _;
encoder.encode_sequence_fn(self.len(), |seq| {
for v in self {
seq.push(v)?;
}
Ok(())
})
}
#[inline]
fn as_encode(&self) -> &Self::Encode {
self
}
}
#[cfg(feature = "musli02")]
impl<'de, M, A, T> musli_core02::Decode<'de, M, A> for Set<T>
where
A: musli_core02::Allocator,
T: Key + musli_core02::Decode<'de, M, A>,
{
#[inline]
fn decode<D>(decoder: D) -> Result<Self, D::Error>
where
D: musli_core02::Decoder<'de, Mode = M, Allocator = A>,
{
use musli_core02::de::{Decoder as _, SequenceDecoder as _};
decoder.decode_sequence(|seq| {
let mut set = Set::new();
while let Some(value) = seq.try_decode_next()? {
set.insert(value.decode()?);
}
Ok(set)
})
}
}
#[cfg(feature = "musli-zerocopy01")]
unsafe impl<T> musli_zerocopy01::ZeroCopy for Set<T>
where
T: Key,
T::SetStorage: crate::raw::TransparentRawStorage,
<T::SetStorage as RawStorage>::Value: musli_zerocopy01::ZeroCopy,
{
const ANY_BITS: bool =
<<T::SetStorage as RawStorage>::Value as musli_zerocopy01::ZeroCopy>::ANY_BITS;
const PADDED: bool =
<<T::SetStorage as RawStorage>::Value as musli_zerocopy01::ZeroCopy>::PADDED;
const CAN_SWAP_BYTES: bool =
<<T::SetStorage as RawStorage>::Value as musli_zerocopy01::ZeroCopy>::CAN_SWAP_BYTES;
#[inline]
unsafe fn pad(padder: &mut musli_zerocopy01::buf::Padder<'_, Self>) {
unsafe {
<<T::SetStorage as RawStorage>::Value as musli_zerocopy01::ZeroCopy>::pad(
padder.transparent(),
);
}
}
#[inline]
unsafe fn validate(
validator: &mut musli_zerocopy01::buf::Validator<'_, Self>,
) -> Result<(), musli_zerocopy01::Error> {
unsafe {
<<T::SetStorage as RawStorage>::Value as musli_zerocopy01::ZeroCopy>::validate(
validator.transparent(),
)
}
}
#[inline]
fn swap_bytes<E>(self) -> Self
where
E: musli_zerocopy01::ByteOrder,
{
Set::from_raw(musli_zerocopy01::ZeroCopy::swap_bytes::<E>(self.as_raw()))
}
}
impl<T, const N: usize> From<[T; N]> for Set<T>
where
T: Key,
{
fn from(arr: [T; N]) -> Self {
Self::from_iter(arr)
}
}