//! A `Vec`-like wrapper type that only allocates if a provided buffer is first exhausted.
usestd::mem::{
MaybeUninit,
ManuallyDrop,
};
usestd::marker::{Send,Sync,PhantomData};
usestd::ops::Drop;
usestd::slice;
#[repr(C)]
#[derive(Debug)]
structStackBuffer<T>
{
fill_ptr: usize,
buf_ptr: *mutMaybeUninit<T>,
}
impl<T>CloneforStackBuffer<T>
{
fnclone(&self)-> Self{
Self{
fill_ptr: self.fill_ptr,
buf_ptr: self.buf_ptr,
}
}
}
impl<T>CopyforStackBuffer<T>{}
#[repr(C)]
#[derive(Debug, Clone)]
structHeapBuffer<T>
{
_fill_ptr: usize,// vec.len()
buf: Vec<T>,
}
#[repr(C)]
unionInternal<T>
{
stack: StackBuffer<T>,
heap: ManuallyDrop<HeapBuffer<T>>,
}
/// A growable vector with a backing slice that will move its elements to the heap if the slice space is exhausted.
pubstructAVec<'a,T>
{
/// max size of `inner.stack` before it's moved to `inner.heap`.
stack_sz: usize,
inner: Internal<T>,
_stack: PhantomData<&'amut[MaybeUninit<T>]>,
}
unsafeimpl<'a,T>SendforAVec<'a,T>{}
unsafeimpl<'a,T>SyncforAVec<'a,T>{}
impl<'a,T>DropforAVec<'a,T>
{
fndrop(&mutself){
ifself.is_allocated(){
// All stack elements have been moved to the heap. Drop the heap buffer.
unsafe{
ManuallyDrop::drop(&mutself.inner.heap);
}
}else{
ifstd::mem::needs_drop::<T>(){
// Drop the allocated stack elements in place
unsafe{
std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(self.inner.stack.buf_ptras*mutT,self.fill_ptr()));// I think this drops the elements, we don't need to loop.