use crate::sorted_vec::SortedVec;
use std::mem::ManuallyDrop;
use std::ptr::NonNull;
#[derive(Debug)]
pub struct UnsortedVec<T>(pub(crate) Vec<T>);
impl<T> Default for UnsortedVec<T>
where
T: Default,
{
fn default() -> UnsortedVec<T> {
UnsortedVec(Vec::default())
}
}
impl<T> PartialEq for UnsortedVec<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
fn ne(&self, other: &Self) -> bool {
self.0.ne(&other.0)
}
}
impl<T> Eq for UnsortedVec<T> where T: PartialEq + Eq {}
impl<T> AsRef<[T]> for UnsortedVec<T> {
fn as_ref(&self) -> &[T] {
&self.0
}
}
impl<T> IntoIterator for UnsortedVec<T> {
type Item = T;
type IntoIter = UnsortedVecIterator<Self::Item>;
fn into_iter(self) -> UnsortedVecIterator<T> {
unsafe {
let len = self.0.len();
let cap = self.0.capacity();
let mut me = ManuallyDrop::new(self.0);
let begin = me.as_mut_ptr();
let end = if std::mem::size_of::<T>() == 0 {
std::intrinsics::arith_offset(begin as *const i8, len as isize) as *const T
} else {
begin.add(len) as *const T
};
let result = UnsortedVecIterator {
buf: NonNull::new_unchecked(begin),
ptr: begin,
end,
cap,
};
result
}
}
}
impl<T> UnsortedVec<T> {
pub fn new() -> UnsortedVec<T> {
UnsortedVec(Vec::new())
}
pub fn push(mut self, item: T) -> Self {
self.0.push(item);
self
}
pub fn sort(mut self) -> SortedVec<T>
where
T: Ord,
{
self.0.sort();
SortedVec(self.0)
}
pub fn len(&self) -> usize {
self.0.len()
}
}
#[derive(Debug)]
pub struct UnsortedVecIterator<T> {
pub(crate) buf: NonNull<T>,
pub(crate) ptr: *const T,
pub(crate) end: *const T,
pub(crate) cap: usize,
}
impl<T> Iterator for UnsortedVecIterator<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
unsafe {
if self.ptr as *const _ == self.end {
None
} else {
if std::mem::size_of::<T>() == 0 {
self.ptr = std::intrinsics::arith_offset(self.ptr as *const i8, 1) as *mut T;
Some(std::mem::zeroed())
} else {
let old = self.ptr;
self.ptr = self.ptr.offset(1);
Some(std::ptr::read(old))
}
}
}
}
}
impl<T> Drop for UnsortedVecIterator<T> {
fn drop(&mut self) {
if std::mem::size_of::<T>() != 0 {
unsafe {
let _ = Vec::from_raw_parts(
self.buf.as_ptr(),
self.end.offset_from(self.buf.as_ptr()) as usize,
self.cap,
);
}
}
}
}