use core::mem::ManuallyDrop;
use crate::utils::variance::PhantomCovariantLifetime;
use crate::allocator::{AllocatorProvider, Global};
use crate::vec::types::EcoVec;
use super::common::limit::LIMIT;
pub(crate) struct DynamicVec<'a, const N: usize = LIMIT, A = Global>(
pub(super) Repr<'a, N, A>,
)
where
A: AllocatorProvider;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct InlineVec<const N: usize = LIMIT, A = Global>
where
A: AllocatorProvider,
{
pub(super) buf: [u8; N],
pub(super) tagged_len: u8,
pub(super) allocator: A,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct Referenced<'a, A = Global>
where
A: AllocatorProvider,
{
pub(super) ptr: *const u8,
pub(super) len: usize,
pub(super) _lifetime: PhantomCovariantLifetime<'a>,
pub(super) allocator: A,
}
unsafe impl<A: AllocatorProvider + Send> Send for Referenced<'_, A> {}
unsafe impl<A: AllocatorProvider + Sync> Sync for Referenced<'_, A> {}
#[repr(C)]
pub(super) union Repr<'a, const N: usize, A>
where
A: AllocatorProvider,
{
pub(super) referenced: ManuallyDrop<Referenced<'a, A>>,
pub(super) inline: ManuallyDrop<InlineVec<N, A>>,
pub(super) spilled: ManuallyDrop<EcoVec<u8, A>>,
}
const _: () = {
use core::mem::size_of;
assert!(
size_of::<InlineVec<LIMIT, Global>>() == size_of::<EcoVec<u8, Global>>(),
"InlineVec and EcoVec<u8> must have the same size for the union to work"
);
assert!(
size_of::<Referenced<'static, Global>>() <= size_of::<InlineVec<LIMIT, Global>>(),
"Referenced must not be larger than InlineVec"
);
assert!(size_of::<[u8; LIMIT]>() == LIMIT, "tagged_len offset must equal LIMIT");
assert!(LIMIT <= 63, "LIMIT must be at most 63 to fit in the 6-bit value field");
assert!(size_of::<Global>() == 0, "Global allocator must be zero-sized");
};
#[derive(Debug)]
pub(super) enum Variant<'a, 'v, const N: usize, A>
where
A: AllocatorProvider,
{
Referenced(&'v Referenced<'a, A>),
Inline(&'v InlineVec<N, A>),
Spilled(&'v EcoVec<u8, A>),
}
#[derive(Debug)]
pub(super) enum VariantMut<'a, 'v, const N: usize, A>
where
A: AllocatorProvider,
{
Referenced(&'v mut Referenced<'a, A>),
Inline(&'v mut InlineVec<N, A>),
Spilled(&'v mut EcoVec<u8, A>),
}