use crate::{SType,Set,MutSetOps,trivindex};
use indxvec::{MinMax,Indices,Vecops};
impl<T> Set<T> where T: Copy+PartialOrd+Default {
pub const EMPTYSET:Set<T> = Set{ stype:SType::Empty, ascending:true, data:Vec::new(), index:Vec::new() };
pub fn new(set_type: SType, d: &[T], asc:bool) -> Self {
if d.is_empty() { return Set::EMPTYSET }; match set_type {
SType::Empty => Set::EMPTYSET, SType::Unordered => Set{ stype:SType::Unordered, ascending:true, data:d.to_vec(), index:Vec::new() },
SType::Ordered => Set{ stype:SType::Ordered, ascending:asc, data:d.sortm(asc), index:Vec::new() },
SType::Indexed => Set{ stype:SType::Indexed, ascending:asc, data:d.to_vec(),
index: if asc { d.mergesort_indexed() } else { d.mergesort_indexed().revs() } },
SType::Ranked => Set{ stype:SType::Ranked, ascending:asc, data:d.to_vec(),
index: if asc { d.mergesort_indexed().invindex() } else { d.mergesort_indexed().revs().invindex() } } }
}
pub fn new_empty() -> Self { Self::EMPTYSET }
pub fn new_unordered(d: &[T]) -> Self {
if !d.is_empty() { Set{ stype:SType::Unordered, ascending:true, data:d.to_vec(), index:Vec::new() } }
else { Set::EMPTYSET }
}
pub fn new_ordered(d: &[T], asc:bool) -> Self {
if !d.is_empty() { Set{ stype:SType::Ordered, ascending:asc, data:d.sortm(asc), index:Vec::new() } }
else { Set::EMPTYSET }
}
pub fn new_indexed(d: &[T], asc:bool) -> Self {
if !d.is_empty() { Set{ stype:SType::Indexed, ascending:asc, data:d.to_vec(),
index: if asc { d.mergesort_indexed() } else { d.mergesort_indexed().revs() } } }
else { Set::EMPTYSET }
}
pub fn new_ranked(d: &[T], asc:bool) -> Self {
if !d.is_empty() { Set{ stype:SType::Ranked, ascending:asc, data:d.to_vec(),
index: if asc { d.mergesort_indexed().invindex() } else { d.mergesort_indexed().revs().invindex() } } }
else { Set::EMPTYSET }
}
pub fn to_unordered(&self) -> Self {
match self.stype {
SType::Empty => Set::EMPTYSET, _ => Self{ stype:SType::Unordered, ascending:self.ascending, data:self.data.clone(), index:Vec::new() }
}
}
pub fn to_ordered(&self, asc:bool) -> Self {
match self.stype {
SType::Empty => Set::EMPTYSET,
SType::Unordered => Self{ stype:SType::Ordered, ascending:asc, data:self.data.sortm(asc), index:Vec::new()},
SType::Ordered => if self.ascending == asc { self.clone() } else { Self{ stype:SType::Ordered, ascending:asc, data:self.data.revs(), index:Vec::new() } },
SType::Indexed => Self{ stype:SType::Ordered, ascending:asc,
data:self.index.unindex(&self.data, self.ascending == asc), index:Vec::new() },
SType::Ranked => Self{ stype:SType::Ordered, ascending:asc,
data:self.index.invindex().unindex(&self.data, self.ascending == asc), index:Vec::new() },
}
}
pub fn to_indexed(&self,asc:bool) -> Self {
match self.stype {
SType::Empty => Set::EMPTYSET,
SType::Unordered => Self{ stype:SType::Indexed, ascending:asc, data:self.data.clone(),
index: if asc {self.data.mergesort_indexed()} else {self.data.mergesort_indexed().revs()} },
SType::Ordered => Self{ stype:SType::Indexed, ascending:asc, data:self.data.clone(),
index: trivindex(self.ascending == asc,self.data.len()) },
SType::Indexed => if self.ascending == asc { self.clone() } else { Self{ stype:SType::Indexed, ascending:asc, data:self.data.clone(),
index: self.index.revs() } },
SType::Ranked => Self{ stype:SType::Indexed, ascending:asc, data:self.data.clone(),
index: if self.ascending == asc {self.index.invindex()} else {self.index.invindex().revs()}}
}
}
pub fn to_ranked(&self,asc:bool) -> Self {
match self.stype {
SType::Empty => Set::EMPTYSET,
SType::Unordered => Self{ stype:SType::Ranked, ascending:asc, data:self.data.clone(),
index: if asc {self.data.mergesort_indexed().invindex()}
else {self.data.mergesort_indexed().revs().invindex()} },
SType::Ordered => Self{ stype:SType::Ranked, ascending:asc, data:self.data.clone(),
index: trivindex(self.ascending == asc,self.data.len()) },
SType::Indexed => Self{ stype:SType::Ranked, ascending:asc, data:self.data.clone(),
index: if self.ascending == asc {self.index.invindex()}
else {self.index.revs().invindex()}},
SType::Ranked => if self.ascending == asc { self.clone() } else { Self{ stype:SType::Ranked, ascending:asc, data:self.data.clone(),
index: {self.index.complindex()} } }
}
}
pub fn to_same(&self, s:&Self) -> Self {
match self.stype {
SType::Empty => Set::EMPTYSET, SType::Unordered => s.to_unordered(),
SType::Ordered => s.to_ordered(self.ascending),
SType::Indexed => s.to_indexed(self.ascending),
SType::Ranked => s.to_ranked(self.ascending)
}
}
pub fn insert(&self, item:T) -> Self {
let mut scopy = self.clone();
scopy.minsert(item);
scopy
}
pub fn delete(&self, item:T) -> Self {
let mut scopy = self.clone();
if scopy.mdelete(item) { scopy } else { self.clone() }
}
pub fn reverse(&self) -> Self {
let mut scopy = self.clone();
scopy.mreverse();
scopy
}
pub fn nonrepeat(&self) -> Self {
let mut scopy = self.clone();
scopy.mnonrepeat();
scopy
}
pub fn union(&self, s: &Self) -> Self {
let mut scopy = self.clone();
scopy.munion(s);
scopy
}
pub fn intersection(&self, s: &Self) -> Self {
let mut scopy = self.clone();
scopy.mintersection(s);
scopy
}
pub fn difference(&self, s: &Self) -> Self {
let mut scopy = self.clone();
scopy.mdifference(s);
scopy
}
pub fn infsup(&self) -> MinMax<T> where T: Default {
match self.stype {
SType::Empty => Default::default(),
SType::Unordered => self.data.minmax(),
SType::Ordered => {
let last = self.data.len()-1;
if self.ascending { MinMax{min:self.data[0],minindex:0,max:self.data[last],maxindex:last} }
else { MinMax{min:self.data[last],minindex:last,max:self.data[0],maxindex:0} }
},
SType::Indexed => {
let last = self.data.len()-1;
let firstval = self.data[self.index[0]];
let lastval = self.data[self.index[last]];
if self.ascending { MinMax{min:firstval,minindex:self.index[0],max:lastval,maxindex:self.index[last]} }
else { MinMax{min:lastval,minindex:self.index[last],max:firstval,maxindex:self.index[0]} }
},
SType::Ranked => {
let last = self.data.len()-1;
let si = self.index.invindex(); let firstval = self.data[si[0]];
let lastval = self.data[si[last]];
if self.ascending { MinMax{min:firstval,minindex:si[0],max:lastval,maxindex:si[last]} }
else { MinMax{min:lastval,minindex:si[last],max:firstval,maxindex:si[0]} }
}
}
}
pub fn search(&self, m: T) -> Option<usize> {
match self.stype {
SType::Empty => None,
SType::Unordered => self.data.member(m,true), SType::Ordered => { let r = self.data.binsearch(&m);
if r.start == r.end { None } else { Some(r.start) } },
SType::Indexed => { let r = self.data.binsearch_indexed(&self.index,&m);
if r.start == r.end { None } else { Some(self.index[r.start]) } },
SType::Ranked => { let r = self.data.binsearch_indexed(&self.index.invindex(),&m);
if r.start == r.end { None } else { Some(self.index[r.start]) }}
}
}
pub fn member(&self, m: T) -> bool {
self.search(m).is_some()
}
}