use std::cmp::Ordering;
use crate::idx::Idx;
use crate::qty::MocQty;
use super::cell::{Cell, MocCell};
use super::cellrange::{CellRange, MocCellRange};
use super::range::MocRange;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CellOrCellRange<T: Idx> {
Cell(Cell<T>),
CellRange(CellRange<T>),
}
impl<T: Idx> CellOrCellRange<T> {
fn get_depth_idx_low(&self) -> (u8, &T) {
match &self {
CellOrCellRange::Cell(Cell { depth, idx }) => (*depth, idx),
CellOrCellRange::CellRange(CellRange { depth, range }) => (*depth, &range.start),
}
}
pub fn flat_cmp<Q: MocQty<T>>(&self, other: &Self) -> Ordering {
let (d1, i_l) = self.get_depth_idx_low();
let (d2, i_r) = other.get_depth_idx_low();
match d1.cmp(&d2) {
Ordering::Equal => i_l.cmp(i_r),
Ordering::Less => i_l.unsigned_shl(Q::shift(d2 - d1) as u32).cmp(i_r),
Ordering::Greater => i_l.cmp(&i_r.unsigned_shl(Q::shift(d1 - d2) as u32)),
}
}
pub fn overlap<Q: MocQty<T>>(&self, other: &Self) -> bool {
let range1: MocRange<T, Q> = self.into();
let range2: MocRange<T, Q> = other.into();
!(range1.0.end <= range2.0.start || range2.0.end <= range1.0.start)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum MocCellOrCellRange<T: Idx, Q: MocQty<T>> {
MocCell(MocCell<T, Q>),
MocCellRange(MocCellRange<T, Q>),
}