use std::cmp::Ordering;
use std::marker::PhantomData;
use std::ops::Range;
use crate::idx::Idx;
use crate::qty::MocQty;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CellRange<T: Idx> {
pub depth: u8,
pub range: Range<T>,
}
impl<T: Idx> CellRange<T> {
pub fn new(depth: u8, start: T, end: T) -> Self {
CellRange::from_depth_range(depth, start..end)
}
pub fn from_depth_range(depth: u8, range: Range<T>) -> Self {
CellRange { depth, range }
}
pub fn flat_cmp<Q: MocQty<T>>(&self, other: &Self) -> Ordering {
match self.depth.cmp(&other.depth) {
Ordering::Equal => self.range.start.cmp(&other.range.start),
Ordering::Less => self
.range
.start
.unsigned_shl(Q::shift(other.depth - self.depth) as u32)
.cmp(&other.range.start),
Ordering::Greater => self.range.start.cmp(
&other
.range
.start
.unsigned_shl(Q::shift(self.depth - other.depth) as u32),
),
}
}
}
#[repr(transparent)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct MocCellRange<T: Idx, Q: MocQty<T>>(pub CellRange<T>, PhantomData<Q>);
impl<T: Idx, Q: MocQty<T>> Ord for MocCellRange<T, Q> {
fn cmp(&self, other: &Self) -> Ordering {
match self.0.depth.cmp(&other.0.depth) {
Ordering::Equal => self.0.range.start.cmp(&other.0.range.start),
Ordering::Less => self
.0
.range
.start
.unsigned_shl(Q::shift(other.0.depth - self.0.depth) as u32)
.cmp(&other.0.range.start),
Ordering::Greater => self.0.range.start.cmp(
&other
.0
.range
.start
.unsigned_shl(Q::shift(self.0.depth - other.0.depth) as u32),
),
}
}
}
impl<T: Idx, Q: MocQty<T>> PartialOrd for MocCellRange<T, Q> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T: Idx, Q: MocQty<T>> From<CellRange<T>> for MocCellRange<T, Q> {
fn from(cell_range: CellRange<T>) -> Self {
Self(cell_range, PhantomData)
}
}