#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use smallvec::SmallVec;
use std::{fmt::Debug, ops::Deref};
pub type InnerBuff<T> = SmallVec<[T; 8]>;
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(transparent)]
pub struct SortedBuffer<T> {
inner: InnerBuff<T>,
}
impl<T> SortedBuffer<T> {
pub fn new() -> Self {
SortedBuffer {
inner: InnerBuff::<T>::new(),
}
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
#[inline]
pub fn as_slice(&self) -> &[T] {
&self.inner
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.inner
}
#[inline]
pub fn contains(&self, value: &T) -> bool
where
T: Ord,
{
self.inner.binary_search(value).is_ok()
}
#[inline]
pub fn iter(&self) -> std::slice::Iter<'_, T> {
self.inner.iter()
}
#[inline]
pub fn insert_sorted_unique(v: &mut SortedBuffer<T>, value: T)
where
T: Ord,
{
match v.inner.binary_search(&value) {
Ok(_) => {}
Err(pos) => v.inner.insert(pos, value),
}
}
#[inline]
pub fn remove_sorted(v: &mut SortedBuffer<T>, value: &T)
where
T: Ord,
{
if let Ok(pos) = v.inner.binary_search(value) {
v.inner.remove(pos);
}
}
#[inline]
pub fn set_sorted_unique(dst: &mut SortedBuffer<T>, src: impl IntoIterator<Item = T>)
where
T: Ord,
{
dst.inner.clear();
dst.inner.extend(src);
dst.inner.sort_unstable();
dst.inner.dedup();
}
}
impl<T> Deref for SortedBuffer<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> FromIterator<T> for SortedBuffer<T>
where
T: Ord,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut buffer = SortedBuffer::<T>::new();
SortedBuffer::set_sorted_unique(&mut buffer, iter);
buffer
}
}
impl<T, I> From<I> for SortedBuffer<T>
where
I: IntoIterator<Item = T>,
T: Ord,
{
fn from(iter: I) -> Self {
let mut buffer = SortedBuffer::<T>::new();
SortedBuffer::set_sorted_unique(&mut buffer, iter);
buffer
}
}
impl<T> Debug for SortedBuffer<T>
where
T: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.inner.as_slice())?;
return Ok(());
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sorted_buffer_insert_remove() {
let mut buffer = SortedBuffer::new();
SortedBuffer::insert_sorted_unique(&mut buffer, 5);
SortedBuffer::insert_sorted_unique(&mut buffer, 3);
SortedBuffer::insert_sorted_unique(&mut buffer, 8);
SortedBuffer::insert_sorted_unique(&mut buffer, 5);
assert_eq!(&*buffer, &[3, 5, 8]);
SortedBuffer::remove_sorted(&mut buffer, &5);
assert_eq!(&*buffer, &[3, 8]);
SortedBuffer::remove_sorted(&mut buffer, &10); assert_eq!(&*buffer, &[3, 8]);
}
#[test]
fn test_sorted_buffer_from_iter() {
let vec = vec![4, 2, 7, 2, 5];
let buffer: SortedBuffer<i32> = vec.into_iter().collect();
assert_eq!(&*buffer, &[2, 4, 5, 7]);
}
}