use std::{ops::{AddAssign, Add, Index, SubAssign}, result};
use crate::has_one::*;
use std::fmt::Debug;
use crate::collections::List;
pub struct GapFillingCounter<T, HO>
where T: PartialEq, HO: HasOne<T>
{
value: T,
gaps: List<T>, has_one: HO
}
impl<T, HO> GapFillingCounter<T, HO>
where T: PartialEq + Default + AddAssign + SubAssign + Copy,
HO: HasOne<T>
{
pub fn new_has_one(has_one: HO) -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one
}
}
pub fn start_at_has_one(value: T, has_one: HO) -> Self
{
Self
{
value,
gaps: List::new(),
has_one
}
}
pub fn next(&mut self) -> T
{
if let Some(val) = self.gaps.pop()
{
return val;
}
self.value += HO::one();
self.value
}
pub fn gap_value(&mut self, val: T) -> bool
{
if val == self.value
{
self.value -= HO::one();
if let Some(index) = self.gaps.index_of(&val)
{
self.gaps.remove_at(index);
}
return true;
}
else if !self.gaps.contains(&val)
{
self.gaps.add(val);
return true;
}
false
}
pub fn un_gap_value(&mut self, val: T) -> bool
{
self.gaps.remove(val)
}
pub fn gaps_len(&self) -> usize
{
self.gaps.len()
}
pub fn new_i8() -> GapFillingCounter<i8, I8HasOne>
{
GapFillingCounter::<i8, I8HasOne>::new()
}
pub fn new_i16() -> GapFillingCounter<i16, I16HasOne>
{
GapFillingCounter::<i16, I16HasOne>::new()
}
pub fn new_i32() -> GapFillingCounter<i32, I32HasOne>
{
GapFillingCounter::<i32, I32HasOne>::new()
}
pub fn new_i64() -> GapFillingCounter<i64, I64HasOne>
{
GapFillingCounter::<i64, I64HasOne>::new()
}
pub fn new_i128() -> GapFillingCounter<i128, I128HasOne>
{
GapFillingCounter::<i128, I128HasOne>::new()
}
pub fn new_isize() -> GapFillingCounter<isize, ISizeHasOne>
{
GapFillingCounter::<isize, ISizeHasOne>::new()
}
pub fn new_u8() -> GapFillingCounter<u8, U8HasOne>
{
GapFillingCounter::<u8, U8HasOne>::new()
}
pub fn new_u16() -> GapFillingCounter<u16, U16HasOne>
{
GapFillingCounter::<u16, U16HasOne>::new()
}
pub fn new_u32() -> GapFillingCounter<u32, U32HasOne>
{
GapFillingCounter::<u32, U32HasOne>::new()
}
pub fn new_u64() -> GapFillingCounter<u64, U64HasOne>
{
GapFillingCounter::<u64, U64HasOne>::new()
}
pub fn new_u128() -> GapFillingCounter<u128, U128HasOne>
{
GapFillingCounter::<u128, U128HasOne>::new()
}
pub fn new_usize() -> GapFillingCounter<usize, USizeHasOne>
{
GapFillingCounter::<usize, USizeHasOne>::new()
}
}
impl GapFillingCounter<i8, I8HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: I8HasOne()
}
}
}
impl GapFillingCounter<i16, I16HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: I16HasOne()
}
}
}
impl GapFillingCounter<i32, I32HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: I32HasOne()
}
}
}
impl GapFillingCounter<i64, I64HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: I64HasOne()
}
}
}
impl GapFillingCounter<i128, I128HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: I128HasOne()
}
}
}
impl GapFillingCounter<isize, ISizeHasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: ISizeHasOne()
}
}
}
impl GapFillingCounter<u8, U8HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: U8HasOne()
}
}
}
impl GapFillingCounter<u16, U16HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: U16HasOne()
}
}
}
impl GapFillingCounter<u32, U32HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: U32HasOne()
}
}
}
impl GapFillingCounter<u64, U64HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: U64HasOne()
}
}
}
impl GapFillingCounter<u128, U128HasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: U128HasOne()
}
}
}
impl GapFillingCounter<usize, USizeHasOne>
{
pub fn new() -> Self
{
Self
{
value: Default::default(),
gaps: List::new(),
has_one: USizeHasOne()
}
}
}
impl<T, HO> Debug for GapFillingCounter<T, HO>
where T: PartialEq + Debug, HO: Debug + HasOne<T>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GapFillingCounter").field("value", &self.value).field("gaps", &self.gaps).field("has_one", &self.has_one).finish()
}
}