use crate::DifferenceMap;
use crate::DifferenceMapInternal;
use crate::DynSortedDisjointMap;
use crate::IntersectionMap;
use crate::IntoRangeValuesIter;
use crate::NotIter;
use crate::NotMap;
use crate::SymDiffMergeMap;
use crate::UnionMergeMap;
use crate::intersection_iter_map::IntersectionIterMap;
use crate::map::ValueRef;
use crate::range_values::RangeValuesIter;
use crate::range_values::RangeValuesToRangesIter;
use crate::sorted_disjoint::SortedDisjoint;
use crate::sym_diff_iter_map::SymDiffIterMap;
use crate::{Integer, RangeMapBlaze, union_iter_map::UnionIterMap};
use alloc::format;
use alloc::rc::Rc;
use alloc::string::String;
use alloc::vec::Vec;
use core::cmp::Ordering;
use core::fmt::Debug;
use core::iter::FusedIterator;
use core::marker::PhantomData;
use core::ops;
use core::ops::RangeInclusive;
pub trait SortedStartsMap<T, VR>: Iterator<Item = (RangeInclusive<T>, VR)> + FusedIterator
where
T: Integer,
VR: ValueRef,
{
}
pub trait PrioritySortedStartsMap<T, VR>: Iterator<Item = Priority<T, VR>> + FusedIterator
where
T: Integer,
VR: ValueRef,
{
}
pub trait SortedDisjointMap<T, VR>: SortedStartsMap<T, VR>
where
T: Integer,
VR: ValueRef,
{
#[inline]
fn into_sorted_disjoint(self) -> RangeValuesToRangesIter<T, VR, Self>
where
Self: Sized,
{
RangeValuesToRangesIter::new(self)
}
#[inline]
fn union<R>(self, other: R) -> UnionMergeMap<T, VR, Self, R::IntoIter>
where
R: IntoIterator<Item = Self::Item>,
R::IntoIter: SortedDisjointMap<T, VR>,
Self: Sized,
{
UnionIterMap::new2(self, other.into_iter())
}
#[inline]
fn intersection<R>(self, other: R) -> IntersectionMap<T, VR, Self, R::IntoIter>
where
R: IntoIterator<Item = Self::Item>,
R::IntoIter: SortedDisjointMap<T, VR>,
Self: Sized,
{
let other = other.into_iter();
let sorted_disjoint = self.into_sorted_disjoint();
IntersectionIterMap::new(other, sorted_disjoint)
}
#[inline]
fn map_and_set_intersection<R>(self, other: R) -> IntersectionIterMap<T, VR, Self, R::IntoIter>
where
R: IntoIterator<Item = RangeInclusive<T>>,
R::IntoIter: SortedDisjoint<T>,
Self: Sized,
{
IntersectionIterMap::new(self, other.into_iter())
}
#[inline]
fn difference<R>(self, other: R) -> DifferenceMap<T, VR, Self, R::IntoIter>
where
R: IntoIterator<Item = Self::Item>,
R::IntoIter: SortedDisjointMap<T, VR>,
Self: Sized,
{
let sorted_disjoint_map = other.into_iter();
let complement = sorted_disjoint_map.complement();
IntersectionIterMap::new(self, complement)
}
#[inline]
fn map_and_set_difference<R>(self, other: R) -> DifferenceMapInternal<T, VR, Self, R::IntoIter>
where
R: IntoIterator<Item = RangeInclusive<T>>,
R::IntoIter: SortedDisjoint<T>,
Self: Sized,
{
let sorted_disjoint = other.into_iter();
let complement = sorted_disjoint.complement();
IntersectionIterMap::new(self, complement)
}
#[inline]
fn complement(self) -> NotIter<T, RangeValuesToRangesIter<T, VR, Self>>
where
Self: Sized,
{
let sorted_disjoint = self.into_sorted_disjoint();
sorted_disjoint.complement()
}
#[inline]
fn complement_with(
self,
v: &VR::Target,
) -> RangeToRangeValueIter<'_, T, VR::Target, NotIter<T, impl SortedDisjoint<T>>>
where
Self: Sized,
{
let complement = self.complement();
RangeToRangeValueIter::new(complement, v)
}
#[inline]
fn symmetric_difference<R>(self, other: R) -> SymDiffMergeMap<T, VR, Self, R::IntoIter>
where
R: IntoIterator<Item = Self::Item>,
R::IntoIter: SortedDisjointMap<T, VR>,
Self: Sized,
VR: ValueRef,
{
SymDiffIterMap::new2(self, other.into_iter())
}
fn equal<R>(self, other: R) -> bool
where
R: IntoIterator<Item = Self::Item>,
R::IntoIter: SortedDisjointMap<T, VR>,
Self: Sized,
{
use itertools::Itertools;
self.zip_longest(other).all(|pair| {
match pair {
itertools::EitherOrBoth::Both(
(self_range, self_value),
(other_range, other_value),
) => {
self_range == other_range && self_value.borrow() == other_value.borrow()
}
_ => false, }
})
}
#[inline]
#[allow(clippy::wrong_self_convention)]
fn is_empty(mut self) -> bool
where
Self: Sized,
{
self.next().is_none()
}
#[inline]
#[allow(clippy::wrong_self_convention)]
fn is_universal(self) -> bool
where
Self: Sized,
{
let mut expected_start = T::min_value();
for (range, _) in self {
let (start, end) = range.into_inner();
if start != expected_start {
return false;
}
if end == T::max_value() {
return true;
}
expected_start = end.add_one();
}
false
}
fn into_range_map_blaze(self) -> RangeMapBlaze<T, VR::Target>
where
Self: Sized,
{
RangeMapBlaze::from_sorted_disjoint_map(self)
}
}
pub trait IntoString {
fn into_string(self) -> String;
}
impl<T, I> IntoString for I
where
T: Debug,
I: Iterator<Item = T>,
{
fn into_string(self) -> String {
self.map(|item| format!("{item:?}"))
.collect::<Vec<String>>()
.join(", ")
}
}
#[allow(clippy::module_name_repetitions)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Debug, Clone)]
pub struct CheckSortedDisjointMap<T, VR, I> {
iter: I,
seen_none: bool,
previous: Option<(RangeInclusive<T>, VR)>,
}
impl<T, VR, I> CheckSortedDisjointMap<T, VR, I>
where
T: Integer,
VR: ValueRef,
I: Iterator<Item = (RangeInclusive<T>, VR)>,
{
#[inline]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub fn new<J>(iter: J) -> Self
where
J: IntoIterator<Item = (RangeInclusive<T>, VR), IntoIter = I>,
{
Self {
iter: iter.into_iter(),
seen_none: false,
previous: None,
}
}
}
impl<T, VR, I> Default for CheckSortedDisjointMap<T, VR, I>
where
T: Integer,
VR: ValueRef,
I: Iterator<Item = (RangeInclusive<T>, VR)> + Default,
{
fn default() -> Self {
Self::new(I::default())
}
}
impl<T, VR, I> FusedIterator for CheckSortedDisjointMap<T, VR, I>
where
T: Integer,
VR: ValueRef,
I: Iterator<Item = (RangeInclusive<T>, VR)>,
{
}
fn range_value_clone<T, VR>(range_value: &(RangeInclusive<T>, VR)) -> (RangeInclusive<T>, VR)
where
T: Integer,
VR: ValueRef,
{
let (range, value) = range_value;
(range.clone(), value.clone())
}
impl<T, VR, I> Iterator for CheckSortedDisjointMap<T, VR, I>
where
T: Integer,
VR: ValueRef,
I: Iterator<Item = (RangeInclusive<T>, VR)>,
{
type Item = (RangeInclusive<T>, VR);
#[allow(clippy::manual_assert)] fn next(&mut self) -> Option<Self::Item> {
let range_value = self.iter.next();
let Some(range_value) = range_value else {
self.seen_none = true;
return None;
};
if self.seen_none {
panic!("a value must not be returned after None")
}
let (start, end) = range_value.0.clone().into_inner();
if start > end {
panic!("start must be <= end")
}
let Some(previous) = self.previous.take() else {
self.previous = Some(range_value_clone(&range_value));
return Some(range_value);
};
let previous_end = *previous.0.end();
if previous_end >= start {
panic!("ranges must be disjoint and sorted")
}
if previous_end.add_one() == start && previous.1.borrow() == range_value.1.borrow() {
panic!("touching ranges must have different values")
}
self.previous = Some(range_value_clone(&range_value));
Some(range_value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
#[derive(Clone, Debug)]
pub struct Priority<T, VR> {
range_value: (RangeInclusive<T>, VR),
priority_number: usize,
}
impl<T, VR> Priority<T, VR> {
pub(crate) const fn new(range_value: (RangeInclusive<T>, VR), priority_number: usize) -> Self {
Self {
range_value,
priority_number,
}
}
}
impl<T, VR> Priority<T, VR>
where
T: Integer,
VR: ValueRef,
{
pub const fn range_value(&self) -> &(RangeInclusive<T>, VR) {
&self.range_value
}
pub fn into_range_value(self) -> (RangeInclusive<T>, VR) {
self.range_value
}
pub const fn set_range(&mut self, range: RangeInclusive<T>) {
self.range_value.0 = range;
}
pub const fn start(&self) -> T {
*self.range_value.0.start()
}
pub const fn end(&self) -> T {
*self.range_value.0.end()
}
pub const fn start_and_end(&self) -> (T, T) {
((*self.range_value.0.start()), (*self.range_value.0.end()))
}
pub const fn value(&self) -> &VR {
&self.range_value.1
}
}
impl<T, VR> PartialEq for Priority<T, VR>
where
T: Integer,
VR: ValueRef,
{
fn eq(&self, other: &Self) -> bool {
self.priority_number == other.priority_number
}
}
impl<T, VR> Eq for Priority<T, VR>
where
T: Integer,
VR: ValueRef,
{
}
impl<T, VR> Ord for Priority<T, VR>
where
T: Integer,
VR: ValueRef,
{
fn cmp(&self, other: &Self) -> Ordering {
debug_assert_ne!(
self.priority_number, other.priority_number,
"Priority numbers are expected to be distinct for comparison."
);
self.priority_number.cmp(&other.priority_number)
}
}
impl<T, VR> PartialOrd for Priority<T, VR>
where
T: Integer,
VR: ValueRef,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone, Debug)]
pub struct RangeToRangeValueIter<'a, T, V, I> {
inner: I,
value: &'a V,
phantom: PhantomData<T>,
}
impl<'a, T, V, I> RangeToRangeValueIter<'a, T, V, I>
where
T: Integer,
V: Eq + Clone,
I: SortedDisjoint<T>,
{
pub(crate) const fn new(inner: I, value: &'a V) -> Self {
Self {
inner,
value,
phantom: PhantomData,
}
}
}
impl<T, V, I> FusedIterator for RangeToRangeValueIter<'_, T, V, I>
where
T: Integer,
V: Eq + Clone,
I: SortedDisjoint<T>,
{
}
impl<'a, T, V, I> Iterator for RangeToRangeValueIter<'a, T, V, I>
where
T: Integer,
V: Eq + Clone,
I: SortedDisjoint<T>,
{
type Item = (RangeInclusive<T>, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|range| (range, self.value))
}
}
impl<'a, T, V, I> SortedStartsMap<T, &'a V> for RangeToRangeValueIter<'a, T, V, I>
where
T: Integer,
V: Eq + Clone,
I: SortedDisjoint<T>,
{
}
impl<'a, T, V, I> SortedDisjointMap<T, &'a V> for RangeToRangeValueIter<'a, T, V, I>
where
T: Integer,
V: Eq + Clone,
I: SortedDisjoint<T>,
{
}
macro_rules! impl_sorted_map_traits_and_ops {
($IterType:ty, $V:ty, $VR:ty, $($more_generics:tt)*) => {
#[allow(single_use_lifetimes)]
impl<$($more_generics)*, T> SortedStartsMap<T, $VR> for $IterType
where
T: Integer,
{
}
#[allow(single_use_lifetimes)]
impl<$($more_generics)*, T> SortedDisjointMap<T, $VR> for $IterType
where
T: Integer,
{
}
#[allow(single_use_lifetimes)]
impl<$($more_generics)*, T> ops::Not for $IterType
where
T: Integer,
{
type Output = NotMap<T, $VR, Self>;
#[inline]
fn not(self) -> Self::Output {
self.complement()
}
}
#[allow(single_use_lifetimes)]
impl<$($more_generics)*, T, R> ops::BitOr<R> for $IterType
where
T: Integer,
R: SortedDisjointMap<T, $VR>,
{
type Output = UnionMergeMap<T, $VR, Self, R>;
#[inline]
fn bitor(self, other: R) -> Self::Output {
SortedDisjointMap::union(self, other)
}
}
#[allow(single_use_lifetimes)]
impl<$($more_generics)*, T, R> ops::Sub<R> for $IterType
where
T: Integer,
R: SortedDisjointMap<T, $VR>,
{
type Output = DifferenceMap<T, $VR, Self, R>;
#[inline]
fn sub(self, other: R) -> Self::Output {
SortedDisjointMap::difference(self, other)
}
}
#[allow(single_use_lifetimes)]
impl<$($more_generics)*, T, R> ops::BitXor<R> for $IterType
where
T: Integer,
R: SortedDisjointMap<T, $VR>,
{
type Output = SymDiffMergeMap<T, $VR, Self, R>;
#[allow(clippy::suspicious_arithmetic_impl)]
#[inline]
fn bitxor(self, other: R) -> Self::Output {
SortedDisjointMap::symmetric_difference(self, other)
}
}
#[allow(single_use_lifetimes)]
impl<$($more_generics)*, T, R> ops::BitAnd<R> for $IterType
where
T: Integer,
R: SortedDisjointMap<T, $VR>,
{
type Output = IntersectionMap<T, $VR, Self, R>;
#[inline]
fn bitand(self, other: R) -> Self::Output {
SortedDisjointMap::intersection(self, other)
}
}
}
}
impl_sorted_map_traits_and_ops!(CheckSortedDisjointMap<T, VR, I>, VR::Value, VR, VR: ValueRef, I: Iterator<Item = (RangeInclusive<T>, VR)>);
impl_sorted_map_traits_and_ops!(DynSortedDisjointMap<'a, T, VR>, VR::Value, VR, 'a, VR: ValueRef);
impl_sorted_map_traits_and_ops!(IntersectionIterMap<T, VR, I0, I1>, VR::Value, VR, VR: ValueRef, I0: SortedDisjointMap<T, VR>, I1: SortedDisjoint<T>);
impl_sorted_map_traits_and_ops!(IntoRangeValuesIter<T, V>, V, Rc<V>, V: Eq + Clone);
impl_sorted_map_traits_and_ops!(RangeValuesIter<'a, T, V>, V, &'a V, 'a, V: Eq + Clone);
impl_sorted_map_traits_and_ops!(SymDiffIterMap<T, VR, I>, VR::Value, VR, VR: ValueRef, I: PrioritySortedStartsMap<T, VR>);
impl_sorted_map_traits_and_ops!(UnionIterMap<T, VR, I>, VR::Value, VR, VR: ValueRef, I: PrioritySortedStartsMap<T, VR>);