use std::borrow::Borrow;
use std::hash::{self, Hash};
use std::iter::Extend;
use std::ops::Deref;
#[macro_export]
macro_rules! sortedvec {
( $ ( $ x : expr ) , * ) => {
{
let inner = vec![ $ ( $x, )* ];
$crate::from_vec(inner, |x| x)
}
}
}
pub fn from_vec<T, F, K>(v: Vec<T>, f: F) -> SortedVec<T, F>
where
F: Clone + for<'t> Fn(&'t T) -> &'t K,
K: Ord + Eq + ?Sized,
{
SortedVec::from_vec(v, f)
}
pub struct SortedVec<T, F> {
inner: Vec<T>,
comp: F,
}
impl<T, F, K> SortedVec<T, F>
where
F: Clone + for<'t> Fn(&'t T) -> &'t K,
K: Ord + Eq + ?Sized,
{
pub fn split_off(&mut self, at: usize) -> Self {
let other_inner = self.inner.split_off(at);
Self {
inner: other_inner,
comp: self.comp.clone(),
}
}
}
impl<T, F, K> SortedVec<T, F>
where
F: for<'t> Fn(&'t T) -> &'t K,
K: Ord + Eq + ?Sized,
{
pub fn new(comp: F) -> Self {
Self {
inner: Vec::new(),
comp,
}
}
pub fn from_vec(mut vec: Vec<T>, comp: F) -> Self {
vec.sort_unstable_by(|ref a, ref b| {
let lhs = comp(a);
let rhs = comp(b);
lhs.cmp(&rhs)
});
let sorted = Self { inner: vec, comp };
debug_assert!(sorted.is_sorted());
sorted
}
pub fn insert(&mut self, val: T) {
let ref key = (self.comp)(&val);
let search = self
.inner
.binary_search_by(|probe| (self.comp)(probe).cmp(key));
let idx = match search {
Ok(i) | Err(i) => i,
};
self.inner.insert(idx, val);
debug_assert!(self.is_sorted());
}
pub fn comperator(&self) -> &F {
&self.comp
}
pub fn find(&self, key: &K) -> Option<&T> {
self.inner
.binary_search_by(|probe| (self.comp)(probe).cmp(key))
.ok()
.and_then(|idx| self.inner.get(idx))
}
pub fn contains(&self, key: &K) -> bool {
self.inner
.binary_search_by(|probe| (self.comp)(probe).cmp(key))
.is_ok()
}
pub fn into_inner(self) -> Vec<T> {
self.inner
}
pub fn remove(&mut self, index: usize) -> T {
self.inner.remove(index)
}
pub fn truncate(&mut self, len: usize) {
self.inner.truncate(len)
}
pub fn dedup_by_key(&mut self) {
let mut dummy = Vec::new();
std::mem::swap(&mut dummy, &mut self.inner);
dummy.dedup_by(|a, b| (self.comp)(a) == (self.comp)(b));
std::mem::swap(&mut dummy, &mut self.inner);
}
pub fn pop(&mut self) -> Option<T> {
self.inner.pop()
}
fn sort(&mut self) {
let mut dummy = Vec::new();
std::mem::swap(&mut dummy, &mut self.inner);
dummy.sort_unstable_by(|ref a, ref b| {
let lhs = (&self.comp)(a);
let rhs = (&self.comp)(b);
lhs.cmp(&rhs)
});
std::mem::swap(&mut dummy, &mut self.inner);
debug_assert!(self.is_sorted());
}
fn is_sorted(&self) -> bool {
if self.inner.len() == 0 {
return true;
}
for i in 0..(self.inner.len() - 1) {
if (self.comp)(&self.inner[i]) > (self.comp)(&self.inner[i + 1]) {
return false;
}
}
true
}
}
pub struct IntoIter<T> {
inner: std::vec::IntoIter<T>,
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<T, F> IntoIterator for SortedVec<T, F> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
IntoIter {
inner: self.inner.into_iter(),
}
}
}
impl<T, F, K> Extend<T> for SortedVec<T, F>
where
F: for<'t> Fn(&'t T) -> &'t K,
K: Ord + Eq + ?Sized,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
self.inner.extend(iter);
self.sort();
}
}
impl<T, F> Hash for SortedVec<T, F>
where
T: Hash,
{
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
Hash::hash(&*self.inner, state)
}
}
impl<T, F> Deref for SortedVec<T, F> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T, F> Borrow<[T]> for SortedVec<T, F> {
fn borrow(&self) -> &[T] {
&self.inner
}
}
impl<T, F> AsRef<[T]> for SortedVec<T, F> {
fn as_ref(&self) -> &[T] {
&self.inner
}
}
impl<T, F> AsRef<Vec<T>> for SortedVec<T, F> {
fn as_ref(&self) -> &Vec<T> {
&self.inner
}
}
#[cfg(test)]
mod tests {}