use crate::Set;
use crate::VecSet;
use core::fmt;
use core::iter::Chain;
use core::slice::Iter;
use crate::Element;
pub struct SymmetricDifference<'a, E: Element> {
pub(crate) iter: Chain<Difference<'a, E>, Difference<'a, E>>,
}
#[derive(Clone)]
pub struct Difference<'a, E: Element> {
pub(crate) iter: Iter<'a, E>,
pub(crate) other: &'a VecSet<E>,
}
#[derive(Clone)]
pub struct Intersection<'a, E: Element> {
pub(crate) iter: Iter<'a, E>,
pub(crate) other: &'a VecSet<E>,
}
#[derive(Clone)]
pub struct Union<'a, E: Element> {
pub(crate) iter: Chain<Iter<'a, E>, Difference<'a, E>>,
}
impl<E: Element> Clone for SymmetricDifference<'_, E> {
#[inline]
fn clone(&self) -> Self {
SymmetricDifference {
iter: self.iter.clone(),
}
}
}
impl<'a, E: Element> Iterator for SymmetricDifference<'a, E> {
type Item = &'a E;
#[inline]
fn next(&mut self) -> Option<&'a E> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn fold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.iter.fold(init, f)
}
}
impl<'a, E: Element> Iterator for Difference<'a, E> {
type Item = &'a E;
#[inline]
fn next(&mut self) -> Option<&'a E> {
self.iter.by_ref().find(|&item| !self.other.contains(item))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.iter.fold(init, |acc, elt| {
if self.other.contains(elt) {
acc
} else {
f(acc, elt)
}
})
}
}
impl<'a, E: Element> Iterator for Intersection<'a, E> {
type Item = &'a E;
#[inline]
fn next(&mut self) -> Option<&'a E> {
loop {
let elt = self.iter.next()?;
if self.other.contains(elt) {
return Some(elt);
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.iter.fold(init, |acc, elt| {
if self.other.contains(elt) {
f(acc, elt)
} else {
acc
}
})
}
}
impl<'a, E: Element> Iterator for Union<'a, E> {
type Item = &'a E;
#[inline]
fn next(&mut self) -> Option<&'a E> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
#[inline]
fn fold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.iter.fold(init, f)
}
}
impl<E: Element> fmt::Debug for Difference<'_, E>
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<E: Element> fmt::Debug for SymmetricDifference<'_, E>
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<E: Element> fmt::Debug for Intersection<'_, E>
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<E: Element> fmt::Debug for Union<'_, E>
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}