use crate::AsView;
use crate::PrefixSet;
use either::{Left, Right};
use super::{map::CoverKeys, JointPrefix};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "P::P1: serde::Serialize, P::P2: serde::Serialize",
deserialize = "P::P1: serde::Deserialize<'de>, P::P2: serde::Deserialize<'de>",
))
)]
pub struct JointPrefixSet<P: JointPrefix> {
pub t1: PrefixSet<P::P1>,
pub t2: PrefixSet<P::P2>,
}
impl<P: JointPrefix> JointPrefixSet<P> {
pub fn new() -> Self {
Self {
t1: PrefixSet::new(),
t2: PrefixSet::new(),
}
}
#[inline(always)]
pub fn len(&self) -> usize {
self.t1.len() + self.t2.len()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn contains(&self, prefix: &P) -> bool {
fork_ref!(self, prefix, contains)
}
pub fn get(&self, prefix: &P) -> Option<P> {
fork_ref!(self, prefix as P, get)
}
pub fn get_lpm(&self, prefix: &P) -> Option<P> {
fork_ref!(self, prefix as P, get_lpm)
}
pub fn get_spm(&self, prefix: &P) -> Option<P> {
fork_ref!(self, prefix as P, get_spm)
}
pub fn insert(&mut self, prefix: P) -> bool {
fork!(self, prefix, insert)
}
pub fn remove(&mut self, prefix: &P) -> bool {
fork_ref!(self, prefix, remove)
}
pub fn remove_keep_tree(&mut self, prefix: &P) -> bool {
fork_ref!(self, prefix, remove_keep_tree)
}
pub fn remove_children(&mut self, prefix: &P) {
fork_ref!(self, prefix, remove_children)
}
pub fn clear(&mut self) {
self.t1.clear();
self.t2.clear();
}
pub fn iter(&self) -> Iter<'_, P> {
self.into_iter()
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(P) -> bool,
{
self.t1.retain(|p| f(P::from_p1(p)));
self.t2.retain(|p| f(P::from_p2(p)));
}
pub fn children<'a>(&'a self, prefix: &P) -> Iter<'a, P> {
Iter(match prefix.p1_or_p2_ref() {
Left(p1) => super::map::Iter {
i1: Some(self.t1.0.children(p1)),
i2: None,
},
Right(p2) => super::map::Iter {
i1: None,
i2: Some(self.t2.0.children(p2)),
},
})
}
pub fn cover<'a, 'p>(&'a self, prefix: &'p P) -> CoverKeys<'a, 'p, P, ()> {
CoverKeys(match prefix.p1_or_p2_ref() {
Left(p1) => super::map::Cover::P1(self.t1.0.cover(p1)),
Right(p2) => super::map::Cover::P2(self.t2.0.cover(p2)),
})
}
pub fn union<'a>(&'a self, other: &'a JointPrefixSet<P>) -> Union<'a, P> {
Union(super::map::Union {
i1: Some(self.t1.view().union(&other.t1)),
i2: Some(self.t2.view().union(&other.t2)),
})
}
pub fn intersection<'a>(&'a self, other: &'a JointPrefixSet<P>) -> Intersection<'a, P> {
Intersection(super::map::Intersection {
i1: Some(self.t1.view().intersection(&other.t1)),
i2: Some(self.t2.view().intersection(&other.t2)),
})
}
pub fn difference<'a>(&'a self, other: &'a JointPrefixSet<P>) -> Difference<'a, P> {
Difference(super::map::Difference {
i1: Some(self.t1.view().difference(&other.t1)),
i2: Some(self.t2.view().difference(&other.t2)),
})
}
pub fn covering_difference<'a>(
&'a self,
other: &'a JointPrefixSet<P>,
) -> CoveringDifference<'a, P> {
CoveringDifference(super::map::CoveringDifference {
i1: Some(self.t1.view().covering_difference(&other.t1)),
i2: Some(self.t2.view().covering_difference(&other.t2)),
})
}
}
impl<P: JointPrefix> Default for JointPrefixSet<P> {
fn default() -> Self {
Self::new()
}
}
impl<P> PartialEq for JointPrefixSet<P>
where
P: JointPrefix + PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.iter().zip(other.iter()).all(|(a, b)| a == b)
}
}
impl<P> Eq for JointPrefixSet<P> where P: JointPrefix + Eq {}
pub struct Iter<'a, P: JointPrefix>(super::map::Iter<'a, P, ()>);
impl<P: JointPrefix> Default for Iter<'_, P> {
fn default() -> Self {
Self(Default::default())
}
}
impl<P: JointPrefix> Clone for Iter<'_, P> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<P: JointPrefix> Iterator for Iter<'_, P> {
type Item = P;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(p, _)| p)
}
}
#[derive(Clone)]
pub struct IntoIter<P: JointPrefix>(super::map::IntoIter<P, ()>);
impl<P: JointPrefix> Iterator for IntoIter<P> {
type Item = P;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(p, _)| p)
}
}
impl<P: JointPrefix> IntoIterator for JointPrefixSet<P> {
type Item = P;
type IntoIter = IntoIter<P>;
fn into_iter(self) -> Self::IntoIter {
IntoIter(super::map::IntoIter {
i1: Some(self.t1.0.into_iter()),
i2: Some(self.t2.0.into_iter()),
})
}
}
impl<'a, P: JointPrefix> IntoIterator for &'a JointPrefixSet<P> {
type Item = P;
type IntoIter = Iter<'a, P>;
fn into_iter(self) -> Self::IntoIter {
Iter(super::map::Iter {
i1: Some(self.t1.0.iter()),
i2: Some(self.t2.0.iter()),
})
}
}
impl<P: JointPrefix> FromIterator<P> for JointPrefixSet<P> {
fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> Self {
let mut set = Self::new();
for p in iter {
set.insert(p);
}
set
}
}
pub struct Union<'a, P: JointPrefix>(super::map::Union<'a, P, (), ()>);
impl<P: JointPrefix> Iterator for Union<'_, P> {
type Item = P;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|x| x.into_prefix())
}
}
pub struct Intersection<'a, P: JointPrefix>(super::map::Intersection<'a, P, (), ()>);
impl<P: JointPrefix> Iterator for Intersection<'_, P> {
type Item = P;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(p, _, _)| p)
}
}
pub struct Difference<'a, P: JointPrefix>(super::map::Difference<'a, P, (), ()>);
impl<P: JointPrefix> Iterator for Difference<'_, P> {
type Item = (P, Option<P>);
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|x| (x.prefix, x.right.map(|(p, _)| p)))
}
}
pub struct CoveringDifference<'a, P: JointPrefix>(super::map::CoveringDifference<'a, P, (), ()>);
impl<P: JointPrefix> Iterator for CoveringDifference<'_, P> {
type Item = P;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(p, _)| p)
}
}