use crate::Element;
use core::fmt::Debug;
use core::ops::{BitAndAssign, BitOrAssign, BitXorAssign, SubAssign};
pub trait Set<'a>:
Debug
+ Clone
+ Default
+ BitAndAssign<&'a Self>
+ BitAndAssign<&'a Self::Element>
+ BitOrAssign<&'a Self>
+ BitOrAssign<&'a Self::Element>
+ BitXorAssign<&'a Self>
+ BitXorAssign<&'a Self::Element>
+ SubAssign<&'a Self>
+ SubAssign<&'a Self::Element>
where
Self: 'a,
{
type Element: Element + 'a;
type Iter: Iterator<Item = &'a Self::Element>;
type Difference: Iterator<Item = &'a Self::Element>;
type Intersection: Iterator<Item = &'a Self::Element>;
type SymmetricDifference: Iterator<Item = &'a Self::Element>;
type Union: Iterator<Item = &'a Self::Element>;
fn new() -> Self;
fn capacity(&self) -> usize;
fn clear(&mut self);
fn contains(&self, value: &Self::Element) -> bool;
fn difference(&'a self, other: &'a Self) -> Self::Difference;
fn difference_ref(&'a self, other: &'a Self) -> Self::Difference;
fn insert(&mut self, value: Self::Element);
fn intersection(&'a self, other: &'a Self) -> Self::Intersection;
#[inline]
fn intersection_update(&mut self, rhs: &Self) {
self.retain(|&x| rhs.contains(&x));
}
#[inline]
fn intersection_item_update(&mut self, value: &Self::Element) {
self.retain(|&x| x == *value);
}
fn is_empty(&self) -> bool;
fn iter(&'a self) -> Self::Iter;
fn len(&self) -> usize;
fn remove(&mut self, value: &Self::Element);
fn retain<F>(&mut self, f: F)
where
F: FnMut(&Self::Element) -> bool;
fn symmetric_difference(&'a self, other: &'a Self) -> Self::SymmetricDifference;
fn symmetric_difference_update(&mut self, rhs: &Self);
#[inline]
fn symmetric_difference_item_update(&mut self, value: &Self::Element) {
if self.contains(value) {
self.remove(value);
} else {
self.insert(*value);
}
}
fn union(&'a self, other: &'a Self) -> Self::Union;
fn union_update(&mut self, rhs: &Self);
#[inline]
fn union_item_update(&mut self, value: &Self::Element) {
self.insert(*value);
}
fn with_capacity(capacity: usize) -> Self;
#[inline]
fn bitand_assign_set(&mut self, rhs: &Self) {
self.intersection_update(rhs);
}
#[inline]
fn bitand_assign_item(&mut self, rhs: &Self::Element) {
self.intersection_item_update(rhs);
}
#[inline]
fn bitor_assign_set(&mut self, rhs: &Self) {
self.union_update(rhs);
}
#[inline]
fn bitor_assign_item(&mut self, rhs: &Self::Element) {
self.union_item_update(rhs);
}
#[inline]
fn bitxor_assign_set(&mut self, rhs: &Self) {
self.symmetric_difference_update(rhs);
}
#[inline]
fn bitxor_assign_item(&mut self, rhs: &Self::Element) {
self.symmetric_difference_item_update(rhs);
}
#[inline]
fn sub_assign_set(&mut self, rhs: &Self) {
self.retain(|x| !rhs.contains(x));
}
#[inline]
fn sub_assign_item(&mut self, rhs: &Self::Element) {
self.remove(rhs);
}
}
#[macro_export]
macro_rules! build_set_bit_ops {
($set_type:ty) => {
impl<'a, E: Element> BitAndAssign<&'a $set_type> for $set_type {
#[inline]
fn bitand_assign(&mut self, rhs: &$set_type) {
self.bitand_assign_set(rhs);
}
}
impl<'a, E: Element> BitAndAssign<&'a E> for $set_type {
#[inline]
fn bitand_assign(&mut self, rhs: &E) {
self.bitand_assign_item(rhs);
}
}
impl<'a, E: Element> BitOrAssign<&'a $set_type> for $set_type {
#[inline]
fn bitor_assign(&mut self, rhs: &$set_type) {
self.bitor_assign_set(rhs);
}
}
impl<'a, E: Element> BitOrAssign<&'a E> for $set_type {
#[inline]
fn bitor_assign(&mut self, rhs: &E) {
self.bitor_assign_item(rhs);
}
}
impl<'a, E: Element> BitXorAssign<&'a $set_type> for $set_type {
#[inline]
fn bitxor_assign(&mut self, rhs: &$set_type) {
self.bitxor_assign_set(rhs);
}
}
impl<'a, E: Element> BitXorAssign<&'a E> for $set_type {
#[inline]
fn bitxor_assign(&mut self, rhs: &E) {
self.bitxor_assign_item(rhs);
}
}
impl<'a, E: Element> SubAssign<&'a $set_type> for $set_type {
#[inline]
fn sub_assign(&mut self, rhs: &$set_type) {
self.sub_assign_set(rhs);
}
}
impl<'a, E: Element> SubAssign<&'a E> for $set_type {
#[inline]
fn sub_assign(&mut self, rhs: &E) {
self.sub_assign_item(rhs);
}
}
};
}