use std::ops::RangeInclusive;
use std::{
marker::PhantomData,
ops::{Add, Bound, Sub},
};
use crate::{GetBeginEnd, Mrs};
#[derive(Clone, Copy, Debug)]
pub struct NumberIncDecCpCmp<T>
where
T: Copy + Clone,
{
min: T,
max: T,
}
#[derive(Clone, Copy, Debug)]
pub struct AnyIncDecCpCmp<T>
where
T: PartialOrd + Clone + Copy,
{
min: T,
max: T,
}
impl<T> AnyIncDecCpCmp<T>
where
T: PartialOrd + Clone + Copy,
{
pub fn new(min: T, max: T) -> Self {
Self { min, max }
}
pub fn set_min(&mut self, v: T) {
self.min = v;
}
pub fn set_max(&mut self, v: T) {
self.max = v;
}
}
impl<T> CpCmp<T> for AnyIncDecCpCmp<T>
where
T: PartialOrd + Copy,
{
fn cp(&self, v: &T) -> T {
return *v;
}
fn min_ref(&self) -> &T {
return &self.min;
}
fn max_ref(&self) -> &T {
return &self.max;
}
fn lt(&self, a: &T, b: &T) -> bool {
return a < b;
}
fn min(&self) -> T {
return self.min;
}
fn max(&self) -> T {
return self.max;
}
}
impl<T, V> IncDecCpCmp<T, V> for AnyIncDecCpCmp<T>
where
V: Copy,
T: PartialOrd + Copy + Add<V, Output = T> + Sub<V, Output = T>,
{
fn inc(&self, a: &T, b: &V) -> Option<T> {
let x = *a;
let c = a.add(*b);
if x <= c {
return Some(c);
}
return None;
}
fn dec(&self, a: &T, b: &V) -> Option<T> {
let x = *a;
let c = a.sub(*b);
if x >= c {
return Some(c);
}
return None;
}
fn cp_v(&self, v: &V) -> V {
return *v;
}
}
impl<T> NumberIncDecCpCmp<T>
where
T: Clone + Copy,
NumberIncDecCpCmp<T>: DefaultValues<T, T>,
{
pub fn defaults() -> Self {
return Self::new(
NumberIncDecCpCmp::default_min(),
NumberIncDecCpCmp::default_max(),
);
}
pub fn new(min: T, max: T) -> Self {
Self { min, max }
}
pub fn set_min(&mut self, v: T) {
self.min = v;
}
pub fn set_max(&mut self, v: T) {
self.max = v;
}
}
pub trait CpCmp<T> {
fn cp(&self, v: &T) -> T;
fn min_ref(&self) -> &T;
fn max_ref(&self) -> &T;
fn lt(&self, a: &T, b: &T) -> bool;
fn min(&self) -> T;
fn max(&self) -> T;
fn gt(&self, a: &T, b: &T) -> bool {
return self.lt(b, a);
}
fn eq(&self, a: &T, b: &T) -> bool {
return !self.lt(a, b) && !self.lt(b, a);
}
fn ne(&self, a: &T, b: &T) -> bool {
return self.lt(a, b) || self.lt(b, a);
}
fn le(&self, a: &T, b: &T) -> bool {
return self.lt(a, b) || !self.lt(b, a);
}
fn ge(&self, a: &T, b: &T) -> bool {
return self.lt(b, a) || !self.lt(a, b);
}
fn contains(&self, a: &T, b: &T, c: &T) -> bool {
return !(self.lt(c, a) || self.lt(b, c));
}
fn cp_tpl_ref(&self, src: (&T, &T)) -> (T, T) {
return (self.cp(src.0), self.cp(src.1));
}
fn overlap(&self, a: &T, b: &T, c: &T, d: &T) -> bool {
return self.contains(a, b, c)
|| self.contains(a, b, d)
|| self.contains(c, d, a)
|| self.contains(c, d, b);
}
fn is_invalid_set(&self, a: &T, b: &T) -> bool {
return self.lt(b, a) || self.lt(a, self.min_ref()) || self.lt(self.max_ref(), b);
}
}
pub trait IncDecCpCmp<T, V>: CpCmp<T> {
fn inc(&self, a: &T, b: &V) -> Option<T>;
fn dec(&self, a: &T, b: &V) -> Option<T>;
fn cp_v(&self, v: &V) -> V;
fn rebound_start(&self, start: Bound<&T>, rebound: &V) -> Option<T> {
match start {
Bound::Included(begin) => Some(self.cp(begin)),
Bound::Excluded(begin) => self.inc(begin, rebound),
Bound::Unbounded => Some(self.min()),
}
}
fn rebound_end(&self, end: Bound<&T>, rebound: &V) -> Option<T> {
match end {
Bound::Included(end) => Some(self.cp(end)),
Bound::Excluded(end) => self.dec(end, rebound),
Bound::Unbounded => Some(self.max()),
}
}
}
pub trait DefaultValues<T, V>: IncDecCpCmp<T, V> {
fn default_step(&self) -> V;
fn default_rebound(&self) -> V;
fn default_min() -> T;
fn default_max() -> T;
}
macro_rules! impl_inc_dec_cp_cmp_trait_i {
($($t:ty),*) => {
$(
impl CpCmp<$t> for NumberIncDecCpCmp<$t> {
fn min(&self) ->$t { self.min }
fn max(&self) ->$t { self.max }
fn min_ref(&self) ->&$t { &self.min }
fn max_ref(&self) ->&$t { &self.max }
fn cp(&self,v: &$t) ->$t {
return v.clone();
}
fn lt(&self,a:&$t,b: &$t) ->bool {
return a<b;
}
}
impl IncDecCpCmp<$t,$t> for NumberIncDecCpCmp<$t> {
fn dec(&self, a: &$t, b:&$t) ->Option<$t> {
if *b<=0 { return None}
return a.clone().checked_sub(b.clone());
}
fn inc(&self, a: &$t, b: &$t) -> Option<$t> {
if *b<=0 { return None}
return a.clone().checked_add(b.clone())
}
fn cp_v(&self,v: &$t) ->$t {
return *v;
}
}
impl DefaultValues<$t,$t> for NumberIncDecCpCmp<$t> {
fn default_step(&self) ->$t { return 1}
fn default_rebound(&self) ->$t { return 1}
fn default_min() ->$t { <$t>::MIN }
fn default_max() ->$t { <$t>::MAX }
}
)*
};
}
macro_rules! impl_inc_dec_cp_cmp_trait_u {
($($t:ty),*) => {
$(
impl CpCmp<$t> for NumberIncDecCpCmp<$t> {
fn min(&self) ->$t { self.min }
fn max(&self) ->$t { self.max }
fn min_ref(&self) ->&$t { &self.min }
fn max_ref(&self) ->&$t { &self.max }
fn cp(&self,v: &$t) ->$t {
return v.clone();
}
fn lt(&self,a:&$t,b: &$t) ->bool {
return a<b;
}
}
impl IncDecCpCmp<$t,$t> for NumberIncDecCpCmp<$t> {
fn dec(&self, a: &$t, b:&$t) ->Option<$t> {
if *b==0 { return None}
return a.clone().checked_sub(b.clone());
}
fn inc(&self, a: &$t, b: &$t) -> Option<$t> {
if *b==0 { return None}
return a.clone().checked_add(b.clone())
}
fn cp_v(&self,v: &$t) ->$t {
return *v;
}
}
impl DefaultValues<$t,$t> for NumberIncDecCpCmp<$t> {
fn default_step(&self) ->$t { return 1}
fn default_rebound(&self) ->$t { return 1}
fn default_min() ->$t { <$t>::MIN }
fn default_max() ->$t { <$t>::MAX }
}
)*
};
}
macro_rules! impl_inc_dec_cp_cmp_trait_f {
($($t:ty),*) => {
$(
impl CpCmp<$t> for NumberIncDecCpCmp<$t> {
fn min(&self) ->$t { self.min }
fn max(&self) ->$t { self.max }
fn min_ref(&self) ->&$t { &self.min }
fn max_ref(&self) ->&$t { &self.max }
fn cp(&self,v: &$t) ->$t {
return v.clone();
}
fn lt(&self,a:&$t,b: &$t) ->bool {
return a<b;
}
}
impl IncDecCpCmp<$t,$t> for NumberIncDecCpCmp<$t> {
fn dec(&self, a: &$t, b:&$t) ->Option<$t> {
let res=a - b;
if res.is_nan() || res >=*a { None } else { Some(res) }
}
fn inc(&self, a: &$t, b: &$t) -> Option<$t> {
let res=a + b;
if res.is_nan() || res <=*a { None } else { Some(res) }
}
fn cp_v(&self,v: &$t) ->$t {
return *v;
}
}
impl DefaultValues<$t,$t> for NumberIncDecCpCmp<$t> {
fn default_step(&self) ->$t { return 1.0}
fn default_rebound(&self) ->$t { return 1.0 }
fn default_min() ->$t { <$t>::MIN }
fn default_max() ->$t { <$t>::MAX }
}
)*
};
}
impl_inc_dec_cp_cmp_trait_u!(u8, u16, u32, u64, u128, usize);
impl_inc_dec_cp_cmp_trait_i!(i8, i16, i32, i64, i128, isize);
impl_inc_dec_cp_cmp_trait_f!(f32, f64);
pub trait GetBeginEndOption<T, R: GetBeginEnd<T>> {
fn factory(&self, opt: Option<(T, T)>) -> Option<R>;
fn new_range(&self, src: (T, T)) -> R;
}
#[derive(Copy, Clone)]
pub struct MrsFactory<T> {
_t: PhantomData<T>,
}
#[derive(Copy, Clone)]
pub struct RiFactory<T> {
_t: PhantomData<T>,
}
impl<T> RiFactory<T> {
pub fn new() -> Self {
return Self { _t: PhantomData };
}
}
impl<T> MrsFactory<T> {
pub fn new() -> Self {
return Self { _t: PhantomData };
}
}
impl<T> GetBeginEndOption<T, Mrs<T>> for MrsFactory<T> {
fn new_range(&self, src: (T, T)) -> Mrs<T> {
return Mrs::new(src.0, src.1);
}
fn factory(&self, opt: Option<(T, T)>) -> Option<Mrs<T>> {
match opt {
Some((a, z)) => Some(Mrs::new(a, z)),
None => None,
}
}
}
impl<T> GetBeginEndOption<T, RangeInclusive<T>> for RiFactory<T> {
fn new_range(&self, src: (T, T)) -> RangeInclusive<T> {
return RangeInclusive::new(src.0, src.1);
}
fn factory(&self, opt: Option<(T, T)>) -> Option<RangeInclusive<T>> {
match opt {
Some((a, z)) => Some(RangeInclusive::new(a, z)),
None => None,
}
}
}