use crate::unsorted_vec::UnsortedVec;
#[derive(Debug, Default, PartialEq, Eq)]
pub struct SortedVec<T>(pub(crate) Vec<T>);
impl<T> AsRef<[T]> for SortedVec<T> {
fn as_ref(&self) -> &[T] {
&self.0
}
}
impl<T> IntoIterator for SortedVec<T> {
type Item = T;
type IntoIter = SortedVecIterator<Self::Item>;
fn into_iter(self) -> SortedVecIterator<T> {
let result = SortedVecIterator {
ptr: self.0.as_ptr(),
len: self.0.len(),
index: 0,
};
std::mem::forget(self);
result
}
}
impl<T> std::convert::TryFrom<Vec<T>> for SortedVec<T>
where
T: PartialEq + PartialOrd,
{
type Error = &'static str;
fn try_from(from: Vec<T>) -> Result<SortedVec<T>, &'static str> {
if from.is_sorted() {
Ok(SortedVec(from))
} else {
Err("attempting to perform a conversion from a non-sorted `Vec` to `SortedVec`.")
}
}
}
impl<T> SortedVec<T> {
pub fn push(mut self, item: T) -> UnsortedVec<T> {
self.0.push(item);
UnsortedVec(self.0)
}
}
#[derive(Debug)]
pub struct SortedVecIterator<T> {
pub(crate) ptr: *const T,
pub(crate) len: usize,
pub(crate) index: usize,
}
impl<Ty> Iterator for SortedVecIterator<Ty> {
type Item = Ty;
fn next(&mut self) -> Option<Ty> {
if self.index >= self.len {
None
} else {
let current = self.index;
self.index += 1;
Some(unsafe { std::ptr::read(self.ptr.add(current)) })
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
fn count(self) -> usize
where
Self: Sized,
{
self.len
}
fn last(self) -> Option<Self::Item>
where
Self: Sized,
{
if self.len == 0 {
None
} else {
unsafe { Some(std::ptr::read(self.ptr.add(self.len - 1))) }
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if n >= self.len {
None
} else {
unsafe { Some(std::ptr::read(self.ptr.add(n))) }
}
}
fn max(self) -> Option<Self::Item>
where
Self: Sized,
Self::Item: Ord,
{
if self.len == 0 {
None
} else {
unsafe { Some(std::ptr::read(self.ptr.add(self.len - 1))) }
}
}
fn min(self) -> Option<Self::Item>
where
Self: Sized,
Self::Item: Ord,
{
if self.len == 0 {
None
} else {
unsafe { Some(std::ptr::read(self.ptr.add(0))) }
}
}
}