use core::cmp::Ordering;
use core::mem::ManuallyDrop;
use core::slice;
use std::borrow::Borrow;
use std::fmt;
use std::iter::Chain;
use std::iter::FromIterator;
use std::ops::BitAnd;
use std::ops::BitOr;
use std::ops::BitXor;
use std::ops::Sub;
use super::linear_map::Keys;
use super::linear_map::LinearMap;
#[derive(Clone, Hash)]
#[allow(clippy::derived_hash_with_manual_eq)]
pub struct LinearSet<T> {
map: LinearMap<T, ()>,
}
impl<T> LinearSet<T> {
#[inline]
pub fn from_vec_unchecked(storage: Vec<T>) -> Self {
let mut manually_drop = ManuallyDrop::new(storage);
let storage = unsafe {
Vec::from_raw_parts(
manually_drop.as_mut_ptr().cast::<T>().cast::<(T, ())>(),
manually_drop.len(),
manually_drop.capacity(),
)
};
Self {
map: LinearMap::from_vec_unchecked(storage),
}
}
}
impl<T: Eq> LinearSet<T> {
#[inline]
pub const fn new() -> Self {
Self {
map: LinearMap::new(),
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
map: LinearMap::with_capacity(capacity),
}
}
}
impl<T> LinearSet<T>
where
T: Eq,
{
#[inline]
pub fn capacity(&self) -> usize {
self.map.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional);
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.map.shrink_to_fit();
}
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.map.shrink_to(min_capacity);
}
#[inline]
pub fn truncate(&mut self, len: usize) {
self.map.truncate(len);
}
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
Iter {
iter: self.map.keys(),
}
}
#[inline]
pub fn iter_unchecked_mut(&mut self) -> IterUncheckedMut<'_, T> {
let base_ptr = (self.map.storage.as_mut_slice() as *mut [(T, ())]).cast::<T>();
let slice = unsafe { core::slice::from_raw_parts_mut(base_ptr, self.map.storage.len()) };
IterUncheckedMut {
iter: slice.iter_mut(),
}
}
pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T> {
Difference {
iter: self.iter(),
other,
}
}
pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T> {
SymmetricDifference {
iter: self.difference(other).chain(other.difference(self)),
}
}
pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T> {
Intersection {
iter: self.iter(),
other,
}
}
pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T> {
Union {
iter: self.iter().chain(other.difference(self)),
}
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline]
pub fn drain(&mut self) -> Drain<'_, T> {
Drain {
iter: self.map.drain(),
}
}
pub fn clear(&mut self) {
self.map.clear();
}
#[inline]
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&T) -> bool,
{
self.map.retain(|k, _| f(k));
}
#[inline]
pub fn contains<Q>(&self, value: &Q) -> bool
where
T: Borrow<Q>,
Q: ?Sized + Eq,
{
self.map.contains_key(value)
}
pub fn is_disjoint(&self, other: &Self) -> bool {
self.iter().all(|v| !other.contains(v))
}
pub fn is_subset(&self, other: &Self) -> bool {
self.iter().all(|v| other.contains(v))
}
#[inline]
pub fn is_superset(&self, other: &Self) -> bool {
other.is_subset(self)
}
#[inline]
pub fn get_index(&self, index: usize) -> Option<&T> {
Some(&self.map.get_index(index)?.0)
}
#[inline]
pub fn insert(&mut self, value: T) -> bool {
self.map.insert(value, ()).is_none()
}
#[inline]
pub fn remove<Q>(&mut self, value: &Q) -> bool
where
T: Borrow<Q>,
Q: ?Sized + Eq,
{
self.map.remove(value).is_some()
}
#[inline]
pub fn shift_remove<Q>(&mut self, value: &Q) -> bool
where
T: Borrow<Q>,
Q: ?Sized + Eq,
{
self.map.shift_remove(value).is_some()
}
#[inline]
pub fn sort(&mut self)
where
T: Ord,
{
self.map.sort_keys();
}
#[inline]
pub fn sort_by<F>(&mut self, mut cmp: F)
where
F: FnMut(&T, &T) -> Ordering,
{
self.map.sort_by(|t1, _, t2, _| cmp(t1, t2));
}
#[inline]
pub fn sort_unstable_by<F>(&mut self, mut cmp: F)
where
F: FnMut(&T, &T) -> Ordering,
{
self.map.sort_unstable_by(|t1, _, t2, _| cmp(t1, t2));
}
}
impl<T> PartialEq for LinearSet<T>
where
T: Eq,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().all(|key| other.contains(key))
}
}
impl<T> Eq for LinearSet<T> where T: Eq {}
impl<T: Eq + Ord> PartialOrd for LinearSet<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.map.cmp(&other.map))
}
}
impl<T: Eq + Ord> Ord for LinearSet<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.map.cmp(&other.map)
}
}
impl<T> fmt::Debug for LinearSet<T>
where
T: Eq + fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T> FromIterator<T> for LinearSet<T>
where
T: Eq,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let iterator = iter.into_iter();
let lower = iterator.size_hint().0;
let mut set = Self::with_capacity(lower);
set.extend(iterator);
set
}
}
impl<T> Extend<T> for LinearSet<T>
where
T: Eq,
{
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for k in iter {
self.insert(k);
}
}
}
impl<'a, T> Extend<&'a T> for LinearSet<T>
where
T: 'a + Eq + Copy,
{
#[inline]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned());
}
}
impl<T> Default for LinearSet<T>
where
T: Eq,
{
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<T: Eq> From<LinearSet<T>> for Vec<T> {
#[inline]
fn from(other: LinearSet<T>) -> Self {
let storage = Vec::<_>::from(other.map);
let mut manually_drop = ManuallyDrop::new(storage);
unsafe {
Self::from_raw_parts(
manually_drop.as_mut_ptr().cast::<(T, ())>().cast::<T>(),
manually_drop.len(),
manually_drop.capacity(),
)
}
}
}
impl<T: Eq> From<Vec<T>> for LinearSet<T> {
#[inline]
fn from(other: Vec<T>) -> Self {
other.into_iter().collect()
}
}
impl<T: Eq + Clone, const N: usize> From<[T; N]> for LinearSet<T> {
#[inline]
fn from(arr: [T; N]) -> Self {
Self::from(arr.to_vec())
}
}
impl<T> BitOr<&LinearSet<T>> for &LinearSet<T>
where
T: Eq + Clone,
{
type Output = LinearSet<T>;
fn bitor(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.union(rhs).cloned().collect()
}
}
impl<T> BitAnd<&LinearSet<T>> for &LinearSet<T>
where
T: Eq + Clone,
{
type Output = LinearSet<T>;
fn bitand(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.intersection(rhs).cloned().collect()
}
}
impl<T> BitXor<&LinearSet<T>> for &LinearSet<T>
where
T: Eq + Clone,
{
type Output = LinearSet<T>;
fn bitxor(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.symmetric_difference(rhs).cloned().collect()
}
}
impl<T> Sub<&LinearSet<T>> for &LinearSet<T>
where
T: Eq + Clone,
{
type Output = LinearSet<T>;
fn sub(self, rhs: &LinearSet<T>) -> LinearSet<T> {
self.difference(rhs).cloned().collect()
}
}
#[allow(missing_debug_implementations)]
pub struct Iter<'a, K> {
iter: Keys<'a, K, ()>,
}
#[allow(missing_debug_implementations)]
pub struct IterUncheckedMut<'a, K> {
iter: slice::IterMut<'a, K>,
}
#[allow(missing_debug_implementations)]
pub struct IntoIter<K> {
iter: super::linear_map::IntoIter<K, ()>,
}
#[allow(missing_debug_implementations)]
pub struct Drain<'a, K> {
iter: super::linear_map::Drain<'a, K, ()>,
}
#[allow(missing_debug_implementations)]
pub struct Intersection<'a, T> {
iter: Iter<'a, T>,
other: &'a LinearSet<T>,
}
#[allow(missing_debug_implementations)]
pub struct Difference<'a, T> {
iter: Iter<'a, T>,
other: &'a LinearSet<T>,
}
#[allow(missing_debug_implementations)]
pub struct SymmetricDifference<'a, T> {
iter: Chain<Difference<'a, T>, Difference<'a, T>>,
}
#[allow(missing_debug_implementations)]
pub struct Union<'a, T> {
iter: Chain<Iter<'a, T>, Difference<'a, T>>,
}
impl<'a, T> IntoIterator for &'a LinearSet<T>
where
T: Eq,
{
type Item = &'a T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<T> IntoIterator for LinearSet<T>
where
T: Eq,
{
type Item = T;
type IntoIter = IntoIter<T>;
#[inline]
fn into_iter(self) -> IntoIter<T> {
IntoIter {
iter: self.map.into_iter(),
}
}
}
impl<K> Clone for Iter<'_, K> {
#[inline]
fn clone(&self) -> Self {
Iter {
iter: self.iter.clone(),
}
}
}
impl<'a, K> Iterator for Iter<'a, K> {
type Item = &'a K;
#[inline]
fn next(&mut self) -> Option<&'a K> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<K> ExactSizeIterator for Iter<'_, K> {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<'a, K> Iterator for IterUncheckedMut<'a, K> {
type Item = &'a mut K;
#[inline]
fn next(&mut self) -> Option<&'a mut K> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<K> ExactSizeIterator for IterUncheckedMut<'_, K> {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K> Iterator for IntoIter<K> {
type Item = K;
#[inline]
fn next(&mut self) -> Option<K> {
self.iter.next().map(|(k, _)| k)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<K> ExactSizeIterator for IntoIter<K> {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K> Iterator for Drain<'_, K> {
type Item = K;
#[inline]
fn next(&mut self) -> Option<K> {
self.iter.next().map(|(k, _)| k)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<K> ExactSizeIterator for Drain<'_, K> {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T> Clone for Intersection<'_, T> {
#[inline]
fn clone(&self) -> Self {
Intersection {
iter: self.iter.clone(),
..*self
}
}
}
impl<'a, T> Iterator for Intersection<'a, T>
where
T: Eq,
{
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
loop {
match self.iter.next() {
None => return None,
Some(elt) => {
if self.other.contains(elt) {
return Some(elt);
}
}
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl<T> Clone for Difference<'_, T> {
#[inline]
fn clone(&self) -> Self {
Difference {
iter: self.iter.clone(),
..*self
}
}
}
impl<'a, T> Iterator for Difference<'a, T>
where
T: Eq,
{
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
loop {
match self.iter.next() {
None => return None,
Some(elt) => {
if !self.other.contains(elt) {
return Some(elt);
}
}
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl<T> Clone for SymmetricDifference<'_, T> {
#[inline]
fn clone(&self) -> Self {
SymmetricDifference {
iter: self.iter.clone(),
}
}
}
impl<'a, T> Iterator for SymmetricDifference<'a, T>
where
T: Eq,
{
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<T> Clone for Union<'_, T> {
#[inline]
fn clone(&self) -> Self {
Union {
iter: self.iter.clone(),
}
}
}
impl<'a, T> Iterator for Union<'a, T>
where
T: Eq,
{
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
#[allow(dead_code)]
fn assert_covariance() {
fn set<'new>(v: LinearSet<&'static str>) -> LinearSet<&'new str> {
v
}
fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
v
}
fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> {
v
}
fn difference<'a, 'new>(v: Difference<'a, &'static str>) -> Difference<'a, &'new str> {
v
}
fn symmetric_difference<'a, 'new>(
v: SymmetricDifference<'a, &'static str>,
) -> SymmetricDifference<'a, &'new str> {
v
}
fn intersection<'a, 'new>(v: Intersection<'a, &'static str>) -> Intersection<'a, &'new str> {
v
}
fn union<'a, 'new>(v: Union<'a, &'static str>) -> Union<'a, &'new str> {
v
}
}
#[cfg(feature = "serde")]
impl<T> serde::Serialize for LinearSet<T>
where
T: serde::Serialize + Eq,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.collect_seq(self.iter())
}
}
#[cfg(feature = "serde")]
impl<'de, T> serde::Deserialize<'de> for LinearSet<T>
where
T: serde::Deserialize<'de> + Eq,
{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use core::marker::PhantomData;
use serde::de::SeqAccess;
use serde::de::Visitor;
struct LinearSetSeqVisitor<T>(PhantomData<T>);
impl<'de, T> Visitor<'de> for LinearSetSeqVisitor<T>
where
T: serde::Deserialize<'de> + Eq,
{
type Value = LinearSet<T>;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("a sequence of T elements")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut set = LinearSet::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(elt) = seq.next_element::<T>()? {
set.insert(elt);
}
Ok(set)
}
}
let set = deserializer.deserialize_seq(LinearSetSeqVisitor::<T>(PhantomData))?;
Ok(set)
}
}
#[cfg(feature = "speedy")]
impl<'a, C, T> speedy::Readable<'a, C> for LinearSet<T>
where
C: speedy::Context,
T: speedy::Readable<'a, C> + Eq,
{
#[inline]
fn read_from<R: speedy::Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
let length = reader.read_u32()? as usize;
reader.read_collection(length)
}
#[inline]
fn minimum_bytes_needed() -> usize {
4
}
}
#[cfg(feature = "speedy")]
impl<C, T> speedy::Writable<C> for LinearSet<T>
where
C: speedy::Context,
T: speedy::Writable<C>,
{
#[inline]
fn write_to<W: ?Sized + speedy::Writer<C>>(
&self,
writer: &mut W,
) -> Result<(), <C as speedy::Context>::Error> {
self.map.write_to(writer)
}
#[inline]
fn bytes_needed(&self) -> Result<usize, <C as speedy::Context>::Error> {
self.map.bytes_needed()
}
}