use std::{
cell::RefCell,
mem,
ops::{Add, RangeBounds, RangeInclusive, Sub},
rc::Rc,
};
use crate::{
AnyIncDecCpCmp, Column, Consolidate, ConsolidateChecker, ConsolidateMrsP, ConsolidationOrder,
CpCmp, DefaultValues, GetBeginEnd, GetBeginEndOption, IncDecCpCmp, Intersector,
NumberIncDecCpCmp, OverlapIter, RiFactory,
};
pub struct Columns<
T,
V,
I: Iterator<Item = S>,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
C: IncDecCpCmp<T, V>,
F: GetBeginEndOption<T, R> + Copy + Clone,
> {
isec: RefCell<Intersector<T, V, C, RangeInclusive<T>, RiFactory<T>>>,
factory: F,
columns: RefCell<Vec<Column<T, V, R, S, F, I, C>>>,
cmp: C,
order: ConsolidationOrder,
rebound: V,
}
impl<S: RangeBounds<T>, T: Copy + Clone + PartialOrd, I: Iterator<Item = S>>
Columns<T, T, I, RangeInclusive<T>, S, NumberIncDecCpCmp<T>, RiFactory<T>>
where
NumberIncDecCpCmp<T>: DefaultValues<T, T>,
{
pub fn num(order: ConsolidationOrder, step: T, rebound: T, min: T, max: T) -> Self {
let cmp = NumberIncDecCpCmp::new(min, max);
let factory = RiFactory::new();
return Self::new(order, cmp, factory, step, rebound);
}
pub fn num_sr(sr: T) -> Self {
let cmp = NumberIncDecCpCmp::defaults();
let factory = RiFactory::new();
return Self::new(ConsolidationOrder::Forward, cmp, factory, sr, sr);
}
pub fn num_defaults() -> Self {
let cmp = NumberIncDecCpCmp::defaults();
return Self::num(
ConsolidationOrder::Forward,
cmp.default_step(),
cmp.default_step(),
cmp.min(),
cmp.max(),
);
}
pub fn num_defaults_rev() -> Self {
let cmp = NumberIncDecCpCmp::defaults();
return Self::num(
ConsolidationOrder::Reverse,
cmp.default_step(),
cmp.default_step(),
cmp.min(),
cmp.max(),
);
}
}
impl<S: RangeBounds<T>, T, V, I: Iterator<Item = S>>
Columns<T, V, I, RangeInclusive<T>, S, AnyIncDecCpCmp<T>, RiFactory<T>>
where
V: Copy,
T: PartialOrd + Copy + Add<V, Output = T> + Sub<V, Output = T>,
{
pub fn any(order: ConsolidationOrder, cmp: AnyIncDecCpCmp<T>, step: V, rebound: V) -> Self {
return Self::new(order, cmp, RiFactory::new(), step, rebound);
}
}
impl<
T,
V,
I: Iterator<Item = S>,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
C: IncDecCpCmp<T, V> + Copy + Clone,
F: GetBeginEndOption<T, R> + Copy + Clone,
> Columns<T, V, I, R, S, C, F>
{
pub fn new(order: ConsolidationOrder, cmp: C, factory: F, step: V, rebound: V) -> Self {
let rb = cmp.cp_v(&rebound);
return Self {
isec: RefCell::new(Intersector::new(
Vec::new(),
step,
rebound,
cmp,
RiFactory::new(),
)),
factory,
columns: RefCell::new(Vec::new()),
cmp,
order,
rebound: rb,
};
}
pub fn add_column(&self, iter: I) -> Result<usize, Column<T, V, R, S, F, I, C>> {
let con = Consolidate::new(iter, self.cmp, self.factory, self.cmp.cp_v(&self.rebound));
let checker = ConsolidateChecker::new(self.order, con);
match Column::new(&mut *self.isec.borrow_mut(), checker) {
Ok(res) => {
let idx = res.get_column();
match idx {
Ok(id) => {
self.columns.borrow_mut().push(res);
return Ok(id);
}
Err(_) => {
return Err(res);
}
}
}
Err(res) => Err(res),
}
}
}
impl<
T,
V,
I: Iterator<Item = S>,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
C: IncDecCpCmp<T, V> + Copy + Clone,
F: GetBeginEndOption<T, R> + Copy + Clone,
> IntoIterator for Columns<T, V, I, R, S, C, F>
{
type Item = (
RangeInclusive<T>,
Result<(), &'static str>,
Vec<Result<Vec<Rc<ConsolidateMrsP<T, R, S>>>, &'static str>>,
);
type IntoIter = ColumnsIter<T, V, I, R, S, C, F>;
fn into_iter(self) -> Self::IntoIter {
return ColumnsIter::new(
self.isec.into_inner().into_iter(),
self.columns.into_inner(),
self.order,
true,
);
}
}
pub struct ColumnsIter<
T,
V,
I: Iterator<Item = S>,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
C: IncDecCpCmp<T, V>,
F: GetBeginEndOption<T, R> + Copy + Clone,
> {
iter: RefCell<OverlapIter<T, V, C, RangeInclusive<T>, RiFactory<T>>>,
cols: Vec<Column<T, V, R, S, F, I, C>>,
order: ConsolidationOrder,
needs_init: bool,
}
impl<
T,
V,
I: Iterator<Item = S>,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
C: IncDecCpCmp<T, V>,
F: GetBeginEndOption<T, R> + Copy + Clone,
> ColumnsIter<T, V, I, R, S, C, F>
{
pub fn new(
iter: OverlapIter<T, V, C, RangeInclusive<T>, RiFactory<T>>,
cols: Vec<Column<T, V, R, S, F, I, C>>,
order: ConsolidationOrder,
needs_init: bool,
) -> Self {
Self {
iter: RefCell::new(iter),
cols,
order,
needs_init,
}
}
pub fn get_column<'a>(&self, idx: usize) -> Option<&'a Column<T, V, R, S, F, I, C>> {
let res = self.cols.get(idx);
return unsafe {
mem::transmute::<
Option<&'_ Column<T, V, R, S, F, I, C>>,
Option<&'a Column<T, V, R, S, F, I, C>>,
>(res)
};
}
pub fn into_inner(
self,
) -> (
OverlapIter<T, V, C, RangeInclusive<T>, RiFactory<T>>,
Vec<Column<T, V, R, S, F, I, C>>,
ConsolidationOrder,
bool,
) {
return (
self.iter.into_inner(),
self.cols,
self.order,
self.needs_init,
);
}
pub fn next_last<'r>(&self) -> (Option<&'r RangeInclusive<T>>, Option<&'r RangeInclusive<T>>) {
let iter = &*self.iter.borrow();
let (last, next);
match &self.order {
ConsolidationOrder::Forward => (next, last) = iter.ln(),
ConsolidationOrder::Reverse => (next, last) = iter.lb(),
}
return unsafe {
mem::transmute::<
(Option<&'_ RangeInclusive<T>>, Option<&'_ RangeInclusive<T>>),
(Option<&'r RangeInclusive<T>>, Option<&'r RangeInclusive<T>>),
>((next, last))
};
}
}
impl<
T,
V,
I: Iterator<Item = S>,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
C: IncDecCpCmp<T, V>,
F: GetBeginEndOption<T, R> + Copy + Clone,
> Iterator for ColumnsIter<T, V, I, R, S, C, F>
{
type Item = (
RangeInclusive<T>,
Result<(), &'static str>,
Vec<Result<Vec<Rc<ConsolidateMrsP<T, R, S>>>, &'static str>>,
);
fn next(&mut self) -> Option<Self::Item> {
if self.needs_init {
let next;
self.needs_init = false;
match &self.order {
ConsolidationOrder::Forward => next = self.iter.borrow_mut().next(),
ConsolidationOrder::Reverse => next = self.iter.borrow_mut().next_back(),
}
if next.is_none() {
return None;
}
let filter = next.unwrap();
let mut cols = Vec::new();
let mut err = Ok(());
for col in &mut self.cols {
cols.push(col.filter_column(&filter));
if col.in_err() {
err = Err("Problem in one ore more Columns")
}
}
return Some((filter, err, cols));
}
let (next, last) = self.next_last();
let mut redo = false;
let n;
{
let iter = &mut *self.iter.borrow_mut();
if let Some(r) = next {
for col in &mut self.cols {
if col.update_column(r, iter, false) {
redo = true;
}
}
} else if let Some(r) = last {
redo = true;
for col in &mut self.cols {
col.update_column(r, iter, true);
}
} else {
return None;
}
if redo {
match &self.order {
ConsolidationOrder::Forward => n = iter.recompute_next(),
ConsolidationOrder::Reverse => n = iter.recompute_back(),
}
} else {
match &self.order {
ConsolidationOrder::Forward => n = iter.next(),
ConsolidationOrder::Reverse => n = iter.next_back(),
}
}
}
let mut cols = Vec::new();
if n.is_none() {
return None;
}
let filter = n.unwrap();
let mut err = Ok(());
for col in &mut self.cols {
cols.push(col.filter_column(&filter));
if col.in_err() {
err = Err("Problem in one ore more Columns")
}
}
return Some((filter, err, cols));
}
}