use std::borrow::Borrow;
use std::cmp::Ordering;
use std::convert::From;
use std::ops::Deref;
#[repr(transparent)]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct UniqueSortedVec<T>(Vec<T>);
impl<T> UniqueSortedVec<T> {
#[inline]
pub const fn new() -> Self {
Self(Vec::new())
}
}
impl<T: Ord> UniqueSortedVec<T> {
#[inline]
pub fn to_ref<U: Ord + ?Sized>(&self) -> UniqueSortedVec<&U>
where
T: Borrow<U>,
{
UniqueSortedVec(self.0.iter().map(Borrow::borrow).collect())
}
#[inline]
pub fn union(mut self, mut other: Self) -> Self {
match (self.as_slice(), other.as_slice()) {
(_, []) => self,
([], _) => other,
([.., tail_x], [.., tail_y]) => {
let last = match tail_x.cmp(tail_y) {
Ordering::Greater => self.0.pop().unwrap(),
Ordering::Less => other.0.pop().unwrap(),
Ordering::Equal => {
other.0.pop().unwrap();
self.0.pop().unwrap()
}
};
let mut new_head = self.union(other);
new_head.0.push(last);
new_head
}
}
}
#[inline]
pub fn contains(&self, x: &T) -> bool {
self.0.binary_search(x).is_ok()
}
#[inline]
pub fn find_first_following(&self, x: &T) -> Option<&T> {
let (Ok(i) | Err(i)) = self.0.binary_search(x);
self.0.get(i)
}
}
impl<T: Ord> From<Vec<T>> for UniqueSortedVec<T> {
#[inline]
fn from(mut vec: Vec<T>) -> Self {
vec.sort_unstable();
vec.dedup();
Self(vec)
}
}
impl<T: Ord> From<UniqueSortedVec<T>> for Vec<T> {
#[inline]
fn from(val: UniqueSortedVec<T>) -> Self {
val.0
}
}
impl<T: Ord> Deref for UniqueSortedVec<T> {
type Target = Vec<T>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}