#![no_std]
extern crate alloc;
pub mod same;
use alloc::vec::Vec;
pub use crate::same::SameLayout;
pub struct SameVec<T> {
elements: Vec<T>,
}
pub struct TempVec<'lt, T> {
from: &'lt mut dyn DynBufferWith<T>,
vec: Vec<T>,
}
impl<T> SameVec<T> {
pub fn new() -> Self {
SameVec::default()
}
pub fn with_capacity(cap: usize) -> Self {
SameVec {
elements: Vec::with_capacity(cap),
}
}
pub fn use_for<U>(&mut self, marker: SameLayout<T, U>) -> TempVec<'_, U> {
let from = Wrap::new(&mut self.elements, marker);
let elements = core::mem::take(&mut from.elements);
let vec = from.marker.forget_vec(elements);
TempVec { from, vec, }
}
}
impl<T> Default for SameVec<T> {
fn default() -> Self {
SameVec { elements: Vec::new() }
}
}
impl<T> Drop for TempVec<'_, T> {
fn drop(&mut self) {
self.from.swap_internal_with(&mut self.vec);
}
}
impl<T> core::ops::Deref for TempVec<'_, T> {
type Target = Vec<T>;
fn deref(&self) -> &Vec<T> {
&self.vec
}
}
impl<T> core::ops::DerefMut for TempVec<'_, T> {
fn deref_mut(&mut self) -> &mut Vec<T> {
&mut self.vec
}
}
struct Wrap<T, U> {
marker: SameLayout<T, U>,
elements: alloc::vec::Vec<T>,
}
trait DynBufferWith<T> {
fn swap_internal_with(&mut self, _: &mut Vec<T>);
}
impl<T, U> Wrap<T, U> {
fn new(vec: &mut Vec<T>, _: SameLayout<T, U>) -> &mut Self {
unsafe { &mut *(vec as *mut _ as *mut Wrap<T, U>) }
}
}
impl<T, U> DynBufferWith<U> for Wrap<T, U> {
fn swap_internal_with(&mut self, v: &mut Vec<U>) {
let mut temp = core::mem::take(v);
temp.clear();
let mut temp = self.marker.transpose().forget_vec(temp);
core::mem::swap(&mut temp, &mut self.elements);
temp.clear();
*v = self.marker.forget_vec(temp);
}
}