use std::collections::BTreeSet;
mod construct;
mod convert;
mod operations;
pub mod spans;
pub use spans::SumSize;
use super::WithMin;
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct OrdMask<T: Ord + Clone + WithMin> {
key_points: Vec<T>,
based_on_universal: bool,
}
impl<T: Ord + Clone + WithMin> AsRef<OrdMask<T>> for OrdMask<T> {
fn as_ref(&self) -> &OrdMask<T> {
self
}
}
impl<T: Ord + Clone + WithMin> OrdMask<T> {
pub const fn is_empty(&self) -> bool {
!self.based_on_universal && self.key_points.is_empty()
}
pub const fn is_universal(&self) -> bool {
self.based_on_universal && self.key_points.is_empty()
}
pub fn is_valid(&self) -> bool {
crate::utils::is_increasing::<true, _>(&self.key_points).0
}
pub const fn based_on_universal(&self) -> &bool {
&self.based_on_universal
}
pub const fn mut_based_on_universal(&mut self) -> &mut bool {
&mut self.based_on_universal
}
pub fn included(&self, value: &T) -> bool {
let partition_point = self.key_points.partition_point(|x| x <= value);
self.based_on_universal == partition_point.is_multiple_of(2)
}
pub fn excluded(&self, value: &T) -> bool {
!self.included(value)
}
pub fn contains(&self, value: &T) -> bool {
self.included(value)
}
pub const fn is_max_value_included(&self) -> bool {
self.based_on_universal == self.key_points.len().is_multiple_of(2)
}
pub fn simplify(&mut self) -> bool {
let len = match self.key_points.len() {
0 => return false,
n => n,
};
let mut write_index = 0;
let mut read_index = 0;
#[inline(always)]
fn move_to_next_value<T: PartialEq>(idx: &mut usize, arr: &[T], len: usize, now_value: &T) {
while *idx < len && &arr[*idx] == now_value {
*idx += 1;
}
}
move_to_next_value(&mut read_index, &self.key_points, len, &T::MIN);
if read_index != 0 && !read_index.is_multiple_of(2) {
self.based_on_universal = !self.based_on_universal;
}
while read_index < len {
let (start_index, now_value) = (read_index, self.key_points[read_index].clone());
read_index += 1;
move_to_next_value(&mut read_index, &self.key_points, len, &now_value);
if !(read_index - start_index).is_multiple_of(2) {
self.key_points[write_index] = now_value;
write_index += 1;
}
}
self.key_points.truncate(write_index);
write_index < len
}
pub const fn key_points(&self) -> &Vec<T> {
&self.key_points
}
pub const unsafe fn mut_key_points(&mut self) -> &mut Vec<T> {
&mut self.key_points
}
pub fn get_suspicious_points<I>(masks: I) -> BTreeSet<T>
where
I: IntoIterator,
I::Item: AsRef<OrdMask<T>>,
{
let mut result = BTreeSet::new();
let mut has_universal = false;
for item in masks {
let item = item.as_ref();
result.extend(item.key_points.clone());
if item.based_on_universal {
has_universal = true;
}
}
if has_universal {
result.insert(T::MIN);
}
result
}
}