use std::ptr::null_mut;
use crate::{FixedArray, ArrayInitializer, WeakArena};
pub struct UninitArray<T> where T: Sized {
pub (crate) _arena: WeakArena,
pub (crate) _capacity: usize,
pub (crate) _metadata: *mut ArrayMetadata<T>,
}
impl<T> UninitArray<T> where T: Sized {
pub fn len(&self) -> usize {
if self._arena.is_alive() {
unsafe { (*self._metadata)._len }
} else {
0
}
}
pub fn capacity(&self) -> usize {
self._capacity
}
pub unsafe fn data_mut(&mut self) -> *mut T {
(*self._metadata)._data
}
pub unsafe fn initialized_to_len(self, len: usize) -> FixedArray<T> {
if len > self._capacity {
panic!("set_len exceeds capacity");
}
(*self._metadata)._len = len;
FixedArray {
_arena: self._arena,
_metadata: self._metadata,
}
}
pub fn start_initializer(self) -> ArrayInitializer<T> {
ArrayInitializer {
uninit_array: self,
initialized_len: 0,
}
}
}
pub (crate) struct ArrayMetadata<T> {
pub _len: usize,
pub _data: *mut T,
}
pub (crate) fn drop_array<T>(data: *const u8) {
let metadata: &mut ArrayMetadata<T> = unsafe { std::mem::transmute::<*const u8, &mut ArrayMetadata<T>>(data) };
if metadata._data == null_mut() {
return;
}
let len = metadata._len;
metadata._len = 0;
for item_ptr in unsafe { FixedArray::<T>::iter_impl(metadata._data as *const u8, len) } {
let item_ref: &T = unsafe { std::mem::transmute::<*const T, &T>(item_ptr) };
let item: T = unsafe { std::mem::transmute_copy::<T, T>(item_ref) };
drop(item);
}
metadata._data = null_mut();
}