use core::mem;
use core::ops::{Deref, Index};
use core::slice::SliceIndex;
use super::Slice;
#[derive(Debug)]
pub struct Ordered<'a, T> {
inner: Slice<'a, T>,
start: usize,
}
impl<'a, T> Ordered<'a, T> {
pub fn new<S>(slice: S) -> Self
where S: Into<Slice<'a, T>>
{
Ordered {
inner: slice.into(),
start: 0,
}
}
pub fn init(&mut self) -> Option<&mut T> {
self.inner.as_mut_slice().get_mut(self.start)
}
pub fn push(&mut self) -> Option<usize>
where T: Ord,
{
let next = self.inner.as_slice()
.get(self.start)?;
let idx = self.ordered_slice()
.binary_search(next)
.unwrap_or_else(|x| x);
let moving = self.start - idx;
self.start += 1;
self.inner[idx..self.start]
.rotate_left(moving);
Some(idx)
}
pub fn pop(&mut self, idx: usize) -> Option<()> {
let moving = self.start
.checked_sub(idx)?
.checked_sub(1)?;
self.inner[idx..self.start]
.rotate_right(moving);
self.start -= 1;
Some(())
}
pub fn ordered_slice(&self) -> &[T] {
&self.inner.as_slice()[..self.start]
}
pub fn get<I>(&self, idx: I) -> Option<&I::Output>
where I: SliceIndex<[T]>
{
self.ordered_slice().get(idx)
}
pub fn replace_at(&mut self, idx: usize, new: T) -> Option<T>
where T: Ord,
{
let mutable = &mut self.inner[..self.start];
assert!(mutable.len() < usize::max_value());
if let Some(prev) = mutable.get(idx.wrapping_sub(1)) {
if !(prev <= &new) {
return None;
}
}
if let Some(next) = mutable.get(idx.wrapping_add(1)) {
if !(&new <= next) {
return None;
}
}
mutable.get_mut(idx)
.map(|slot| mem::replace(slot, new))
}
}
impl<'a, C, T> From<C> for Ordered<'a, T>
where Slice<'a, T>: From<C>
{
fn from(collection: C) -> Self {
Self::new(collection)
}
}
impl<T, I: SliceIndex<[T]>> Index<I> for Ordered<'_, T> {
type Output = I::Output;
fn index(&self, idx: I) -> &I::Output {
self.ordered_slice().index(idx)
}
}
impl<T> Deref for Ordered<'_, T> {
type Target = [T];
fn deref(&self) -> &[T] {
self.ordered_slice()
}
}