use crate::prelude::*;
use std::marker::PhantomData;
use std::mem::transmute;
macro_rules! dyn_cast_panic {
($a: expr, $b: expr) => {{
if $a != $b {
panic!(
"Cannot cast a DynamicVector of len {}, to a StaticVector with len {}",
$a, $b
)
}
}};
}
pub trait DynamicVec<T> {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
unsafe fn as_ptr(&self) -> *const T;
unsafe fn as_mut_ptr(&mut self) -> *mut T {
transmute(self.as_ptr())
}
fn pretend_static<const LEN: usize>(self) -> PretendStaticVec<T, Self, LEN>
where
Self: Clone,
{
dyn_cast_panic!(self.len(), LEN);
PretendStaticVec(Box::new(self), PhantomData)
}
unsafe fn pretend_static_unchecked<const LEN: usize>(self) -> PretendStaticVec<T, Self, LEN>
where
Self: Clone,
{
PretendStaticVec(Box::new(self), PhantomData)
}
fn moo_ref<'a, const LEN: usize>(&'a self) -> StaticVecRef<'a, T, LEN>
where
T: Copy,
{
dyn_cast_panic!(self.len(), LEN);
unsafe { transmute(self.as_ptr()) }
}
fn moo<'a, const LEN: usize>(&'a self) -> StaticCowVec<'a, T, LEN>
where
T: Copy,
{
dyn_cast_panic!(self.len(), LEN);
unsafe { StaticCowVec::from_ptr(self.as_ptr()) }
}
}
pub struct PretendStaticVec<I, T: DynamicVec<I> + ?Sized, const LEN: usize>(Box<T>, PhantomData<I>);
impl<I, T: DynamicVec<I>, const LEN: usize> StaticVec<I, LEN> for PretendStaticVec<I, T, LEN> {
unsafe fn as_ptr(&self) -> *const I {
self.0.as_ptr()
}
}
impl<T> DynamicVec<T> for [T] {
fn len(&self) -> usize {
self.len()
}
unsafe fn as_ptr(&self) -> *const T {
self as *const [T] as *const T
}
}
impl<T> DynamicVec<T> for Vec<T> {
fn len(&self) -> usize {
self.len()
}
unsafe fn as_ptr(&self) -> *const T {
&self[0] as *const T
}
}
impl<T> DynamicVec<T> for Box<[T]> {
fn len(&self) -> usize {
self.as_ref().len()
}
unsafe fn as_ptr(&self) -> *const T {
self as *const Box<[T]> as *const T
}
}