use core::hash::{Hash,Hasher};
use core::fmt::{Display,Formatter,Result};
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
use core::ops::{BitAnd,BitAndAssign,BitOr,BitOrAssign,BitXor,BitXorAssign};
use core::mem::swap;
use std::collections::hash_set::{Iter,IntoIter};
use core::cmp::Ordering;
use core::str::FromStr;
use super::algorithm::{CustomDisplay, CustomFromStr};
use super::UDSI::{Container, UniContainer, Unique};
#[derive(Debug, Clone, Default)]
pub struct HashSet<T> {
pub cont: std::collections::HashSet<T>
}
impl<T: PartialEq> PartialEq for HashSet<T> {
fn eq(&self, other: &Self) -> bool {
self.cont.iter().eq(other.cont.iter())
}
}
impl<T: PartialEq> Eq for HashSet<T> {}
impl<T: PartialOrd> PartialOrd for HashSet<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.cont.iter().partial_cmp(other.cont.iter())
}
}
impl<T: Ord> Ord for HashSet<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.cont.iter().cmp(other.cont.iter())
}
}
impl<T: Hash> Hash for HashSet<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.cont.iter().collect::<Vec<_>>().hash(state);
}
}
impl<T> Container<T> for HashSet<T> {
fn len(&self) -> usize {
self.cont.len()
}
}
impl<T> UniContainer<T> for HashSet<T> {
fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T> where T: 'a {
self.cont.iter()
}
}
impl<T: Display> CustomDisplay<T> for HashSet<T> {}
impl<T: Display> Display for HashSet<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
self.display(f, "HashSet", '{', '}')
}
}
impl<T: Eq + Hash> Extend<T> for HashSet<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.cont.extend(iter);
}
}
impl<T: Eq + Hash> FromIterator<T> for HashSet<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut cont = Self::new();
cont.extend(iter);
cont
}
}
impl<T> IntoIterator for HashSet<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.cont.into_iter()
}
}
impl<'a,T> IntoIterator for &'a HashSet<T> {
type Item = &'a T;
type IntoIter = Iter<'a,T>;
fn into_iter(self) -> Self::IntoIter {
self.cont.iter()
}
}
impl<T,U: Into<std::collections::HashSet<T>>> From<U> for HashSet<T> {
fn from(value: U) -> Self {
use crate::hash_set;
hash_set![cont: value.into()]
}
}
impl<T: Eq + Hash + FromStr + Default> CustomFromStr<T> for HashSet<T> where <T as FromStr>::Err : Display {}
impl<T: Eq + Hash + FromStr + Default> FromStr for HashSet<T> where <T as FromStr>::Err : Display {
type Err = String;
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
Self::from_string(s, "HashSet", |cont, _, elem| {cont.cont.insert(elem);})
}
}
#[macro_export]
macro_rules! hash_set {
[cont: $x:expr] => {
{
use $crate::structs::hash_set::HashSet;
HashSet { cont: ($x)}
}
};
[$($x:expr),*] => {
{
use $crate::structs::hash_set::HashSet;
HashSet { cont: (std::collections::HashSet::from([$($x),*])) }
}
};
}
impl<T: Ord + Hash + Clone> Unique<T> for HashSet<T> {
fn add(&mut self, elem: T) -> &mut Self {
self.cont.insert(elem);
self
}
fn add_slice(&mut self, elems: Vec<T>) -> &mut Self {
self.cont.extend(elems);
self
}
fn contains(&self, elem: &T) -> bool {
self.cont.contains(elem)
}
fn contains_fn(&self, mut f: impl FnMut(&T) -> bool) -> bool {
for elem in &self.cont { if f(elem) { return true } }
false
}
fn contains_slice(&self, elems: &[T]) -> bool {
for elem in elems { if !self.cont.contains(elem) { return false } }
true
}
fn count(&self, elem: &T) -> usize {
usize::from(self.contains(elem))
}
fn count_fn(&self, mut f: impl FnMut(&T) -> bool) -> usize {
let mut count=0;
for i in &self.cont { if f(i) {count+=1;} }
count
}
fn count_slice(&self, elems: &[T]) -> usize {
usize::from(self.contains_slice(elems))
}
fn replace(&mut self, what: &T, to_what: Option<&T>) -> &mut Self {
if self.cont.remove(what) { if let Some(val) = to_what { self.cont.insert(val.clone()); } }
self
}
fn replace_fn(&mut self, mut f: impl FnMut(&T)->bool, to_what: Option<&T>) -> &mut Self {
let mut tmp=std::collections::HashSet::new();
swap(&mut tmp,&mut self.cont);
let mut insert_to_what=false;
for elem in tmp {
if f(&elem) { insert_to_what=true; }
else { self.cont.insert(elem); }
}
if insert_to_what { if let Some(towhat)=to_what { self.cont.insert(towhat.clone()); } }
self
}
fn replace_slice(&mut self, slice: &[T], to_what: Option<&[T]>) -> &mut Self {
if self.contains_slice(slice) {
for item in slice { self.cont.remove(item); }
if let Some(towhat)=to_what {self.extend(towhat.into_iter().cloned())}
}
self
}
fn clear(&mut self) -> &mut Self {
self.cont.clear();
self
}
fn maxi(&self) -> &T {
debug_assert!(!self.cont.is_empty(), "Tried to get min in empty HashSet!");
self.cont.iter().max().unwrap()
}
fn mini(&self) -> &T {
debug_assert!(!self.cont.is_empty(), "Tried to get min in empty HashSet!");
self.cont.iter().min().unwrap()
}
fn union(&mut self, other: Self) -> &mut Self {
self.cont.extend(other.cont);
self
}
fn difference(&mut self, other: &Self) -> &mut Self {
for i in other.iter() { self.cont.remove(i); }
self
}
fn intersect(&mut self, other: &Self) -> &mut Self {
let mut out=std::collections::HashSet::new();
swap(&mut self.cont, &mut out);
for i in out { if other.contains(&i) { self.cont.insert(i); } }
self
}
fn sym_diff(&mut self, other: Self) -> &mut Self {
let mut temp=std::collections::HashSet::new();
for i in other { if !self.cont.remove(&i) { temp.insert(i); } }
self.cont.extend(temp);
self
}
fn is_subset(&self, other: &Self) -> bool {
self.cont.is_subset(&other.cont)
}
fn is_superset(&self, other: &Self) -> bool {
self.cont.is_superset(&other.cont)
}
}
impl<T> HashSet<T> {
#[must_use]
pub fn new() -> Self {
Self {
cont: std::collections::HashSet::new(),
}
}
}
impl<T: Clone + Add<Output = T>> HashSet<T> {
#[must_use = "Sum does not consume the Set"]
pub fn sum(&self) -> T {
debug_assert!(!self.cont.is_empty(), "Can't add elements together in empty OrdSet!");
let mut iter=self.cont.iter();
let mut out=iter.next().unwrap().clone();
for elem in iter {
out=out+elem.clone();
}
out
}
}
impl<T: Eq + Hash + Clone> HashSet<HashSet<T>> {
#[must_use = "Join consumes the Set"]
pub fn join(self, sep: Option<&Vec<T>>) -> HashSet<T> {
let mut res=HashSet::new();
for elem in self {
res.cont.extend(elem.cont);
}
if let Some(val) = sep { res.cont.extend(val.clone()); }
res
}
}
macro_rules! scalar_op {
($for:tt, $trait:tt, $trait2:tt, $name:ident, $name2:ident) => {
impl<T: Clone + Hash + Eq + $trait<Output = T>> $trait<T> for $for<T> {
type Output = Self;
fn $name(mut self, rhs: T) -> Self::Output {
self.$name2(rhs);
self
}
}
impl<T: Clone + Hash + Eq + $trait<Output = T>> $trait2<T> for $for<T> {
fn $name2(&mut self, rhs: T) {
let mut tmp=$for::new();
swap(&mut tmp,self);
*self=tmp.into_iter().map(|x| x.$name(rhs.clone())).collect();
}
}
};
(shift $for:tt, $trait:tt, $trait2:tt, $name:ident, $name2:ident) => {
impl<T: Clone + Hash + Eq + $trait<U, Output = T>, U: Clone> $trait<U> for $for<T> {
type Output = Self;
fn $name(mut self, rhs: U) -> Self::Output {
self.$name2(rhs);
self
}
}
impl<T: Clone + Hash + Eq + $trait<U, Output = T>, U: Clone> $trait2<U> for $for<T> {
fn $name2(&mut self, rhs: U) {
let mut tmp=$for::new();
swap(&mut tmp,self);
*self=tmp.into_iter().map(|x| x.$name(rhs.clone())).collect();
}
}
};
($for:tt, $trait:tt, $name:ident) => {
impl<T: Hash + Eq + $trait<Output = T>> $trait for $for<T> {
type Output = Self;
fn $name(self) -> Self::Output {
self.into_iter().map(|x| x.$name()).collect()
}
}
};
}
scalar_op!(HashSet,Not,not);
scalar_op!(HashSet,Neg,neg);
scalar_op!(HashSet,Add,AddAssign,add,add_assign);
scalar_op!(HashSet,Sub,SubAssign,sub,sub_assign);
scalar_op!(HashSet,Mul,MulAssign,mul,mul_assign);
scalar_op!(HashSet,Div,DivAssign,div,div_assign);
scalar_op!(HashSet,Rem,RemAssign,rem,rem_assign);
scalar_op!(shift HashSet,Shl,ShlAssign,shl,shl_assign);
scalar_op!(shift HashSet,Shr,ShrAssign,shr,shr_assign);
scalar_op!(HashSet,BitAnd,BitAndAssign,bitand,bitand_assign);
scalar_op!(HashSet,BitOr, BitOrAssign, bitor, bitor_assign );
scalar_op!(HashSet,BitXor,BitXorAssign,bitxor,bitxor_assign);